├── .babelrc
├── .eslintrc
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── example
├── .babelrc
├── .gitignore
├── README.md
├── app.js
├── index.html
├── package.json
└── webpack.config.js
├── package.json
├── src
└── index.js
└── test
└── library.spec.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "ecmaFeatures": {
3 | "globalReturn": true,
4 | "jsx": true,
5 | "modules": true
6 | },
7 |
8 | "env": {
9 | "browser": true,
10 | "es6": true,
11 | "node": true
12 | },
13 |
14 | "globals": {
15 | "document": false,
16 | "escape": false,
17 | "navigator": false,
18 | "unescape": false,
19 | "window": false,
20 | "describe": true,
21 | "before": true,
22 | "it": true,
23 | "expect": true,
24 | "sinon": true
25 | },
26 |
27 | "parser": "babel-eslint",
28 |
29 | "plugins": [
30 |
31 | ],
32 |
33 | "rules": {
34 | "block-scoped-var": 1,
35 | "brace-style": [1, "1tbs", { "allowSingleLine": true }],
36 | "camelcase": [1, { "properties": "always" }],
37 | "comma-dangle": [1, "never"],
38 | "comma-spacing": [1, { "before": false, "after": true }],
39 | "comma-style": [1, "last"],
40 | "complexity": 0,
41 | "consistent-return": 1,
42 | "consistent-this": 0,
43 | "curly": [1, "multi-line"],
44 | "default-case": 0,
45 | "dot-location": [1, "property"],
46 | "dot-notation": 0,
47 | "eol-last": 1,
48 | "eqeqeq": [1, "allow-null"],
49 | "func-names": 0,
50 | "func-style": 0,
51 | "generator-star-spacing": [1, "both"],
52 | "guard-for-in": 0,
53 | "handle-callback-err": [1, "^(err|error|anySpecificError)$" ],
54 | "indent": [1, 4, { "SwitchCase": 1 }],
55 | "key-spacing": [1, { "beforeColon": false, "afterColon": true }],
56 | "linebreak-style": 0,
57 | "max-depth": 0,
58 | "max-len": [1, 110, 4],
59 | "max-nested-callbacks": 0,
60 | "max-params": 0,
61 | "max-statements": 0,
62 | "new-cap": [1, { "newIsCap": true, "capIsNew": false }],
63 | "newline-after-var": [1, "always"],
64 | "new-parens": 1,
65 | "no-alert": 0,
66 | "no-array-constructor": 1,
67 | "no-bitwise": 0,
68 | "no-caller": 1,
69 | "no-catch-shadow": 0,
70 | "no-cond-assign": 1,
71 | "no-console": 0,
72 | "no-constant-condition": 0,
73 | "no-continue": 0,
74 | "no-control-regex": 1,
75 | "no-debugger": 1,
76 | "no-delete-var": 1,
77 | "no-div-regex": 0,
78 | "no-dupe-args": 1,
79 | "no-dupe-keys": 1,
80 | "no-duplicate-case": 1,
81 | "no-else-return": 1,
82 | "no-empty": 0,
83 | "no-empty-character-class": 1,
84 | "no-empty-label": 1,
85 | "no-eq-null": 0,
86 | "no-eval": 1,
87 | "no-ex-assign": 1,
88 | "no-extend-native": 1,
89 | "no-extra-bind": 1,
90 | "no-extra-boolean-cast": 1,
91 | "no-extra-parens": 0,
92 | "no-extra-semi": 0,
93 | "no-extra-strict": 0,
94 | "no-fallthrough": 1,
95 | "no-floating-decimal": 1,
96 | "no-func-assign": 1,
97 | "no-implied-eval": 1,
98 | "no-inline-comments": 0,
99 | "no-inner-declarations": [1, "functions"],
100 | "no-invalid-regexp": 1,
101 | "no-irregular-whitespace": 1,
102 | "no-iterator": 1,
103 | "no-label-var": 1,
104 | "no-labels": 1,
105 | "no-lone-blocks": 0,
106 | "no-lonely-if": 0,
107 | "no-loop-func": 0,
108 | "no-mixed-requires": 0,
109 | "no-mixed-spaces-and-tabs": [1, false],
110 | "no-multi-spaces": 0,
111 | "no-multi-str": 1,
112 | "no-multiple-empty-lines": [0, { "max": 1 }],
113 | "no-native-reassign": 1,
114 | "no-negated-in-lhs": 1,
115 | "no-nested-ternary": 0,
116 | "no-new": 1,
117 | "no-new-func": 1,
118 | "no-new-object": 1,
119 | "no-new-require": 1,
120 | "no-new-wrappers": 1,
121 | "no-obj-calls": 1,
122 | "no-octal": 1,
123 | "no-octal-escape": 1,
124 | "no-path-concat": 0,
125 | "no-plusplus": 0,
126 | "no-process-env": 0,
127 | "no-process-exit": 0,
128 | "no-proto": 1,
129 | "no-redeclare": 1,
130 | "no-regex-spaces": 1,
131 | "no-reserved-keys": 0,
132 | "no-restricted-modules": 0,
133 | "no-return-assign": 1,
134 | "no-script-url": 0,
135 | "no-self-compare": 1,
136 | "no-sequences": 1,
137 | "no-shadow": 0,
138 | "no-shadow-restricted-names": 1,
139 | "no-spaced-func": 1,
140 | "no-sparse-arrays": 1,
141 | "no-sync": 0,
142 | "no-ternary": 0,
143 | "no-throw-literal": 1,
144 | "no-trailing-spaces": 1,
145 | "no-undef": 1,
146 | "no-undef-init": 1,
147 | "no-undefined": 0,
148 | "no-underscore-dangle": 0,
149 | "no-unneeded-ternary": 1,
150 | "no-unreachable": 1,
151 | "no-unused-expressions": 0,
152 | "no-unused-vars": [1, { "vars": "all", "args": "none" }],
153 | "no-use-before-define": 1,
154 | "no-var": 0,
155 | "no-void": 0,
156 | "no-warning-comments": 0,
157 | "no-with": 1,
158 | "one-var": 0,
159 | "operator-assignment": 0,
160 | "operator-linebreak": [1, "after"],
161 | "padded-blocks": 0,
162 | "quote-props": 0,
163 | "quotes": [1, "single", "avoid-escape"],
164 | "radix": 1,
165 | "semi": [1, "always"],
166 | "semi-spacing": 0,
167 | "sort-vars": 0,
168 | "space-after-keywords": [1, "always"],
169 | "space-before-blocks": [1, "always"],
170 | "space-before-function-paren": [1, {"anonymous": "always", "named": "never"}],
171 | "space-in-brackets": 0,
172 | "space-in-parens": [1, "never"],
173 | "space-infix-ops": 1,
174 | "space-return-throw-case": 1,
175 | "space-unary-ops": [1, { "words": true, "nonwords": false }],
176 | "spaced-comment": [1, "always"],
177 | "strict": 0,
178 | "use-isnan": 1,
179 | "valid-jsdoc": 0,
180 | "valid-typeof": 1,
181 | "vars-on-top": 1,
182 | "wrap-iife": [1, "any"],
183 | "wrap-regex": 0,
184 | "yoda": [1, "never"]
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # node-waf configuration
20 | .lock-wscript
21 |
22 | # Compiled binary addons (http://nodejs.org/api/addons.html)
23 | build/Release
24 |
25 | # Dependency directory
26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
27 | node_modules
28 | lib
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Krasimir Tsonev
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | build_lib:
2 | node_modules/.bin/browserify src/index.js -o lib/react-turkce-textarea.browserify.js -t babelify -x react
3 |
4 | build_example:
5 | node_modules/.bin/browserify example/app.js -o example/bundle.browserify.js -t babelify
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Turkish Textarea
2 |
3 | İngilizce klavye ile yazılan yazıları otomatik olarak Türkçe karakterlerle düzelten, React için bir textarea bileşeni.
4 |
5 | Örneğin İngilizce karakterlerle Ustun Ozgur yazdığınızda bunu Üstün Özgür olarak düzeltir.
6 |
7 | ## Demo
8 |
9 | http://ustun.github.io/react-turkish-textarea/
10 |
11 | ## Kurulum
12 |
13 | Önce gereksinimleri kurun. (Bu paketler peer dependency olduğu için npm 3'ten itibaren otomatik olarak kurulmayacaklar.)
14 |
15 | ```shell
16 | npm install react --save
17 | npm install turkish-deasciifier --save
18 | ```
19 | Daha sonra `react-turkish-textarea` paketini kurun.
20 |
21 | ```shell
22 | npm install react-turkish-textarea --save
23 | ```
24 |
25 |
26 | ## Kullanım
27 |
28 |
29 | ```js
30 |
31 | var TurkishTextArea = require('react-turkish-textarea');
32 |
33 | var MyComponent = React.createClass({
34 |
35 | render: function () {
36 | return (
37 |
38 |
Ornek form
39 |
42 |
43 | );
44 |
45 | }
46 | });
47 | ```
48 |
49 | Normal bir textarea bileşenine aktarabilen tüm özellikler TurkishTextarea bileşenine de aktarılabilir.
50 |
51 | ```js
52 | var MyComponent = React.createClass({
53 |
54 | getInitialState: function () {
55 | return {value: ''};
56 | },
57 |
58 | render: function () {
59 | return (
60 |
61 |
Ornek form
62 |
65 |
66 | );
67 |
68 | }
69 |
70 | });
71 |
72 | ```
73 |
74 | ## Örnekler
75 |
76 | Örnek bir kullanım için example/ klasörüne göz atabilirsiniz.
77 |
78 | ## Nasıl Çalışır?
79 |
80 | Bu kod arkaplanda [Dr. Deniz Yüret](http://www.denizyuret.com/)'in Emacs icin yazdığı eklentiyi JavaScript'e
81 | çeviren [Mustafa Emre Acer](http://www.mustafaacer.com/)'in [Turkish Deasciifier](https://github.com/meacer/deasciifier/) kodunu React bileşeniyle
82 | entegre etmektedir. Deasciifier hakkında ayrıntılı bilgi için:
83 |
84 | - http://www.denizyuret.com/2006/11/emacs-turkish-mode.html
85 | - http://www.deasciifier.com/
86 |
87 | ## npm'deki turkish-deasciifier paketi
88 | - Kodun orijinali: https://github.com/meacer/deasciifier/
89 | - Mac OS X servisi hali: https://github.com/f/deasciifier
90 | - npm'deki kütüphanesi: https://github.com/ustun/turkish-deasciifier
91 |
92 | ## Scripts
93 |
94 | * `npm run build` - produces production version of your library under the `lib` folder
95 | * `npm run dev` - produces development version of your library and runs a watcher
96 | * `npm run test` - well ... it runs the tests :)
97 |
--------------------------------------------------------------------------------
/example/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | bundle*
2 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # Kullanım
2 |
3 | ```
4 | npm install
5 | npm run build
6 |
7 | ```
8 |
9 | Daha sonra index.html dosyasını açın.
10 |
--------------------------------------------------------------------------------
/example/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import TurkishTextArea from 'react-turkish-textarea';
5 |
6 | const MyComponent = React.createClass({
7 |
8 | render: function () {
9 | return (
10 |
11 |
Ornek form
12 |
15 |
16 | );
17 |
18 | }
19 | });
20 |
21 | ReactDOM.render(, document.getElementById('app-1'));
22 |
23 |
24 | const MyComponent2 = React.createClass({
25 |
26 | getInitialState() {
27 | return {value: ''};
28 | },
29 |
30 | onChange(e) {
31 | this.setState({value: e.target.value.toUpperCase()});
32 | },
33 |
34 | render: function () {
35 | return (
36 |
37 |
Ornek form
38 |
44 |
45 | );
46 |
47 | }
48 | });
49 |
50 | ReactDOM.render(, document.getElementById('app-2'));
51 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "babel-preset-es2015": "^6.3.13",
14 | "babel-preset-react": "^6.3.13",
15 | "webpack": "^1.12.10",
16 | "babel-loader": "^6.2.1"
17 | },
18 | "dependencies": {
19 | "react": "^0.14.6",
20 | "react-dom": "^0.14.6",
21 | "react-turkish-textarea": "^0.2.0",
22 | "turkish-deasciifier": "1.0.0"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/example/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | var config = {
4 | entry: './app.js',
5 | devtool: 'source-map',
6 | output: {
7 | filename: 'bundle.js',
8 | },
9 | module: {
10 | loaders: [
11 | {
12 | test: /(\.jsx|\.js)$/,
13 | loader: 'babel',
14 | exclude: /(node_modules|bower_components)/
15 | }
16 | ]
17 | }
18 | };
19 |
20 | module.exports = config;
21 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-turkish-textarea",
3 | "version": "0.2.0",
4 | "description": "Ingilizce klavye ile yazilan yazilari otomatik olarak Turkce harflerle duzelten bir React textarea bileseni",
5 | "main": "lib/react-turkish-textarea.js",
6 | "scripts": {
7 | "build": "WEBPACK_ENV=build babel src/index.js -o lib/react-turkish-textarea.js",
8 | "dev": "WEBPACK_ENV=dev babel src/index.js -o lib/react-turkish-textarea.js --watch",
9 | "test": "tape ./test/*.spec.js"
10 | },
11 | "devDependencies": {
12 | "babel": "6.3.13",
13 | "babel-cli": "^6.4.0",
14 | "babel-core": "^6.1.18",
15 | "babel-eslint": "4.1.3",
16 | "babel-preset-es2015": "^6.3.13",
17 | "babel-preset-react": "^6.3.13",
18 | "deasciifier": "0.0.2",
19 | "eslint": "1.7.2",
20 | "react": "^0.14.6",
21 | "webpack": "1.12.9"
22 | },
23 | "repository": {
24 | "type": "git",
25 | "url": "https://github.com/ustun/react-turkish-textarea.git"
26 | },
27 | "keywords": [
28 | "react-component",
29 | "textarea",
30 | "turkish",
31 | "react"
32 | ],
33 | "author": "Ustun Ozgur",
34 | "license": "MIT",
35 | "bugs": {
36 | "url": "https://github.com/ustun/react-turkish-textarea/issues"
37 | },
38 | "homepage": "https://github.com/ustun/react-turkish-textarea",
39 | "peerDependencies": {
40 | "react": "^0.14.0",
41 | "turkish-deasciifier": "1.0.0"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Deasciifier from 'turkish-deasciifier';
3 |
4 | const deascii = new Deasciifier();
5 |
6 | const TurkishTextArea = React.createClass({
7 |
8 | getDefaultProps() {
9 | return {
10 | enableCorrectionOnChange: true,
11 | enableCorrectionOnPaste: true,
12 | showToggleButtonForCorrectionOnChange: true,
13 | showToggleButtonForCorrectionOnPaste: true,
14 | showButtonForManualCorrection: true,
15 | labelForEnableCorrectionOnChange: 'Otomatik düzelt',
16 | labelForEnableCorrectionOnPaste: 'Yapıştırdıktan sonra otomatik düzelt',
17 | labelForManualCorrectionButton: 'Düzelt'
18 | };
19 | },
20 |
21 | getInitialState() {
22 | return {
23 | value: '',
24 | enableCorrectionOnPaste: this.props.enableCorrectionOnPaste,
25 | enableCorrectionOnChange: this.props.enableCorrectionOnChange
26 | };
27 | },
28 |
29 | setValue(value) {
30 | this.setState({value});
31 | },
32 |
33 | onChange(e) {
34 | if (!this.state.enableCorrectionOnChange) {
35 | if (this.props.onChange) {
36 | this.props.onChange(e);
37 | } else {
38 | this.setValue(e.target.value);
39 | }
40 | return;
41 | }
42 |
43 | // prevent calling onChange after onPaste, otherwise we get double input
44 | // FIXME: find a less hacky way
45 | if (this._justPasted) {
46 | this._justPasted = false;
47 | return;
48 | }
49 |
50 | const turkishValue = deascii.turkish_correct_last_word(e.target.value);
51 |
52 | if (this.props.onChange) {
53 | e.target.value = turkishValue;
54 | this.props.onChange(e);
55 | } else {
56 | this.setValue(turkishValue);
57 | }
58 | },
59 |
60 | onPaste(e) {
61 | if (!this.state.enableCorrectionOnPaste) {
62 | this.props.onPaste && this.props.onPaste(e);
63 | return;
64 | }
65 |
66 | const pastedValue = e.clipboardData.getData('Text');
67 | const turkishValue = deascii.deasciify(pastedValue);
68 |
69 | e.target.value = turkishValue;
70 |
71 | if (this.props.onChange) {
72 | this.props.onChange(e);
73 | } else {
74 | this.setValue(turkishValue);
75 | }
76 | this.props.onPaste && this.props.onPaste(e);
77 |
78 | this._justPasted = true;
79 | },
80 |
81 | toggleEnableCorrectionOnChange() {
82 | this.setState({enableCorrectionOnChange: !this.state.enableCorrectionOnChange});
83 |
84 | },
85 |
86 | toggleEnableCorrectionOnPaste() {
87 | this.setState({enableCorrectionOnPaste: !this.state.enableCorrectionOnPaste});
88 |
89 | },
90 |
91 | correctManually() {
92 | const turkishValue = deascii.deasciify(this.refs.tx.value);
93 |
94 | if (this.props.onChange) {
95 | this.props.onChange({target: {value: turkishValue}});
96 | } else {
97 | this.setValue(turkishValue);
98 | }
99 |
100 | this.refs.tx.focus();
101 |
102 | },
103 |
104 | render() {
105 | const customProps = {
106 | onChange: this.onChange,
107 | onPaste: this.onPaste,
108 | ref: 'tx'
109 | };
110 |
111 | const finalProps = Object.assign({},
112 | {value: this.state.value},
113 | this.props,
114 | customProps);
115 |
116 | // var textArea =
117 | var showControls = this.props.showToggleButtonForCorrectionOnPaste || this.props.showToggleButtonForCorrectionOnChange;
118 |
119 | if (showControls) {
120 | return
121 |
122 |
123 |
124 | {this.props.showToggleButtonForCorrectionOnChange && }
129 |
130 | {this.props.showToggleButtonForCorrectionOnPaste && }
135 |
136 | {this.props.showButtonForManualCorrection && }
137 |
;
138 | } else {
139 | return ;
140 | }
141 |
142 | }
143 | });
144 |
145 | export default TurkishTextArea;
146 |
--------------------------------------------------------------------------------
/test/library.spec.js:
--------------------------------------------------------------------------------
1 | import chai from 'chai';
2 | import Library from '../lib/library.js';
3 |
4 | chai.expect();
5 |
6 | const expect = chai.expect;
7 |
8 | var lib;
9 |
10 | describe('Given an instance of my library', function () {
11 | before(function () {
12 | lib = new Library();
13 | });
14 | describe('when I need the name', function () {
15 | it('should return the name', () => {
16 | expect(lib.name).to.be.equal('Library');
17 | });
18 | });
19 | });
--------------------------------------------------------------------------------