├── .babelrc ├── .gitignore ├── .storybook ├── addons.js └── config.js ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── scripts └── prepublish.sh ├── src ├── FormsySegmentedControl.js ├── SegmentedControl.css ├── SegmentedControl.js ├── SegmentedControlWithoutStyles.js ├── index.js └── stories │ └── index.js └── storybook-static ├── favicon.ico ├── iframe.html ├── index.html └── static ├── manager.b0555856446f50d36ba7.bundle.js └── preview.a17f4ba072e45092cfbf.bundle.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ], 6 | "plugins": [ 7 | "@babel/plugin-syntax-dynamic-import", 8 | "@babel/plugin-syntax-import-meta", 9 | "@babel/plugin-proposal-class-properties", 10 | "@babel/plugin-proposal-json-strings", 11 | [ 12 | "@babel/plugin-proposal-decorators", 13 | { 14 | "legacy": true 15 | } 16 | ], 17 | "@babel/plugin-proposal-function-sent", 18 | "@babel/plugin-proposal-export-namespace-from", 19 | "@babel/plugin-proposal-numeric-separator", 20 | "@babel/plugin-proposal-throw-expressions", 21 | "@babel/plugin-proposal-export-default-from", 22 | "@babel/plugin-proposal-logical-assignment-operators", 23 | "@babel/plugin-proposal-optional-chaining", 24 | [ 25 | "@babel/plugin-proposal-pipeline-operator", 26 | { 27 | "proposal": "minimal" 28 | } 29 | ], 30 | "@babel/plugin-proposal-nullish-coalescing-operator", 31 | "@babel/plugin-proposal-do-expressions", 32 | "@babel/plugin-proposal-function-bind" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # production 7 | build 8 | dist 9 | 10 | # misc 11 | .DS_Store 12 | npm-debug.log 13 | -------------------------------------------------------------------------------- /.storybook/addons.js: -------------------------------------------------------------------------------- 1 | import '@storybook/addon-actions/register'; 2 | import '@storybook/addon-links/register'; 3 | -------------------------------------------------------------------------------- /.storybook/config.js: -------------------------------------------------------------------------------- 1 | import { configure } from '@storybook/react'; 2 | 3 | function loadStories() { 4 | require('../src/stories'); 5 | } 6 | 7 | configure(loadStories, module); 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 by Loren Sands-Ramshaw 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | 9 | 10 | 11 | For src/SegmentedControl.css: 12 | 13 | Copyright (c) 2016 by François St-Germain (http://codepen.io/fstgerm/pen/Jafyj) 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | . 3 | 4 | [![npm version](https://badge.fury.io/js/segmented-control.svg)](https://badge.fury.io/js/segmented-control) 5 | 6 | `` – a good-lookin' segmented control React component 7 | 8 | `` - a version that doesn't import [the stylesheet](https://github.com/lorensr/segmented-control/blob/master/src/SegmentedControl.css) (if `` doesn't work in your build system—eg Next.js) 9 | 10 | `` – a version for [Formsy](https://github.com/christianalfoni/formsy-react) 11 | 12 | 13 | 14 | 15 | - [UX background](#ux-background) 16 | - [Component](#component) 17 | - [Usage](#usage) 18 | - [Plain](#plain) 19 | - [Without styles](#without-styles) 20 | - [Formsy](#formsy) 21 | - [Development](#development) 22 | - [Credits](#credits) 23 | 24 | 25 | 26 | ## UX background 27 | 28 | In iOS, a segmented control is usually used to [display different views](https://developer.apple.com/ios/human-interface-guidelines/ui-controls/segmented-controls/) (the equivalent of [tabs](https://material.google.com/components/tabs.html) in material design). However, segmented controls are increasingly being used in lieu of [plain radio buttons](https://material.google.com/components/selection-controls.html#selection-controls-radio-button) or select inputs (dropdowns, or material [menus](https://material.google.com/components/menus.html)). See for instance the designer [lukew](http://www.twitter.com/lukew)'s recommendations: 29 | 30 | - [Dropdowns should be the UI of Last Resort](http://www.lukew.com/ff/entry.asp?1950) 31 | - [Obvious Always Wins](http://www.lukew.com/ff/entry.asp?1945) 32 | - [Video: Using Radio Groups for Input](http://www.lukew.com/ff/entry.asp?1890) 33 | 34 | Other good choices are radio groups, like [this Ionic component](http://ionicframework.com/docs/v2/components/#radio), 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. 35 | 36 | A similar component in material design is the [toggle button](https://material.google.com/components/buttons.html#buttons-toggle-buttons). 37 | 38 | ## Component 39 | 40 | **Demo:** [lorensr.me/segmented-control](http://lorensr.me/segmented-control/) 41 | 42 | [![two](https://www.dropbox.com/s/ryzcbps1vuo04ad/Screenshot%202016-08-09%2023.38.02.png?raw=1)](http://lorensr.me/segmented-control/?selectedKind=SegmentedControl&selectedStory=Two%20options&full=0&down=1&left=1&panelRight=0) 43 | [![three](https://www.dropbox.com/s/z2j729rl7ul8bma/Screenshot%202016-08-09%2023.38.32.png?raw=1)](http://lorensr.me/segmented-control/?selectedKind=SegmentedControl&selectedStory=Three%20options&full=0&down=1&left=1&panelRight=0) 44 | [![disabled](https://www.dropbox.com/s/n0qn7vysoo6b98g/Screenshot%202016-08-09%2023.38.39.png?raw=1)](http://lorensr.me/segmented-control/?selectedKind=SegmentedControl&selectedStory=One%20disabled&full=0&down=1&left=1&panelRight=0) 45 | [![formsy](https://www.dropbox.com/s/yh5nksg7ndu3nio/Screenshot%202016-08-09%2023.38.46.png?raw=1)](http://lorensr.me/segmented-control/?selectedKind=FormsySegmentedControl&selectedStory=Three%20options&full=0&down=1&left=1&panelRight=0) 46 | 47 | ## Usage 48 | 49 | ```sh 50 | npm install --save segmented-control 51 | ``` 52 | 53 | ### Plain 54 | 55 | `` props: 56 | 57 | - `className: PropTypes.string`: optional custom `className` for the container in addition to the default `segmented-control` class. 58 | - `name: PropTypes.string.isRequired`: name of the radio ``s. Also the attribute included in the first argument of Formsy's `onSubmit`. 59 | - `options: PropTypes.array.isRequired`: Maximum length 10, each element an object of the form: 60 | - `label`: display text 61 | - `value`: value passed to `setValue` and Formsy's `onSubmit` 62 | - `default: true`: one object must have this 63 | - `disabled: true`: optional 64 | - `style: PropTypes.object`: common styles are width and color 65 | - `setValue: PropTypes.func`: callback on input change, passed the value string. Called once initially with the default value on mount. 66 | 67 | ```jsx 68 | import { SegmentedControl } from 'segmented-control' 69 | 70 | this.doSomething(newValue)} 79 | style={{ width: 400, color: '#ab47bc' }} // purple400 80 | /> 81 | ``` 82 | 83 | ### Without styles 84 | 85 | As above, but with a different import statement: 86 | 87 | ```js 88 | import SegmentedControlWithoutStyles from 'segmented-control/SegmentedControlWithoutStyles' 89 | ``` 90 | 91 | ### Formsy 92 | 93 | `` 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](http://lorensr.me/segmented-control/?selectedKind=FormsySegmentedControl&selectedStory=Three%20options&full=0&down=1&left=1&panelRight=0)). In the example below, the first arg of `onSubmit` would be `{exampleInput: 'two'}`: 94 | 95 | ```jsx 96 | import Formsy from 'formsy-react' 97 | import Button from '@material-ui/core/Button' 98 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider' 99 | import { FormsySegmentedControl } from 'segmented-control' 100 | 101 | 102 | 105 | 114 | 127 | 128 | 129 | ``` 130 | 131 | ## Development 132 | 133 | ```sh 134 | git clone git@github.com:lorensr/segmented-control.git 135 | npm install 136 | npm start 137 | ``` 138 | 139 | [http://localhost:9009](http://localhost:9009) 140 | 141 | 142 | ### Credits 143 | 144 | - Contributions by [these fine folks](https://github.com/lorensr/segmented-control/graphs/contributors) 145 | - CSS from [@fstgerm](https://github.com/fstgerm): http://code.fstgerm.com/pure-css-segmented-controls/ 146 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "segmented-control", 3 | "version": "0.2.1", 4 | "description": "💅 A good-lookin' segmented control React component", 5 | "homepage": "https://github.com/lorensr/segmented-control", 6 | "scripts": { 7 | "start": "start-storybook -p 9009", 8 | "build-storybook": "build-storybook", 9 | "deploy-storybook": "storybook-to-ghpages", 10 | "prepublishOnly": "sh scripts/prepublish.sh", 11 | "postversion": "git push && git push --follow-tags", 12 | "release": "release patch && echo 'now run npm publish'" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/lorensr/segmented-control/issues" 16 | }, 17 | "license": "MIT", 18 | "main": "dist/index.js", 19 | "exports": { 20 | ".": "./dist/index.js", 21 | "./SegmentedControlWithoutStyles": "./dist/SegmentedControlWithoutStyles.js", 22 | "./SegmentedControl": "./dist/SegmentedControl.js", 23 | "./FormsySegmentedControl": "./dist/FormsySegmentedControl.js" 24 | }, 25 | "files": [ 26 | "dist" 27 | ], 28 | "keywords": [ 29 | "react", 30 | "reactjs", 31 | "react-component", 32 | "segmented-control", 33 | "forms", 34 | "input", 35 | "select", 36 | "radio", 37 | "formsy", 38 | "formsy-react", 39 | "formsy-component" 40 | ], 41 | "repository": { 42 | "type": "git", 43 | "url": "https://github.com/lorensr/segmented-control.git" 44 | }, 45 | "devDependencies": { 46 | "@babel/cli": "^7.12.7", 47 | "@babel/core": "^7.12.7", 48 | "@babel/plugin-proposal-class-properties": "^7.0.0", 49 | "@babel/plugin-proposal-decorators": "^7.0.0", 50 | "@babel/plugin-proposal-do-expressions": "^7.0.0", 51 | "@babel/plugin-proposal-export-default-from": "^7.0.0", 52 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 53 | "@babel/plugin-proposal-function-bind": "^7.0.0", 54 | "@babel/plugin-proposal-function-sent": "^7.0.0", 55 | "@babel/plugin-proposal-json-strings": "^7.0.0", 56 | "@babel/plugin-proposal-logical-assignment-operators": "^7.0.0", 57 | "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", 58 | "@babel/plugin-proposal-numeric-separator": "^7.0.0", 59 | "@babel/plugin-proposal-optional-chaining": "^7.0.0", 60 | "@babel/plugin-proposal-pipeline-operator": "^7.0.0", 61 | "@babel/plugin-proposal-throw-expressions": "^7.0.0", 62 | "@babel/plugin-syntax-dynamic-import": "^7.0.0", 63 | "@babel/plugin-syntax-import-meta": "^7.0.0", 64 | "@babel/plugin-transform-runtime": "^7.12.10", 65 | "@babel/preset-env": "^7.12.7", 66 | "@babel/preset-react": "^7.12.7", 67 | "@babel/runtime": "^7.12.5", 68 | "@emotion/react": "^11.10.5", 69 | "@material-ui/core": "^5.0.0-beta.5", 70 | "@storybook/addon-actions": "^6.1.14", 71 | "@storybook/addon-centered": "^5.3.21", 72 | "@storybook/addon-links": "^6.1.14", 73 | "@storybook/addons": "^6.1.14", 74 | "@storybook/react": "^6.1.14", 75 | "babel-core": "^7.0.0-bridge.0", 76 | "babel-eslint": "^10.1.0", 77 | "react": "^17.0.0", 78 | "react-dom": "^17.0.0", 79 | "react-lumberjack": "^2.0.0", 80 | "react-scripts": "^4.0.1", 81 | "release": "^6.3.1" 82 | }, 83 | "dependencies": { 84 | "create-react-class": "^15.7.0", 85 | "formsy-react": "^2.3.0", 86 | "lodash": "^4.14.1", 87 | "prop-types": "^15.7.2" 88 | }, 89 | "peerDependencies": { 90 | "react": "^17.0.1", 91 | "react-dom": "^17.0.0" 92 | }, 93 | "eslintConfig": { 94 | "extends": "./node_modules/react-scripts/config/eslint.js" 95 | }, 96 | "author": { 97 | "name": "Loren Sands-Ramshaw", 98 | "url": "http://lorensr.me" 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /scripts/prepublish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf ./dist 4 | ./node_modules/.bin/babel --ignore __tests__ --plugins=@babel/plugin-transform-runtime ./src --out-dir ./dist 5 | cp ./src/*.css ./dist/ 6 | -------------------------------------------------------------------------------- /src/FormsySegmentedControl.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { withFormsy } from 'formsy-react' 3 | 4 | import SegmentedControl from './SegmentedControl' 5 | 6 | class FormsySegmentedControl extends Component { 7 | render() { 8 | return ( 9 | { 12 | this.props.setValue && this.props.setValue(val) 13 | return this.props.setValue(val) // Formsy's setValue 14 | }} 15 | /> 16 | ) 17 | } 18 | } 19 | 20 | export default withFormsy(FormsySegmentedControl) 21 | -------------------------------------------------------------------------------- /src/SegmentedControl.css: -------------------------------------------------------------------------------- 1 | .segmented-control { 2 | position: relative; 3 | display: inline-block; 4 | border: 1px solid currentColor; 5 | font-style: normal; 6 | font-weight: normal; 7 | text-decoration: none; 8 | overflow: hidden; 9 | margin: 0.8em auto; 10 | -moz-border-radius: 2px; 11 | -webkit-border-radius: 2px; 12 | border-radius: 2px; 13 | -moz-box-sizing: border-box; 14 | -webkit-box-sizing: border-box; 15 | box-sizing: border-box; 16 | -moz-user-select: -moz-none; 17 | -ms-user-select: none; 18 | -webkit-user-select: none; 19 | user-select: none; 20 | -moz-transition-duration: 0.8s; 21 | -o-transition-duration: 0.8s; 22 | -webkit-transition-duration: 0.8s; 23 | transition-duration: 0.8s; 24 | -moz-transition-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95); 25 | -o-transition-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95); 26 | -webkit-transition-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95); 27 | transition-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95); 28 | -webkit-tap-highlight-color: transparent; 29 | } 30 | .segmented-control > input { 31 | position: absolute; 32 | left: -10000px; 33 | opacity: 0; 34 | } 35 | .segmented-control > input[type='checkbox'] ~ label { 36 | -moz-transition-duration: 0; 37 | -o-transition-duration: 0; 38 | -webkit-transition-duration: 0; 39 | transition-duration: 0; 40 | } 41 | .segmented-control > input[type='checkbox'] ~ label:before { 42 | opacity: 0; 43 | } 44 | 45 | 46 | 47 | 48 | 49 | /* 50 | this section controls the division of the slider 51 | if you have 2 options = 50%, 3 options = 33% and so on 52 | but also the selected input matters. (input-1)*percentage 53 | you'll also need to add a new entry for the new option 54 | to do so just copy the last entry and change the numbers to [new highest] 55 | and also make sure to set left: xx% correctly 56 | */ 57 | .segmented-control > input:disabled:nth-child(1) ~ label:nth-of-type(1) { 58 | opacity: 0.3; 59 | cursor: not-allowed; 60 | } 61 | .segmented-control > input:nth-child(1):checked ~ label:nth-of-type(1):after, 62 | .segmented-control > input:nth-child(1):checked ~ label:nth-of-type(1):before { 63 | opacity: 1; 64 | } 65 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(1):after, 66 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(1):before, 67 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(1) ~ label:after, 68 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(1) ~ label:before { 69 | left: 0; 70 | } 71 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(2):after, 72 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(2):before, 73 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(2) ~ label:after, 74 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(2) ~ label:before { 75 | left: 0; 76 | } 77 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(3):after, 78 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(3):before, 79 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(3) ~ label:after, 80 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(3) ~ label:before { 81 | left: 0; 82 | } 83 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(4):after, 84 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(4):before, 85 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(4) ~ label:after, 86 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(4) ~ label:before { 87 | left: 0; 88 | } 89 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(5):after, 90 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(5):before, 91 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(5) ~ label:after, 92 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(5) ~ label:before { 93 | left: 0; 94 | } 95 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(6):after, 96 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(6):before, 97 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:after, 98 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:before { 99 | left: 0; 100 | } 101 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(7):after, 102 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(7):before, 103 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:after, 104 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:before { 105 | left: 0; 106 | } 107 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(8):after, 108 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(8):before, 109 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:after, 110 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:before { 111 | left: 0; 112 | } 113 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(9):after, 114 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(9):before, 115 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:after, 116 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:before { 117 | left: 0; 118 | } 119 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(10):after, 120 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(10):before, 121 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:after, 122 | .segmented-control > input:nth-child(1):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:before { 123 | left: 0; 124 | } 125 | 126 | 127 | /* entry #2 */ 128 | .segmented-control > input:disabled:nth-child(2) ~ label:nth-of-type(2) { 129 | opacity: 0.3; 130 | cursor: not-allowed; 131 | } 132 | .segmented-control > input:nth-child(2):checked ~ label:nth-of-type(2):after, 133 | .segmented-control > input:nth-child(2):checked ~ label:nth-of-type(2):before { 134 | opacity: 1; 135 | } 136 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(2):after, 137 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(2):before, 138 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(2) ~ label:after, 139 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(2) ~ label:before { 140 | left: 50%; 141 | } 142 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(3):after, 143 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(3):before, 144 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(3) ~ label:after, 145 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(3) ~ label:before { 146 | left: 33.33333%; 147 | } 148 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(4):after, 149 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(4):before, 150 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(4) ~ label:after, 151 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(4) ~ label:before { 152 | left: 25%; 153 | } 154 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(5):after, 155 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(5):before, 156 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(5) ~ label:after, 157 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(5) ~ label:before { 158 | left: 20%; 159 | } 160 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(6):after, 161 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(6):before, 162 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:after, 163 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:before { 164 | left: 16.66%; 165 | } 166 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(7):after, 167 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(7):before, 168 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:after, 169 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:before { 170 | left: 14.28%; 171 | } 172 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(8):after, 173 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(8):before, 174 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:after, 175 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:before { 176 | left: 12.5%; 177 | } 178 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(9):after, 179 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(9):before, 180 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:after, 181 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:before { 182 | left: 11.1111%; 183 | } 184 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(10):after, 185 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(10):before, 186 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:after, 187 | .segmented-control > input:nth-child(2):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:before { 188 | left: 10%; 189 | } 190 | 191 | /* entry #3 */ 192 | .segmented-control > input:disabled:nth-child(3) ~ label:nth-of-type(3) { 193 | opacity: 0.3; 194 | cursor: not-allowed; 195 | } 196 | .segmented-control > input:nth-child(3):checked ~ label:nth-of-type(3):after, 197 | .segmented-control > input:nth-child(3):checked ~ label:nth-of-type(3):before { 198 | opacity: 1; 199 | } 200 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(3):after, 201 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(3):before, 202 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(3) ~ label:after, 203 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(3) ~ label:before { 204 | left: 66.66667%; 205 | } 206 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(4):after, 207 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(4):before, 208 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(4) ~ label:after, 209 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(4) ~ label:before { 210 | left: 50%; 211 | } 212 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(5):after, 213 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(5):before, 214 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(5) ~ label:after, 215 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(5) ~ label:before { 216 | left: 40%; 217 | } 218 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(6):after, 219 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(6):before, 220 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:after, 221 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:before { 222 | left: 33.3333%; 223 | } 224 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(7):after, 225 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(7):before, 226 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:after, 227 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:before { 228 | left: 28.57%; 229 | } 230 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(8):after, 231 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(8):before, 232 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:after, 233 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:before { 234 | left: 25%; 235 | } 236 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(9):after, 237 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(9):before, 238 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:after, 239 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:before { 240 | left: 22.2222%; 241 | } 242 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(10):after, 243 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(10):before, 244 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:after, 245 | .segmented-control > input:nth-child(3):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:before { 246 | left: 20%; 247 | } 248 | 249 | /* entry #4 */ 250 | .segmented-control > input:disabled:nth-child(4) ~ label:nth-of-type(4) { 251 | opacity: 0.3; 252 | cursor: not-allowed; 253 | } 254 | .segmented-control > input:nth-child(4):checked ~ label:nth-of-type(4):after, 255 | .segmented-control > input:nth-child(4):checked ~ label:nth-of-type(4):before { 256 | opacity: 1; 257 | } 258 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(4):after, 259 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(4):before, 260 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(4) ~ label:after, 261 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(4) ~ label:before { 262 | left: 75%; 263 | } 264 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(5):after, 265 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(5):before, 266 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(5) ~ label:after, 267 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(5) ~ label:before { 268 | left: 60%; 269 | } 270 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(6):after, 271 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(6):before, 272 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:after, 273 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:before { 274 | left: 50%; 275 | } 276 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(7):after, 277 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(7):before, 278 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:after, 279 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:before { 280 | left: 42.86%; 281 | } 282 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(8):after, 283 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(8):before, 284 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:after, 285 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:before { 286 | left: 37.5%; 287 | } 288 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(9):after, 289 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(9):before, 290 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:after, 291 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:before { 292 | left: 33.333%; 293 | } 294 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(10):after, 295 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(10):before, 296 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:after, 297 | .segmented-control > input:nth-child(4):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:before { 298 | left: 30%; 299 | } 300 | 301 | /* entry #5 */ 302 | .segmented-control > input:disabled:nth-child(5) ~ label:nth-of-type(5) { 303 | opacity: 0.3; 304 | cursor: not-allowed; 305 | } 306 | .segmented-control > input:nth-child(5):checked ~ label:nth-of-type(5):after, 307 | .segmented-control > input:nth-child(5):checked ~ label:nth-of-type(5):before { 308 | opacity: 1; 309 | } 310 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(5):after, 311 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(5):before, 312 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(5) ~ label:after, 313 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(5) ~ label:before { 314 | left: 80%; 315 | } 316 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(6):after, 317 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(6):before, 318 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:after, 319 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:before { 320 | left: 66.6667%; 321 | } 322 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(7):after, 323 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(7):before, 324 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:after, 325 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:before { 326 | left: 57.14%; 327 | } 328 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(8):after, 329 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(8):before, 330 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:after, 331 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:before { 332 | left: 50%; 333 | } 334 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(9):after, 335 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(9):before, 336 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:after, 337 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:before { 338 | left: 44.4444%; 339 | } 340 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(10):after, 341 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(10):before, 342 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:after, 343 | .segmented-control > input:nth-child(5):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:before { 344 | left: 40%; 345 | } 346 | 347 | /* entry #6 */ 348 | .segmented-control > input:disabled:nth-child(6) ~ label:nth-of-type(6) { 349 | opacity: 0.3; 350 | cursor: not-allowed; 351 | } 352 | .segmented-control > input:nth-child(6):checked ~ label:nth-of-type(6):after, 353 | .segmented-control > input:nth-child(6):checked ~ label:nth-of-type(6):before { 354 | opacity: 1; 355 | } 356 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(6):after, 357 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(6):before, 358 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:after, 359 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(6) ~ label:before { 360 | left: 83.3333%; 361 | } 362 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(7):after, 363 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(7):before, 364 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:after, 365 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:before { 366 | left: 71.43%; 367 | } 368 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(8):after, 369 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(8):before, 370 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:after, 371 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:before { 372 | left: 62.5%; 373 | } 374 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(9):after, 375 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(9):before, 376 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:after, 377 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:before { 378 | left: 55.56%; 379 | } 380 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(10):after, 381 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(10):before, 382 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:after, 383 | .segmented-control > input:nth-child(6):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:before { 384 | left: 50%; 385 | } 386 | 387 | /* entry #7 */ 388 | .segmented-control > input:disabled:nth-child(7) ~ label:nth-of-type(7) { 389 | opacity: 0.3; 390 | cursor: not-allowed; 391 | } 392 | .segmented-control > input:nth-child(7):checked ~ label:nth-of-type(7):after, 393 | .segmented-control > input:nth-child(7):checked ~ label:nth-of-type(7):before { 394 | opacity: 1; 395 | } 396 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(7):after, 397 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(7):before, 398 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:after, 399 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(7) ~ label:before { 400 | left: 85.71%; 401 | } 402 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(8):after, 403 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(8):before, 404 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:after, 405 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:before { 406 | left: 75%; 407 | } 408 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(9):after, 409 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(9):before, 410 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:after, 411 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:before { 412 | left: 66.6667%; 413 | } 414 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(10):after, 415 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(10):before, 416 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:after, 417 | .segmented-control > input:nth-child(7):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:before { 418 | left: 60%; 419 | } 420 | 421 | /* entry #8 */ 422 | .segmented-control > input:disabled:nth-child(8) ~ label:nth-of-type(8) { 423 | opacity: 0.3; 424 | cursor: not-allowed; 425 | } 426 | .segmented-control > input:nth-child(8):checked ~ label:nth-of-type(8):after, 427 | .segmented-control > input:nth-child(8):checked ~ label:nth-of-type(8):before { 428 | opacity: 1; 429 | } 430 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(8):after, 431 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(8):before, 432 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:after, 433 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(8) ~ label:before { 434 | left: 87.5%; 435 | } 436 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(9):after, 437 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(9):before, 438 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:after, 439 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:before { 440 | left: 77.7778%; 441 | } 442 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(10):after, 443 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(10):before, 444 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:after, 445 | .segmented-control > input:nth-child(8):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:before { 446 | left: 70%; 447 | } 448 | 449 | /* entry #9 */ 450 | .segmented-control > input:disabled:nth-child(9) ~ label:nth-of-type(9) { 451 | opacity: 0.3; 452 | cursor: not-allowed; 453 | } 454 | .segmented-control > input:nth-child(9):checked ~ label:nth-of-type(9):after, 455 | .segmented-control > input:nth-child(9):checked ~ label:nth-of-type(9):before { 456 | opacity: 1; 457 | } 458 | .segmented-control > input:nth-child(9):checked ~ label:first-of-type:nth-last-of-type(9):after, 459 | .segmented-control > input:nth-child(9):checked ~ label:first-of-type:nth-last-of-type(9):before, 460 | .segmented-control > input:nth-child(9):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:after, 461 | .segmented-control > input:nth-child(9):checked ~ label:first-of-type:nth-last-of-type(9) ~ label:before { 462 | left: 88.8889%; 463 | } 464 | .segmented-control > input:nth-child(9):checked ~ label:first-of-type:nth-last-of-type(10):after, 465 | .segmented-control > input:nth-child(9):checked ~ label:first-of-type:nth-last-of-type(10):before, 466 | .segmented-control > input:nth-child(9):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:after, 467 | .segmented-control > input:nth-child(9):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:before { 468 | left: 80%; 469 | } 470 | 471 | /* entry #10 */ 472 | .segmented-control > input:disabled:nth-child(10) ~ label:nth-of-type(10) { 473 | opacity: 0.3; 474 | cursor: not-allowed; 475 | } 476 | .segmented-control > input:nth-child(10):checked ~ label:nth-of-type(10):after, 477 | .segmented-control > input:nth-child(10):checked ~ label:nth-of-type(10):before { 478 | opacity: 1; 479 | } 480 | .segmented-control > input:nth-child(10):checked ~ label:first-of-type:nth-last-of-type(10):after, 481 | .segmented-control > input:nth-child(10):checked ~ label:first-of-type:nth-last-of-type(10):before, 482 | .segmented-control > input:nth-child(10):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:after, 483 | .segmented-control > input:nth-child(10):checked ~ label:first-of-type:nth-last-of-type(10) ~ label:before { 484 | left: 90%; 485 | } 486 | 487 | /* this section controls the size of the options for each number of total options */ 488 | .segmented-control > label:first-of-type:nth-last-of-type(1), 489 | .segmented-control > label:first-of-type:nth-last-of-type(1):after, 490 | .segmented-control > label:first-of-type:nth-last-of-type(1):before, 491 | .segmented-control > label:first-of-type:nth-last-of-type(1) ~ label, 492 | .segmented-control > label:first-of-type:nth-last-of-type(1) ~ label:after, 493 | .segmented-control > label:first-of-type:nth-last-of-type(1) ~ label:before { 494 | width: 100%; 495 | } 496 | .segmented-control > label:first-of-type:nth-last-of-type(2), 497 | .segmented-control > label:first-of-type:nth-last-of-type(2):after, 498 | .segmented-control > label:first-of-type:nth-last-of-type(2):before, 499 | .segmented-control > label:first-of-type:nth-last-of-type(2) ~ label, 500 | .segmented-control > label:first-of-type:nth-last-of-type(2) ~ label:after, 501 | .segmented-control > label:first-of-type:nth-last-of-type(2) ~ label:before { 502 | width: 50%; 503 | } 504 | .segmented-control > label:first-of-type:nth-last-of-type(3), 505 | .segmented-control > label:first-of-type:nth-last-of-type(3):after, 506 | .segmented-control > label:first-of-type:nth-last-of-type(3):before, 507 | .segmented-control > label:first-of-type:nth-last-of-type(3) ~ label, 508 | .segmented-control > label:first-of-type:nth-last-of-type(3) ~ label:after, 509 | .segmented-control > label:first-of-type:nth-last-of-type(3) ~ label:before { 510 | width: 33.33333%; 511 | } 512 | .segmented-control > label:first-of-type:nth-last-of-type(4), 513 | .segmented-control > label:first-of-type:nth-last-of-type(4):after, 514 | .segmented-control > label:first-of-type:nth-last-of-type(4):before, 515 | .segmented-control > label:first-of-type:nth-last-of-type(4) ~ label, 516 | .segmented-control > label:first-of-type:nth-last-of-type(4) ~ label:after, 517 | .segmented-control > label:first-of-type:nth-last-of-type(4) ~ label:before { 518 | width: 25%; 519 | } 520 | .segmented-control > label:first-of-type:nth-last-of-type(5), 521 | .segmented-control > label:first-of-type:nth-last-of-type(5):after, 522 | .segmented-control > label:first-of-type:nth-last-of-type(5):before, 523 | .segmented-control > label:first-of-type:nth-last-of-type(5) ~ label, 524 | .segmented-control > label:first-of-type:nth-last-of-type(5) ~ label:after, 525 | .segmented-control > label:first-of-type:nth-last-of-type(5) ~ label:before { 526 | width: 20%; 527 | } 528 | .segmented-control > label:first-of-type:nth-last-of-type(6), 529 | .segmented-control > label:first-of-type:nth-last-of-type(6):after, 530 | .segmented-control > label:first-of-type:nth-last-of-type(6):before, 531 | .segmented-control > label:first-of-type:nth-last-of-type(6) ~ label, 532 | .segmented-control > label:first-of-type:nth-last-of-type(6) ~ label:after, 533 | .segmented-control > label:first-of-type:nth-last-of-type(6) ~ label:before { 534 | width: 16.6667%; 535 | } 536 | .segmented-control > label:first-of-type:nth-last-of-type(7), 537 | .segmented-control > label:first-of-type:nth-last-of-type(7):after, 538 | .segmented-control > label:first-of-type:nth-last-of-type(7):before, 539 | .segmented-control > label:first-of-type:nth-last-of-type(7) ~ label, 540 | .segmented-control > label:first-of-type:nth-last-of-type(7) ~ label:after, 541 | .segmented-control > label:first-of-type:nth-last-of-type(7) ~ label:before { 542 | width: 14.2857%; 543 | } 544 | .segmented-control > label:first-of-type:nth-last-of-type(8), 545 | .segmented-control > label:first-of-type:nth-last-of-type(8):after, 546 | .segmented-control > label:first-of-type:nth-last-of-type(8):before, 547 | .segmented-control > label:first-of-type:nth-last-of-type(8) ~ label, 548 | .segmented-control > label:first-of-type:nth-last-of-type(8) ~ label:after, 549 | .segmented-control > label:first-of-type:nth-last-of-type(8) ~ label:before { 550 | width: 12.5%; 551 | } 552 | .segmented-control > label:first-of-type:nth-last-of-type(9), 553 | .segmented-control > label:first-of-type:nth-last-of-type(9):after, 554 | .segmented-control > label:first-of-type:nth-last-of-type(9):before, 555 | .segmented-control > label:first-of-type:nth-last-of-type(9) ~ label, 556 | .segmented-control > label:first-of-type:nth-last-of-type(9) ~ label:after, 557 | .segmented-control > label:first-of-type:nth-last-of-type(9) ~ label:before { 558 | width: 11.1111%; 559 | } 560 | .segmented-control > label:first-of-type:nth-last-of-type(10), 561 | .segmented-control > label:first-of-type:nth-last-of-type(10):after, 562 | .segmented-control > label:first-of-type:nth-last-of-type(10):before, 563 | .segmented-control > label:first-of-type:nth-last-of-type(10) ~ label, 564 | .segmented-control > label:first-of-type:nth-last-of-type(10) ~ label:after, 565 | .segmented-control > label:first-of-type:nth-last-of-type(10) ~ label:before { 566 | width: 10%; 567 | } 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | .segmented-control > label { 586 | display: inline-block; 587 | padding: 0 0.71em; 588 | cursor: pointer; 589 | float: left; 590 | line-height: 3em; 591 | font-style: inherit; 592 | font-weight: inherit; 593 | text-decoration: inherit; 594 | -moz-transition-property: none; 595 | -o-transition-property: none; 596 | -webkit-transition-property: none; 597 | transition-property: none; 598 | -moz-transition-duration: inherit; 599 | -o-transition-duration: inherit; 600 | -webkit-transition-duration: inherit; 601 | transition-duration: inherit; 602 | -moz-transition-timing-function: inherit; 603 | -o-transition-timing-function: inherit; 604 | -webkit-transition-timing-function: inherit; 605 | transition-timing-function: inherit; 606 | } 607 | .segmented-control > label:before, 608 | .segmented-control > label:after { 609 | position: absolute; 610 | left: 0; 611 | top: 0; 612 | width: 100%; 613 | height: 100%; 614 | pointer-events: none; 615 | } 616 | .segmented-control > label:after { 617 | color: white; 618 | content: attr(data-value); 619 | text-align: center; 620 | padding: inherit; 621 | z-index: 10; 622 | font-style: inherit; 623 | text-decoration: inherit; 624 | font-weight: inherit; 625 | opacity: 0; 626 | -moz-transition-property: opacity, left; 627 | -o-transition-property: opacity, left; 628 | -webkit-transition-property: opacity, left; 629 | transition-property: opacity, left; 630 | -moz-transition-duration: inherit; 631 | -o-transition-duration: inherit; 632 | -webkit-transition-duration: inherit; 633 | transition-duration: inherit; 634 | -moz-transition-timing-function: inherit; 635 | -o-transition-timing-function: inherit; 636 | -webkit-transition-timing-function: inherit; 637 | transition-timing-function: inherit; 638 | } 639 | .segmented-control > label:after, 640 | .segmented-control > label { 641 | text-align: center; 642 | text-overflow: ellipsis; 643 | white-space: nowrap; 644 | overflow: hidden; 645 | -moz-box-sizing: border-box; 646 | -webkit-box-sizing: border-box; 647 | box-sizing: border-box; 648 | } 649 | .segmented-control > label:before { 650 | content: ""; 651 | color: inherit; 652 | background: currentColor; 653 | -moz-transition-property: left; 654 | -o-transition-property: left; 655 | -webkit-transition-property: left; 656 | transition-property: left; 657 | -moz-transition-duration: inherit; 658 | -o-transition-duration: inherit; 659 | -webkit-transition-duration: inherit; 660 | transition-duration: inherit; 661 | -moz-transition-timing-function: inherit; 662 | -o-transition-timing-function: inherit; 663 | -webkit-transition-timing-function: inherit; 664 | transition-timing-function: inherit; 665 | } 666 | 667 | .segmented-control.italic, 668 | .segmented-control .italic { 669 | font-style: italic; 670 | } 671 | .segmented-control.bold, 672 | .segmented-control .bold { 673 | font-weight: bold; 674 | } 675 | .segmented-control.underline, 676 | .segmented-control .underline { 677 | text-decoration: underline; 678 | } 679 | .segmented-control.line-through, 680 | .segmented-control .line-through { 681 | text-decoration: line-through; 682 | } 683 | 684 | -------------------------------------------------------------------------------- /src/SegmentedControl.js: -------------------------------------------------------------------------------- 1 | import './SegmentedControl.css' 2 | import SegmentedControlWithoutStyles from './SegmentedControlWithoutStyles' 3 | 4 | export default SegmentedControlWithoutStyles 5 | -------------------------------------------------------------------------------- /src/SegmentedControlWithoutStyles.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import PropTypes from 'prop-types' 3 | import find from 'lodash/find' 4 | import extend from 'lodash/extend' 5 | 6 | class SegmentedControlWithoutStyles extends Component { 7 | static propTypes = { 8 | className: PropTypes.string, 9 | name: PropTypes.string.isRequired, 10 | options: PropTypes.array.isRequired, 11 | style: PropTypes.object, 12 | setValue: PropTypes.func, 13 | } 14 | 15 | componentDidMount() { 16 | const defaultOption = find(this.props.options, { default: true }) 17 | this.setValue(defaultOption.value) 18 | } 19 | 20 | setValue(val) { 21 | this.props.setValue && this.props.setValue(val) 22 | } 23 | 24 | render() { 25 | const getId = (option) => this.props.name + option.value 26 | 27 | const defaultStyle = { 28 | width: '100%', 29 | } 30 | 31 | const style = extend(defaultStyle, this.props.style) 32 | 33 | let containerClassName = 'segmented-control' 34 | 35 | if (typeof this.props.className !== 'undefined') { 36 | containerClassName = `${containerClassName} ${this.props.className}` 37 | } 38 | 39 | return ( 40 |
41 | {this.props.options.map((option) => ( 42 | this.setValue(option.value)} 50 | /> 51 | ))} 52 | {this.props.options.map((option) => ( 53 | 60 | ))} 61 |
62 | ) 63 | } 64 | } 65 | 66 | export default SegmentedControlWithoutStyles 67 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export SegmentedControl from './SegmentedControl' 2 | export SegmentedControlWithoutStyles from './SegmentedControlWithoutStyles' 3 | export FormsySegmentedControl from './FormsySegmentedControl' 4 | -------------------------------------------------------------------------------- /src/stories/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Formsy from 'formsy-react' 3 | import { storiesOf } from '@storybook/react' 4 | import { action } from '@storybook/addon-actions' 5 | import centered from '@storybook/addon-centered' 6 | import Button from '@material-ui/core/Button' 7 | import ThemeProvider from '@material-ui/core/styles/ThemeProvider' 8 | 9 | import SegmentedControl from '../SegmentedControl' 10 | import SegmentedControlWithoutStyles from '../SegmentedControlWithoutStyles' 11 | import FormsySegmentedControl from '../FormsySegmentedControl' 12 | 13 | storiesOf('SegmentedControl', module) 14 | .addDecorator(centered) 15 | .add('Two options', () => ( 16 | 26 | )) 27 | .add('Three options', () => ( 28 | 38 | )) 39 | .add('One disabled', () => ( 40 | 51 | )) 52 | .add('Ten options', () => ( 53 | 70 | )) 71 | 72 | storiesOf('FormsySegmentedControl', module) 73 | .addDecorator(centered) 74 | .add('Three options', () => ( 75 | 76 | 77 | 87 | 100 | 101 | 102 | )) 103 | 104 | storiesOf('SegmentedControlWithoutStyles', module) 105 | .addDecorator(centered) 106 | .add('Two options without styles', () => ( 107 | 116 | )) 117 | -------------------------------------------------------------------------------- /storybook-static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorensr/segmented-control/70699c759dab1eeab6adaa98d87062b5d10a9492/storybook-static/favicon.ico -------------------------------------------------------------------------------- /storybook-static/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | Storybook 14 | 15 | 16 | 17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /storybook-static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Storybook 9 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | 45 | --------------------------------------------------------------------------------