Home | History | Annotate | Download | only in paper-action-dialog
      1 <!--
      2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
      3 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
      4 The complete set of authors may be found at http://polymer.github.io/AUTHORS
      5 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
      6 Code distributed by Google as part of the polymer project is also
      7 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
      8 -->
      9 
     10 <!--
     11 `paper-autogrow-textarea` is an element containing a textarea that grows in height as more
     12 lines of input are entered. Unless an explicit height or the `maxRows` property is set, it will
     13 never scroll.
     14 
     15 Example:
     16 
     17     <paper-autogrow-textarea id="a1">
     18         <textarea id="t1"></textarea>
     19     </paper-autogrow-textarea>
     20 
     21 Because the `textarea`'s `value` property is not observable, if you set the `value` imperatively
     22 you must call `update` to notify this element the value has changed.
     23 
     24 Example:
     25 
     26     /* using example HTML above */
     27     t1.value = 'some\ntext';
     28     a1.update();
     29 
     30 @group Paper Elements
     31 @element paper-autogrow-textarea
     32 @status unstable
     33 -->
     34 
     35 <link href="../polymer/polymer.html" rel="import">
     36 
     37 <polymer-element name="paper-autogrow-textarea" on-input="{{inputAction}}">
     38 <template>
     39 
     40   <style>
     41     :host {
     42       display: inline-block;
     43       position: relative;
     44       width: 400px;
     45     }
     46 
     47     .mirror-text {
     48       visibility: hidden;
     49       word-wrap: break-word;
     50     }
     51 
     52     ::content textarea {
     53       padding: 0;
     54       margin: 0;
     55       border: none;
     56       outline: none;
     57       resize: none;
     58       /* see comments in template */
     59       width: 100%;
     60       height: 100%;
     61     }
     62 
     63     ::content textarea:invalid {
     64       box-shadow: none;
     65     }
     66   </style>
     67 
     68   <!-- the mirror sizes the input/textarea so it grows with typing -->
     69   <div id="mirror" class="mirror-text" aria-hidden="true">&nbsp;</div>
     70 
     71   <!-- size the input/textarea with a div, because the textarea has intrinsic size in ff -->
     72   <div class="textarea-container" fit>
     73     <content></content>
     74   </div>
     75 
     76 </template>
     77 <script>
     78 
     79   Polymer({
     80 
     81     publish: {
     82 
     83         /**
     84          * The textarea that should auto grow.
     85          *
     86          * @attribute target
     87          * @type HTMLTextAreaElement
     88          * @default null
     89          */
     90         target: null,
     91 
     92         /**
     93          * The initial number of rows.
     94          *
     95          * @attribute rows
     96          * @type number
     97          * @default 1
     98          */
     99         rows: 1,
    100 
    101         /**
    102          * The maximum number of rows this element can grow to until it
    103          * scrolls. 0 means no maximum.
    104          *
    105          * @attribute maxRows
    106          * @type number
    107          * @default 0
    108          */
    109         maxRows: 0
    110     },
    111 
    112     tokens: null,
    113 
    114     observe: {
    115       rows: 'updateCached',
    116       maxRows: 'updateCached'
    117     },
    118 
    119     constrain: function(tokens) {
    120       var _tokens;
    121       tokens = tokens || [''];
    122       // Enforce the min and max heights for a multiline input to avoid measurement
    123       if (this.maxRows > 0 && tokens.length > this.maxRows) {
    124         _tokens = tokens.slice(0, this.maxRows);
    125       } else {
    126         _tokens = tokens.slice(0);
    127       }
    128       while (this.rows > 0 && _tokens.length < this.rows) {
    129         _tokens.push('');
    130       }
    131       return _tokens.join('
'
) + '&nbsp;'; 132 }, 133 134 valueForMirror: function(input) { 135 this.tokens = (input && input.value) ? input.value.replace(/&/gm, '&amp;').replace(/"/gm, '&quot;').replace(/'/gm, '&#39;').replace(/</gm, '&lt;').replace(/>/gm, '&gt;').split('\n') : ['']; 136 return this.constrain(this.tokens); 137 }, 138 139 /** 140 * Sizes this element to fit the input value. This function is automatically called 141 * when the user types in new input, but you must call this function if the value 142 * is updated imperatively. 143 * 144 * @method update 145 * @param Element The input 146 */ 147 update: function(input) { 148 this.$.mirror.innerHTML = this.valueForMirror(input); 149 }, 150 151 updateCached: function() { 152 this.$.mirror.innerHTML = this.constrain(this.tokens); 153 }, 154 155 inputAction: function(e) { 156 this.update(e.target); 157 } 158 159 }); 160 161 </script> 162 </polymer-element> 163