Giter VIP home page Giter VIP logo

segmented-control's Introduction

.

npm version

<SegmentedControl> – a good-lookin' segmented control React component

<SegmentedControlWithoutStyles> - a version that doesn't import the stylesheet (if <SegmentedControl> doesn't work in your build systemβ€”eg Next.js)

<FormsySegmentedControl> – a version for Formsy

UX background

In iOS, a segmented control is usually used to display different views (the equivalent of tabs in material design). However, segmented controls are increasingly being used in lieu of plain radio buttons or select inputs (dropdowns, or material menus). See for instance the designer lukew's recommendations:

Other good choices are radio groups, like this Ionic component, or a button list, as used in the Yo or Thumbtack apps, that looks the same, except on click, instead of seeing a checkmark, you're taken to the next screen.

A similar component in material design is the toggle button.

Component

Demo: lorensr.me/segmented-control

two three disabled formsy

Usage

npm install --save segmented-control

Plain

<SegmentedControl> props:

  • className: PropTypes.string: optional custom className for the container in addition to the default segmented-control class.
  • name: PropTypes.string.isRequired: name of the radio <input>s. Also the attribute included in the first argument of Formsy's onSubmit.
  • options: PropTypes.array.isRequired: Maximum length 10, each element an object of the form:
    • label: display text
    • value: value passed to setValue and Formsy's onSubmit
    • default: true: one object must have this
    • disabled: true: optional
  • style: PropTypes.object: common styles are width and color
  • setValue: PropTypes.func: callback on input change, passed the value string. Called once initially with the default value on mount.
import { SegmentedControl } from 'segmented-control'

<SegmentedControl
  name="oneDisabled"
  options={[
    { label: "One", value: "one", disabled: true },
    { label: "Two", value: "two" },
    { label: "Three", value: "three", default: true },
    { label: "Four", value: "four" }
  ]}
  setValue={newValue => this.doSomething(newValue)}
  style={{ width: 400, color: '#ab47bc' }} // purple400
  />

Without styles

As above, but with a different import statement:

import SegmentedControlWithoutStyles from 'segmented-control/SegmentedControlWithoutStyles'

Formsy

<FormsySegmentedControl> has the same props, but includes Formsy.Mixin and calls Formsy's setValue, so that the value is included in onSubmit (see the event triggered by submitting the demo form). In the example below, the first arg of onSubmit would be {exampleInput: 'two'}:

import Formsy from 'formsy-react'
import Button from '@material-ui/core/Button'
import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider'
import { FormsySegmentedControl } from 'segmented-control'

<MuiThemeProvider>
  <Formsy.Form
    onValidSubmit={this.onSubmit}
    >
    <FormsySegmentedControl
      name="exampleInput"
      options={[
        { label: "One", value: "one" },
        { label: "Two", value: "two", default: true },
        { label: "Three", value: "three" }
      ]}
      style={{ width: 300, color: 'rgb(0, 188, 212)' }} // match default material-ui primary teal
      />
    <Button
      variant="contained"
      type="submit"
      label="submit formsy form"
      style={{
        display: 'block',
        width: 200,
        margin: "20px auto"
      }}
      primary
    >
      Submit
    </Button>
  </Formsy.Form>
</MuiThemeProvider>

Development

git clone [email protected]:lorensr/segmented-control.git
npm install
npm start

http://localhost:9009

Credits

segmented-control's People

Contributors

dependabot[bot] avatar kevin-kientopp avatar loan-laux avatar loanlaux avatar lorensr avatar polarisation avatar structbylightning avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

segmented-control's Issues

Next.js error: Global CSS cannot be imported from within node_modules.

I am using Next.js 10.2.0 and when I use SegmentedControlWithoutStyles this error appears

error - ./node_modules/segmented-control/dist/SegmentedControl.css
Global CSS cannot be imported from within node_modules.
Read more: https://nextjs.org/docs/messages/css-npm
Location: node_modules/segmented-control/dist/SegmentedControl.js

Support React 17

I need segmented-control to work with a React 17 project of mine.

I tried updating the dependencies myself but hit a roadblock as formsy-react still requires React 16, partly because airbnb-prop-types still requires React 16.

