UNPKG

@discoveryjs/discovery

Version:

Frontend framework for rapid data (JSON) analysis, shareable serverless reports and dashboards

241 lines (239 loc) 12.7 kB
const defaultDemoData = [ { name: 'Alice', age: 34, occupation: 'Engineer' }, { name: 'Bob', age: 42, occupation: 'Doctor' }, { name: 'Charlie', age: 9, occupation: 'Student' }, { name: 'David', age: 50, occupation: 'Doctor' }, { name: 'Eve', age: 15, occupation: 'Engineer' } ]; export default { beforeDemo: ['md:"A view to display tabular data, usually an array of objects. When no column setup is provided, it infers columns from all keys of objects in the input data and auto-detects sorting for scalar values."'], demo: { view: 'table' }, demoData: [ { foo: 1, bar: 'bar', baz: 'zab' }, { foo: 2, baz: 'xyz' }, { foo: 3, bar: 'qux', baz: 'baz' }, { foo: 4, bar: 'aaa', baz: 'abc' } ], examples: [ { title: 'Columns setup', beforeDemo: { view: 'md', source: [ 'To set up columns, the `cols` property is used. When an array of objects is used for `cols`, it specifies the exact set of columns. Each object contains a configuration for the `table-cell` view with additional properties that apply at the table level:\n', '- `header` – a text for the column header\n', '- `footer` – a config for the footer cell\n', '- `headerClassName` - specifies className for a header cell, works as `className` for any view (i.e. can be a string, an array, a function, etc.)\n', '- `sorting` – a sorting function or query for the column\n' ] }, highlightProps: ['cols', 'header', 'footer', 'headerClassName', 'sorting'], demo: { view: 'table', cols: [ { header: 'Name', sorting: 'name asc', data: 'name', footer: 'text:"Total:"' }, { header: 'Age', headerClassName: 'age', className: 'number', content: 'text:age + " y.o."', footer: { data: 'size()' } } ] }, demoData: defaultDemoData }, { title: 'Adjastments of infered columns', beforeDemo: { view: 'md', source: [ 'In cases where adjustments are needed for inferred columns, an object can be used for the `cols` option, where each key is the name of a property from the objects:', '- If a key is missing from the inferred columns, a new column is added with the specified configuration.', '- If a key matches one of the inferred columns:', ' - If the specified configuration is falsy (i.e., `null`, `undefined`, or `false`), then the column is omitted.', ' - Otherwise, options from the specified configuration override properties of the inferred configuration.', '', '> When specified configuration is a string, it expands into object `{ content: value }`.', 'The default inferred configuration:', '```js', '{', ' header: key,', ' sorting: `$[${JSON.stringify(key)}] ascN`,', ' view: "table-cell",', ' data: value => value?.[key]', '}', '```' ].join('\n') }, afterDemo: [ 'struct:#.id.pageLink(#.page, #.params)' ], highlightProps: ['cols'], demo: { view: 'table', cols: { age: 'text:age + " y.o."', occupation: false, extraColumn: { header: 'Extra column', content: 'text:age >= 21 ? "Adult" : "Child"' } } }, demoData: defaultDemoData }, { title: 'Sorting', beforeDemo: { view: 'md', source: [ 'To specify a sorting function, use the `sorting` property in the column options. When a value for `sorting` is set, the column becomes sortable, allowing users to toggle sorting by clicking the column header. The value can be a function `(a, b) => number` or a string representing a jora query that returns a [comparator function](https://discoveryjs.github.io/jora/#article:jora-syntax-functions&!anchor=comparator-functions) (e.g., "name asc, complex.expression desc"), otherwise the value ignores. The function should take two rows\' data (`a` and `b`) and return a negative number if `a` is less than `b`, a positive number if `a` is greater than `b`, or zero otherwise.', '', '> The `table` view automatically displays a sorting direction indicator (icon) on a column when a comparator function returns `<= 0` or `>= 0` for each pair of consecutive rows.', '', '> Note: A sorting (comparator) function has no access to the table\'s context, so any attempt to access context (`#`) values within a comparator function produced by a query will return `undefined`.', '', 'The `table` view attempts to infer a sorting function for a column when the `sorting` option is not explicitly specified, by executing the following steps:', '- Use `data` if it is a string or function to extract column values from row data; otherwise, use the row\'s data.', '- If `content` is a string formatted as `"view-name:query"`, use the `query` to extract a value from the previous step.', ' > To prevent sorting inference from the `content` value, specify content in another format, often by wrapping it in an array, e.g., `{ content: "text:name" }` → `{ content: ["text:name"] }`.', '- If any condition is met, construct a sorting (comparator) function.', ' > If neither `data` nor `content` options meet the conditions, a sorting function cannot be inferred, and the column becomes non-sortable.', '', '> Note: When inferring a comparator function, the when, whenData, and contentWhen options are not considered for now. If these options are needed to affect sorting, an explicit sorting function should be specified.' ].join('\n') }, highlightProps: ['sorting', 'data', 'content'], demo: { view: 'table', cols: [ { header: 'Sorting from data', data: 'name' }, { header: 'Sorting from content', content: 'text:age' }, { header: 'Sorting from data&content', data: '{ name, age }', content: 'text:`${age} ${name}`' }, { header: 'Explicit sorting', sorting: 'name asc, age desc', content: ['text:`${name} ${age}`'] } ] }, demoData: defaultDemoData }, { title: 'Displaying non-object values', beforeDemo: ['md:"When input data (an array) contains non-object values, such values are display using `struct` view in a single cell spanning all the columns"'], highlightProps: ['data', 'valueCol'], demo: [ 'h3:"Table with non-object values"', { view: 'table', data: [ 123, 'string', null, { foo: 1, bar: 2 }, [1, 2, 3] ] }, 'h3:"Enforce displaying of a [value] column"', { view: 'table', valueCol: true } ], demoData: defaultDemoData }, { title: 'Setup cell display', beforeDemo: { view: 'md', source: [ 'To manage cell display, the following options are available in the `cols` setting:', '- `colWhen` (similar to `when` and `whenData` options) allows disabling column rendering based on the table\'s data.', '- `when` and `whenData` apply to `table-cell` and behave the same way as they do for any view, to disabling rendering of the cell itself.', '- `contentWhen` (similar to `when` and `whenData` options) allows disabling cell content rendering based on the cell\'s data.', '- `colSpan` allows setting a relevant attribute for a table cell. (Note: subsequent cells should be disabled using `when` or `whenData`).' ].join('\n') }, highlightProps: ['contentWhen', 'colWhen', 'colSpan', 'when'], demo: { view: 'table', data: '.({ name, age, fare: age > 21 ? "Full" : age > 12 ? "Half" })', cols: { name: { contentWhen: '$ != "Bob"' }, age: { colWhen: 'size() > 10' }, fare: { colSpan: '=fare ? 1 : 2', content: { data: 'fare', view: 'switch', content: [ { when: '$', content: 'text' }, { content: 'text:"Not applicable"' } ] } }, price: { when: 'fare', data: 'fare = "Full" ? 50 : 25', content: 'text:"$" + $' } } }, demoData: defaultDemoData }, { title: 'Cell details', beforeDemo: { view: 'md', source: [ 'Table cells can display an additional detail view of their content when clicked. Clicking the same cell again, or a different cell with details, will hide the view. To enable and customize the detail view, use the `details` option.', '', 'By default, if the `details` option is not explicitly defined, it will automatically activate for cells containing an object or a non-empty array, as long as no custom `content` is specified. In this case, a default `struct` view will be used to display the data.', '', 'You can control the visibility of detail views using the `detailsWhen` option. This option accepts a function that checks the cell\'s data and disables the details view if the function returns a falsy value.' ] }, highlightProps: ['details', 'detailsWhen'], demo: { view: 'table', cols: [ { header: 'Group', data: 'group' }, { header: 'Default', data: 'peoples' }, { header: 'Custom details', data: 'peoples', details: ['h2:"Custom detail views"', 'table'] }, { header: 'Disable default details', data: 'peoples', details: false }, { header: 'Conditional details', data: 'peoples', detailsWhen: 'size() > 2' } ] }, demoData: [ { group: 'Kids', max: 21 }, { group: 'Adults', min: 21 }, { group: 'All' } ].map(({ group, min = 0, max = 100 }) => ({ group, peoples: defaultDemoData.filter(item => item.age > min && item.age < max) })) }, { title: 'Setup footer cell display', beforeDemo: { view: 'md', source: [ 'A setup for footer cell is similar to a [regular cell](#!setup-cell-display), the same set of options are supported, except `colWhen`.', '', 'When value for the `footer` is an object without a `view` property, it\'s interpreted as a footer config. Otherwise, it is treated as footer cell content, equivalent to passing `{ content: value }`.' ] }, highlightProps: ['footer'], demoData: defaultDemoData, demo: { view: 'table', cols: { name: { footer: 'text:"Raw data"' }, age: { footer: { colSpan: 2 } } } } } ] };