Feature Specification: Advanced Interactive Table Plugin

December 15, 2025 · View on GitHub

Feature Branch: 001-advanced-table
Created: 2025-12-11
Status: Draft
Input: User description: "yasgui plugin, developer guide attached. purpose: display results in a table. have a search function that filters rows and highlights searched text. copy complete table to clipboard as markdown or csv. download table as csv. have control that allows to toggle display of full URI's or abbreviated with prefix. have control that allows to toggle display of datatypes. have control that fits table to data. have control that fits table to window. have control that performs ellipsis on the table content (abbreviating the content and ending with ... when clicking on the cell the full text is shown). infinite vertical scroll. allow horizontal scroll. use full available vertical and horizontal. allow column resizing with guides. row number in first column. cell range selection and copy of selection to clipboard with normal control+c command. not editable. sort rows by clicking on the column header. colors need to respond to yasgui theming"

Clarifications

Session 2025-12-11

  • Q: Search Highlight Color - Should search term highlighting use a hardcoded yellow color or adapt to themes? → A: Use theme-responsive highlight color (via CSS variable) that adapts to light/dark mode
  • Q: Ellipsized Cell Expansion Behavior - Should full content appear in overlay, inline expansion, or side panel? → A: Modal/tooltip overlay that appears above the table (preserves table layout)
  • Q: Theme Change Detection - How should plugin respond to YASGUI theme changes? → A: Use MutationObserver to watch data-theme attribute changes with 500ms polling fallback for dynamic theme adaptation
  • Q: Visual Guides During Column Resize - What type of visual guides should appear (column highlight, vertical line, measurements)? → A: Standard behavior of the library that we are going to use to implement the table
  • Q: Infinite Scroll Implementation Strategy - Should infinite scroll load all rows, use virtual scrolling, or batch loading? → A: Virtual scrolling (windowing) - render only visible rows plus buffer
  • Q: Row Number Column Behavior During Horizontal Scroll - Should row numbers be fixed/sticky, scroll with content, or use floating overlay? → A: Whatever is used by the library that we are going to implement

User Scenarios & Testing (mandatory)

User Story 1 - Basic Table Display with Navigation (Priority: P1) 🎯 MVP

Users can view SPARQL query results in a table format with all columns and rows properly displayed, allowing them to navigate large result sets efficiently.

Why this priority: This is the core functionality of the plugin. Without the ability to display results in a table format with navigation, the plugin has no value.

Independent Test: Can be fully tested by executing a SPARQL query and verifying that results appear in a table with proper column headers, row numbers, infinite vertical scroll, and horizontal scroll when needed. Delivers immediate value for users who need to inspect query results.

Acceptance Scenarios:

  1. Given YASGUI receives SPARQL SELECT results with 5 columns and 100 rows, When the table plugin is selected, Then all columns appear with correct headers matching SPARQL variable names, all 100 rows are accessible via infinite scroll, and row numbers appear in the first column
  2. Given a table is displayed with content wider than viewport, When user scrolls horizontally, Then content scrolls smoothly while row numbers remain visible per the table library's standard column pinning behavior
  3. Given SPARQL results contain URIs, literals, blank nodes, and typed values, When rendered in table, Then each cell displays the appropriate value with correct data type representation
  4. Given a table is displayed, When user scrolls vertically, Then rows render seamlessly using virtual scrolling (only visible rows plus buffer are rendered) without page reload or visible lag

User Story 2 - Column Sorting and Resizing (Priority: P1) 🎯 MVP

Users can sort table data by clicking column headers and adjust column widths to fit their data inspection needs.

Why this priority: Sorting is essential for data analysis and exploration. Column resizing ensures users can view content optimally regardless of data length. Together these make the table immediately useful for real-world data inspection.

Independent Test: Can be fully tested by displaying a result set, clicking on column headers to verify ascending/descending sort, and dragging column borders to verify resizing works with visual guides. Delivers independent value for data analysis.

Acceptance Scenarios:

  1. Given a table with numeric data in a column, When user clicks the column header once, Then rows sort in ascending order, and clicking again sorts in descending order
  2. Given a table with string data, When user clicks column header, Then rows sort alphabetically (case-insensitive)
  3. Given a table is displayed, When user hovers over column border, Then cursor changes to resize indicator and visual guides appear per the table library's standard behavior
  4. Given user drags a column border, When user releases, Then column width adjusts and guides disappear, and all content reflows appropriately

