Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Implement OnyxDataGridRenderer support component #1851

Closed
16 tasks done
JoCa96 opened this issue Sep 11, 2024 · 2 comments
Closed
16 tasks done

Implement OnyxDataGridRenderer support component #1851

JoCa96 opened this issue Sep 11, 2024 · 2 comments
Assignees
Labels
dev Requires technical expertise
Milestone

Comments

@JoCa96
Copy link
Collaborator

JoCa96 commented Sep 11, 2024

Why?

According to our #1660 we want to abstract the rendering of the OnyxDataGrid. We implement this TableRenderLayer via the OnyxDataGridRenderer support component.

It encompasses a minimal API that renders an HTML compliant table with only permitted content elements:

Permitted content

In this order:

  • an optional element,
  • zero or more elements,
  • an optional element,
  • either one of the following:
    • zero or more elements
    • one or more elements
  • an optional element

The TableRenderLayer must be stateless.
Its main purpose is to create an HTML compliant table structure.
The table should be rendered according to the following rules:

  • columns describes the horizontal layout of the table, every entry MUST result in a column and <th>element
  • rows describe the vertical layout of the table, every entry MUST result in a row and a <tr> element
  • so there should not be any "unused" entries in either column or row
  • extensions should only follow table concepts that are supported/specified by the HTML spec
  • the entry keys of a row must match the specified columns or colgroups
  • the content of the table data cells (<td>...</td>) in a row can be any content

Design

Figma

Acceptance criteria

  • The OnyxDataGridRenderer is implemented:
    • Does not have internal state
    • Renders and supports only compliant HTML
    • Uses and offers BEM classes
    • Is styled according to the Figma design
  • [Can render:
    • table header
    • table rows
    • combined rows
    • column categories

Definition of Done

  • The following component requirements are implemented:
    • density
  • covered by tests
    • functional tests (Playwright or unit test)
    • visual tests (Playwright screenshots)
  • follow-up tickets were created if necessary
  • updated version + documentation is deployed
  • Storybook can show the feature
  • Namings are aligned with Figma

Approval

Implementation details

The following is the code used by the PoC of #1660.
@JoCa96 - I would consider making the id key dynamic. Column and row grouping, as well as styling was not yet considered.

import type { FunctionalComponent, HTMLAttributes, TdHTMLAttributes } from "vue";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
type AnyKey = keyof any;

export type TableEntry = {
  id: string | number;
  [key: AnyKey]: unknown;
};

export type Metadata = Record<string, unknown>;

export type CellRenderFunc<
  TEntry extends TableEntry,
  TMetadata extends Metadata,
> = FunctionalComponent<RenderCellProps<TEntry, TMetadata>>;

/**
 * Props of the TableRenderLayer
 */
export type RendererProps<TEntry extends TableEntry, TMetadata extends Metadata> = {
  theadProps?: HTMLAttributes;
  tbodyProps?: HTMLAttributes;
  columns: RenderHeader<TEntry>[];
  rows: RenderRow<TEntry, TMetadata>[];
};

export type RenderHeader<
  TEntry extends TableEntry,
  TKey extends keyof TEntry = keyof TEntry,
  TProps extends object = object,
> = {
  /**
   * Key of the column - usually a key of the tabledata.
   * But can also be used for custom columns.
   */
  key: TKey;
  /**
   * Attributes and data that is provided to the component using `v-bind`.
   */
  headerProps: HTMLAttributes & TProps;
  /**
   * The component that renders the header content.
   */
  header: FunctionalComponent<TProps>;
};

export type RenderRow<TEntry extends TableEntry, TMetadata extends Metadata> = {
  /**
   * Unique id of the row.
   */
  id: TableEntry["id"];
  trProps?: HTMLAttributes;
  cells: Record<keyof TEntry, RenderCell<TEntry, TMetadata> | undefined>;
};

export type RenderCell<TEntry extends TableEntry, TMetadata extends Metadata> = {
  props: RenderCellProps<TEntry, TMetadata>;
  tdProps?: TdHTMLAttributes;
  /**
   * The component that renders the actual cell content.
   */
  is: CellRenderFunc<TEntry, TMetadata>;
};

export type RenderCellProps<TEntry extends TableEntry, TMetadata extends Metadata> = {
  /**
   * Complete row data
   */
  row: TEntry;
  /**
   * Data that is provided to the component via the `metadata` prop
   */
  metadata?: TMetadata;
  /**
   * table data that is provided to the component via the `modelValue` prop
   */
  modelValue: TEntry[keyof TEntry];
};

Basic structure:

<template>
  <table>
    <thead v-bind="props.theadProps">
      <tr>
        <th v-for="col in props.columns" :key="col.key">
          <component :is="col.header" v-bind="col.headerProps" />
        </th>
      </tr>
    </thead>
    <tbody v-bind="props.tbodyProps">
      <tr v-for="row in props.rows" :key="row.id" v-bind="row.trProps">
        <td v-for="col in props.columns" :key="col.key" v-bind="row.cells[col.key].tdProps">
          <component :is="row.cells[col.key].is" v-bind="row.cells[col.key].props" />
        </td>
      </tr>
    </tbody>
  </table>
</template>

Applicable ARIA Pattern

@JoCa96 JoCa96 added this to the Tables milestone Sep 11, 2024
@JoCa96 JoCa96 self-assigned this Sep 11, 2024
@JoCa96 JoCa96 added dev Requires technical expertise 0-refinement All issues that can or need to be estimated in our next refinement labels Sep 11, 2024
@mj-hof mj-hof removed the 0-refinement All issues that can or need to be estimated in our next refinement label Sep 11, 2024
@larsrickert larsrickert self-assigned this Sep 13, 2024
@larsrickert
Copy link
Collaborator

@JoCa96 Vacation handover:

larsrickert added a commit that referenced this issue Oct 1, 2024
Relates to #1851

Implement basic `OnyxDataGridRenderer` component

---------

Co-authored-by: Maja Zarkova <maja.zarkova@mail.schwarz>
Co-authored-by: Jonathan Carle <jonathan_leo.carle@mail.schwarz>
@jannick-ux
Copy link
Contributor

@larsrickert please set "striped" and "vertical border" to true as default for the data grid. Rest looks amazing :D

larsrickert added a commit that referenced this issue Oct 8, 2024
…y default (#1905)

Relates to
#1851 (comment)

As requested from Jannick, changed the default value for the striped and
withVerticalBorders property to `true`.
JoCa96 pushed a commit that referenced this issue Oct 9, 2024
Relates to #1851

Implement Playwright screenshot tests for the OnyxDataGridRenderer.

## Checklist

- [x] If a new component is added, at least one [Playwright screenshot
test](https://github.com/SchwarzIT/onyx/actions/workflows/playwright-screenshots.yml)
is added

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
dev Requires technical expertise
Projects
Status: Done
Development

No branches or pull requests

4 participants