diff --git a/packages/sage-react/lib/Table/Table.jsx b/packages/sage-react/lib/Table/Table.jsx index 7884a58558..9292f6447d 100644 --- a/packages/sage-react/lib/Table/Table.jsx +++ b/packages/sage-react/lib/Table/Table.jsx @@ -353,12 +353,32 @@ Table.defaultProps = { }; Table.propTypes = { + /** + * Sets the caption for the component. + */ caption: PropTypes.string, + + /** Sets the caption position for the component. */ captionSide: PropTypes.oneOf(Object.values(Table.CAPTION_SIDE)), + + /** The CSS class that will be applied to the container. */ className: PropTypes.string, + + /** When set to `true`, adds borders for cleaner readability. */ hasBorders: PropTypes.bool, + + /** Deprecated */ hasDataBeyondCurrentRows: PropTypes.bool, - // Headers provide a simpler alternative to schema + + /** + * An array of strings that will serve as the headers for the table. + * Headers provide a simpler alternative to schema. + * + * The number of items in the array need to coincide with the number of keys in your data. + * + * When combined with the Schema property, the headers can + * be an object and will match based on Key names. + */ headers: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.oneOfType([ PropTypes.shape(cellPropTypes), @@ -366,24 +386,50 @@ Table.propTypes = { ])), PropTypes.shape({}), ]), + + /** + * When set to true, allows the table to scroll horizontally without + * breaking its parent container. + */ isResponsive: PropTypes.bool, + + /** + * Allows a function to be passed, which will be executed when a row is + * selected. + */ onSelectRowHook: PropTypes.func, + + /** Resets the top margin of the component. */ resetAbove: PropTypes.bool, + + /** Resets the bottom margin of the component. */ resetBelow: PropTypes.bool, + + /** Array of items to populate the table. These items are key/value pairs. */ rows: PropTypes.arrayOf(PropTypes.oneOfType([ PropTypes.shape(cellPropTypes), PropTypes.arrayOf(dataPropTypes), PropTypes.shape({}), ])), - // Schema provides a structure for applying settings to headers and cells + + /** + * Provides a structure for applying the column order, and may specify the data types + * to the headers and cells. + */ schema: PropTypes.shape({}), + + /** Adds a background color when a user hovers over rows. */ selectable: PropTypes.bool, + + /** Additional information for Select all column. */ selectAllConfigs: PropTypes.shape({ id: PropTypes.string.isRequired, name: PropTypes.string.isRequired, label: PropTypes.string.isRequired, onChange: PropTypes.func, }), + + /** An array of the selected rows when `selectable` set to `true` */ selectedRows: PropTypes.oneOfType([ PropTypes.oneOf([SELECTION_TYPES.ALL]), PropTypes.arrayOf(PropTypes.oneOfType([ @@ -392,6 +438,10 @@ Table.propTypes = { PropTypes.string, ])), ]), + + /** When true, shows the checkbox in the header row. */ showSelectAll: PropTypes.bool, + + /** Allows you to provide additional HTML attributes. */ tableAttributes: PropTypes.shape({}), }; diff --git a/packages/sage-react/lib/Table/Table.story.jsx b/packages/sage-react/lib/Table/Table.story.jsx deleted file mode 100644 index befe35def6..0000000000 --- a/packages/sage-react/lib/Table/Table.story.jsx +++ /dev/null @@ -1,112 +0,0 @@ -import React from 'react'; -import { Panel } from '../Panel'; -import { Table } from './Table'; -import { dataCollection } from './sample-data/contacts'; -import { domains } from './sample-data/domains'; -import { selectArgs } from '../story-support/helpers'; -import { SageClassnames } from '../configs'; - -export default { - title: 'Sage/Table', - component: Table, - // displays description on Docs tab - parameters: { - docs: { - description: { - component: 'Basic table component.' - }, - }, - }, - argTypes: { - ...selectArgs({ - captionSide: Table.CAPTION_SIDE - }) - }, - args: { - headers: { - first: { - label: 'Header override' - } - }, - hasDataBeyondCurrentRows: false, - rows: dataCollection, - schema: { - id: false, - first: { - label: 'First name', - }, - email: false, - phone: { - label: 'Phone' - } - }, - showSelectAll: true, - selectAllConfigs: { - id: 'select-all', - name: 'select-all', - label: 'Select all items', - }, - // onSelectRowHook: (data) => { - // // Work with returned data set as needed. - // console.log(data); - // } - } -}; -const Template = (args) => ; - -export const Default = Template.bind({}); -Default.decorators = [ - (Story) => ( - <> - - {Story()} - -
-

NOTE: Wiring the select all checkbox requires the following:

- -
- - ) -]; - -export const TableWithRichContent = Template.bind({}); -TableWithRichContent.args = { - rows: domains, - schema: { - domain: { - label: 'Domain', - dataType: Table.DATA_TYPES.STRING, - }, - status: { - label: 'Status', - dataType: Table.DATA_TYPES.LABEL, - }, - options: { - label: '', - dataType: Table.DATA_TYPES.HTML, - }, - } -}; - -TableWithRichContent.decorators = [ - (Story) => ( - <> - - {Story()} - - - ) -]; diff --git a/packages/sage-react/lib/Table/Table.story.mdx b/packages/sage-react/lib/Table/Table.story.mdx new file mode 100644 index 0000000000..a5e90dcce3 --- /dev/null +++ b/packages/sage-react/lib/Table/Table.story.mdx @@ -0,0 +1,362 @@ +import { ArgsTable, Canvas, Meta, Source, Story } from '@storybook/addon-docs'; +import { selectArgs } from '../story-support/helpers'; + +import { dataCollection } from './sample-data/contacts'; +import { domains } from './sample-data/domains'; + +import { Table } from './Table'; + + + +# Table +Tables are a fundamental tool in web development and design, serving as a structured way to present tabular data. + +## Usage Guidelines + +### When to use +- Data that needs to be rendered in tabular format. +- Need to provide sorting, filtering, and/or pagination. + +### When not to use +- If your data does NOT need to be rendered with data columns. + +## Accessibility +Table component is built accessibly with native HTML in mind. + +## Properties + + + +## Variants +### Default + +export const DefaultTemplate = (args) =>
; + + +`}> + + { DefaultTemplate.bind({}) } + + + +### With Headers + + +`}> + + { DefaultTemplate.bind({}) } + + + +### Headers and Schemas +Should you provide both properties `headers` and `schemas` there are few things you will need to take into +consideration. + +1. `headers` can be passed an object. +2. The keys in `headers` should align with the key names in the `schema` +3. The headers will override the label specified in `schema`. + +Here is a table outlining the properties: + +|Property Name|Description| +|-----|-------| +|attributes|Additional HTML attributes you want to add.| +|className|The CSS Classname to be applied to the Table Header.| +|dataType|The Sage DataType for the Table Header.| +|label|The text content of the Table Header.| +|style|Additional styles to be applied.| + +Given the header and schema information, let's look at some examples. + +#### Header override + + + { DefaultTemplate.bind({}) } + + + +#### Schema Order +The order of the Schema determines the placement of the columns. + +With the given schema below, the order of the columns will be `Email, First, Phone`. `ID` will be ignored +since it is set to `false`. + + + +Data used can be in any order as the schema will determine the order. + + + +`}> + + { DefaultTemplate.bind({}) } + + + + +### With Rich Content +With the schema set and DataType specified to HTML, it will render the markup in the column. + + console.log('do something!')} + icon={SageTokens.ICONS.PEN} + iconOnly={true} + > + Edit + + ), + }, + { + domain: 'courses.daydreamsurfshop.com', + status: { + value: { + value: 'Connected', + color: Label.COLORS.SUCCESS, + }, + }, + options: ( + + ), + }, + ]} + schema={{ + domain: { + label: 'Domain', + dataType: Table.DATA_TYPES.STRING, + }, + status: { + label: 'Status', + dataType: Table.DATA_TYPES.LABEL, + }, + options: { + label: '', + dataType: Table.DATA_TYPES.HTML, + }, + } + }} /> +`}> + + { DefaultTemplate.bind({}) } + + + diff --git a/packages/sage-react/lib/Table/TableHeader.jsx b/packages/sage-react/lib/Table/TableHeader.jsx index 743c461ed5..b92f809a31 100644 --- a/packages/sage-react/lib/Table/TableHeader.jsx +++ b/packages/sage-react/lib/Table/TableHeader.jsx @@ -3,7 +3,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { parseCellData } from './helpers'; -import { cellPropTypes } from './configs'; +import { dataPropTypes } from './configs'; export const TableHeader = ({ attributes, @@ -40,6 +40,21 @@ TableHeader.defaultProps = { }; TableHeader.propTypes = { - ...cellPropTypes, + /** Allows you to provide additional HTML attributes. */ + attributes: PropTypes.shape({}), + children: PropTypes.node, + + /** The CSS class name for the Table Header. */ + className: PropTypes.string, + + /** The data type for the Table Header. */ + dataType: PropTypes.string, + + /** Additional styles to be applied. */ + style: PropTypes.shape({}), + + /** The content of the Header. */ + value: dataPropTypes, + }; diff --git a/packages/sage-react/lib/Table/TableRow.jsx b/packages/sage-react/lib/Table/TableRow.jsx index d27401fe47..ece694d29a 100644 --- a/packages/sage-react/lib/Table/TableRow.jsx +++ b/packages/sage-react/lib/Table/TableRow.jsx @@ -126,16 +126,36 @@ TableRow.defaultProps = { schema: {} }; TableRow.propTypes = { + /** The CSS class name for the table row. */ className: PropTypes.string, + + /** A collection of column data. */ cells: PropTypes.arrayOf(PropTypes.shape(cellPropTypes)), + + /** When true, the row will have borders. */ hasBorders: PropTypes.bool, + + /** The id of the row. */ id: PropTypes.oneOfType([ PropTypes.number, PropTypes.string, ]).isRequired, + + /** A function that will execute when row is selected. */ onSelect: PropTypes.func, + + /** When true, the row will be selectable. */ selectable: PropTypes.bool, + + /** When true, indicates that the row is selected. */ selected: PropTypes.bool, + + /** + * Provides a structure for applying the column order, and may specify the data types + * to the headers and cells. + */ schema: PropTypes.shape({}), + + /** The data types that could be renedered in a Table Cell. */ typeRenderers: PropTypes.shape({}), }; diff --git a/packages/sage-react/lib/Table/helpers.js b/packages/sage-react/lib/Table/helpers.js index 0f6c9f1256..322a8f354d 100644 --- a/packages/sage-react/lib/Table/helpers.js +++ b/packages/sage-react/lib/Table/helpers.js @@ -72,9 +72,11 @@ export const parseRowData = (row, schema) => { return parseCellData(cell, field); }); } else if (row instanceof Object) { - // An object for the row must be parse by the keys in contains - // and such an object will assume the keys are field names - parsedRow = Object.keys(row).map((field) => parseCellData(row[field], field)); + if (schema !== null && Object.keys(schema).length > 0) { + parsedRow = Object.keys(schema).map((field) => parseCellData(row[field], field)); + } else { + parsedRow = Object.keys(row).map((field) => parseCellData(row[field], field)); + } } return parsedRow;