User Story 3 - Search and Filter (Priority: P2)

Users can search for specific text within the table, with matching rows filtered and search terms highlighted in the results.

Why this priority: Search is critical for working with large result sets. It enables users to quickly locate specific data without manual scanning.

Independent Test: Can be fully tested by entering search terms in a search box and verifying that only matching rows appear and search terms are highlighted. Delivers independent value for finding specific data in large result sets.

Acceptance Scenarios:

  1. Given a table with 1000 rows, When user types "example" in search box, Then only rows containing "example" (case-insensitive) are displayed
  2. Given search results are displayed, When user views the filtered rows, Then all instances of the search term are highlighted using theme-responsive styling that maintains WCAG AA contrast in both light and dark modes
  3. Given a search filter is active, When user clears the search box, Then all rows become visible again and highlighting is removed
  4. Given user searches for text that appears in multiple columns, When results are filtered, Then rows where ANY column matches are displayed

User Story 4 - URI and Datatype Display Controls (Priority: P2)

Users can toggle between full URIs and prefixed abbreviations, and show or hide datatype annotations on literal values.

Why this priority: SPARQL results often contain long URIs that make tables difficult to read. Toggling between full and abbreviated forms plus controlling datatype visibility gives users flexibility for different inspection tasks.

Independent Test: Can be fully tested by toggling the URI display control and verifying URIs switch between full form (e.g., http://example.org/resource) and prefixed form (e.g., ex:resource), and toggling datatype control to show/hide annotations like ^^xsd:integer.

Acceptance Scenarios:

  1. Given table contains URIs with known prefixes, When user toggles URI display to "abbreviated", Then URIs are displayed as prefix:localName (e.g., foaf:Person)
  2. Given URI display is set to "abbreviated", When user toggles to "full", Then complete URIs are displayed (e.g., http://xmlns.com/foaf/0.1/Person)
  3. Given table contains typed literals (e.g., "42"^^xsd:integer), When datatype display is enabled, Then datatype annotations are shown after the value
  4. Given datatype display is enabled, When user toggles it off, Then only the literal values are shown without type annotations

User Story 5 - Cell Content Management (Priority: P2)

Users can view full content of cells that contain long text by clicking on ellipsized cells, and they can adjust the table view to fit data or viewport.

Why this priority: Long content (like descriptions or long URIs) can make tables unwieldy. Ellipsis with click-to-expand gives users control over detail level, and fit controls optimize space usage.

Independent Test: Can be fully tested by enabling ellipsis mode, verifying that long content is truncated with "...", clicking cells to see full content, and using fit controls to verify table adjusts to data width or viewport width.

Acceptance Scenarios:

  1. Given ellipsis mode is enabled and a cell contains text longer than column width, When table is rendered, Then cell shows truncated text ending with "..."
  2. Given an ellipsized cell, When user clicks on it, Then full content is displayed in a modal or tooltip overlay that appears above the table without affecting table layout
  3. Given a table is displayed, When user clicks "Fit to Data" control, Then columns resize to show all content without truncation
  4. Given a table is displayed, When user clicks "Fit to Window" control, Then columns resize proportionally to fill the available viewport width

User Story 6 - Selection and Copy (Priority: P2)

Users can select individual cells, ranges of cells, or entire rows, and copy selected data to clipboard in plain text format using standard keyboard shortcuts.

Why this priority: Users frequently need to extract subsets of data for use in other applications. Cell range selection with Ctrl+C support provides familiar, efficient data extraction.

Independent Test: Can be fully tested by clicking cells to select them, dragging to select ranges, pressing Ctrl+C, and verifying clipboard contains the selected data in tab-separated format.

Acceptance Scenarios:

  1. Given a table is displayed, When user clicks a cell, Then cell is highlighted with selection styling
  2. Given a cell is selected, When user holds Shift and clicks another cell, Then all cells in the rectangular range are selected
  3. Given cells are selected, When user presses Ctrl+C, Then selected data is copied to clipboard in tab-separated format (rows separated by newlines, cells by tabs)
  4. Given user wants to select an entire row, When user clicks row number, Then all cells in that row are selected

User Story 7 - Export Functionality (Priority: P3)

Users can export the complete table (or filtered results) to clipboard as Markdown, CSV, or TSV (tab-delimited) formats, and download results as CSV file through YASR's download interface.

Why this priority: While cell selection handles small data extraction, full table export is valuable for documentation (Markdown) and data analysis in external tools (CSV/TSV). Lower priority than core viewing and interaction features.

Independent Test: Can be fully tested by clicking export controls and verifying that clipboard receives properly formatted Markdown, CSV, or TSV, and that CSV download through YASR produces a valid file.

Acceptance Scenarios:

  1. Given a table with data is displayed, When user clicks "Copy as Markdown", Then clipboard contains properly formatted Markdown table with headers and alignment, and visual notification confirms success
  2. Given a table with data is displayed, When user clicks "Copy as CSV", Then clipboard contains CSV format with headers and quoted fields where necessary, and visual notification confirms success
  3. Given a table with data is displayed, When user clicks "Copy as TSV", Then clipboard contains tab-delimited format with headers, and visual notification confirms success
  4. Given a table is displayed, When user uses YASR's download interface, Then browser downloads a .csv file with all visible data (respecting active filters)
  5. Given a search filter is active showing 50 of 500 rows, When user exports or downloads, Then only the 50 filtered rows are included

Edge Cases

  • What happens when a SPARQL result contains no rows (empty result set)?
  • What happens when a result contains 100,000+ rows?
  • How does the system handle cells with extremely long content (10,000+ characters)?
  • What happens when SPARQL variable names contain special characters or are very long?
  • How does sorting handle null/undefined values or blank nodes?
  • What happens when a URI cannot be abbreviated because its namespace is not in the prefix list?
  • How does the search function handle special regex characters entered by user?
  • What happens when user attempts to resize column to zero width or negative width?
  • How does cell selection behave when user scrolls during a drag selection?
  • What happens when user attempts to copy >100MB of data to clipboard?

Requirements (mandatory)

Functional Requirements

Core Display

  • FR-001: Plugin MUST render SPARQL SELECT query results as a table with columns and rows
  • FR-002: Plugin MUST display SPARQL variable names as column headers
  • FR-003: Plugin MUST display a row number column as the first column, starting from 1, using the table library's standard column behavior for visibility during horizontal scroll
  • FR-004: Plugin MUST support infinite vertical scrolling using virtual scrolling (windowing) technique that renders only visible rows plus buffer to efficiently navigate through large result sets
  • FR-005: Plugin MUST support horizontal scrolling when table width exceeds viewport width
  • FR-006: Plugin MUST utilize full available vertical and horizontal space in the YASR container
  • FR-007: Plugin MUST NOT allow editing of cell content (read-only)

Cell Content Display

  • FR-008: Plugin MUST correctly render URIs, literals, blank nodes, and typed literals
  • FR-009: Plugin MUST provide a toggle control to switch between full URIs and prefixed abbreviations
  • FR-010: Plugin MUST provide a toggle control to show or hide datatype annotations on literals
  • FR-011: Plugin MUST provide an ellipsis mode control that truncates cell content with "..." when enabled
  • FR-012: Plugin MUST display full cell content in a modal or tooltip overlay when user clicks on an ellipsized cell, preserving table layout
  • FR-012a: Plugin MUST display full cell content as tooltip when user hovers over any cell

Sorting

  • FR-013: Plugin MUST allow users to sort rows by clicking on column headers
  • FR-014: Plugin MUST support ascending and descending sort orders (toggle on repeated clicks)
  • FR-015: Plugin MUST handle sorting of different data types (strings, numbers, URIs, blank nodes)

Column Sizing

  • FR-016: Plugin MUST allow users to resize columns by dragging column borders
  • FR-017: Plugin MUST display visual guides during column resize operations using the standard behavior provided by the chosen table library
  • FR-018: Plugin MUST provide a "Fit to Data" control that sizes columns to their content
  • FR-019: Plugin MUST provide a "Fit to Window" control that sizes columns to fill viewport width

Search and Filter

  • FR-020: Plugin MUST provide a search input that filters rows based on cell content
  • FR-021: Plugin MUST perform case-insensitive search across all columns
  • FR-022: Plugin MUST highlight search term occurrences in filtered results using theme-responsive styling via CSS variables
  • FR-023: Plugin MUST update row count display to show filtered vs total rows

Selection and Copy

  • FR-024: Plugin MUST allow users to select individual cells by clicking
  • FR-025: Plugin MUST allow users to select cell ranges by dragging or Shift+Click
  • FR-026: Plugin MUST allow users to select entire rows by clicking row numbers
  • FR-027: Plugin MUST support copying selected data to clipboard via Ctrl+C (Cmd+C on Mac)
  • FR-028: Plugin MUST format copied data as tab-separated values (rows separated by newlines)

Export and Download

  • FR-029: Plugin MUST provide a control to copy entire table to clipboard as Markdown format with visual notification
  • FR-030: Plugin MUST provide a control to copy entire table to clipboard as CSV format with visual notification
  • FR-030a: Plugin MUST provide a control to copy entire table to clipboard as TSV (tab-delimited) format with visual notification
  • FR-031: Plugin MUST integrate with YASR's download interface to provide CSV download capability
  • FR-032: Plugin MUST respect active search filters when exporting or downloading

Theming

  • FR-033: Plugin MUST respond to YASGUI theme changes (light/dark mode) dynamically using MutationObserver with polling fallback
  • FR-034: Plugin MUST use YASGUI CSS variables for colors, borders, and backgrounds
  • FR-035: Plugin MUST ensure text contrast meets WCAG AA standards in both themes

Plugin Integration

  • FR-036: Plugin MUST implement YASGUI plugin interface (canHandleResults, draw, getIcon, etc.)
  • FR-037: Plugin MUST only activate for SPARQL SELECT query results (not CONSTRUCT, ASK, etc.)
  • FR-038: Plugin MUST handle plugin initialization, rendering, and cleanup lifecycle events
  • FR-039: Plugin MUST persist user preferences (column widths, sort state, display options) to localStorage

Key Entities

  • SPARQL Result Binding: Represents a single variable binding from SPARQL results, containing value and type (uri, literal, bnode) and optional datatype/language
  • Table Column: Represents a column in the table, containing header name, width, sort state, and visibility settings
  • Table Row: Represents a row of data, containing bindings for each variable plus row number and selection state
  • Display Configuration: Represents user preferences including URI display mode (full/abbreviated), datatype visibility, ellipsis mode, column widths, and sort settings
  • Selection Range: Represents selected cells, containing start cell coordinates, end cell coordinates, and selected data

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: Users can view SPARQL result sets with 10,000+ rows without UI freezing or lag exceeding 2 seconds for initial render
  • SC-002: Users can locate specific data in large result sets using search in under 5 seconds (for typical result sets under 50,000 rows)
  • SC-003: Users can copy selected data to clipboard and paste into Excel, Google Sheets, or text editors with correct formatting 100% of the time
  • SC-004: Users can export tables as CSV files that open correctly in Excel and other CSV-compatible applications without encoding or format errors
  • SC-005: Users can complete common tasks (view results, sort by column, search, copy data) using only keyboard navigation for accessibility
  • SC-006: Plugin renders correctly in latest two major versions of Chrome, Firefox, Safari, and Edge without visual glitches or functionality issues
  • SC-007: Table text remains readable with sufficient contrast in both light and dark themes (WCAG AA compliance: 4.5:1 for normal text, 3:1 for large text)
  • SC-008: Column resizing operations complete within 100ms with smooth visual feedback
  • SC-009: Search and filter operations return results within 500ms for result sets under 10,000 rows
  • SC-010: 95% of users can successfully complete primary tasks (view, search, export) on first attempt without consulting documentation

Assumptions

  1. SPARQL results are provided in standard YASGUI result format (JSON bindings)
  2. Browser supports modern JavaScript features (ES2018) and CSS features required by YASGUI
  3. Users have basic familiarity with SPARQL query results and table interfaces
  4. Prefix definitions are fetched from YASR's getPrefixes() method and merged with common prefixes for URI abbreviation
  5. LocalStorage is available for persisting user preferences
  6. Clipboard API is available for copy operations (with execCommand fallback for older browsers)
  7. Result sets are finite (not streaming) and fit in browser memory
  8. The plugin is used within YASGUI/YASR environment with standard plugin lifecycle
  9. Build system uses esbuild for UMD and ESM module generation