├── .eslintrc ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── README.md ├── docs-assets └── thumbnail.jpg ├── docs └── screenshot.png ├── package.json └── src ├── textselect.jsx └── textselect.less /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "plugins": [ 4 | "react" 5 | ], 6 | "env": { 7 | "browser": true, 8 | "node": true 9 | }, 10 | "ecmaFeatures": { 11 | "arrowFunctions": true, 12 | "blockBindings": true, 13 | "classes": true, 14 | "defaultParams": true, 15 | "destructuring": true, 16 | "forOf": true, 17 | "generators": false, 18 | "modules": true, 19 | "objectLiteralComputedProperties": true, 20 | "objectLiteralDuplicateProperties": false, 21 | "objectLiteralShorthandMethods": true, 22 | "objectLiteralShorthandProperties": true, 23 | "spread": true, 24 | "superInFunctions": true, 25 | "templateStrings": true, 26 | "jsx": true 27 | }, 28 | "rules": { 29 | /** 30 | * Strict mode 31 | */ 32 | // babel inserts "use strict"; for us 33 | // http://eslint.org/docs/rules/strict 34 | "strict": [2, "never"], 35 | 36 | /** 37 | * ES6 38 | */ 39 | "no-var": 0, // http://eslint.org/docs/rules/no-var 40 | 41 | /** 42 | * Variables 43 | */ 44 | "no-shadow": 2, // http://eslint.org/docs/rules/no-shadow 45 | "no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names 46 | "no-unused-vars": [2, { // http://eslint.org/docs/rules/no-unused-vars 47 | "vars": "local", 48 | "args": "after-used" 49 | }], 50 | "no-use-before-define": 2, // http://eslint.org/docs/rules/no-use-before-define 51 | 52 | /** 53 | * Possible errors 54 | */ 55 | "comma-dangle": [2, "never"], // http://eslint.org/docs/rules/comma-dangle 56 | "no-cond-assign": [2, "always"], // http://eslint.org/docs/rules/no-cond-assign 57 | "no-console": 0, // http://eslint.org/docs/rules/no-console 58 | "no-debugger": 1, // http://eslint.org/docs/rules/no-debugger 59 | "no-alert": 1, // http://eslint.org/docs/rules/no-alert 60 | "no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition 61 | "no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys 62 | "no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case 63 | "no-empty": 2, // http://eslint.org/docs/rules/no-empty 64 | "no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign 65 | "no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast 66 | "no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi 67 | "no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign 68 | "no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations 69 | "no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp 70 | "no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace 71 | "no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls 72 | "no-reserved-keys": 2, // http://eslint.org/docs/rules/no-reserved-keys 73 | "no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays 74 | "no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable 75 | "use-isnan": 2, // http://eslint.org/docs/rules/use-isnan 76 | "block-scoped-var": 2, // http://eslint.org/docs/rules/block-scoped-var 77 | 78 | /** 79 | * Best practices 80 | */ 81 | "consistent-return": 2, // http://eslint.org/docs/rules/consistent-return 82 | "curly": [2, "multi-line"], // http://eslint.org/docs/rules/curly 83 | "default-case": 2, // http://eslint.org/docs/rules/default-case 84 | "dot-notation": [2, { // http://eslint.org/docs/rules/dot-notation 85 | "allowKeywords": true 86 | }], 87 | "eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq 88 | "guard-for-in": 2, // http://eslint.org/docs/rules/guard-for-in 89 | "no-caller": 2, // http://eslint.org/docs/rules/no-caller 90 | "no-else-return": 2, // http://eslint.org/docs/rules/no-else-return 91 | "no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null 92 | "no-eval": 2, // http://eslint.org/docs/rules/no-eval 93 | "no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native 94 | "no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind 95 | "no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough 96 | "no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal 97 | "no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval 98 | "no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks 99 | "no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func 100 | "no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str 101 | "no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign 102 | "no-new": 2, // http://eslint.org/docs/rules/no-new 103 | "no-new-func": 2, // http://eslint.org/docs/rules/no-new-func 104 | "no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers 105 | "no-octal": 2, // http://eslint.org/docs/rules/no-octal 106 | "no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape 107 | "no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign 108 | "no-proto": 2, // http://eslint.org/docs/rules/no-proto 109 | "no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare 110 | "no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign 111 | "no-script-url": 2, // http://eslint.org/docs/rules/no-script-url 112 | "no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare 113 | "no-sequences": 2, // http://eslint.org/docs/rules/no-sequences 114 | "no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal 115 | "no-with": 2, // http://eslint.org/docs/rules/no-with 116 | "radix": 2, // http://eslint.org/docs/rules/radix 117 | "vars-on-top": 2, // http://eslint.org/docs/rules/vars-on-top 118 | "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife 119 | "yoda": 2, // http://eslint.org/docs/rules/yoda 120 | 121 | /** 122 | * Style 123 | */ 124 | "indent": [2, 2], // http://eslint.org/docs/rules/ 125 | "brace-style": [2, // http://eslint.org/docs/rules/brace-style 126 | "1tbs", { 127 | "allowSingleLine": true 128 | }], 129 | "quotes": [ 130 | 2, "single", "avoid-escape" // http://eslint.org/docs/rules/quotes 131 | ], 132 | "camelcase": [2, { // http://eslint.org/docs/rules/camelcase 133 | "properties": "never" 134 | }], 135 | "comma-spacing": [2, { // http://eslint.org/docs/rules/comma-spacing 136 | "before": false, 137 | "after": true 138 | }], 139 | "comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style 140 | "eol-last": 2, // http://eslint.org/docs/rules/eol-last 141 | "func-names": 1, // http://eslint.org/docs/rules/func-names 142 | "key-spacing": [2, { // http://eslint.org/docs/rules/key-spacing 143 | "beforeColon": false, 144 | "afterColon": true 145 | }], 146 | "new-cap": [2, { // http://eslint.org/docs/rules/new-cap 147 | "newIsCap": true 148 | }], 149 | "no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines 150 | "max": 2 151 | }], 152 | "no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary 153 | "no-new-object": 2, // http://eslint.org/docs/rules/no-new-object 154 | "no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func 155 | "no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces 156 | "no-wrap-func": 2, // http://eslint.org/docs/rules/no-wrap-func 157 | "no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle 158 | "one-var": [2, "never"], // http://eslint.org/docs/rules/one-var 159 | "padded-blocks": [2, "never"], // http://eslint.org/docs/rules/padded-blocks 160 | "semi": [2, "always"], // http://eslint.org/docs/rules/semi 161 | "semi-spacing": [2, { // http://eslint.org/docs/rules/semi-spacing 162 | "before": false, 163 | "after": true 164 | }], 165 | "space-after-keywords": 2, // http://eslint.org/docs/rules/space-after-keywords 166 | "space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks 167 | "space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren 168 | "space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops 169 | "space-return-throw-case": 2, // http://eslint.org/docs/rules/space-return-throw-case 170 | "spaced-line-comment": 2, // http://eslint.org/docs/rules/spaced-line-comment 171 | 172 | /** 173 | * JSX style 174 | */ 175 | "react/display-name": 0, 176 | "react/jsx-boolean-value": 2, 177 | "react/jsx-quotes": [2, "single"], 178 | "react/jsx-no-undef": 2, 179 | "react/jsx-sort-props": 0, 180 | "react/jsx-sort-prop-types": 0, 181 | "react/jsx-uses-react": 2, 182 | "react/jsx-uses-vars": 2, 183 | "react/no-did-mount-set-state": [2, "allow-in-func"], 184 | "react/no-did-update-set-state": 2, 185 | "react/no-multi-comp": 2, 186 | "react/no-unknown-property": 2, 187 | "react/prop-types": 2, 188 | "react/react-in-jsx-scope": 2, 189 | "react/self-closing-comp": 2, 190 | "react/wrap-multilines": 2, 191 | "react/sort-comp": [2, { 192 | "order": [ 193 | "displayName", 194 | "mixins", 195 | "statics", 196 | "propTypes", 197 | "getDefaultProps", 198 | "getInitialState", 199 | "componentWillMount", 200 | "componentDidMount", 201 | "componentWillReceiveProps", 202 | "shouldComponentUpdate", 203 | "componentWillUpdate", 204 | "componentWillUnmount", 205 | "everything-else", 206 | "render" 207 | ] 208 | }] 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | *.log 3 | dist -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | *.log 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | #0.2.0 2 | Add object options support via `lodash.map`. 3 | 4 | #0.1.12 5 | Add white version. 6 | 7 | #0.1.4 8 | Fix issue when the input parent didn't had a relative position. 9 | 10 | #0.1.3 11 | Select wasn't opening when clicked on the arrow. 12 | 13 | #0.1.0 14 | Pre compiling ES6/JSX and LESS. 15 | 16 | #0.0.x 17 | Initial release 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Text Select 2 | 3 | ## UNMAINTAINED 4 | 5 | Unmantained for now. 6 | 7 | -- 8 | 9 | Simple component to put an invisible `Select` dropdown over a text. 10 | 11 | [Live demo](http://javierbyte.github.io/react-textselect/) 12 | 13 | ![react-textselect screenshot](docs/screenshot.png) 14 | 15 | ## Installation 16 | 17 | ``` 18 | npm install react-textselect --save 19 | ``` 20 | 21 | ## Usage. 22 | 23 | ```jsx 24 | var TextSelect = require('react-textselect'); 25 | 26 | 30 | ``` 31 | 32 | 33 | ### Add styles. 34 | 35 | Dont forget to add styles. 36 | 37 | ```html 38 | 39 | ``` 40 | 41 | # Build 42 | 43 | If you want to build this from source, you will need babel and less. 44 | 45 | ``` 46 | npm install -g babel less 47 | ``` 48 | 49 | And run the pre publish script 50 | 51 | ``` 52 | npm run prepublish 53 | ``` 54 | -------------------------------------------------------------------------------- /docs-assets/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javierbyte/react-textselect/ccd5594fe126997800694515b2f25c08adaa0873/docs-assets/thumbnail.jpg -------------------------------------------------------------------------------- /docs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javierbyte/react-textselect/ccd5594fe126997800694515b2f25c08adaa0873/docs/screenshot.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-textselect", 3 | "version": "0.2.0", 4 | "description": "Select dropdown over text in React.", 5 | "main": "dist/textselect.js", 6 | "scripts": { 7 | "prepublish": "mkdir -p dist && babel src/textselect.jsx -u -o dist/textselect.js --stage 1 && lessc src/textselect.less dist/textselect.css", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [ 11 | "react", 12 | "react-component", 13 | "component", 14 | "text", 15 | "select" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/javierbyte/react-textselect" 20 | }, 21 | "author": "javierbyte", 22 | "license": "ISC", 23 | "devDependencies": { 24 | "standard": "^5.3.1" 25 | }, 26 | "dependencies": { 27 | "prop-types": "15.6.1", 28 | "lodash.map": "^3.1.4" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/textselect.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react') 2 | var PropTypes = require('prop-types') 3 | var lodashMap = require('lodash.map') 4 | 5 | var TextSelect = React.createClass({ 6 | propTypes: { 7 | options: PropTypes.any.isRequired, 8 | active: PropTypes.any.isRequired, 9 | onChange: PropTypes.func.isRequired, 10 | className: PropTypes.string 11 | }, 12 | 13 | getInitialState() { 14 | return { 15 | selectedOption: this.props.active 16 | } 17 | }, 18 | componentWillReceiveProps(nextProps) { 19 | (this.props.active !== nextProps.active) && this.setState({ selectedOption: nextProps.active }); 20 | } 21 | 22 | handleChange (event) { 23 | this.setState({ 24 | selectedOption: event.target.value 25 | }); 26 | 27 | this.props.onChange(event, event.target.value, this.props.options[event.target.value]) 28 | }, 29 | 30 | render () { 31 | var {options, active, className} = this.props 32 | 33 | var classes = 'react-textselect' 34 | if (className) classes += ' ' + className 35 | 36 | return ( 37 | 38 | {options[active]} 39 | 40 | 47 | 48 | ) 49 | } 50 | }) 51 | 52 | module.exports = TextSelect 53 | -------------------------------------------------------------------------------- /src/textselect.less: -------------------------------------------------------------------------------- 1 | .react-textselect { 2 | border-bottom: 1px solid rgba(0, 0, 0, .33); 3 | overflow: hidden; 4 | padding-right: 1em; 5 | margin-right: .17em; 6 | cursor: pointer; 7 | position: relative; 8 | 9 | &::after { 10 | position: absolute; 11 | top: 50%; 12 | right: 0; 13 | display: block; 14 | content: ''; 15 | height: 0; 16 | width: 0; 17 | border: .33em solid transparent; 18 | border-top: .33em solid rgba(0, 0, 0, .33); 19 | margin-top: -.17em; 20 | } 21 | 22 | &-input { 23 | font-size: 1.2em; 24 | position: absolute; 25 | top: 0; 26 | left: 0; 27 | right: 0; 28 | width: 100%; 29 | opacity: 0; 30 | z-index: 1; 31 | } 32 | 33 | &.bright { 34 | &::after { 35 | border-top: .33em solid rgba(255, 255, 255, .33); 36 | } 37 | } 38 | } 39 | --------------------------------------------------------------------------------