playbook_ui 12.15.0 → 12.16.0.pre.alpha.tiptaptestingpart1528

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_background/_background.tsx +1 -1
  3. data/app/pb_kits/playbook/pb_background/background.rb +1 -1
  4. data/app/pb_kits/playbook/pb_badge/_badge.scss +1 -0
  5. data/app/pb_kits/playbook/pb_badge/_badge.tsx +1 -1
  6. data/app/pb_kits/playbook/pb_badge/badge.rb +5 -1
  7. data/app/pb_kits/playbook/pb_badge/badge.test.js +16 -1
  8. data/app/pb_kits/playbook/pb_body/_body_mixins.scss +3 -3
  9. data/app/pb_kits/playbook/pb_caption/_caption_mixin.scss +2 -2
  10. data/app/pb_kits/playbook/pb_enhanced_element/index.ts +1 -1
  11. data/app/pb_kits/playbook/pb_icon_stat_value/_icon_stat_value.tsx +5 -5
  12. data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.html.erb +1 -1
  13. data/app/pb_kits/playbook/pb_nav/_item.tsx +6 -6
  14. data/app/pb_kits/playbook/pb_nav/_nav.tsx +2 -2
  15. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.scss +0 -5
  16. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +0 -4
  17. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorButton.tsx +49 -0
  18. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorTypes.ts +9 -0
  19. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx +62 -0
  20. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx +128 -0
  21. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarHistory.tsx +45 -0
  22. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarNodes.tsx +59 -0
  23. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.scss +1 -1
  24. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +23 -9
  25. data/app/pb_kits/playbook/pb_rich_text_editor/_tiptap_styles.scss +192 -0
  26. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.jsx +36 -0
  27. data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +1 -0
  28. data/app/pb_kits/playbook/pb_rich_text_editor/docs/index.js +1 -0
  29. data/app/pb_kits/playbook/pb_table/{_table.jsx → _table.tsx} +9 -11
  30. data/app/pb_kits/playbook/pb_table/{_table_row.jsx → _table_row.tsx} +7 -8
  31. data/app/pb_kits/playbook/pb_table/docs/_table_with_background_kit.html.erb +41 -0
  32. data/app/pb_kits/playbook/pb_table/docs/_table_with_background_kit.jsx +62 -0
  33. data/app/pb_kits/playbook/pb_table/docs/example.yml +2 -0
  34. data/app/pb_kits/playbook/pb_table/docs/index.js +1 -0
  35. data/app/pb_kits/playbook/pb_table/{index.js → index.ts} +4 -4
  36. data/app/pb_kits/playbook/pb_textarea/_textarea.tsx +129 -0
  37. data/app/pb_kits/playbook/pb_textarea/{index.js → index.tsx} +2 -0
  38. data/app/pb_kits/playbook/pb_textarea/textarea.test.js +213 -0
  39. data/app/pb_kits/playbook/tokens/_colors.scss +16 -1
  40. data/lib/playbook/version.rb +2 -2
  41. metadata +23 -13
  42. data/app/pb_kits/playbook/pb_flex/_flex_item.jsx +0 -41
  43. data/app/pb_kits/playbook/pb_textarea/_textarea.jsx +0 -135
@@ -14,6 +14,7 @@ try {
14
14
  } catch (_e) { /* do nothing */ }
15
15
 
16
16
  import { TrixEditor } from "react-trix"
17
+ import EditorToolbar from './TipTap/Toolbar'
17
18
 
