playbook_ui 16.2.0.pre.alpha.advancedtablecascadingcollapsereact14676 → 16.2.0.pre.alpha.faiconbuttonfix14520
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/Components/CustomCell.tsx +4 -17
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +1 -3
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableActions.ts +9 -21
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/ExpansionControlHelpers.tsx +1 -25
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +1 -5
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +1 -74
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +1 -2
- data/app/pb_kits/playbook/pb_collapsible/index.js +4 -16
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +1 -4
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +2 -2
- data/app/pb_kits/playbook/pb_dialog/index.js +5 -45
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +0 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +2 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +1 -1
- data/app/pb_kits/playbook/pb_dropdown/index.js +13 -68
- data/app/pb_kits/playbook/pb_dropdown/keyboard_accessibility.js +3 -19
- data/app/pb_kits/playbook/pb_enhanced_element/element_observer.ts +1 -1
- data/app/pb_kits/playbook/pb_enhanced_element/index.ts +1 -2
- data/app/pb_kits/playbook/pb_icon/icon.rb +19 -168
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +0 -2
- data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_pagination/_pagination.scss +1 -101
- data/app/pb_kits/playbook/pb_pagination/_pagination.test.jsx +1 -172
- data/app/pb_kits/playbook/pb_pagination/_pagination.tsx +15 -178
- data/app/pb_kits/playbook/pb_pagination/docs/_pagination_default.jsx +1 -1
- data/app/pb_kits/playbook/pb_passphrase/_passphrase.tsx +0 -4
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +0 -2
- data/app/pb_kits/playbook/pb_select/_select.tsx +0 -2
- data/app/pb_kits/playbook/pb_select/select.html.erb +2 -2
- data/app/pb_kits/playbook/pb_star_rating/star_rating.html.erb +1 -1
- data/app/pb_kits/playbook/pb_star_rating/subcomponents/_star_rating_interactive.tsx +0 -1
- data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +0 -2
- data/app/pb_kits/playbook/pb_text_input/text_input.html.erb +2 -2
- data/app/pb_kits/playbook/pb_textarea/_textarea.tsx +21 -43
- data/app/pb_kits/playbook/pb_textarea/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_textarea/docs/index.js +8 -9
- data/app/pb_kits/playbook/pb_textarea/textarea.html.erb +4 -4
- data/app/pb_kits/playbook/pb_textarea/textarea.rb +2 -6
- data/app/pb_kits/playbook/pb_textarea/textarea.test.js +1 -134
- data/app/pb_kits/playbook/pb_time_picker/_time_picker.tsx +0 -6
- data/app/pb_kits/playbook/pb_time_picker/time_picker.test.jsx +2 -2
- data/app/pb_kits/playbook/pb_tooltip/index.js +15 -60
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +1 -1
- data/dist/chunks/{_pb_line_graph-BGY7jEks.js → _pb_line_graph-BSLb5VXP.js} +1 -1
- data/dist/chunks/{_typeahead-QhswHQnq.js → _typeahead-DXIBDeMj.js} +1 -1
- data/dist/chunks/{globalProps-CK2YuA9O.js → globalProps-DyTB8IdV.js} +1 -1
- data/dist/chunks/{lib-DspaUdlc.js → lib-9wz3x5jl.js} +1 -1
- data/dist/chunks/vendor.js +5 -5
- data/dist/menu.yml +1 -1
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/forms/builder/checkbox_field.rb +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +6 -12
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_cascade_collapse.jsx +0 -50
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_cascade_collapse.md +0 -1
- data/app/pb_kits/playbook/pb_kit_registry/index.ts +0 -180
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_react_reset_key.jsx +0 -100
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_react_reset_key.md +0 -1
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_input_options.jsx +0 -68
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import React, { useState, useEffect
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
2
|
import classnames from 'classnames'
|
|
3
3
|
import { GlobalProps, globalProps } from '../utilities/globalProps'
|
|
4
4
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
|
5
5
|
import Icon from '../pb_icon/_icon';
|
|
6
|
-
import Body from '../pb_body/_body';
|
|
7
|
-
import Flex from '../pb_flex/_flex';
|
|
8
|
-
import Detail from '../pb_detail/_detail';
|
|
9
6
|
|
|
10
7
|
type PaginationProps = {
|
|
11
8
|
aria?: { [key: string]: string },
|
|
@@ -32,104 +29,16 @@ const Pagination = ( props: PaginationProps) => {
|
|
|
32
29
|
total = 1,
|
|
33
30
|
} = props
|
|
34
31
|
const [currentPage, setCurrentPage] = useState(current);
|
|
35
|
-
const [isMobile, setIsMobile] = useState(false);
|
|
36
|
-
// State for dropdown menu
|
|
37
|
-
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
38
|
-
const [dropdownPosition, setDropdownPosition] = useState<'below' | 'above'>('below');
|
|
39
|
-
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
40
|
-
|
|
41
|
-
// Detect mobile screen size (767px and below)
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
const checkMobile = () => {
|
|
44
|
-
setIsMobile(window.innerWidth <= 767);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
checkMobile();
|
|
48
|
-
|
|
49
|
-
// Throttle resize event to prevent performance issues in Nitro where
|
|
50
|
-
// the Nitro Nav is also listening to the resize event and causing multiple re-renders
|
|
51
|
-
let timeoutId: NodeJS.Timeout | null = null;
|
|
52
|
-
const throttledCheckMobile = () => {
|
|
53
|
-
if (timeoutId === null) {
|
|
54
|
-
timeoutId = setTimeout(() => {
|
|
55
|
-
checkMobile();
|
|
56
|
-
timeoutId = null;
|
|
57
|
-
}, 150);
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
window.addEventListener('resize', throttledCheckMobile);
|
|
62
|
-
|
|
63
|
-
return () => {
|
|
64
|
-
window.removeEventListener('resize', throttledCheckMobile);
|
|
65
|
-
if (timeoutId) clearTimeout(timeoutId);
|
|
66
|
-
};
|
|
67
|
-
}, []);
|
|
68
|
-
|
|
69
|
-
// Close dropdown when clicking outside
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
const handleClickOutside = (event: MouseEvent) => {
|
|
72
|
-
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
73
|
-
setIsDropdownOpen(false);
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
if (isDropdownOpen) {
|
|
78
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return () => {
|
|
82
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
83
|
-
};
|
|
84
|
-
}, [isDropdownOpen]);
|
|
85
|
-
|
|
86
|
-
// Determine dropdown position based on available space
|
|
87
|
-
const checkDropdownPosition = () => {
|
|
88
|
-
if (dropdownRef.current) {
|
|
89
|
-
const rect = dropdownRef.current.getBoundingClientRect();
|
|
90
|
-
const dropdownHeight = 200;
|
|
91
|
-
const spaceBelow = window.innerHeight - rect.bottom;
|
|
92
|
-
const spaceAbove = rect.top;
|
|
93
|
-
|
|
94
|
-
if (spaceBelow < dropdownHeight && spaceAbove > spaceBelow) {
|
|
95
|
-
setDropdownPosition('above');
|
|
96
|
-
} else {
|
|
97
|
-
setDropdownPosition('below');
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const handleDropdownToggle = () => {
|
|
103
|
-
if (!isDropdownOpen) {
|
|
104
|
-
checkDropdownPosition();
|
|
105
|
-
}
|
|
106
|
-
setIsDropdownOpen(!isDropdownOpen);
|
|
107
|
-
};
|
|
108
32
|
|
|
109
33
|
const handlePageChange = (pageNumber: number) => {
|
|
110
34
|
if (pageNumber >= 1 && pageNumber <= total) {
|
|
111
35
|
setCurrentPage(pageNumber);
|
|
112
|
-
setIsDropdownOpen(false);
|
|
113
36
|
if (onChange) {
|
|
114
37
|
onChange(pageNumber);
|
|
115
38
|
}
|
|
116
39
|
}
|
|
117
40
|
};
|
|
118
41
|
|
|
119
|
-
const createPageOptions = () => {
|
|
120
|
-
const options = [];
|
|
121
|
-
|
|
122
|
-
for (let pageNumber = 1; pageNumber <= total; pageNumber++) {
|
|
123
|
-
options.push({
|
|
124
|
-
label: String(pageNumber),
|
|
125
|
-
value: String(pageNumber),
|
|
126
|
-
id: `page-${pageNumber}`
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return options;
|
|
131
|
-
};
|
|
132
|
-
|
|
133
42
|
const renderPageButtons = (): JSX.Element[] => {
|
|
134
43
|
const buttons: JSX.Element[] = [];
|
|
135
44
|
|
|
@@ -244,92 +153,20 @@ const Pagination = ( props: PaginationProps) => {
|
|
|
244
153
|
className={classes}
|
|
245
154
|
id={id}
|
|
246
155
|
>
|
|
247
|
-
<div className=
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
</Flex>
|
|
262
|
-
</li>
|
|
263
|
-
<div className="pagination-dropdown"
|
|
264
|
-
ref={dropdownRef}
|
|
265
|
-
>
|
|
266
|
-
<div
|
|
267
|
-
className="pagination-dropdown-trigger"
|
|
268
|
-
onClick={handleDropdownToggle}
|
|
269
|
-
>
|
|
270
|
-
<Flex alignItems="center"
|
|
271
|
-
gap="xxs"
|
|
272
|
-
justify="between"
|
|
273
|
-
>
|
|
274
|
-
<Detail bold
|
|
275
|
-
color="default"
|
|
276
|
-
>
|
|
277
|
-
{currentPage}
|
|
278
|
-
</Detail>
|
|
279
|
-
<Detail color="default">
|
|
280
|
-
of {total}
|
|
281
|
-
</Detail>
|
|
282
|
-
<Icon color="primary"
|
|
283
|
-
icon={isDropdownOpen ? "chevron-up" : "chevron-down"}
|
|
284
|
-
size="xs"
|
|
285
|
-
/>
|
|
286
|
-
</Flex>
|
|
287
|
-
</div>
|
|
288
|
-
{isDropdownOpen && (
|
|
289
|
-
<div className={`pagination-dropdown-menu ${dropdownPosition}`}>
|
|
290
|
-
{createPageOptions().map((option) => (
|
|
291
|
-
<div
|
|
292
|
-
className={`pagination-dropdown-option ${Number(option.value) === currentPage ? 'active' : ''}`}
|
|
293
|
-
key={option.id}
|
|
294
|
-
onClick={() => handlePageChange(Number(option.value))}
|
|
295
|
-
>
|
|
296
|
-
<Body>Page {option.label}</Body>
|
|
297
|
-
</div>
|
|
298
|
-
))}
|
|
299
|
-
</div>
|
|
300
|
-
)}
|
|
301
|
-
</div>
|
|
302
|
-
<li
|
|
303
|
-
className={`pagination-right ${currentPage === total ? "disabled" : ""}`}
|
|
304
|
-
onClick={() => handlePageChange(currentPage + 1)}
|
|
305
|
-
>
|
|
306
|
-
<Flex alignItems="center">
|
|
307
|
-
<Detail color="default"
|
|
308
|
-
marginRight="xxs"
|
|
309
|
-
>
|
|
310
|
-
Next
|
|
311
|
-
</Detail>
|
|
312
|
-
<Icon icon="chevron-right" />
|
|
313
|
-
</Flex>
|
|
314
|
-
</li>
|
|
315
|
-
</Flex>
|
|
316
|
-
) : (
|
|
317
|
-
<>
|
|
318
|
-
<li
|
|
319
|
-
className={`pagination-left ${currentPage === 1 ? "disabled" : ""}`}
|
|
320
|
-
onClick={() => handlePageChange(currentPage - 1)}
|
|
321
|
-
>
|
|
322
|
-
<Icon icon="chevron-left" />
|
|
323
|
-
</li>
|
|
324
|
-
{renderPageButtons()}
|
|
325
|
-
<li
|
|
326
|
-
className={`pagination-right ${currentPage === total ? "disabled" : ""}`}
|
|
327
|
-
onClick={() => handlePageChange(currentPage + 1)}
|
|
328
|
-
>
|
|
329
|
-
<Icon icon="chevron-right" />
|
|
330
|
-
</li>
|
|
331
|
-
</>
|
|
332
|
-
)}
|
|
156
|
+
<div className="pb_pagination">
|
|
157
|
+
<li
|
|
158
|
+
className={`pagination-left ${currentPage === 1 ? 'disabled' : ''}`}
|
|
159
|
+
onClick={() => handlePageChange(currentPage - 1)}
|
|
160
|
+
>
|
|
161
|
+
<Icon icon="chevron-left" />
|
|
162
|
+
</li>
|
|
163
|
+
{renderPageButtons()}
|
|
164
|
+
<li
|
|
165
|
+
className={`pagination-right ${currentPage === total ? 'disabled' : ''}`}
|
|
166
|
+
onClick={() => handlePageChange(currentPage + 1)}
|
|
167
|
+
>
|
|
168
|
+
<Icon icon="chevron-right" />
|
|
169
|
+
</li>
|
|
333
170
|
</div>
|
|
334
171
|
</div>
|
|
335
172
|
);
|
|
@@ -119,14 +119,12 @@ const Passphrase = (props: PassphraseProps): React.ReactElement => {
|
|
|
119
119
|
{hasLabel && (requiredIndicator ? (
|
|
120
120
|
<Caption
|
|
121
121
|
className="passphrase-label"
|
|
122
|
-
color="lighter"
|
|
123
122
|
>
|
|
124
123
|
{label} <span className="required_indicator">*</span>
|
|
125
124
|
</Caption>
|
|
126
125
|
) : (
|
|
127
126
|
<Caption
|
|
128
127
|
className="passphrase-label"
|
|
129
|
-
color="lighter"
|
|
130
128
|
text={label}
|
|
131
129
|
/>
|
|
132
130
|
))}
|
|
@@ -144,14 +142,12 @@ const Passphrase = (props: PassphraseProps): React.ReactElement => {
|
|
|
144
142
|
orientation="column"
|
|
145
143
|
>
|
|
146
144
|
<Caption
|
|
147
|
-
color="lighter"
|
|
148
145
|
marginBottom="xs"
|
|
149
146
|
text="Tips for a good passphrase"
|
|
150
147
|
/>
|
|
151
148
|
<div>
|
|
152
149
|
{tips.map((tip, i) => (
|
|
153
150
|
<Caption
|
|
154
|
-
color="lighter"
|
|
155
151
|
key={i}
|
|
156
152
|
marginBottom="xs"
|
|
157
153
|
size="xs"
|
|
@@ -262,7 +262,6 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
|
|
|
262
262
|
{
|
|
263
263
|
requiredIndicator ? (
|
|
264
264
|
<Caption className="pb_text_input_kit_label"
|
|
265
|
-
color="lighter"
|
|
266
265
|
marginBottom="xs"
|
|
267
266
|
>
|
|
268
267
|
{label} <span style={{ color: `${colors.error}` }}>*</span>
|
|
@@ -270,7 +269,6 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
|
|
|
270
269
|
) : (
|
|
271
270
|
<Caption
|
|
272
271
|
className="pb_text_input_kit_label"
|
|
273
|
-
color="lighter"
|
|
274
272
|
marginBottom="xs"
|
|
275
273
|
text={label}
|
|
276
274
|
/>
|
|
@@ -134,14 +134,12 @@ const Select = ({
|
|
|
134
134
|
>
|
|
135
135
|
{requiredIndicator ? (
|
|
136
136
|
<Caption
|
|
137
|
-
color="lighter"
|
|
138
137
|
dark={props.dark}>
|
|
139
138
|
{label}
|
|
140
139
|
<span style={{ color: "#DA0014" }}> *</span>
|
|
141
140
|
</Caption>
|
|
142
141
|
) : (
|
|
143
142
|
<Caption
|
|
144
|
-
color="lighter"
|
|
145
143
|
dark={props.dark}
|
|
146
144
|
text={label}
|
|
147
145
|
/>
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
<% if object.label %>
|
|
5
5
|
<label class="pb_select_kit_label" for="<%= object.input_options[:id] || object.name %>">
|
|
6
6
|
<% if object.required_indicator %>
|
|
7
|
-
<%= pb_rails("caption", props: {
|
|
7
|
+
<%= pb_rails("caption", props: { dark: object.dark }) do %>
|
|
8
8
|
<%= object.label %><span style="color: #DA0014;"> *</span>
|
|
9
9
|
<% end %>
|
|
10
10
|
<% else %>
|
|
11
|
-
<%= pb_rails("caption", props: {
|
|
11
|
+
<%= pb_rails("caption", props: { text: object.label, dark: object.dark }) %>
|
|
12
12
|
<% end %>
|
|
13
13
|
</label>
|
|
14
14
|
<% end %>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<% else %>
|
|
38
38
|
<%= pb_rails("flex", props: { data: {"pb-star-rating-wrapper": "true" }, orientation: "column" }) do %>
|
|
39
39
|
<% if object.label.present? %>
|
|
40
|
-
<%= pb_rails("caption", props: {
|
|
40
|
+
<%= pb_rails("caption", props: {text: object.label, margin_bottom:"xs"}) %>
|
|
41
41
|
<% end %>
|
|
42
42
|
|
|
43
43
|
<%= hidden_input_tag %>
|
|
@@ -253,7 +253,6 @@ const TextInput = (props: TextInputProps, ref: React.LegacyRef<HTMLInputElement>
|
|
|
253
253
|
requiredIndicator ? (
|
|
254
254
|
<Caption
|
|
255
255
|
className="pb_text_input_kit_label"
|
|
256
|
-
color="lighter"
|
|
257
256
|
dark={dark}
|
|
258
257
|
>
|
|
259
258
|
{label} <span style={{ color: dark ? colors.text_error_dark : colors.text_error }}>*</span>
|
|
@@ -261,7 +260,6 @@ const TextInput = (props: TextInputProps, ref: React.LegacyRef<HTMLInputElement>
|
|
|
261
260
|
) : (
|
|
262
261
|
<Caption
|
|
263
262
|
className="pb_text_input_kit_label"
|
|
264
|
-
color="lighter"
|
|
265
263
|
dark={dark}
|
|
266
264
|
text={label}
|
|
267
265
|
/>
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
<% if object.label.present? %>
|
|
3
3
|
<label for="<%= object.input_options[:id] || object.id %>">
|
|
4
4
|
<% if object.required_indicator %>
|
|
5
|
-
<%= pb_rails("caption", props: { dark: object.dark, classname: "pb_text_input_kit_label"
|
|
5
|
+
<%= pb_rails("caption", props: { dark: object.dark, classname: "pb_text_input_kit_label" }) do %>
|
|
6
6
|
<%= object.label %><span style="color: #DA0014;"> *</span>
|
|
7
7
|
<% end %>
|
|
8
8
|
<% else %>
|
|
9
|
-
<%= pb_rails("caption", props: { text: object.label, dark: object.dark, classname: "pb_text_input_kit_label"
|
|
9
|
+
<%= pb_rails("caption", props: { text: object.label, dark: object.dark, classname: "pb_text_input_kit_label" }) %>
|
|
10
10
|
<% end %>
|
|
11
11
|
</label>
|
|
12
12
|
<% end %>
|
|
@@ -29,7 +29,6 @@ type TextareaProps = {
|
|
|
29
29
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
|
30
30
|
id?: string,
|
|
31
31
|
inline?: boolean,
|
|
32
|
-
inputOptions?: { [k: string]: any },
|
|
33
32
|
object?: string,
|
|
34
33
|
method?: string,
|
|
35
34
|
label?: string,
|
|
@@ -55,7 +54,6 @@ const Textarea = ({
|
|
|
55
54
|
htmlOptions = {},
|
|
56
55
|
id,
|
|
57
56
|
inline = false,
|
|
58
|
-
inputOptions = {},
|
|
59
57
|
resize = 'none',
|
|
60
58
|
error,
|
|
61
59
|
label,
|
|
@@ -77,9 +75,6 @@ const Textarea = ({
|
|
|
77
75
|
}
|
|
78
76
|
})
|
|
79
77
|
|
|
80
|
-
const containerId = id
|
|
81
|
-
const textareaId = inputOptions?.id ?? (id ? `${id}-input` : undefined)
|
|
82
|
-
|
|
83
78
|
const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
|
|
84
79
|
// Apply emoji mask if enabled using centralized helper
|
|
85
80
|
if (emojiMask) {
|
|
@@ -119,40 +114,13 @@ const Textarea = ({
|
|
|
119
114
|
const ariaProps: {[key: string]: string} = buildAriaProps(aria)
|
|
120
115
|
const dataProps: {[key: string]: string} = buildDataProps(data)
|
|
121
116
|
const htmlProps = buildHtmlProps(htmlOptions)
|
|
122
|
-
|
|
123
|
-
const {
|
|
124
|
-
"aria-describedby": customAriaDescribedBy,
|
|
125
|
-
"aria-invalid": customAriaInvalid,
|
|
126
|
-
data: inputOptionsData,
|
|
127
|
-
...inputOptionsWithoutAriaAndData
|
|
128
|
-
} = inputOptions || {}
|
|
129
|
-
|
|
130
|
-
const textareaDataProps = buildDataProps(inputOptionsData || {})
|
|
131
|
-
const errorId = error ? (containerId ? `${containerId}-error` : (textareaId ? `${textareaId}-error` : undefined)) : undefined
|
|
132
|
-
const ariaDescribedBy = [errorId, customAriaDescribedBy].filter(Boolean).join(" ")
|
|
133
|
-
|
|
134
|
-
const textareaAttrs = {
|
|
135
|
-
...(textareaId ? { id: textareaId } : {}),
|
|
136
|
-
"aria-describedby": ariaDescribedBy || undefined,
|
|
137
|
-
"aria-invalid": customAriaInvalid !== undefined ? customAriaInvalid : !!error,
|
|
138
|
-
name,
|
|
139
|
-
rows,
|
|
140
|
-
placeholder,
|
|
141
|
-
value,
|
|
142
|
-
disabled,
|
|
143
|
-
required,
|
|
144
|
-
onChange: emojiMask ? handleChange : onChange,
|
|
145
|
-
onPaste: emojiMask ? handlePaste : undefined,
|
|
146
|
-
...inputOptionsWithoutAriaAndData,
|
|
147
|
-
...textareaDataProps
|
|
148
|
-
}
|
|
149
|
-
|
|
150
117
|
const checkIfZero = (characterCount: string | number) => {
|
|
151
118
|
return characterCount == 0 ? characterCount.toString() : characterCount
|
|
152
119
|
}
|
|
153
120
|
const characterCounter = () => {
|
|
154
121
|
return maxCharacters && characterCount ? `${checkIfZero(characterCount)} / ${maxCharacters}` : `${checkIfZero(characterCount)}`
|
|
155
122
|
}
|
|
123
|
+
const errorId = error ? `${id}-error` : undefined
|
|
156
124
|
|
|
157
125
|
return (
|
|
158
126
|
<div
|
|
@@ -160,29 +128,39 @@ const Textarea = ({
|
|
|
160
128
|
{...dataProps}
|
|
161
129
|
{...htmlProps}
|
|
162
130
|
className={classes}
|
|
163
|
-
id={containerId}
|
|
164
131
|
>
|
|
165
132
|
{label && (
|
|
166
|
-
<label
|
|
133
|
+
<label htmlFor={id}>
|
|
167
134
|
{
|
|
168
135
|
requiredIndicator ? (
|
|
169
|
-
<Caption className="pb_text_input_kit_label"
|
|
170
|
-
|
|
171
|
-
>
|
|
172
|
-
{label} <span style={{ color: `${colors.text_error}` }}>{"*"}</span>
|
|
136
|
+
<Caption className="pb_text_input_kit_label">
|
|
137
|
+
{label} <span style={{ color: `${colors.text_error}` }}>*</span>
|
|
173
138
|
</Caption>
|
|
174
139
|
) : (
|
|
175
140
|
<Caption className="pb_text_input_kit_label"
|
|
176
|
-
color="lighter"
|
|
177
141
|
text={label}
|
|
178
142
|
/>
|
|
179
143
|
)
|
|
180
144
|
}
|
|
181
145
|
</label>
|
|
182
146
|
)}
|
|
183
|
-
{children ||
|
|
184
|
-
|
|
185
|
-
|
|
147
|
+
{children || (
|
|
148
|
+
<textarea
|
|
149
|
+
aria-describedby={errorId}
|
|
150
|
+
aria-invalid={!!error}
|
|
151
|
+
disabled={disabled}
|
|
152
|
+
id={id}
|
|
153
|
+
name={name}
|
|
154
|
+
onChange={emojiMask ? handleChange : onChange}
|
|
155
|
+
onPaste={emojiMask ? handlePaste : undefined}
|
|
156
|
+
placeholder={placeholder}
|
|
157
|
+
ref={ref}
|
|
158
|
+
required={required}
|
|
159
|
+
rows={rows}
|
|
160
|
+
value={value}
|
|
161
|
+
{...props}
|
|
162
|
+
/>
|
|
163
|
+
)}
|
|
186
164
|
|
|
187
165
|
{error ? (
|
|
188
166
|
<>
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export { default as TextareaDefault } from
|
|
1
|
+
export { default as TextareaDefault } from './_textarea_default.jsx'
|
|
2
2
|
export { default as TextareaDisabled } from './_textarea_disabled.jsx'
|
|
3
|
-
export { default as TextareaResize } from
|
|
4
|
-
export { default as TextareaCustom } from
|
|
5
|
-
export { default as TextareaError } from
|
|
6
|
-
export { default as TextareaCharacterCounter } from
|
|
7
|
-
export { default as TextareaInline } from
|
|
8
|
-
export { default as TextareaEmojiMask } from
|
|
9
|
-
export { default as TextareaRequiredIndicator } from
|
|
10
|
-
export { default as TextareaInputOptions } from "./_textarea_input_options.jsx"
|
|
3
|
+
export { default as TextareaResize } from './_textarea_resize.jsx'
|
|
4
|
+
export { default as TextareaCustom } from './_textarea_custom.jsx'
|
|
5
|
+
export { default as TextareaError } from './_textarea_error.jsx'
|
|
6
|
+
export { default as TextareaCharacterCounter } from './_textarea_character_counter.jsx'
|
|
7
|
+
export { default as TextareaInline } from './_textarea_inline.jsx'
|
|
8
|
+
export { default as TextareaEmojiMask } from './_textarea_emoji_mask.jsx'
|
|
9
|
+
export { default as TextareaRequiredIndicator } from './_textarea_required_indicator.jsx'
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<%= pb_content_tag(:div, id:
|
|
1
|
+
<%= pb_content_tag(:div, id: nil) do %>
|
|
2
2
|
<% if object.label.present? %>
|
|
3
|
-
<label for="<%= object.
|
|
3
|
+
<label for="<%= object.input_options[:id] || object.id %>" >
|
|
4
4
|
<% if object.required_indicator %>
|
|
5
|
-
<%= pb_rails("caption", props: {
|
|
5
|
+
<%= pb_rails("caption", props: { text: object.label, dark: object.dark }) do %>
|
|
6
6
|
<%= object.label %><span style="color: #DA0014;"> *</span>
|
|
7
7
|
<% end %>
|
|
8
8
|
<% else %>
|
|
9
|
-
<%= pb_rails("caption", props: {
|
|
9
|
+
<%= pb_rails("caption", props: {text: object.label, dark: object.dark}) %>
|
|
10
10
|
<% end %>
|
|
11
11
|
</label>
|
|
12
12
|
<% end %>
|
|
@@ -52,7 +52,7 @@ module Playbook
|
|
|
52
52
|
'aria-describedby': error.present? ? error_id : nil,
|
|
53
53
|
'aria-invalid': error.present?,
|
|
54
54
|
disabled: disabled,
|
|
55
|
-
id:
|
|
55
|
+
id: input_options[:id] || id || "object_method",
|
|
56
56
|
max_characters: max_characters,
|
|
57
57
|
name: name,
|
|
58
58
|
onkeyup: onkeyup,
|
|
@@ -71,12 +71,8 @@ module Playbook
|
|
|
71
71
|
result
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
def textarea_id
|
|
75
|
-
input_options[:id].presence || (id.present? ? "#{id}-input" : "object_method")
|
|
76
|
-
end
|
|
77
|
-
|
|
78
74
|
def error_id
|
|
79
|
-
|
|
75
|
+
"#{id}-error" if error.present?
|
|
80
76
|
end
|
|
81
77
|
|
|
82
78
|
private
|