playbook_ui 16.1.0.pre.alpha.play264213818 → 16.1.0.pre.rc.0
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/advanced_table.html.erb +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +0 -4
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_inline_row_loading.md +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +1 -51
- data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +0 -34
- data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +0 -19
- data/app/pb_kits/playbook/pb_background/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_background/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_card/docs/_card_light.html.erb +3 -35
- data/app/pb_kits/playbook/pb_form/docs/_form_with_required_indicator.html.erb +1 -3
- data/app/pb_kits/playbook/pb_icon/icon.rb +1 -6
- data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +33 -35
- data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.jsx +1 -1
- data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.md +1 -1
- data/app/pb_kits/playbook/pb_multiple_users/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_multiple_users/multiple_users.html.erb +7 -51
- data/app/pb_kits/playbook/pb_multiple_users/multiple_users.rb +0 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +6 -33
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +0 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/index.js +0 -2
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.rb +0 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.test.js +18 -33
- data/app/pb_kits/playbook/pb_textarea/_textarea.tsx +11 -29
- data/app/pb_kits/playbook/pb_textarea/docs/example.yml +1 -4
- data/app/pb_kits/playbook/pb_textarea/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_textarea/index.ts +5 -12
- data/app/pb_kits/playbook/pb_textarea/textarea.html.erb +10 -10
- data/app/pb_kits/playbook/pb_textarea/textarea.rb +0 -30
- data/app/pb_kits/playbook/pb_textarea/textarea.test.js +1 -18
- data/dist/chunks/{_pb_line_graph-BgKF_zz1.js → _pb_line_graph-hxi01lk7.js} +1 -1
- data/dist/chunks/{_typeahead-B9a6ZsEP.js → _typeahead-BgLnlhzP.js} +1 -1
- data/dist/chunks/{globalProps-BhVYCqRf.js → globalProps-DgYwLYNx.js} +1 -1
- data/dist/chunks/{lib-DD34ZrWL.js → lib-NLxTo8OB.js} +1 -1
- data/dist/chunks/vendor.js +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/lib/playbook/align_content.rb +3 -13
- data/lib/playbook/align_items.rb +3 -13
- data/lib/playbook/align_self.rb +3 -13
- data/lib/playbook/display.rb +0 -5
- data/lib/playbook/flex.rb +3 -13
- data/lib/playbook/flex_direction.rb +3 -13
- data/lib/playbook/flex_grow.rb +3 -13
- data/lib/playbook/flex_shrink.rb +3 -13
- data/lib/playbook/flex_wrap.rb +3 -13
- data/lib/playbook/justify_content.rb +3 -13
- data/lib/playbook/justify_self.rb +3 -13
- data/lib/playbook/order.rb +3 -13
- data/lib/playbook/spacing.rb +9 -39
- data/lib/playbook/text_align.rb +3 -13
- data/lib/playbook/version.rb +2 -2
- data/lib/playbook/vertical_align.rb +3 -13
- data/lib/playbook/z_index.rb +0 -5
- metadata +6 -47
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_inline_row_loading_rails.html.erb +0 -64
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_inline_row_loading_rails.md +0 -18
- data/app/pb_kits/playbook/pb_background/docs/_background_responsive.jsx +0 -30
- data/app/pb_kits/playbook/pb_background/docs/_background_responsive.md +0 -1
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_input_display.html.erb +0 -74
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_input_display.jsx +0 -87
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_input_display.md +0 -3
- data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.html.erb +0 -30
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_required_indicator.jsx +0 -35
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_required_indicator.md +0 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_required_indicator.html.erb +0 -10
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_required_indicator.jsx +0 -21
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_required_indicator.md +0 -3
- data/app/pb_kits/playbook/pb_table/docs/_sections.yml +0 -68
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_input_options.html.erb +0 -39
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_input_options.md +0 -3
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_required_indicator.html.erb +0 -5
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_required_indicator.jsx +0 -25
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_required_indicator.md +0 -3
- data/app/pb_kits/playbook/utilities/test/globalProps/borderRadius.test.js +0 -33
- data/app/pb_kits/playbook/utilities/test/globalProps/bottom.test.js +0 -60
- data/app/pb_kits/playbook/utilities/test/globalProps/cursor.test.js +0 -42
- data/app/pb_kits/playbook/utilities/test/globalProps/dark.test.js +0 -33
- data/app/pb_kits/playbook/utilities/test/globalProps/gap.test.js +0 -87
- data/app/pb_kits/playbook/utilities/test/globalProps/globalProps.integration.test.js +0 -936
- data/app/pb_kits/playbook/utilities/test/globalProps/height.test.js +0 -68
- data/app/pb_kits/playbook/utilities/test/globalProps/htmlOptions.test.js +0 -510
- data/app/pb_kits/playbook/utilities/test/globalProps/left.test.js +0 -60
- data/app/pb_kits/playbook/utilities/test/globalProps/lineHeight.test.js +0 -33
- data/app/pb_kits/playbook/utilities/test/globalProps/margin.test.js +0 -95
- data/app/pb_kits/playbook/utilities/test/globalProps/numberSpacing.test.js +0 -33
- data/app/pb_kits/playbook/utilities/test/globalProps/overflow.test.js +0 -68
- data/app/pb_kits/playbook/utilities/test/globalProps/padding.test.js +0 -95
- data/app/pb_kits/playbook/utilities/test/globalProps/position.test.js +0 -33
- data/app/pb_kits/playbook/utilities/test/globalProps/right.test.js +0 -60
- data/app/pb_kits/playbook/utilities/test/globalProps/shadow.test.js +0 -33
- data/app/pb_kits/playbook/utilities/test/globalProps/textAlign.test.js +0 -41
- data/app/pb_kits/playbook/utilities/test/globalProps/top.test.js +0 -60
- data/app/pb_kits/playbook/utilities/test/globalProps/verticalAlign.test.js +0 -40
- data/app/pb_kits/playbook/utilities/test/globalProps/width.test.js +0 -66
- data/app/pb_kits/playbook/utilities/test/globalProps/zIndex.test.js +0 -50
|
@@ -21,9 +21,6 @@ module Playbook
|
|
|
21
21
|
prop :template
|
|
22
22
|
prop :placeholder
|
|
23
23
|
prop :input_options
|
|
24
|
-
prop :label
|
|
25
|
-
prop :required_indicator, type: Playbook::Props::Boolean,
|
|
26
|
-
default: false
|
|
27
24
|
|
|
28
25
|
def classname
|
|
29
26
|
generate_classname("pb_rich_text_editor_kit", simple_class, focus_class, sticky_class, separator: " ")
|
|
@@ -54,8 +51,6 @@ module Playbook
|
|
|
54
51
|
template: template,
|
|
55
52
|
placeholder: placeholder,
|
|
56
53
|
inputOptions: input_options,
|
|
57
|
-
label: label,
|
|
58
|
-
requiredIndicator: required_indicator,
|
|
59
54
|
}
|
|
60
55
|
end
|
|
61
56
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { render, screen, fireEvent, waitFor
|
|
2
|
+
import { render, screen, fireEvent, waitFor } from '../utilities/test-utils'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
5
|
|
|
@@ -89,14 +89,14 @@ const TestAdvancedEditor = ({ toolbarOnFocus = false, ...props }) => {
|
|
|
89
89
|
describe('Advanced TipTap Editor works as expected', () => {
|
|
90
90
|
test('renders advanced editor with toolbar', () => {
|
|
91
91
|
render(<TestAdvancedEditor />)
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
const kit = screen.getByTestId(testId)
|
|
94
94
|
expect(kit).toHaveClass(kitClass)
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
// Check for advanced container
|
|
97
97
|
const advancedContainer = kit.querySelector('.pb_rich_text_editor_advanced_container')
|
|
98
98
|
expect(advancedContainer).toBeInTheDocument()
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
// Check for toolbar
|
|
101
101
|
const toolbar = kit.querySelector('.toolbar')
|
|
102
102
|
expect(toolbar).toBeInTheDocument()
|
|
@@ -104,7 +104,7 @@ describe('Advanced TipTap Editor works as expected', () => {
|
|
|
104
104
|
|
|
105
105
|
test('renders advanced editor without toolbar when advancedEditorToolbar is false', () => {
|
|
106
106
|
render(<TestAdvancedEditor advancedEditorToolbar={false} />)
|
|
107
|
-
|
|
107
|
+
|
|
108
108
|
const kit = screen.getByTestId(testId)
|
|
109
109
|
const toolbar = kit.querySelector('.toolbar')
|
|
110
110
|
expect(toolbar).not.toBeInTheDocument()
|
|
@@ -112,17 +112,17 @@ describe('Advanced TipTap Editor works as expected', () => {
|
|
|
112
112
|
|
|
113
113
|
test('shows/hides toolbar on focus when focus is enabled', async () => {
|
|
114
114
|
render(<TestAdvancedEditor focus />)
|
|
115
|
-
|
|
115
|
+
|
|
116
116
|
const kit = screen.getByTestId(testId)
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
// Initially toolbar should be hidden
|
|
119
119
|
let toolbar = kit.querySelector('.toolbar')
|
|
120
120
|
expect(toolbar).not.toBeInTheDocument()
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
const editorElement = kit.querySelector('.ProseMirror')
|
|
123
123
|
// Focus the editor
|
|
124
124
|
fireEvent.focus(editorElement)
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
// Toolbar should now be visible
|
|
127
127
|
await waitFor(() => {
|
|
128
128
|
toolbar = kit.querySelector('.toolbar')
|
|
@@ -133,7 +133,7 @@ describe('Advanced TipTap Editor works as expected', () => {
|
|
|
133
133
|
|
|
134
134
|
test('supports simple prop with advanced editor', () => {
|
|
135
135
|
render(<TestAdvancedEditor simple />)
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
const kit = screen.getByTestId(testId)
|
|
138
138
|
const toolbar = kit.querySelector('.toolbar')
|
|
139
139
|
expect(toolbar).toBeInTheDocument()
|
|
@@ -144,7 +144,7 @@ describe('Advanced TipTap Editor works as expected', () => {
|
|
|
144
144
|
|
|
145
145
|
test('supports sticky prop with advanced editor', () => {
|
|
146
146
|
render(<TestAdvancedEditor sticky />)
|
|
147
|
-
|
|
147
|
+
|
|
148
148
|
const kit = screen.getByTestId(testId)
|
|
149
149
|
const stickyToolbar = kit.querySelector('.pb_rich_text_editor_tiptap_toolbar_sticky')
|
|
150
150
|
expect(stickyToolbar).toBeInTheDocument()
|
|
@@ -154,52 +154,37 @@ describe('Advanced TipTap Editor works as expected', () => {
|
|
|
154
154
|
test('applies aria-label when provided', () => {
|
|
155
155
|
const ariaLabel = 'Rich Text Editor'
|
|
156
156
|
render(<TestAdvancedEditor aria={{ label: ariaLabel }} />)
|
|
157
|
-
|
|
157
|
+
|
|
158
158
|
const kit = screen.getByTestId(testId)
|
|
159
159
|
expect(kit).toHaveAttribute('aria-label', ariaLabel)
|
|
160
160
|
})
|
|
161
161
|
|
|
162
162
|
test('supports inline prop with advanced editor', () => {
|
|
163
163
|
render(<TestAdvancedEditor inline />)
|
|
164
|
-
|
|
164
|
+
|
|
165
165
|
const kit = screen.getByTestId(testId)
|
|
166
166
|
const toolbar = kit.querySelector('.toolbar')
|
|
167
167
|
expect(toolbar).toBeInTheDocument()
|
|
168
168
|
expect(kit).toHaveClass(`${kitClass} inline`)
|
|
169
169
|
})
|
|
170
170
|
|
|
171
|
-
test('renders required indicator asterisk when requiredIndicator is true', () => {
|
|
172
|
-
render(
|
|
173
|
-
<RichTextEditor
|
|
174
|
-
data={{ testid: testId }}
|
|
175
|
-
label="Label"
|
|
176
|
-
requiredIndicator
|
|
177
|
-
/>
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
const kit = screen.getByTestId(testId)
|
|
181
|
-
const label = within(kit).getByText(/Label/)
|
|
182
|
-
|
|
183
|
-
expect(label).toBeInTheDocument()
|
|
184
|
-
expect(kit).toHaveTextContent('*')
|
|
185
|
-
})
|
|
186
|
-
|
|
187
171
|
describe('TipTap Editor Functionality', () => {
|
|
188
172
|
test('can type and update content', async () => {
|
|
189
173
|
render(<TestAdvancedEditor />)
|
|
190
|
-
|
|
174
|
+
|
|
191
175
|
const kit = screen.getByTestId(testId)
|
|
192
176
|
const editorContent = kit.querySelector('.ProseMirror')
|
|
193
|
-
|
|
177
|
+
|
|
194
178
|
// Focus and type in the editor
|
|
195
179
|
fireEvent.focus(editorContent)
|
|
196
|
-
fireEvent.input(editorContent, {
|
|
180
|
+
fireEvent.input(editorContent, {
|
|
197
181
|
target: { textContent: 'New content' }
|
|
198
182
|
})
|
|
199
|
-
|
|
183
|
+
|
|
200
184
|
await waitFor(() => {
|
|
201
185
|
expect(editorContent).toHaveTextContent('New content')
|
|
202
186
|
})
|
|
203
187
|
})
|
|
204
188
|
})
|
|
205
189
|
})
|
|
190
|
+
|
|
@@ -13,7 +13,6 @@ import Body from '../pb_body/_body'
|
|
|
13
13
|
import Caption from '../pb_caption/_caption'
|
|
14
14
|
import Flex from '../pb_flex/_flex'
|
|
15
15
|
import FlexItem from '../pb_flex/_flex_item'
|
|
16
|
-
import colors from '../tokens/exports/_colors.module.scss'
|
|
17
16
|
|
|
18
17
|
import { stripEmojisForPaste, applyEmojiMask } from '../utilities/emojiMask'
|
|
19
18
|
|
|
@@ -37,7 +36,6 @@ type TextareaProps = {
|
|
|
37
36
|
value?: string,
|
|
38
37
|
name?: string,
|
|
39
38
|
required?: boolean,
|
|
40
|
-
requiredIndicator?: boolean,
|
|
41
39
|
rows?: number,
|
|
42
40
|
resize: "none" | "both" | "horizontal" | "vertical" | "auto",
|
|
43
41
|
onChange?: InputCallback<HTMLTextAreaElement>,
|
|
@@ -52,7 +50,6 @@ const Textarea = ({
|
|
|
52
50
|
disabled,
|
|
53
51
|
emojiMask = false,
|
|
54
52
|
htmlOptions = {},
|
|
55
|
-
id,
|
|
56
53
|
inline = false,
|
|
57
54
|
resize = 'none',
|
|
58
55
|
error,
|
|
@@ -63,7 +60,6 @@ const Textarea = ({
|
|
|
63
60
|
onChange = () => {},
|
|
64
61
|
placeholder,
|
|
65
62
|
required,
|
|
66
|
-
requiredIndicator = false,
|
|
67
63
|
rows = 4,
|
|
68
64
|
value,
|
|
69
65
|
...props
|
|
@@ -88,7 +84,7 @@ const Textarea = ({
|
|
|
88
84
|
if (emojiMask) {
|
|
89
85
|
const pastedText = e.clipboardData.getData('text')
|
|
90
86
|
const filteredText = stripEmojisForPaste(pastedText)
|
|
91
|
-
|
|
87
|
+
|
|
92
88
|
if (pastedText !== filteredText) {
|
|
93
89
|
e.preventDefault()
|
|
94
90
|
const textarea = e.currentTarget
|
|
@@ -97,10 +93,10 @@ const Textarea = ({
|
|
|
97
93
|
const currentValue = textarea.value
|
|
98
94
|
const newValue = currentValue.slice(0, start) + filteredText + currentValue.slice(end)
|
|
99
95
|
const newCursorPosition = start + filteredText.length
|
|
100
|
-
|
|
96
|
+
|
|
101
97
|
textarea.value = newValue
|
|
102
98
|
textarea.selectionStart = textarea.selectionEnd = newCursorPosition
|
|
103
|
-
|
|
99
|
+
|
|
104
100
|
onChange({ ...e, target: textarea, currentTarget: textarea } as unknown as ChangeEvent<HTMLTextAreaElement>)
|
|
105
101
|
}
|
|
106
102
|
}
|
|
@@ -128,21 +124,7 @@ const Textarea = ({
|
|
|
128
124
|
{...htmlProps}
|
|
129
125
|
className={classes}
|
|
130
126
|
>
|
|
131
|
-
|
|
132
|
-
<label htmlFor={id}>
|
|
133
|
-
{
|
|
134
|
-
requiredIndicator ? (
|
|
135
|
-
<Caption className="pb_text_input_kit_label">
|
|
136
|
-
{label} <span style={{ color: `${colors.error}` }}>*</span>
|
|
137
|
-
</Caption>
|
|
138
|
-
) : (
|
|
139
|
-
<Caption className="pb_text_input_kit_label"
|
|
140
|
-
text={label}
|
|
141
|
-
/>
|
|
142
|
-
)
|
|
143
|
-
}
|
|
144
|
-
</label>
|
|
145
|
-
)}
|
|
127
|
+
<Caption text={label} />
|
|
146
128
|
{children || (
|
|
147
129
|
<textarea
|
|
148
130
|
disabled={disabled}
|
|
@@ -161,19 +143,19 @@ const Textarea = ({
|
|
|
161
143
|
{error ? (
|
|
162
144
|
<>
|
|
163
145
|
{characterCount ? (
|
|
164
|
-
<Flex
|
|
165
|
-
spacing="between"
|
|
146
|
+
<Flex
|
|
147
|
+
spacing="between"
|
|
166
148
|
vertical="center"
|
|
167
149
|
>
|
|
168
150
|
<FlexItem>
|
|
169
|
-
<Body
|
|
151
|
+
<Body
|
|
170
152
|
margin="none"
|
|
171
153
|
status="negative"
|
|
172
|
-
text={error}
|
|
154
|
+
text={error}
|
|
173
155
|
/>
|
|
174
156
|
</FlexItem>
|
|
175
157
|
<FlexItem>
|
|
176
|
-
<Caption
|
|
158
|
+
<Caption
|
|
177
159
|
margin="none"
|
|
178
160
|
size="xs"
|
|
179
161
|
text={characterCounter()}
|
|
@@ -181,7 +163,7 @@ const Textarea = ({
|
|
|
181
163
|
</FlexItem>
|
|
182
164
|
</Flex>
|
|
183
165
|
) : (
|
|
184
|
-
<Body
|
|
166
|
+
<Body
|
|
185
167
|
status="negative"
|
|
186
168
|
text={error}
|
|
187
169
|
/>
|
|
@@ -189,7 +171,7 @@ const Textarea = ({
|
|
|
189
171
|
</>
|
|
190
172
|
) : (
|
|
191
173
|
noCount && (
|
|
192
|
-
<Caption
|
|
174
|
+
<Caption
|
|
193
175
|
margin="none"
|
|
194
176
|
size="xs"
|
|
195
177
|
text={characterCounter()}
|
|
@@ -8,8 +8,6 @@ examples:
|
|
|
8
8
|
- textarea_character_counter: Character Counter
|
|
9
9
|
- textarea_inline: Inline
|
|
10
10
|
- textarea_emoji_mask: Emoji Mask
|
|
11
|
-
- textarea_required_indicator: Required Indicator
|
|
12
|
-
- textarea_input_options: Input Options
|
|
13
11
|
|
|
14
12
|
react:
|
|
15
13
|
- textarea_default: Default
|
|
@@ -19,9 +17,8 @@ examples:
|
|
|
19
17
|
- textarea_character_counter: Character Counter
|
|
20
18
|
- textarea_inline: Inline
|
|
21
19
|
- textarea_emoji_mask: Emoji Mask
|
|
22
|
-
- textarea_required_indicator: Required Indicator
|
|
23
20
|
|
|
24
21
|
swift:
|
|
25
22
|
- textarea_default_swift: Default
|
|
26
23
|
- textarea_error_swift: Textarea w/ Error
|
|
27
|
-
- textarea_props_swift: ""
|
|
24
|
+
- textarea_props_swift: ""
|
|
@@ -5,4 +5,3 @@ export { default as TextareaError } from './_textarea_error.jsx'
|
|
|
5
5
|
export { default as TextareaCharacterCounter } from './_textarea_character_counter.jsx'
|
|
6
6
|
export { default as TextareaInline } from './_textarea_inline.jsx'
|
|
7
7
|
export { default as TextareaEmojiMask } from './_textarea_emoji_mask.jsx'
|
|
8
|
-
export { default as TextareaRequiredIndicator } from './_textarea_required_indicator.jsx'
|
|
@@ -11,21 +11,18 @@ export default class PbTextarea extends PbEnhancedElement {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
hasEmojiMask(): boolean {
|
|
14
|
-
if (!this.element) return false
|
|
15
14
|
return (this.element as HTMLElement).dataset.pbEmojiMask === "true"
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
onInput
|
|
19
|
-
if (!this.element) return
|
|
20
|
-
|
|
17
|
+
onInput(): void {
|
|
21
18
|
if ((this.element as HTMLElement).closest('.resize_auto')) {
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
this.style.height = 'auto'
|
|
20
|
+
this.style.height = (this.scrollHeight) + 'px'
|
|
24
21
|
}
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
handleEmojiInput = (): void => {
|
|
28
|
-
if (!this.
|
|
25
|
+
if (!this.hasEmojiMask()) return
|
|
29
26
|
|
|
30
27
|
if (this.skipNextEmojiFilter) {
|
|
31
28
|
this.skipNextEmojiFilter = false
|
|
@@ -36,7 +33,7 @@ export default class PbTextarea extends PbEnhancedElement {
|
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
handleEmojiPaste = (event: ClipboardEvent): void => {
|
|
39
|
-
if (!this.
|
|
36
|
+
if (!this.hasEmojiMask()) return
|
|
40
37
|
|
|
41
38
|
const pastedText = event.clipboardData?.getData('text') || ''
|
|
42
39
|
const filteredText = stripEmojisForPaste(pastedText)
|
|
@@ -60,8 +57,6 @@ export default class PbTextarea extends PbEnhancedElement {
|
|
|
60
57
|
}
|
|
61
58
|
|
|
62
59
|
connect(): void {
|
|
63
|
-
if (!this.element) return
|
|
64
|
-
|
|
65
60
|
if ((this.element as HTMLElement).closest('.resize_auto')) {
|
|
66
61
|
this.element.setAttribute('style', 'height:' + (this.element as HTMLTextAreaElement).scrollHeight + 'px;overflow-y:hidden;')
|
|
67
62
|
this.element.addEventListener('input', this.onInput, false)
|
|
@@ -74,8 +69,6 @@ export default class PbTextarea extends PbEnhancedElement {
|
|
|
74
69
|
}
|
|
75
70
|
|
|
76
71
|
disconnect(): void {
|
|
77
|
-
if (!this.element) return
|
|
78
|
-
|
|
79
72
|
this.element.removeEventListener('input', this.onInput, false)
|
|
80
73
|
this.element.removeEventListener('input', this.handleEmojiInput, false)
|
|
81
74
|
this.element.removeEventListener('paste', this.handleEmojiPaste as EventListener, false)
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
<%= pb_content_tag do %>
|
|
2
2
|
<% if object.label.present? %>
|
|
3
|
-
<% if object.required_indicator %>
|
|
4
|
-
<%= pb_rails("caption", props: { text: object.label, dark: object.dark }) do %>
|
|
5
|
-
<%= object.label %><span style="color: #DA0014;"> *</span>
|
|
6
|
-
<% end %>
|
|
7
|
-
<% else %>
|
|
8
3
|
<%= pb_rails("caption", props: {text: object.label, dark: object.dark}) %>
|
|
9
|
-
<% end %>
|
|
10
4
|
<% end %>
|
|
11
5
|
<% if content.present? %>
|
|
12
6
|
<%= content %>
|
|
@@ -14,10 +8,16 @@
|
|
|
14
8
|
<%= pb_rails("body", props: { dark: object.dark, status: "negative", text: object.error }) %>
|
|
15
9
|
<% end %>
|
|
16
10
|
<% else %>
|
|
17
|
-
<%=
|
|
18
|
-
object
|
|
19
|
-
|
|
20
|
-
object.
|
|
11
|
+
<%= text_area(
|
|
12
|
+
:object,
|
|
13
|
+
:method,
|
|
14
|
+
:data => object.textarea_options[:data],
|
|
15
|
+
:max_characters => object.max_characters,
|
|
16
|
+
:name => object.name,
|
|
17
|
+
:onkeyup => object.onkeyup,
|
|
18
|
+
:placeholder => object.placeholder,
|
|
19
|
+
:rows => object.rows,
|
|
20
|
+
:value => object.value) %>
|
|
21
21
|
<% if object.error %>
|
|
22
22
|
<% if object.character_count %>
|
|
23
23
|
<%= pb_rails("flex", props: { spacing: "between", vertical: "center" }) do %>
|
|
@@ -8,8 +8,6 @@ module Playbook
|
|
|
8
8
|
prop :error
|
|
9
9
|
prop :inline, type: Playbook::Props::Boolean,
|
|
10
10
|
default: false
|
|
11
|
-
prop :input_options, type: Playbook::Props::HashProp,
|
|
12
|
-
default: {}
|
|
13
11
|
prop :label
|
|
14
12
|
prop :method
|
|
15
13
|
prop :name
|
|
@@ -23,8 +21,6 @@ module Playbook
|
|
|
23
21
|
prop :character_count
|
|
24
22
|
prop :onkeyup
|
|
25
23
|
prop :max_characters
|
|
26
|
-
prop :required_indicator, type: Playbook::Props::Boolean,
|
|
27
|
-
default: false
|
|
28
24
|
|
|
29
25
|
def classname
|
|
30
26
|
generate_classname("pb_textarea_kit") + error_class + resize_class + inline_class
|
|
@@ -40,32 +36,6 @@ module Playbook
|
|
|
40
36
|
}
|
|
41
37
|
end
|
|
42
38
|
|
|
43
|
-
def all_textarea_attributes
|
|
44
|
-
# Merge data attributes: emoji_mask data + input_options data
|
|
45
|
-
data_attrs = textarea_options[:data] || {}
|
|
46
|
-
input_data = input_options[:data] || {}
|
|
47
|
-
merged_data = data_attrs.merge(input_data)
|
|
48
|
-
|
|
49
|
-
base_attributes = {
|
|
50
|
-
id: input_options[:id] || "object_method",
|
|
51
|
-
max_characters: max_characters,
|
|
52
|
-
name: name,
|
|
53
|
-
onkeyup: onkeyup,
|
|
54
|
-
placeholder: placeholder,
|
|
55
|
-
rows: rows,
|
|
56
|
-
value: value,
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
# Merge input_options (excluding data to handle separately)
|
|
60
|
-
input_options_without_data = input_options.except(:data)
|
|
61
|
-
result = base_attributes.merge(input_options_without_data)
|
|
62
|
-
|
|
63
|
-
# Add merged data if present (input_options data takes precedence over emoji_mask data)
|
|
64
|
-
result[:data] = merged_data unless merged_data.empty?
|
|
65
|
-
|
|
66
|
-
result
|
|
67
|
-
end
|
|
68
|
-
|
|
69
39
|
private
|
|
70
40
|
|
|
71
41
|
def error_class
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState } from "react"
|
|
2
|
-
import { render, screen, fireEvent
|
|
2
|
+
import { render, screen, fireEvent } from "../utilities/test-utils"
|
|
3
3
|
|
|
4
4
|
import Textarea from "./_textarea"
|
|
5
5
|
|
|
@@ -265,21 +265,4 @@ describe("Textarea Emoji Mask", () => {
|
|
|
265
265
|
fireEvent.change(textarea, { target: { value: 'àëǒüñ' } })
|
|
266
266
|
expect(textarea.value).toBe('àëǒüñ')
|
|
267
267
|
})
|
|
268
|
-
|
|
269
|
-
test('renders required indicator asterisk when requiredIndicator is true', () => {
|
|
270
|
-
render(
|
|
271
|
-
<Textarea
|
|
272
|
-
data={{ testid: testId }}
|
|
273
|
-
label="Name"
|
|
274
|
-
required
|
|
275
|
-
requiredIndicator
|
|
276
|
-
/>
|
|
277
|
-
)
|
|
278
|
-
|
|
279
|
-
const kit = screen.getByTestId(testId)
|
|
280
|
-
const label = within(kit).getByText(/Name/)
|
|
281
|
-
|
|
282
|
-
expect(label).toBeInTheDocument()
|
|
283
|
-
expect(kit).toHaveTextContent('*')
|
|
284
|
-
})
|
|
285
268
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx}from"react/jsx-runtime";import{useMemo}from"react";import{b as buildAriaProps,a as buildDataProps,c as buildHtmlProps,d as classnames,e as buildCss,g as globalProps}from"./globalProps-
|
|
1
|
+
import{jsx}from"react/jsx-runtime";import{useMemo}from"react";import{b as buildAriaProps,a as buildDataProps,c as buildHtmlProps,d as classnames,e as buildCss,g as globalProps}from"./globalProps-DgYwLYNx.js";import Highcharts from"highcharts";import HighchartsReact from"highcharts-react-official";import{t as typography,c as colors}from"./lib-NLxTo8OB.js";import highchartsMore from"highcharts/highcharts-more";import solidGauge from"highcharts/modules/solid-gauge";const barGraphTheme={title:{text:"",style:{color:colors.text_lt_default,fontFamily:typography.font_family_base,fontWeight:typography.bold,fontSize:typography.heading_3}},subtitle:{text:"",style:{fontFamily:typography.font_family_base,color:colors.text_lt_light,fontWeight:typography.regular,fontSize:typography.text_base}},chart:{type:"column"},tooltip:{backgroundColor:{linearGradient:{x1:0,y1:0,x2:0,y2:1},stops:[[0,colors.bg_dark],[1,colors.bg_dark]]},style:{fontFamily:typography.font_family_base,color:colors.text_dk_default,fontWeight:typography.regular,fontSize:typography.text_smaller}},colors:[colors.data_1,colors.data_2,colors.data_3,colors.data_4,colors.data_5,colors.data_6,colors.data_7],credits:{enabled:false},legend:{enabled:false,itemStyle:{color:colors.text_lt_light,fill:colors.text_lt_light,fontSize:typography.text_smaller}},xAxis:{gridLineWidth:0,lineColor:colors.border_light,tickColor:colors.border_light,labels:{style:{fontFamily:typography.font_family_base,color:colors.text_lt_lighter,fontWeight:typography.bold,fontSize:typography.text_smaller}},title:{style:{color:colors.text_lt_default,fontFamily:typography.font_family_base,fontWeight:typography.regular,fontSize:typography.heading_4}}},yAxis:{alternateGridColor:void 0,minorTickInterval:null,gridLineColor:colors.border_light,minorGridLineColor:colors.border_light,lineWidth:0,tickWidth:0,labels:{style:{fontFamily:typography.font_family_base,color:colors.text_lt_lighter,fontWeight:typography.bold,fontSize:typography.text_smaller}},title:{style:{fontFamily:typography.font_family_base,color:colors.text_lt_lighter,fontWeight:typography.bold,fontSize:typography.text_smaller}}}};const PbBarGraph=props=>{const{aria:aria={},data:data={},id:id,htmlOptions:htmlOptions={},options:options,className:className}=props;const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const classes=classnames(buildCss("pb_pb_bar_graph"),globalProps(props),className);const mergedOptions=useMemo((()=>{if(!options||typeof options!=="object"){console.error("❌ Invalid options passed to <PbBarGraph />",options);return{}}return Highcharts.merge({},barGraphTheme,options)}),[options]);return jsx("div",{children:jsx(HighchartsReact,{containerProps:{className:classnames(classes),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:mergedOptions})})};const pbCircleChartTheme={title:{text:"",style:{color:colors.text_lt_default,fontFamily:typography.font_family_base,fontWeight:typography.bold,fontSize:typography.heading_3}},chart:{type:"pie"},tooltip:{backgroundColor:{linearGradient:{x1:0,y1:0,x2:0,y2:1},stops:[[0,colors.bg_dark],[1,colors.bg_dark]]},pointFormat:'<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.y}</b>',followPointer:true,shadow:false,borderWidth:0,borderRadius:10,style:{fontFamily:typography.font_family_base,color:colors.text_dk_default,fontWeight:typography.regular,fontSize:typography.text_smaller}},plotOptions:{pie:{dataLabels:{enabled:false,connectorShape:"straight",connectorWidth:3,format:"<div>{point.name}</div>",style:{fontFamily:typography.font_family_base,fontSize:typography.text_smaller,color:colors.text_lt_light,fontWeight:typography.regular,textOutline:"2px $white"}},innerSize:"50%",borderColor:"",borderWidth:null,colors:[colors.data_1,colors.data_2,colors.data_3,colors.data_4,colors.data_5,colors.data_6,colors.data_7]}},legend:{layout:"horizontal",align:"center",verticalAlign:"bottom",itemStyle:{fontFamily:typography.font_family_base,color:colors.text_lt_light,fontWeight:typography.regular,fontSize:typography.text_smaller},itemHoverStyle:{color:colors.text_lt_default},itemHiddenStyle:{color:colors.text_lt_lighter}},credits:{enabled:false}};const PbCircleChart=props=>{const{aria:aria={},className:className,data:data={},id:id,htmlOptions:htmlOptions={},options:options}=props;const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const classes=classnames(buildCss("pb_pb_circle_chart"),globalProps(props),className);const mergedOptions=useMemo((()=>{if(!options||typeof options!=="object"){console.error("❌ Invalid options passed to <PbCircleChart />",options);return{}}return Highcharts.merge({},pbCircleChartTheme,options)}),[options]);return jsx("div",{children:jsx(HighchartsReact,{containerProps:{className:classnames(classes),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:mergedOptions})})};const pbGaugeGraphTheme={title:{text:"",style:{fontFamily:typography.font_family_base,fontSize:typography.text_larger}},chart:{type:"solidgauge",events:{render(){this.container;const arc=this.container.querySelector("path.gauge-pane");if(arc)arc.setAttribute("stroke-linejoin","round")}}},pane:{size:"90%",startAngle:-100,endAngle:100,background:[{borderWidth:20,innerRadius:"90%",outerRadius:"90%",shape:"arc",className:"gauge-pane",borderColor:colors.border_light,borderRadius:"50%"}]},tooltip:{backgroundColor:{linearGradient:{x1:0,y1:0,x2:0,y2:1},stops:[[0,colors.bg_dark],[1,colors.bg_dark]]},pointFormat:'<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.y}</b>',followPointer:true,shadow:false,borderWidth:0,borderRadius:10,style:{fontFamily:typography.font_family_base,color:colors.text_dk_default,fontWeight:typography.regular,fontSize:typography.text_smaller}},yAxis:{min:0,max:100,lineWidth:0,tickPositions:[]},plotOptions:{solidgauge:{borderColor:colors.data_1,borderWidth:20,color:colors.data_1,radius:90,innerRadius:"90%",y:-26,dataLabels:{borderWidth:0,color:colors.text_lt_default,enabled:true,format:'<span class="fix">{y:,f}</span>',style:{fontFamily:typography.font_family_base,fontWeight:typography.regular,fontSize:typography.heading_2},y:-26}}},credits:{enabled:false}};const PbGaugeChart=props=>{const{aria:aria={},className:className,data:data={},htmlOptions:htmlOptions={},id:id,ref:ref,options:options={}}=props;const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const classes=classnames(buildCss("pb_pb_gauge_chart"),globalProps(props),className);const mergedOptions=useMemo((()=>{if(!options||typeof options!=="object"){console.error("❌ Invalid options passed to <PbLineGraph />",options);return{}}return Highcharts.merge({},pbGaugeGraphTheme,options)}),[options]);highchartsMore(Highcharts);solidGauge(Highcharts);return jsx("div",{children:jsx(HighchartsReact,{containerProps:{className:classnames(classes),id:id,ref:ref,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:mergedOptions})})};const pbLineGraphTheme={title:{text:"",style:{color:colors.text_lt_default,fontFamily:typography.font_family_base,fontWeight:typography.bold,fontSize:typography.heading_3}},subtitle:{text:"",style:{fontFamily:typography.font_family_base,color:colors.text_lt_light,fontWeight:typography.regular,fontSize:typography.text_base}},chart:{type:"line"},tooltip:{backgroundColor:{linearGradient:{x1:0,y1:0,x2:0,y2:1},stops:[[0,colors.bg_dark],[1,colors.bg_dark]]},followPointer:true,shadow:false,borderWidth:0,borderRadius:10,style:{fontFamily:typography.font_family_base,color:colors.text_dk_default,fontWeight:typography.regular,fontSize:typography.text_smaller}},plotOptions:{line:{dataLabels:{enabled:false}}},credits:{enabled:false},legend:{enabled:false,itemStyle:{fontFamily:typography.font_family_base,color:colors.text_lt_light,fontWeight:typography.regular,fontSize:typography.text_smaller},itemHoverStyle:{color:colors.text_lt_default},itemHiddenStyle:{color:colors.text_lt_lighter}},colors:[colors.data_1,colors.data_2,colors.data_3,colors.data_4,colors.data_5,colors.data_6,colors.data_7],xAxis:{gridLineWidth:0,lineColor:colors.border_light,tickColor:colors.border_light,labels:{style:{fontFamily:typography.font_family_base,color:colors.text_lt_lighter,fontWeight:typography.bold,fontSize:typography.text_smaller}},title:{style:{color:colors.text_lt_default,fontFamily:typography.font_family_base,fontWeight:typography.regular,fontSize:typography.heading_4}}},yAxis:{alternateGridColor:void 0,minorTickInterval:null,gridLineColor:colors.border_light,minorGridLineColor:colors.border_light,lineWidth:0,tickWidth:0,tickPixelInterval:50,labels:{style:{fontFamily:typography.font_family_base,color:colors.text_lt_lighter,fontWeight:typography.bold,fontSize:typography.text_smaller}},title:{style:{fontFamily:typography.font_family_base,color:colors.text_lt_lighter,fontWeight:typography.bold,fontSize:typography.text_smaller}}}};const PbLineGraph=props=>{const{aria:aria={},className:className,data:data={},id:id,htmlOptions:htmlOptions={},options:options}=props;const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const classes=classnames(buildCss("pb_pb_line_graph"),globalProps(props),className);const mergedOptions=useMemo((()=>{if(!options||typeof options!=="object"){console.error("❌ Invalid options passed to <PbLineGraph />",options);return{}}return Highcharts.merge({},pbLineGraphTheme,options)}),[options]);return jsx("div",{children:jsx(HighchartsReact,{containerProps:{className:classnames(classes),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:mergedOptions})})};export{PbBarGraph as P,PbCircleChart as a,PbGaugeChart as b,PbLineGraph as c};
|