From c70ad1ec5f3cee5c614e30b835ce37fc93ae0237 Mon Sep 17 00:00:00 2001 From: workaholicpanda <802931+workaholicpanda@users.noreply.github.com> Date: Sat, 18 Sep 2021 14:27:34 -0400 Subject: [PATCH 1/9] internal PR for squashing (#7) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update Checklist, Dropdown, RangeSlider to accept optional shorthands * update Checklist, RadioItems - added inline props and shorthand options data, update DataTable - params order changed for shorthand support, added TODO * fill component id if not given * fix Dropdown props to accept array of string * remove comments * fix lint issues * generating seed for component id * lint fix in dash-table * lint fix * remove inline props and lint fix * broken eslint :grimacing: * prettier fix * set random id inside dash dependency * lint fixes * bug fix * add inline styling support * fix bugs * add column populating in dash-table * disable restricting dependency type * fix radio options type check * add comments to inline props * add tests for shorthands * remove unused imports * remove tests, refactor assign * use ramda.type instead of typeof * backup commit * add auto generating marks to RangeSlider & Slider * add number support for shorthanded options - Checklist, Dropdown * some refactor to get react-docgen working, slider props re-arrange * fix unit test - remove outdated part * update props comment Co-authored-by: Chris Parmer * fix feedback comments * fix some issues in Checklist, DataTable props * pylint fix * Apply suggestions from code review Co-authored-by: Chris Parmer * copy paste ProTypes to get doc-gen working * Test Slider and RangeSlider shorthand properties * Test Dropdown shorthand properties * Remove unnecessary imports * random seed moved out to global scope, the test for set_random_id was implemented * fix slider markers - respect steps given * assert comparision is fixed * fix slider issues * Add dropdown option sanitization to some additional required places * Convert labels to strings when an Ojbect is passed as options * Add more variants to Dropdown shorthand test * Extend Slider tests * Add test for Dropdown array value type * fix: update inline description & style * chore: pass black format * chore: react doc-gen fix & flake fix * chore: rename test file names to avoid conflict * Handle undefined options in Dropdown * fix: the case when truncated out input marks handled * fix: correct step calculations implemented for sliders * fix: removed Start and End prefix / suffix from labels on Slider * chore: add labels to dropdown tests * chore: lint fix * fix: dropdown options for test * chore: prettier :sleepy: * bump dash-renderer to v1.11.0 This new version is not important for most dash users, only dash-embedded, and they get the renderer elsewhere; but as is there's a mismatch between the local and CDN versions of the renderer * fix: removed a test file which was causing percy tests fail * fix: defining emptiness of dictionary implemented correctly, which fixes the disappearing of explicitely given marks * fix: omit 'step' from props * chore: update props description * chore: remove unnecessary prop type checker * fix: range slider test corrected, formatted to have some margins * fix: the test_ddsh001_dropdown_shorthand_properties test restored back and the DropDowns propTypes are fixed * fix: added bool type to CheckList label/value and RadioItem label/value * fix: the edited JS files are reformatted using lint * feat: implemented SI Units format for unit values of slider * feat: added tests to cover slider SI Units format for unit values * chore: eslint fix * fix: the test adopted to propsTypes which now accepts bool for several components * fix: slider numbers whose ten factor is less than 3 and bigger than -3 are not formatted, so that they can have floating numebrs * fix: lint issue fixed * fix: explicit null prevents auto generating marks in sliders * fix: add snapshot for set_auto_id dependency link and asserts * fix: test marks=None and SI units format * fix: test_persistence - give step=1 to expect integer value output, otherwise 0.1 will be auto assigned * fix: checking RadioItems and Checklist to accept new propTypes added in tests Co-authored-by: workaholicpanda <> Co-authored-by: Chris Parmer Co-authored-by: Szabolcs Markó Co-authored-by: alexcjohnson --- .../dash-core-components/package-lock.json | 1 + .../src/components/Checklist.react.js | 170 +++++++++++------ .../src/components/Dropdown.react.js | 105 ++++++---- .../src/components/RadioItems.react.js | 112 ++++++++--- .../src/components/RangeSlider.react.js | 30 +-- .../src/components/Slider.react.js | 30 +-- .../src/components/css/Dropdown.css | 2 +- .../src/fragments/Dropdown.react.js | 15 +- .../src/fragments/RangeSlider.react.js | 25 +-- .../src/fragments/Slider.react.js | 18 +- .../src/utils/computeSliderMarkers.js | 164 ++++++++++++++++ .../src/utils/optionTypes.js | 25 +++ ...ropdown_radioitems_checklist_shorthands.py | 82 ++++++++ .../dropdown/test_dynamic_options.py | 25 ++- .../integration/misc/test_bcdp_auto_id.py | 46 +++++ .../integration/misc/test_persistence.py | 4 +- .../sliders/test_sliders_shorthands.py | 180 ++++++++++++++++++ .../dash-html-components/package-lock.json | 1 + components/dash-table/package-lock.json | 1 + .../src/dash-table/components/Table/props.ts | 20 ++ .../src/dash-table/dash/DataTable.js | 52 ++--- .../src/dash-table/dash/Sanitizer.ts | 16 +- dash/_dash_renderer.py | 4 +- dash/dash-renderer/package-lock.json | 5 +- dash/dash-renderer/package.json | 2 +- dash/dependencies.py | 8 +- dash/development/base_component.py | 10 + dash/development/component_generator.py | 1 + .../integration/devtools/test_props_check.py | 12 +- tests/unit/development/test_base_component.py | 37 +++- 30 files changed, 981 insertions(+), 222 deletions(-) create mode 100644 components/dash-core-components/src/utils/computeSliderMarkers.js create mode 100644 components/dash-core-components/src/utils/optionTypes.js create mode 100644 components/dash-core-components/tests/integration/dropdown/test_dropdown_radioitems_checklist_shorthands.py create mode 100644 components/dash-core-components/tests/integration/misc/test_bcdp_auto_id.py create mode 100644 components/dash-core-components/tests/integration/sliders/test_sliders_shorthands.py diff --git a/components/dash-core-components/package-lock.json b/components/dash-core-components/package-lock.json index 24f0f878f0..6f0df2e9b3 100644 --- a/components/dash-core-components/package-lock.json +++ b/components/dash-core-components/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "dash-core-components", "version": "2.0.0", "license": "MIT", "dependencies": { diff --git a/components/dash-core-components/src/components/Checklist.react.js b/components/dash-core-components/src/components/Checklist.react.js index 22f3d68af5..fc9a207982 100644 --- a/components/dash-core-components/src/components/Checklist.react.js +++ b/components/dash-core-components/src/components/Checklist.react.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import {append, includes, without} from 'ramda'; import React, {Component} from 'react'; +import {sanitizeOptions} from '../utils/optionTypes'; /** * Checklist is a component that encapsulates several checkboxes. @@ -22,8 +23,8 @@ export default class Checklist extends Component { style, loading_state, value, + inline, } = this.props; - return (
- {options.map(option => ( - - ))} + {sanitizeOptions(options).map(option => { + return ( + + ); + })}
); } } Checklist.propTypes = { - /** - * The ID of this component, used to identify dash components - * in callbacks. The ID needs to be unique across all of the - * components in an app. - */ - id: PropTypes.string, - /** * An array of options */ - options: PropTypes.arrayOf( - PropTypes.exact({ - /** - * The checkbox's label - */ - label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) - .isRequired, - - /** - * The value of the checkbox. This value - * corresponds to the items specified in the - * `value` property. - */ - value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) - .isRequired, - - /** - * If true, this checkbox is disabled and can't be clicked on. - */ - disabled: PropTypes.bool, - }) - ), + options: PropTypes.oneOfType([ + /** + * Array of options where the label and the value are the same thing - [string|number|bool] + */ + PropTypes.arrayOf( + PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.bool, + ]) + ), + /** + * Simpler `options` representation in dictionary format. The order is not guaranteed. + * {`value1`: `label1`, `value2`: `label2`, ... } + * which is equal to + * [{label: `label1`, value: `value1`}, {label: `label2`, value: `value2`}, ...] + */ + PropTypes.object, + /** + * An array of options {label: [string|number], value: [string|number]}, + * an optional disabled field can be used for each option + */ + PropTypes.arrayOf( + PropTypes.exact({ + /** + * The option's label + */ + label: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.bool, + ]).isRequired, + + /** + * The value of the option. This value + * corresponds to the items specified in the + * `value` property. + */ + value: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.bool, + ]).isRequired, + + /** + * If true, this option is disabled and cannot be selected. + */ + disabled: PropTypes.bool, + + /** + * The HTML 'title' attribute for the option. Allows for + * information on hover. For more information on this attribute, + * see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title + */ + title: PropTypes.string, + }) + ), + ]), /** * The currently selected value */ value: PropTypes.arrayOf( - PropTypes.oneOfType([PropTypes.string, PropTypes.number]) + PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.bool, + ]) ), + /** + * The ID of this component, used to identify dash components + * in callbacks. The ID needs to be unique across all of the + * components in an app. + */ + id: PropTypes.string, + /** * The class of the container (div) */ @@ -187,6 +237,13 @@ Checklist.propTypes = { * session: window.sessionStorage, data is cleared once the browser quit. */ persistence_type: PropTypes.oneOf(['local', 'session', 'memory']), + + /** + * Indicates whether labelStyle should be inline or not + * True: Automatically set { 'display': 'inline-block' } to labelStyle + * False: No additional styles are passed into labelStyle. + */ + inline: PropTypes.bool, }; Checklist.defaultProps = { @@ -198,4 +255,5 @@ Checklist.defaultProps = { value: [], persisted_props: ['value'], persistence_type: 'local', + inline: false, }; diff --git a/components/dash-core-components/src/components/Dropdown.react.js b/components/dash-core-components/src/components/Dropdown.react.js index 604cebfe7c..f329443b8d 100644 --- a/components/dash-core-components/src/components/Dropdown.react.js +++ b/components/dash-core-components/src/components/Dropdown.react.js @@ -25,46 +25,65 @@ export default class Dropdown extends Component { } Dropdown.propTypes = { - /** - * The ID of this component, used to identify dash components - * in callbacks. The ID needs to be unique across all of the - * components in an app. - */ - id: PropTypes.string, - /** * An array of options {label: [string|number], value: [string|number]}, * an optional disabled field can be used for each option */ - options: PropTypes.arrayOf( - PropTypes.exact({ - /** - * The dropdown's label - */ - label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) - .isRequired, - - /** - * The value of the dropdown. This value - * corresponds to the items specified in the - * `value` property. - */ - value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) - .isRequired, - - /** - * If true, this option is disabled and cannot be selected. - */ - disabled: PropTypes.bool, - - /** - * The HTML 'title' attribute for the option. Allows for - * information on hover. For more information on this attribute, - * see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title - */ - title: PropTypes.string, - }) - ), + options: PropTypes.oneOfType([ + /** + * Array of options where the label and the value are the same thing - [string|number|bool] + */ + PropTypes.arrayOf( + PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.bool, + ]) + ), + /** + * Simpler `options` representation in dictionary format. The order is not guaranteed. + * {`value1`: `label1`, `value2`: `label2`, ... } + * which is equal to + * [{label: `label1`, value: `value1`}, {label: `label2`, value: `value2`}, ...] + */ + PropTypes.object, + /** + * An array of options {label: [string|number], value: [string|number]}, + * an optional disabled field can be used for each option + */ + PropTypes.arrayOf( + PropTypes.exact({ + /** + * The option's label + */ + label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) + .isRequired, + + /** + * The value of the option. This value + * corresponds to the items specified in the + * `value` property. + */ + value: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.bool, + ]).isRequired, + + /** + * If true, this option is disabled and cannot be selected. + */ + disabled: PropTypes.bool, + + /** + * The HTML 'title' attribute for the option. Allows for + * information on hover. For more information on this attribute, + * see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title + */ + title: PropTypes.string, + }) + ), + ]), /** * The value of the input. If `multi` is false (the default) @@ -77,11 +96,23 @@ Dropdown.propTypes = { value: PropTypes.oneOfType([ PropTypes.string, PropTypes.number, + PropTypes.bool, PropTypes.arrayOf( - PropTypes.oneOfType([PropTypes.string, PropTypes.number]) + PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.bool, + ]) ), ]), + /** + * The ID of this component, used to identify dash components + * in callbacks. The ID needs to be unique across all of the + * components in an app. + */ + id: PropTypes.string, + /** * height of each option. Can be increased when label lengths would wrap around */ diff --git a/components/dash-core-components/src/components/RadioItems.react.js b/components/dash-core-components/src/components/RadioItems.react.js index 8c2ef151b1..fe6d8e42c1 100644 --- a/components/dash-core-components/src/components/RadioItems.react.js +++ b/components/dash-core-components/src/components/RadioItems.react.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import React, {Component} from 'react'; import './css/react-select@1.0.0-rc.3.min.css'; +import {sanitizeOptions} from '../utils/optionTypes'; /** * RadioItems is a component that encapsulates several radio item inputs. @@ -23,6 +24,7 @@ export default class RadioItems extends Component { setProps, loading_state, value, + inline, } = this.props; let ids = {}; @@ -38,9 +40,13 @@ export default class RadioItems extends Component { className={className} style={style} > - {options.map(option => ( + {sanitizeOptions(options).map(option => (