question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add VisualPicker component

See original GitHub issue

The Lightning Reports team would like to implement the <VisualPicker/> component. We will consume it as part of a new feature in 220.

For reference, the Visual Picker spec is here: https://latest-220.lightningdesignsystem.com/components/visual-picker/

Here are the props proposition:

static propTypes = {
    /**
     * **Assistive text for accessibility**
     * This object is merged with the default props object on every render.
     * * `label`: This is used as a visually hidden label if, no `labels.label` is provided.
     * * `icon`: Text for checkmark icon on selected item(s).
     * * `selectedItemLabel`: This is used as a visually hidden label of selected item(s). The default is `Current Selection:`.
    */
    assistiveText: PropTypes.shape({
        label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
        icon: PropTypes.string,
        selectedItemLabel: PropTypes.string
    }),
    /**
     * CSS classes to be added to tag with `.slds-visual-picker`.
     */
    className: PropTypes.oneOfType([
        PropTypes.array,
        PropTypes.object,
        PropTypes.string,
    ]),
    /**
     * CSS classes to be added to tag with `.slds-visual-picker__body`.
     */
    classNameBody: PropTypes.oneOfType([
        PropTypes.array,
        PropTypes.object,
        PropTypes.string,
    ]),
    /**
     * CSS classes to be added to top level tag with `.slds-form-element`.
     */
    classNameContainer: PropTypes.oneOfType([
        PropTypes.array,
        PropTypes.object,
        PropTypes.string,
    ]),
    /**
     * Event Callbacks
     * * `onBlur`: Called when `input` removes focus.
     * * `onFocus`: Called when `input` receives focus.
     * * `onRequestRemoveSelectedOption`: Function called when selected option is to be removed.
     * * `onSelect`: Function called when item is selected.
     */
    events: PropTypes.shape({
        onBlur: PropTypes.func,
        onFocus: PropTypes.func,
        onRequestRemoveSelectedOption: PropTypes.func,
        onSelect: PropTypes.func,
    }),
    /**
     * HTML id for component.
     */
    id: PropTypes.string,
    /**
     * **Text labels for internationalization**
     * This object is merged with the default props object on every render.
     * * `label`: This label appears above the component.
     */
    labels: PropTypes.shape({
        label: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
    }),
    /**
     * **Array of item objects**
     * Each object can contain:
     * * `id`: A unique identifier string.
     * * `label`: A primary string of text for the heading of an item.
     * * `title`: A secondary string of text that renders as a sibling the `label` element.
     * * `visualIndicator`: A node displaying a visual indicator for the item. Not available with `variant=vertical`.
     *
     */
    options: PropTypes.arrayOf(
        PropTypes.PropTypes.shape({
            id: PropTypes.string.isRequired,
            label: PropTypes.string,
            title: PropTypes.string,
            visualIndicator: PropTypes.nodes
        })
    ).isRequired
    /**
     * Adds required (*) styling to label.
     */
    required: PropTypes.bool,
    /**
     * Selected item object.
     * * `id`: A unique identifier string.
     * * `label`: A primary string of text for the heading of an item.
     * * `title`: A secondary string of text that renders as a sibling the `label` element.
     * * `visualIndicator`: A node displaying a visual indicator for the item. Not available with `variant=vertical`.
     */
    selection: PropTypes.shape({
        id: PropTypes.string.isRequired,
        label: PropTypes.string,
        title: PropTypes.string,
        visualIndicator: PropTypes.nodes
    }),
    /**
     * The type of visual picker. The default is `coverableContent`.
     */
     variant: PropTypes.oneOf(['coverableContent', 'link', 'nonCoverableContent', 'vertical']).isRequired,
};

static defaultProps = {
    selectedItemLabel: 'Current Selection:'
    variant: 'coverableContent'
};

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
interactivellamacommented, Dec 26, 2018

Spec needs to allow

  • inputs can be disabled
  • Expose all radio and checkbox props
  • Coverable Content Variant
    • icon
    • title / body
    • size medium (default), large
  • Link Variant
    • icon
    • body
      • title
      • meta/subtext
  • Non-Coverable Content Variant
    • title
    • meta/subtext
    • Custom content thing !!!
    • size medium (default), large
  • Vertical Variant
    • heading
    • meta/subtext

Each of the variants take different data which makes me think that an options array of objects may not be the best implementation.

This is a form element at it’s core, so we will need access to

name
value
checked
onChange
disabled
aria-* attributes

to name a few things that come to mind.

Internal Architecture

I’d like to reuse radio and checkbox with a visual-picker variant that creates the div wrapper and with a custom render prop called renderLabel: Proptype.node that allows a custom rendering of label from VisualPicker. The primary reason is that folks will need access to all radio/checkbox props, especially folks like the Trailhead app that submit actual HTML forms to a server.

Core DOM chucks of Visual Picker

<div class="slds-visual-picker slds-visual-picker_medium">
    <input type="radio" id="visual-picker-197" name="options" value="visual-picker-197" />
    <label for="visual-picker-197">{customLabel}</label>
</div>

The layouts provided by the SLDS site seem really specific to their implementations, especially the non-coverable one, “$150 USD/user/month*”.

This makes me lean toward custom children. Something like:

<VisualPicker inputType="radio|checkbox" name="things" size="medium" />
    <NonCoverable
        title="Lightning Professional"
        description="Complete service CRM for teams of any size"
        content={
            <span class="slds-text-heading_large">$30</span>
            <span class="slds-text-title">USD/user/month *</span>
          }
        /* takes all radio & checkbox props */  />
    <NonCoverable />
    ....
</VisualPicker>

<NonCoverable>, <Coverable>, Link, and Vertical becomes a child component that takes it’s own unique props. If this component was limited to one of these variants and took the same information, an options array would be the best way to go.

What do you think?

0reactions
aswinshenoycommented, Mar 4, 2019

@tanhengyeow sure 👍

Read more comments on GitHub >

github_iconTop Results From Across the Web

Visual Picker - Lightning Design System
A visual picker can be either radio buttons, checkboxes, or links that are visually enhanced. Add the following object(s).
Read more >
Visual Picker in Lightning Web Component Salesforce ️ ️
In this video you will learn how to create Visual Picker in Lightning Web Component. We will use the Lightning Design System to...
Read more >
Visual Picker in Lightning Web Component Salesforce ☁️⚡️
In this video you will learn how to create Visual Picker in Lightning Web Component. We will use the Lightning Design System to...
Read more >
LWC Visual Pickers - sfdcbox.com
Single select picker works with input type radio and multi select with input type checkbox.
Read more >
Make visual picker an aura/lightning component - IdeaExchange
I'm working on adding visual pickers to the quickChoice component on unofficialsf.com. Expand Post. Liked Like
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found