Filing this issue to track the progress of formsy-react's support for React 17. Once this is done, I'll submit a PR if I have time to finalize the work I've done.

Warning: componentWillMount has been renamed, and is not recommended for use.

Warning: componentWillMount has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details.

  • Move code with side effects to componentDidMount, and set initial state in the constructor.
  • Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run npx react-codemod rename-unsafe-lifecycles in your project source folder.

Please update the following components: SegmentedControlWithoutStyles

https://github.com/lorensr/segmented-control/blob/master/src/SegmentedControlWithoutStyles.js#L15

Production build is broken

In my last PR, I updated Babel but forgot to update the prepublish.sh script. This causes JavaScript files not to be compiled, leaving you with only the stylesheet in the dist directory.

onChange event only triggers one time

Something changed and onChange event only triggers on the first click of a segment. This worked until I update cordova and had npm update all of my modules (many, and I don't know which one triggered the problem). I suspect it's React, see facebook/react#8727

REPRO:
environment:
react: [email protected]

(!542)-> node --version
v6.9.1

(!543)-> npm --version
4.0.2

(!544)-> cordova --version
7.0.1

(!545)-> cordova platforms ls
Installed platforms:
android 6.1.2
ios 4.1.1

make a two segment control
click one segment, onChange fires
click the other segment

EXPECTED:

onChange fires

ACTUAL:

it doesn't

NOTES:

I put in a pull request (and have closed it) that changes the key to use the generated ID, that worked "sometimes" but not always.

EDIT: moving the setValue prop's callback to the label (as onClick) seems to work in my instance. YMMV!

{this.props.options.map(option => ( <label key={option.value} onClick={() => this.setValue(option.value)} htmlFor={getId(option)} data-value={option.label} > {option.label} </label> ))}

Optional animation

Would love to have options for animation, and if elected, passing the speed as a prop.

Clicking near the top of the control switches selected value without triggering setValue.

Clicking on the border or slightly above the border of the first segment button causes the visible selected value to switch, but setValue is never called.

Here is a screenshot example.

click

In this image, there are two segments and the second segment is selected. If the user clicks at the location where the cursor is, the animation will play and the first segment will become visibly selected, however, the setValue handler will never be called properly.

Upgrading from 0.1.12 to 0.1.14

Hi there, we are using this module in our project, it was working fine until this morning with that error during the ReactJS project build :
Cannot find module: 'segmented-control'. Make sure this package is installed.
You can install this package by running: npm install segmented-control.

The version looked Deprecated, so we decided to upgrade to 0.1.14.

The install looks fine but the error still the same during the build :
Cannot find module: 'segmented-control'. Make sure this package is installed.
You can install this package by running: npm install segmented-control.

We use it in 1 page only with this import :
import { SegmentedControl } from 'segmented-control'

Did you hear about this ?

I am suspecting the recent upgrade : https://www.npmjs.com/package/segmented-control/v/0.1.14

Regards,

Pierrot

Not specifying a default option shouldn't cause an exception

If none of the options has default: true specified, an exception is thrown in componentWillMount(), since the default option is undefined. The docs do say it's required, but I'd expect default to just default to the first item when it isn't specified.

[Bug] Value should be able to be set by keyboard

Describe the bug
Similar to how standard radio inputs should behave, a user should be able to set the value with their keyboard arrow keys.

To Reproduce
Steps to reproduce the behavior:

  1. Click on an option.
  2. Press the arrow keys on your keyboard to change the selection.
  3. Notice that although the option appears to be changed, the setValue action is not invoked.

Expected behavior
When you change options by the keyboard arrow keys, the setValue action should be called.

Versions (please complete the following information where relevant):

  • segmented-control v0.2.0

Additional context

  • Issue appears to be happening because the setValue function is only assigned to the label's onClick. It should instead be assigned to the input's onChange. This will allow the user to set the value with either their mouse or keyboard. It should not be assigned to the label's onClick or setValue will be invoked twice.
  • Strangely, the arrow keys do work on the demo. Curious what version is deployed there, because it does not appear to be v0.2.0.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.