18
19
  type Editor = {
19
20
  attributeIsActive?: Function,
@@ -27,7 +28,9 @@ type Editor = {
27
28
 
28
29
  type RichTextEditorProps = {
29
30
  aria?: { [key: string]: string },
31
+ advancedEditor?: any,
30
32
  toolbarBottom?: Boolean,
33
+ children?: React.ReactNode | React.ReactNode[]
31
34
  className?: string,
32
35
  data?: { [key: string]: string },
33
36
  focus?: boolean,
@@ -45,7 +48,9 @@ type RichTextEditorProps = {
45
48
  const RichTextEditor = (props: RichTextEditorProps) => {
46
49
  const {
47
50
  aria = {},
51
+ advancedEditor,
48
52
  toolbarBottom = false,
53
+ children,
49
54
  className,
50
55
  data = {},
51
56
  focus = false,
@@ -152,15 +157,24 @@ const RichTextEditor = (props: RichTextEditorProps) => {
152
157
  {...dataProps}
153
158
  className={css}
154
159
  >
155
- <TrixEditor
156
- className=""
157
- fileParamName={name}
158
- mergeTags={[]}
159
- onChange={onChange}
160
- onEditorReady={handleOnEditorReady}
161
- placeholder={placeholder}
162
- value={value}
163
- />
160
+ {
161
+ advancedEditor ? (
162
+ <div>
163
+ <EditorToolbar editor={advancedEditor}/>
164
+ { children }
165
+ </div>
166
+ ) : (
167
+ <TrixEditor
168
+ className=""
169
+ fileParamName={name}
170
+ mergeTags={[]}
171
+ onChange={onChange}
172
+ onEditorReady={handleOnEditorReady}
173
+ placeholder={placeholder}
174
+ value={value}
175
+ />
176
+ )
177
+ }
164
178
  </div>
165
179
  )
166
180
  }
@@ -0,0 +1,192 @@
1
+ @import "../tokens/border_radius";
2
+ @import "../tokens/colors";
3
+ @import "../tokens/spacing";
4
+ @import "../tokens/titles";
5
+ @import "../tokens/line_height";
6
+ @import "../tokens/typography";
7
+ @import "../tokens/shadows";
8
+ @import "../tokens/transition";
9
+
10
+ [class^="pb_rich_text_editor_kit"] {
11
+ .toolbar_button {
12
+ display: flex;
13
+ align-items: center;
14
+ background: $transparent;
15
+ border: none;
16
+ border-radius: $border_rad_heaviest;
17
+ color: $text_lt_light;
18
+ cursor: pointer;
19
+ &_icon {
20
+ width: $space_xl + 2;
21
+ height: $space_xl + 2;
22
+ }
23
+ &.open {
24
+ color: $primary;
25
+ }
26
+ &.active,
27
+ &:active {
28
+ color: $primary;
29
+ background-color: $bg_light;
30
+ }
31
+ &:hover:not([disabled]) {
32
+ background-color: $neutral_subtle;
33
+ }
34
+ &:disabled {
35
+ .pb_icon_kit {
36
+ color: $border_light;
37
+ }
38
+ }
39
+ &:focus-visible {
40
+ outline: none !important;
41
+ }
42
+ }
43
+
44
+ .toolbar {
45
+ border-radius: $border_rad_heaviest $border_rad_heaviest 0 0;
46
+ border: 1px solid $border_light;
47
+ overflow-x: auto;
48
+ &_block {
49
+ gap: $space_xs;
50
+ }
51
+ .editor-dropdown-button {
52
+ background: transparent;
53
+ border: none;
54
+ color: $text_lt_light;
55
+ cursor: pointer;
56
+ font-weight: $light;
57
+ padding: ($space_xs - 1) 0px;
58
+ width: $space_xl * 3;
59
+ }
60
+ }
61
+
62
+ .ProseMirror {
63
+ background: $white;
64
+ border: 1px solid $border_light;
65
+ border-top-color: transparent;
66
+ border-bottom-right-radius: $border_rad_heaviest;
67
+ border-bottom-left-radius: $border_rad_heaviest;
68
+ height: 100%;
69
+ padding: 1rem 1.5rem 1.5rem 1.5rem;
70
+ line-height: $lh_loose;
71
+ :first-child {
72
+ margin-top: 0;
73
+ }
74
+
75
+ h4,
76
+ h5,
77
+ h6,
78
+ ul,
79
+ ol,
80
+ blockquote,
81
+ p {
82
+ margin: 1rem 0 0 0;
83
+ }
84
+
85
+ code {
86
+ font-family: monospace;
87
+ background: $bg_light;
88
+ padding: 0.1rem 0.3rem;
89
+ margin: 0 5px;
90
+ box-shadow: 0 2px 10px $shadow;
91
+ border-radius: 0.25rem;
92
+ overflow: hidden;
93
+ font-size: ($text_small - 1px);
94
+ }
95
+
96
+ pre {
97
+ background: $bg_dark;
98
+ padding: $space_sm;
99
+ border-radius: $border_rad_heaviest;
100
+ margin: 1.5rem 0 2rem 0;
101
+ code {
102
+ background: transparent;
103
+ box-shadow: none;
104
+ border: 0;
105
+ color: #faf6e4;
106
+ }
107
+ }
108
+ a {
109
+ color: $primary;
110
+ border-bottom: 1px solid $primary;
111
+ &:hover {
112
+ color: $text_lt_default;
113
+ border-bottom: 1px solid $text_lt_default;
114
+ }
115
+ }
116
+ blockquote {
117
+ font-size: $font_larger;
118
+ padding: $space_sm $space_md;
119
+ font-style: italic;
120
+ p {
121
+ margin: 0;
122
+ }
123
+ }
124
+ &:focus-visible {
125
+ outline: unset;
126
+ border-color: $primary;
127
+ @include transition_default;
128
+ }
129
+ h1 {
130
+ font-size: $text_larger;
131
+ line-height: $text_larger;
132
+ font-weight: $bolder;
133
+ letter-spacing: $lspace_tight;
134
+ margin: 2.1rem 0 0 0;
135
+ }
136
+ h2 {
137
+ font-size: $text_larger;
138
+ line-height: $text_larger;
139
+ font-weight: $bolder;
140
+ letter-spacing: $lspace_tight;
141
+ margin: 1.9rem 0 0 0;
142
+ }
143
+ h3 {
144
+ font-size: $text_large;
145
+ line-height: $text_large;
146
+ font-weight: $bolder;
147
+ letter-spacing: $lspace_tight;
148
+ margin: 1.7rem 0 0 0;
149
+ }
150
+ h4,
151
+ h5,
152
+ h6 {
153
+ font-size: $text_base;
154
+ line-height: $text_base;
155
+ letter-spacing: $lspace_tight;
156
+ font-weight: $bolder;
157
+ }
158
+ hr {
159
+ margin: 2.2rem 0;
160
+ box-sizing: content-box;
161
+ overflow: hidden;
162
+ background: transparent;
163
+ border-bottom: 1px solid $transparent;
164
+ height: 1px;
165
+ padding: 0;
166
+ background-color: $border_light;
167
+ border: 0;
168
+ }
169
+ ol {
170
+ margin: 1rem 0 0 0;
171
+ padding-left: $space_md;
172
+ list-style: decimal;
173
+ li {
174
+ margin: 2px 0;
175
+ p {
176
+ margin: 0;
177
+ }
178
+ }
179
+ }
180
+ ul {
181
+ list-style-position: disc;
182
+ margin: 1rem 0 0 0;
183
+ padding-left: $space_md;
184
+ li {
185
+ margin: 2px 0;
186
+ p {
187
+ margin: 0;
188
+ }
189
+ }
190
+ }
191
+ }
192
+ }
@@ -0,0 +1,36 @@
1
+ import React from 'react'
2
+ import { RichTextEditor } from '../..'
3
+ import { useEditor, EditorContent } from "@tiptap/react"
4
+ import StarterKit from "@tiptap/starter-kit"
5
+ import Link from '@tiptap/extension-link'
6
+
7
+
8
+ const RichTextEditorAdvancedDefault = (props) => {
9
+
10
+ const editor = useEditor({
11
+ extensions: [
12
+ StarterKit,
13
+ Link
14
+ ],
15
+ content:"Add your text here. You can format your text, add links, quotes, and bullets."
16
+ })
17
+ if (!editor) {
18
+ return null
19
+ }
20
+
21
+
22
+
23
+
24
+ return (
25
+ <div>
26
+ <RichTextEditor
27
+ advancedEditor={editor}
28
+ {...props}
29
+ >
30
+ <EditorContent editor={editor}/>
31
+ </RichTextEditor>
32
+ </div>
33
+ )
34
+ }
35
+
36
+ export default RichTextEditorAdvancedDefault
@@ -13,6 +13,7 @@ examples:
13
13
 
14
14
  react:
15
15
  - rich_text_editor_default: Default
16
+ - rich_text_editor_advanced_default: Advanced Default
16
17
  - rich_text_editor_simple: Simple
17
18
  - rich_text_editor_attributes: Attributes
18
19
  - rich_text_editor_focus: Focus
@@ -7,3 +7,4 @@ export { default as RichTextEditorTemplates } from './_rich_text_editor_template
7
7
  export { default as RichTextEditorToolbarBottom } from './_rich_text_editor_toolbar_bottom.jsx'
8
8
  export { default as RichTextEditorInline } from './_rich_text_editor_inline.jsx'
9
9
  export { default as RichTextEditorPreview } from './_rich_text_editor_preview.jsx'
10
+ export { default as RichTextEditorAdvancedDefault } from './_rich_text_editor_advanced_default.jsx'
@@ -1,19 +1,17 @@
1
- /* @flow */
2
-
3
- import React, { useEffect, type Node } from 'react'
1
+ import React, { useEffect } from 'react'
4
2
  import classnames from 'classnames'
5
3
  import { buildAriaProps, buildDataProps } from '../utilities/props'
6
4
  import { globalProps } from '../utilities/globalProps'
7
- import PbTable from './'
5
+ import PbTable from '.'
8
6
 
9
7
  type TableProps = {
10
- aria?: object,
11
- children: array<Node> | Node,
8
+ aria?: { [key: string]: string },
9
+ children: React.ReactNode[] | React.ReactNode,
12
10
  className: string,
13
11
  collapse?: "sm" | "md" | "lg",
14
12
  container: boolean,
15
13
  dark?: boolean,
16
- data?: object,
14
+ data?: { [key: string]: string },
17
15
  dataTable: boolean,
18
16
  disableHover: boolean,
19
17
  id?: string,
@@ -52,9 +50,9 @@ const Table = (props: TableProps) => {
52
50
 
53
51
  return (
54
52
  <table
55
- {...ariaProps}
56
- {...dataProps}
57
- className={classnames(
53
+ {...ariaProps}
54
+ {...dataProps}
55
+ className={classnames(
58
56
  'pb_table',
59
57
  `table-${size}`,
60
58
  `table-responsive-${responsive}`,
@@ -70,7 +68,7 @@ const Table = (props: TableProps) => {
70
68
  tableCollapseCss,
71
69
  className
72
70
  )}
73
- id={id}
71
+ id={id}
74
72
  >
75
73
  {children}
76
74
  </table>
@@ -1,14 +1,13 @@
1
- /* @flow */
2
1
  import React from 'react'
3
2
  import classnames from 'classnames'
4
3
  import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
5
4
  import { globalProps } from '../utilities/globalProps'
6
5
 
7
6
  type TableRowPropTypes = {
8
- aria?: object,
9
- children: array<React.ReactNode> | React.ReactNode,
7
+ aria?: { [key: string]: string },
8
+ children: React.ReactNode[] | React.ReactNode,
10
9
  className: string,
11
- data?: object,
10
+ data?: { [key: string]: string },
12
11
  id?: string,
13
12
  sideHighlightColor: string,
14
13
  }
@@ -31,10 +30,10 @@ const TableRow = (props: TableRowPropTypes) => {
31
30
 
32
31
  return (
33
32
  <tr
34
- {...ariaProps}
35
- {...dataProps}
36
- className={classes}
37
- id={id}
33
+ {...ariaProps}
34
+ {...dataProps}
35
+ className={classes}
36
+ id={id}
38
37
  >
39
38
  {children}
40
39
  </tr>
@@ -0,0 +1,41 @@
1
+ <%= pb_rails("table", props: { size: "sm", margin_bottom: "lg" }) do %>
2
+ <thead>
3
+ <tr>
4
+ <th>Column 1</th>
5
+ <th>Column 2</th>
6
+ <th>Column 3</th>
7
+ </tr>
8
+ </thead>
9
+ <tbody>
10
+ <tr>
11
+ <td>Value 1</td>
12
+ <td>Value 2</td>
13
+ <td>Value 3</td>
14
+ </tr>
15
+ <%= pb_rails("background", props: { background_color: "error_subtle", tag: "tr" }) do %>
16
+ <td>Value 1</td>
17
+ <td>Value 2</td>
18
+ <td>Value 3</td>
19
+ <% end %>
20
+ <tr>
21
+ <td>Value 1</td>
22
+ <td>Value 2</td>
23
+ <td>Value 3</td>
24
+ </tr>
25
+ <tr>
26
+ <td>Value 1</td>
27
+ <td>Value 2</td>
28
+ <td>Value 3</td>
29
+ </tr>
30
+ <%= pb_rails("background", props: { background_color: "warning_subtle", tag: "tr" }) do %>
31
+ <td>Value 1</td>
32
+ <td>Value 2</td>
33
+ <td>Value 3</td>
34
+ <% end %>
35
+ <tr>
36
+ <td>Value 1</td>
37
+ <td>Value 2</td>
38
+ <td>Value 3</td>
39
+ </tr>
40
+ </tbody>
41
+ <% end %>
@@ -0,0 +1,62 @@
1
+ import React from 'react'
2
+
3
+ import Table from '../_table'
4
+ import Background from "../../pb_background/_background"
5
+
6
+ const TableWithBackgroundKit = (props) => {
7
+ return (
8
+ <div>
9
+ <Table
10
+ {...props}
11
+ >
12
+ <thead>
13
+ <tr>
14
+ <th>{'Column 1'}</th>
15
+ <th>{'Column 2'}</th>
16
+ <th>{'Column 3'}</th>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <tr>
21
+ <td>{'Value 1'}</td>
22
+ <td>{'Value 2'}</td>
23
+ <td>{'Value 3'}</td>
24
+ </tr>
25
+ <Background
26
+ backgroundColor="error_subtle"
27
+ tag='tr'
28
+ >
29
+ <td>{'Value 1'}</td>
30
+ <td>{'Value 2'}</td>
31
+ <td>{'Value 3'}</td>
32
+ </Background>
33
+ <tr>
34
+ <td>{'Value 1'}</td>
35
+ <td>{'Value 2'}</td>
36
+ <td>{'Value 3'}</td>
37
+ </tr>
38
+ <tr>
39
+ <td>{'Value 1'}</td>
40
+ <td>{'Value 2'}</td>
41
+ <td>{'Value 3'}</td>
42
+ </tr>
43
+ <Background
44
+ backgroundColor="warning_subtle"
45
+ tag='tr'
46
+ >
47
+ <td>{'Value 1'}</td>
48
+ <td>{'Value 2'}</td>
49
+ <td>{'Value 3'}</td>
50
+ </Background>
51
+ <tr>
52
+ <td>{'Value 1'}</td>
53
+ <td>{'Value 2'}</td>
54
+ <td>{'Value 3'}</td>
55
+ </tr>
56
+ </tbody>
57
+ </Table>
58
+ </div>
59
+ )
60
+ }
61
+
62
+ export default TableWithBackgroundKit
@@ -20,6 +20,7 @@ examples:
20
20
  - table_two_plus_actions: Table with 2+ Actions
21
21
  - table_action_middle: Table with Actions in the Middle
22
22
  - table_icon_buttons: Table with Icon Buttons
23
+ - table_with_background_kit: Table With Background Kit
23
24
 
24
25
 
25
26
  react:
@@ -43,4 +44,5 @@ examples:
43
44
  - table_two_plus_actions: Table with 2+ Actions
44
45
  - table_action_middle: Table with Actions in the Middle
45
46
  - table_icon_buttons: Table with Icon Buttons
47
+ - table_with_background_kit: Table With Background Kit
46
48
 
@@ -18,3 +18,4 @@ export { default as TableAlignmentColumn } from './_table_alignment_column.jsx'
18
18
  export { default as TableAlignmentRow } from './_table_alignment_row.jsx'
19
19
  export { default as TableAlignmentShiftRow } from './_table_alignment_shift_row.jsx'
20
20
  export { default as TableAlignmentShiftData } from './_table_alignment_shift_data.jsx'
21
+ export { default as TableWithBackgroundKit } from './_table_with_background_kit.jsx'
@@ -9,16 +9,16 @@ export default class PbTable extends PbEnhancedElement {
9
9
  const tables = document.querySelectorAll('.table-responsive-collapse');
10
10
 
11
11
  // Each Table
12
- [].forEach.call(tables, (table) => {
12
+ [].forEach.call(tables, (table: HTMLTableElement) => {
13
13
  // Header Titles
14
- var headers = [].map.call(table.querySelectorAll('th'), (header) => {
14
+ var headers = [].map.call(table.querySelectorAll('th'), (header: Element) => {
15
15
  return header.textContent.replace(/\r?\n|\r/, '')
16
16
  });
17
17
 
18
18
  // for each row in tbody
19
- [].forEach.call(table.querySelectorAll('tbody tr'), (row) => {
19
+ [].forEach.call(table.querySelectorAll('tbody tr'), (row: HTMLTableRowElement) => {
20
20
  // for each cell
21
- [].forEach.call(row.cells, (cell, headerIndex) => {
21
+ [].forEach.call(row.cells, (cell: HTMLTableCellElement, headerIndex: number) => {
22
22
  // apply the attribute
23
23
  cell.setAttribute('data-title', headers[headerIndex])
24
24
  })
@@ -0,0 +1,129 @@
1
+ /* eslint-disable react-hooks/rules-of-hooks */
2
+
3
+ import React, { forwardRef, useEffect, useRef } from 'react'
4
+ import classnames from 'classnames'
5
+
6
+ import PbTextarea from '.'
7
+ import type { InputCallback } from '../types'
8
+
9
+ import { buildAriaProps, buildDataProps } from '../utilities/props'
10
+ import { globalProps, GlobalProps } from '../utilities/globalProps'
11
+
12
+ import Body from '../pb_body/_body'
13
+ import Caption from '../pb_caption/_caption'
14
+ import Flex from '../pb_flex/_flex'
15
+ import FlexItem from '../pb_flex/_flex_item'
16
+
17
+ type TextareaProps = {
18
+ aria?: {[key: string]: string},
19
+ characterCount?: string,
20
+ className?: string,
21
+ children?: React.ReactChild[],
22
+ data?: {[key: string]: string},
23
+ disabled?: boolean,
24
+ error?: string,
25
+ id?: string,
26
+ inline?: boolean,
27
+ object?: string,
28
+ method?: string,
29
+ label?: string,
30
+ maxCharacters?: string,
31
+ placeholder?: string,
32
+ value?: string,
33
+ name?: string,
34
+ required?: boolean,
35
+ rows?: number,
36
+ resize: "none" | "both" | "horizontal" | "vertical" | "auto",
37
+ onChange?: InputCallback<HTMLTextAreaElement>,
38
+ } & GlobalProps
39
+
40
+ const Textarea = ({
41
+ aria = {},
42
+ characterCount,
43
+ className,
44
+ children,
45
+ data = {},
46
+ disabled,
47
+ inline = false,
48
+ resize = 'none',
49
+ error,
50
+ label,
51
+ maxCharacters,
52
+ name,
53
+ onChange = () => {},
54
+ placeholder,
55
+ required,
56
+ rows = 4,
57
+ value,
58
+ ...props
59
+ }: TextareaProps, ref: any) => {
60
+ ref = useRef<HTMLTextAreaElement>(null)
61
+ useEffect(() => {
62
+ if (ref.current && resize === 'auto') {
63
+ PbTextarea.addMatch(ref.current)
64
+ }
65
+ })
66
+
67
+ const errorClass = error ? 'error' : null
68
+ const inlineClass = inline ? 'inline' : ''
69
+ const resizeClass = `resize_${resize}`
70
+ const classes = classnames('pb_textarea_kit', errorClass, inlineClass, resizeClass, globalProps(props), className)
71
+ const noCount = typeof characterCount !== 'undefined'
72
+ const ariaProps: {[key: string]: any} = buildAriaProps(aria)
73
+ const dataProps: {[key: string]: any} = buildDataProps(data)
74
+
75
+ const characterCounter = () => {
76
+ return maxCharacters && characterCount ? `${checkIfZero(characterCount)} / ${maxCharacters}` : `${checkIfZero(characterCount)}`
77
+ }
78
+
79
+ const checkIfZero = (characterCount: string | number) => {
80
+ return characterCount == 0 ? characterCount.toString() : characterCount
81
+ }
82
+
83
+ return (
84
+ <div
85
+ {...ariaProps}
86
+ {...dataProps}
87
+ className={classes}
88
+ >
89
+ <Caption text={label} />
90
+ {children || (
91
+ <textarea
92
+ className="pb_textarea_kit"
93
+ disabled={disabled}
94
+ name={name}
95
+ onChange={onChange}
96
+ placeholder={placeholder}
97
+ ref={ref}
98
+ required={required}
99
+ rows={rows}
100
+ value={value}
101
+ {...props}
102
+ />
103
+ )}
104
+
105
+ {error ? (
106
+ <>
107
+ {characterCount ? (
108
+ <Flex spacing="between" vertical="center">
109
+ <FlexItem>
110
+ <Body margin="none" status="negative" text={error} />
111
+ </FlexItem>
112
+ <FlexItem>
113
+ <Caption margin="none" size="xs" text={characterCounter()} />
114
+ </FlexItem>
115
+ </Flex>
116
+ ) : (
117
+ <Body status="negative" text={error} />
118
+ )}
119
+ </>
120
+ ) : (
121
+ noCount && (
122
+ <Caption margin="none" size="xs" text={characterCounter()} />
123
+ )
124
+ )}
125
+ </div>
126
+ );
127
+ }
128
+
129
+ export default forwardRef(Textarea)
@@ -1,6 +1,8 @@
1
1
  import PbEnhancedElement from '../pb_enhanced_element'
2
2
 
3
3
  export default class PbTextarea extends PbEnhancedElement {
4
+ style: {[key: string]: string}
5
+ scrollHeight: string
4
6
  static get selector() {
5
7
  return '.resize_auto textarea'
6
8
  }