playbook_ui 15.3.0.pre.alpha.PLAY2322popoverconditionalrender11766 → 15.3.0.pre.alpha.PLAY2568richtexteditortiptaprails11790

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.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_popover/_popover.scss +0 -12
  3. data/app/pb_kits/playbook/pb_popover/_popover.tsx +29 -43
  4. data/app/pb_kits/playbook/pb_popover/docs/_popover_close.jsx +0 -7
  5. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx +1 -1
  6. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +66 -9
  7. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.html.erb +127 -0
  8. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default_rails.md +1 -0
  9. data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +1 -0
  10. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +13 -5
  11. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.rb +37 -0
  12. data/dist/chunks/{_line_graph-BxC7m53J.js → _line_graph-BEPzmsbH.js} +1 -1
  13. data/dist/chunks/_typeahead-D2PJbkOa.js +24 -0
  14. data/dist/chunks/{_weekday_stacked-DxdwXyYM.js → _weekday_stacked-BMW-UQod.js} +1 -1
  15. data/dist/chunks/{lib-CGxXTQ75.js → lib-DAV78mo-.js} +1 -1
  16. data/dist/chunks/{pb_form_validation-DebqlUKZ.js → pb_form_validation-BMpMKn3y.js} +1 -1
  17. data/dist/chunks/vendor.js +1 -1
  18. data/dist/playbook-doc.js +1 -19
  19. data/dist/playbook-rails-react-bindings.js +1 -1
  20. data/dist/playbook-rails.js +1 -1
  21. data/dist/playbook.css +1 -1
  22. data/lib/playbook/version.rb +1 -1
  23. metadata +9 -8
  24. data/app/pb_kits/playbook/pb_popover/docs/hook/useSmallScreenIndicator.tsx +0 -27
  25. data/dist/chunks/_typeahead-B1SiFvbF.js +0 -6
  26. /data/app/pb_kits/playbook/pb_rich_text_editor/docs/{_rich_text_editor_advanced_default.md → _rich_text_editor_advanced_default_react.md} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f59d7e7c4376efeb5b93d1b598f303d41137dbf51803939bfc58fe39bf2111c
4
- data.tar.gz: 7a6940c220be0ca9d18b3e2cd9a283539d66df7ee26245320d22e676b8244d93
3
+ metadata.gz: 16e3dd50149b3911c6d5802ac776033c73db6fc8c58fbf708290654e1fdc6ebe
4
+ data.tar.gz: b35ab5af0ac5b6187dfbd62aebdb04e23924e85fe8a13d1e26bf24d25cba9410
5
5
  SHA512:
6
- metadata.gz: f0aff746453cdd793520c58b60da087f0ed804622f33c98b25869cfdb19bb6a601ba4488772991c9edadf3e5bfbcfa1a8be38a883280f229ef62d0c761e7a4c6
7
- data.tar.gz: 807933083868d271c5d7ae0f2b3d0519ca4d35feb9ad1890cbcc3c0cd84c4e24690ee76151bafe2271eefc2683bf03f0ee396738951e77f1ec9307736135c583
6
+ metadata.gz: 778a8a8a0d96671e01cfd9e32e602e3c592a906243372786f616796ff43b2beda24977eaa5710c4a43f7fef41feb3e7a664157b40b80c7ea3ba676275ded2d62
7
+ data.tar.gz: 74230b35214bfee96cff3037d171cd9f4fca908929795812a54121bbb909482029bc88f0ddfbf525edcbfaab98004c0e4e52aefad7922c33509043f5086f1e29
@@ -56,15 +56,3 @@
56
56
  .pb_popover_reference_wrapper {
57
57
  display: inline-block;
58
58
  }
59
-
60
- // Temporary code to replicate bug - DO NOT MERGE
61
- @media (max-width: 619px) {
62
- :root {
63
- --is-pwa: 1;
64
- }
65
- }
66
- @media (min-width: 620px) {
67
- :root {
68
- --is-pwa: 0;
69
- }
70
- }
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable react/no-multi-comp */
2
- import React, { useEffect, useRef, useState } from "react";
2
+ import React, { useEffect, useState } from "react";
3
3
  import ReactDOM from "react-dom";
4
4
  import {
5
5
  Popper,
@@ -89,7 +89,7 @@ const Popover = (props: PbPopoverProps) => {
89
89
  const popoverSpacing =
90
90
  filteredGlobalProps.includes("dark") || !filteredGlobalProps
91
91
  ? "p_sm"
92
- : filteredGlobalProps
92
+ : filteredGlobalProps
93
93
  const overflowHandling = maxHeight || maxWidth ? "overflow_handling" : "";
94
94
  const zIndexStyle = zIndex ? { zIndex: zIndex } : {};
95
95
  const widthHeightStyles = () => {
@@ -170,56 +170,42 @@ const PbReactPopover = (props: PbPopoverProps): React.ReactElement => {
170
170
  minHeight,
171
171
  minWidth,
172
172
  width,
173
- closeOnClick,
174
- shouldClosePopover = noop,
175
173
  } = props;
176
174
 
177
- // Store latest callback in a ref to avoid re-runs
178
- const shouldClosePopoverRef = useRef(shouldClosePopover);
179
-
180
- // Update ref on change
181
175
  useEffect(() => {
182
- shouldClosePopoverRef.current = shouldClosePopover;
183
- }, [shouldClosePopover]);
176
+ const { closeOnClick, shouldClosePopover = noop } = props;
184
177
 
185
- useEffect(() => {
186
178
  if (!closeOnClick) return;
187
179
 
188
- // Function to handle popover event listener and targetId.
189
- // Ensure that whenever the component is conditionally rendered
190
- // that the old listener is removed and the new listener is
191
- // updated with the targetId.
192
- const handleClick = (e: MouseEvent) => {
193
- const target = e.target as HTMLElement
194
-
195
- const targetIsPopover =
196
- target.closest("#" + targetId) !== null;
197
- const targetIsReference =
198
- target.closest("#reference-" + targetId) !== null;
180
+ document.body.addEventListener(
181
+ "click",
182
+ (e: MouseEvent) => {
183
+ const target = e.target as HTMLElement
199
184
 
200
- const shouldClose = () => {
201
- setTimeout(() => shouldClosePopoverRef.current(true), 0);
202
- }
185
+ const targetIsPopover =
186
+ target.closest("#" + targetId) !== null;
187
+ const targetIsReference =
188
+ target.closest("#reference-" + targetId) !== null;
203
189
 
204
- switch (closeOnClick) {
205
- case "outside":
206
- if (!targetIsPopover && !targetIsReference) shouldClose();
207
- break;
208
- case "inside":
209
- if (targetIsPopover) shouldClose();
210
- break;
211
- case "any":
212
- if (targetIsPopover || !targetIsPopover && !targetIsReference) shouldClose();
213
- break;
214
- }
215
- };
190
+ const shouldClose = () => {
191
+ setTimeout(() => shouldClosePopover(true), 0);
192
+ }
216
193
 
217
- document.body.addEventListener("click", handleClick, { capture: true });
218
-
219
- return () => {
220
- document.body.removeEventListener("click", handleClick, { capture: true });
221
- };
222
- }, [targetId, closeOnClick]);
194
+ switch (closeOnClick) {
195
+ case "outside":
196
+ if (!targetIsPopover && !targetIsReference) shouldClose();
197
+ break;
198
+ case "inside":
199
+ if (targetIsPopover) shouldClose();
200
+ break;
201
+ case "any":
202
+ if (targetIsPopover || !targetIsPopover && !targetIsReference) shouldClose();
203
+ break;
204
+ }
205
+ },
206
+ { capture: true }
207
+ );
208
+ }, []);
223
209
 
224
210
  const popoverComponent = (
225
211
  <Popover
@@ -3,14 +3,11 @@ import React, { useState } from 'react'
3
3
  import Button from '../../pb_button/_button'
4
4
  import Flex from '../../pb_flex/_flex'
5
5
  import PbReactPopover from '../../pb_popover/_popover'
6
- // Temporary code to replicate bug - DO NOT MERGE (Revert example when done)
7
- import useSmallScreenIndicator from './hook/useSmallScreenIndicator'
8
6
 
9
7
  const PopoverClose = (props) => {
10
8
  const [showInsidePopover, setInsideShowPopover] = useState(false)
11
9
  const [showOutsidePopover, setOutsideShowPopover] = useState(false)
12
10
  const [showAnyPopover, setAnyShowPopover] = useState(false)
13
- const isPwa = useSmallScreenIndicator()
14
11
 
15
12
  const handleInsideShouldClosePopover = (shouldClosePopover) => {
16
13
  setInsideShowPopover(!shouldClosePopover)
@@ -62,10 +59,6 @@ const PopoverClose = (props) => {
62
59
  />
63
60
  )
64
61
 
65
- if (isPwa) {
66
- return null
67
- }
68
-
69
62
  return (
70
63
  <Flex spacing="between">
71
64
  <PbReactPopover
@@ -96,7 +96,7 @@ const EditorToolbar = ({ editor, extensions, simple, sticky }: any): React.React
96
96
  <SectionSeparator orientation="vertical" />
97
97
  <ToolbarNodes editor={editor} />
98
98
  {
99
- extensions && (
99
+ extensions && extensions.length > 0 && (
100
100
  <>
101
101
  <MoreExtensionsDropdown extensions={extensions}/>
102
102
  </>
@@ -1,6 +1,10 @@
1
1
  import React, { useEffect, useState, useRef } from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { TrixEditor } from 'react-trix'
4
+ // We have to import Tiptap here because it is not compatible with Rails
5
+ import { useEditor, EditorContent, Extensions } from '@tiptap/react'
6
+ import StarterKit from '@tiptap/starter-kit'
7
+ import Link from '@tiptap/extension-link'
4
8
 
5
9
  import inlineFocus from './inlineFocus'
6
10
  import useFocus from './useFocus'
@@ -30,6 +34,7 @@ type Editor = {
30
34
  type RichTextEditorProps = {
31
35
  aria?: { [key: string]: string },
32
36
  advancedEditor?: any,
37
+ railsAdvancedEditor?: boolean,
33
38
  advancedEditorToolbar?: boolean,
34
39
  toolbarBottom?: boolean,
35
40
  children?: React.ReactNode | React.ReactNode[],
@@ -48,13 +53,17 @@ type RichTextEditorProps = {
48
53
  sticky?: boolean,
49
54
  template: string,
50
55
  value?: string,
51
- maxWidth?: string
56
+ maxWidth?: string,
57
+ tipTapOptions?: {
58
+ extensions?: string[]
59
+ }
52
60
  } & GlobalProps
53
61
 
54
62
  const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
55
63
  const {
56
64
  aria = {},
57
65
  advancedEditor,
66
+ railsAdvancedEditor,
58
67
  advancedEditorToolbar = true,
59
68
  toolbarBottom = false,
60
69
  children,
@@ -72,7 +81,8 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
72
81
  sticky = false,
73
82
  template = '',
74
83
  value = '',
75
- maxWidth = "md"
84
+ maxWidth = "md",
85
+ tipTapOptions = {}
76
86
  } = props
77
87
 
78
88
  const ariaProps = buildAriaProps(aria),
@@ -81,6 +91,40 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
81
91
  [showToolbarOnFocus, setShowToolbarOnFocus] = useState(false),
82
92
  containerRef = useRef<HTMLDivElement>(null)
83
93
 
94
+ // POC: hypothetical link for external projects, build extensions array from tipTapOptions for railsAdvancedEditor
95
+ const buildExtensions = (extensionNames?: string[]) => {
96
+ const defaultExtensions = [StarterKit, Link]
97
+
98
+ if (!extensionNames || extensionNames.length === 0) {
99
+ return defaultExtensions
100
+ }
101
+
102
+ // POC: not sure if will work sort of "out of the box/everything goes" like this or will need to permit each of whichever TipTap extensions we want.
103
+ return defaultExtensions
104
+ }
105
+
106
+ // Creates TipTap editor when railsAdvancedEditor is true (from Rails)
107
+ const internalDependencyTiptapEditor = useEditor({
108
+ extensions: buildExtensions(tipTapOptions?.extensions),
109
+ content: value || '',
110
+ onUpdate: ({ editor }) => {
111
+ const html = editor.getHTML()
112
+ const text = editor.getText()
113
+ onChange(html, text)
114
+
115
+ // POC: Update hidden input for TipTap Rails Advanced Editor form submission
116
+ if (railsAdvancedEditor) {
117
+ const hiddenInput = document.getElementById(`hidden-input-${props.id || 'rich-text-editor'}`)
118
+ if (hiddenInput) {
119
+ (hiddenInput as HTMLInputElement).value = html ?? ''
120
+ }
121
+ }
122
+ },
123
+ }, [railsAdvancedEditor])
124
+
125
+ // Uses Internal Dependency TipTap editor if railsAdvancedEditor is true, otherwise uses passed editor instance
126
+ const currentEditor = railsAdvancedEditor ? internalDependencyTiptapEditor : advancedEditor
127
+
84
128
  const htmlProps = buildHtmlProps(htmlOptions)
85
129
 
86
130
  const handleOnEditorReady = (editorInstance: Editor) => {
@@ -140,7 +184,8 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
140
184
  }
141
185
 
142
186
  useEffect(() => {
143
- if (!advancedEditor || !focus) return
187
+ // POC: Updates advancedEditor to currentEditor in useEffect so focus works for Rails and React Advanced Editors
188
+ if (!currentEditor || !focus) return
144
189
 
145
190
  const handleFocus = () => setShowToolbarOnFocus(true)
146
191
 
@@ -149,7 +194,7 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
149
194
  setShowToolbarOnFocus(false)
150
195
  }
151
196
 
152
- const editorElement = advancedEditor?.view?.dom
197
+ const editorElement = currentEditor?.view?.dom
153
198
  if (editorElement) {
154
199
  editorElement.addEventListener('focus', handleFocus)
155
200
  }
@@ -162,7 +207,7 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
162
207
  }
163
208
  document.removeEventListener('mousedown', handleClickOutside)
164
209
  }
165
- }, [advancedEditor, focus])
210
+ }, [currentEditor, focus])
166
211
 
167
212
  //============= end focus prop with advanced editor=================
168
213
 
@@ -201,7 +246,7 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
201
246
  )
202
247
 
203
248
  // Determine if toolbar should be shown
204
- const shouldShowToolbar = focus && advancedEditor ? showToolbarOnFocus : advancedEditorToolbar
249
+ const shouldShowToolbar = focus && currentEditor ? showToolbarOnFocus : advancedEditorToolbar
205
250
 
206
251
  return (
207
252
  <div
@@ -212,20 +257,32 @@ const RichTextEditor = (props: RichTextEditorProps): React.ReactElement => {
212
257
  ref={focus ? containerRef : undefined}
213
258
  >
214
259
  {
215
- advancedEditor ? (
260
+ // POC: Uses currentEditor to render the editor content in return so works for Rails and React Advanced Editors
261
+ currentEditor ? (
216
262
  <div
217
263
  className={classnames("pb_rich_text_editor_advanced_container", {
218
264
  ["toolbar-active"]: shouldShowToolbar,
219
265
  })}
220
266
  >
221
267
  {shouldShowToolbar && (
222
- <EditorToolbar editor={advancedEditor}
268
+ <EditorToolbar editor={currentEditor}
223
269
  extensions={extensions}
224
270
  simple={simple}
225
271
  sticky={sticky}
226
272
  />
227
273
  )}
228
- { children }
274
+ {/* POC: EditorContent ternary needed for TipTap editor in Rails Advanced Editors*/}
275
+ {railsAdvancedEditor ? <EditorContent editor={currentEditor} /> : <>{children}</>}
276
+
277
+ {/* POC: Set up hidden input for TipTap Rails Advanced Editor form submission */}
278
+ {railsAdvancedEditor && (
279
+ <input
280
+ id={`hidden-input-${props.id || 'rich-text-editor'}`}
281
+ name={name || 'content'}
282
+ type="hidden"
283
+ value={currentEditor?.getHTML() ?? ''}
284
+ />
285
+ )}
229
286
  </div>
230
287
  ) : (
231
288
  <TrixEditor
@@ -0,0 +1,127 @@
1
+ <%= pb_rails("caption", props: { text: "Advanced Default" }) %>
2
+ <%= pb_rails("rich_text_editor", props: {
3
+ rails_advanced_editor: true,
4
+ margin_bottom: "md",
5
+ placeholder: "Start typing your content here...",
6
+ value: "Add your text here. You can format your text, add links, quotes, and bullets. This is the <strong>TipTap-based</strong> rich text editor rendered through Rails which requires a direct import of Tiptap into the tsx file.",
7
+ }) %>
8
+
9
+ <%= pb_rails("caption", props: { text: "AdvancedToolbar disabled" }) %>
10
+ <%= pb_rails("rich_text_editor", props: {
11
+ rails_advanced_editor: true,
12
+ advanced_editor_toolbar: false,
13
+ margin_bottom: "md",
14
+ value: "<p>This advanced editor has the toolbar disabled, showing only the content area.</p>"
15
+ }) %>
16
+
17
+ <%= pb_rails("caption", props: { text: "Advanced Simple" }) %>
18
+ <%= pb_rails("rich_text_editor", props: {
19
+ rails_advanced_editor: true,
20
+ margin_bottom: "md",
21
+ simple: true,
22
+ value: "<p>This is a <strong>simple</strong> version of the advanced editor with fewer toolbar options.</p>"
23
+ }) %>
24
+
25
+ <%= pb_rails("caption", props: { text: "Advanced Attributes" }) %>
26
+ <%= pb_rails("rich_text_editor", props: {
27
+ aria: { label: "rich-textarea" },
28
+ data: { key: "value", key2: "value2" },
29
+ name: "textarea-label",
30
+ rails_advanced_editor: true,
31
+ margin_bottom: "md",
32
+ value: "<p>This advanced editor has attributes, aria, and data attributes.</p>"
33
+ }) %>
34
+
35
+ <%= pb_rails("caption", props: { text: "Advanced Focus" }) %>
36
+ <%= pb_rails("rich_text_editor", props: {
37
+ rails_advanced_editor: true,
38
+ focus: true,
39
+ margin_bottom: "md",
40
+ value: "<p>This advanced editor shows the toolbar only when focused.</p>"
41
+ }) %>
42
+
43
+ <%= pb_rails("caption", props: { text: "Advanced Sticky" }) %>
44
+ <%= pb_rails("rich_text_editor", props: {
45
+ rails_advanced_editor: true,
46
+ sticky: true,
47
+ margin_bottom: "md",
48
+ value: "<p>In this example, when you scroll down, the rich text editor's toolbar will scroll along with the page and it will no longer be visible at the top of the page. Dummy text to enable scroll.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna.</p>"
49
+ }) %>
50
+
51
+ <%= pb_rails("caption", props: { text: "Advanced Templates" }) %>
52
+ <%= pb_rails("body", props: { margin_bottom: "md", text: "Not getting into this on POC feels like more of a nice to have" }) %>
53
+
54
+ <%= pb_rails("caption", props: { text: "Advanced Inline" }) %>
55
+ <%= pb_rails("rich_text_editor", props: {
56
+ rails_advanced_editor: true,
57
+ inline: true,
58
+ margin_bottom: "md",
59
+ value: "<p>This advanced editor has an inline toolbar, showing all the formatting options.</p>"
60
+ }) %>
61
+
62
+ <%= pb_rails("caption", props: { text: "Advanced Preview" }) %>
63
+ <%= pb_rails("rich_text_editor", props: {
64
+ id: "advanced-preview-editor",
65
+ rails_advanced_editor: true,
66
+ margin_bottom: "md",
67
+ value: "Add text here, format it, and press \"Preview Output\" to see what your stylized output will look like on the page."
68
+ }) %>
69
+
70
+ <%= pb_rails("button", props: { id: "advanced-preview-button", text: "Preview Output", variant: "secondary" }) %>
71
+
72
+ <div id="advanced-card-obfuscation" style="display:none">
73
+ <%= pb_rails("card", props: { margin_top: "md", max_width: "md", padding: "sm" }) do %>
74
+ <div id="advanced-content-preview" class="tiptap-content">
75
+ </div>
76
+ <% end %>
77
+ </div>
78
+
79
+ <script>
80
+ document.addEventListener('DOMContentLoaded', () => {
81
+ function handleAdvancedButtonClick() {
82
+ // Find the specific TipTap editor container by ID
83
+ const editorContainer = [...document.querySelectorAll('[data-pb-react-props]')]
84
+ .find(element => element.getAttribute('data-pb-react-props')?.includes('"id":"advanced-preview-editor"'))
85
+
86
+ if (!editorContainer) {
87
+ console.log('Editor container not found')
88
+ return
89
+ }
90
+
91
+ // Find the TipTap editor content
92
+ const tiptapEditor = editorContainer.querySelector('.ProseMirror')
93
+ const previewArea = document.getElementById('advanced-content-preview')
94
+ const cardDiv = document.getElementById('advanced-card-obfuscation')
95
+
96
+ console.log('Found elements:', { tiptapEditor, previewArea, cardDiv })
97
+
98
+ if (tiptapEditor && previewArea && cardDiv) {
99
+ // Get the HTML content from the TipTap editor
100
+ const editorContent = tiptapEditor.innerHTML || ''
101
+ console.log('Editor content:', editorContent)
102
+ previewArea.innerHTML = editorContent
103
+ cardDiv.style.display = 'block'
104
+ } else {
105
+ console.log('Missing elements:', { tiptapEditor: !!tiptapEditor, previewArea: !!previewArea, cardDiv: !!cardDiv })
106
+ }
107
+ }
108
+
109
+ document.getElementById('advanced-preview-button')?.addEventListener('click', handleAdvancedButtonClick)
110
+ })
111
+ </script>
112
+
113
+
114
+ <%= pb_rails("caption", props: { margin_top: "md", text: "Bonus: Advanced Extra Extensions (couldnt help thinking about this a little)" }) %>
115
+ <%= pb_rails("body", props: { margin_bottom: "md", text: "Possibly possible: I tried to set up a tip_tap_options prop via which any extensions would need to be passed through after being impoted directly to an external propject. Look at code example for hypothetical use." }) %>
116
+ <% tip_tap_options = {
117
+ extensions: [] # Extensions would be passed here as actual TipTap extension objects. Not sure if would work right away or if rich_text_editor.tsx would need to account for them.
118
+ } %>
119
+ <%= pb_rails("rich_text_editor", props: {
120
+ rails_advanced_editor: true,
121
+ tip_tap_options: tip_tap_options,
122
+ margin_bottom: "md",
123
+ value: "HYPOTHETICALLY extensions can be added via tip_tap_options.extensions array.",
124
+ }) %>
125
+
126
+ <%= pb_rails("caption", props: { text: "Alt thought: some sort of stimulus or enhanced element based RTE that imports TipTap directly into Rails?" }) %>
127
+ <%= pb_rails("body", props: {text: "If anything, may serve as an extension of the EXTENSIONS/tip_tap_options configuration. Not sure if works solo." }) %>
@@ -0,0 +1 @@
1
+ This is a POC for a react-rendered-rails version of the Advanced RTE, which necessarily requires we import Tiptap as an internal dependency since it is not compatible with Rails. Because of that, I'm not sure how we will be able to truly leverage Tiptap extensions/customizability to its full potential. We should be able to provide certain props/prop combos like we do now and provide them as options for customized editors - may require a few more doc examples and methods in the controller than we currently have but once it exists should be usable (for example, if there are usecases or examples of things like horizontal bar, highlight, etc. in Nitro or documented we can build those into the kit HUB request style.)
@@ -1,6 +1,7 @@
1
1
  examples:
2
2
 
3
3
  rails:
4
+ - rich_text_editor_advanced_default: Advanced Default
4
5
  - rich_text_editor_default: Default
5
6
  - rich_text_editor_simple: Simple
6
7
  - rich_text_editor_attributes: Attributes
@@ -1,5 +1,13 @@
1
- <%= react_component('RichTextEditor',
2
- object.rich_text_options,
3
- aria: object.aria,
4
- data: object.data
5
- ) %>
1
+ <% if object.is_rails_advanced? %>
2
+ <%= react_component('RichTextEditor',
3
+ object.rich_text_advanced_options,
4
+ aria: object.aria,
5
+ data: object.data
6
+ ) %>
7
+ <% else %>
8
+ <%= react_component('RichTextEditor',
9
+ object.rich_text_options,
10
+ aria: object.aria,
11
+ data: object.data
12
+ ) %>
13
+ <% end %>
@@ -22,6 +22,18 @@ module Playbook
22
22
  prop :placeholder
23
23
  prop :input_options
24
24
 
25
+ prop :rails_advanced_editor, type: Playbook::Props::Boolean,
26
+ default: false
27
+ prop :advanced_editor_toolbar, type: Playbook::Props::Boolean,
28
+ default: true
29
+ prop :extensions, type: Playbook::Props::HashArray,
30
+ default: []
31
+ prop :max_width, type: Playbook::Props::Enum,
32
+ values: %w[xs sm md lg xl],
33
+ default: "md"
34
+ prop :tip_tap_options, type: Playbook::Props::HashProp,
35
+ default: {}
36
+
25
37
  def classname
26
38
  generate_classname("pb_rich_text_editor_kit", simple_class, focus_class, sticky_class, separator: " ")
27
39
  end
@@ -53,6 +65,31 @@ module Playbook
53
65
  inputOptions: input_options,
54
66
  }
55
67
  end
68
+
69
+ def is_rails_advanced?
70
+ rails_advanced_editor
71
+ end
72
+
73
+ def rich_text_advanced_options
74
+ {
75
+ id: id,
76
+ inline: inline,
77
+ className: classname,
78
+ focus: focus,
79
+ simple: simple,
80
+ sticky: sticky,
81
+ toolbarBottom: toolbar_bottom,
82
+ value: value || "",
83
+ template: template,
84
+ placeholder: placeholder,
85
+ inputOptions: input_options,
86
+ railsAdvancedEditor: rails_advanced_editor,
87
+ advancedEditorToolbar: advanced_editor_toolbar,
88
+ extensions: extensions,
89
+ maxWidth: max_width,
90
+ tipTapOptions: tip_tap_options,
91
+ }
92
+ end
56
93
  end
57
94
  end
58
95
  end
@@ -1 +1 @@
1
- import{jsx,Fragment,jsxs}from"react/jsx-runtime";import{useState,useEffect}from"react";import{f as buildAriaProps,g as buildDataProps,h as buildHtmlProps,H as HighchartsReact,i as Highcharts,j as classnames,k as globalProps,l as HighchartsMore,S as SolidGauge,m as buildCss}from"./_typeahead-B1SiFvbF.js";import{c as colors,h as highchartsTheme,m as merge,a as highchartsDarkTheme,t as typography}from"./lib-CGxXTQ75.js";const mapColors=array=>{const regex=/(data)\-[1-8]/;const newArray=array.map((item=>regex.test(item)?`${colors[`data_${item[item.length-1]}`]}`:item));return newArray};const BarGraph=({aria:aria={},data:data={},align:align="center",axisTitle:axisTitle,dark:dark=false,chartData:chartData,className:className="pb_bar_graph",colors:colors2,htmlOptions:htmlOptions={},customOptions:customOptions={},axisFormat:axisFormat,id:id,pointStart:pointStart,stacking:stacking,subTitle:subTitle,type:type="column",title:title="Title",xAxisCategories:xAxisCategories,yAxisMin:yAxisMin,yAxisMax:yAxisMax,legend:legend=false,toggleLegendClick:toggleLegendClick=true,height:height,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();const staticOptions={title:{text:title},chart:{height:height,type:type},subtitle:{text:subTitle},yAxis:[{labels:{format:typeof axisFormat==="string"?axisFormat:axisFormat&&axisFormat[0]?axisFormat[0].format:""},min:yAxisMin,max:yAxisMax,opposite:false,title:{text:Array.isArray(axisTitle)?axisTitle.length>0?axisTitle[0].name:null:axisTitle},plotLines:typeof yAxisMin!=="undefined"&&yAxisMin!==null?[]:[{value:0,zIndex:10,color:"#E4E8F0"}]}],xAxis:{categories:xAxisCategories},legend:{enabled:legend,align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},colors:colors2!==void 0&&colors2.length>0?mapColors(colors2):highchartsTheme.colors,plotOptions:{series:{stacking:stacking,pointStart:pointStart,borderWidth:stacking?0:"",events:{},dataLabels:{enabled:false}}},series:chartData,credits:false};if(Array.isArray(axisTitle)&&axisTitle.length>1&&axisTitle[1].name){staticOptions.yAxis.push({labels:{format:typeof axisFormat==="string"?axisFormat:axisFormat[1].format},min:yAxisMin,max:yAxisMax,opposite:true,title:{text:axisTitle[1].name},plotLines:typeof yAxisMin!=="undefined"&&yAxisMin!==null?[]:[{value:0,zIndex:10,color:"#E4E8F0"}]})}if(!toggleLegendClick){staticOptions.plotOptions.series.events={legendItemClick:()=>false}}const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(globalProps(filteredProps),className),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};const alignBlockElement=event=>{const itemToMove=document.querySelector(`#wrapper-circle-chart-${event.target.renderTo.id} .pb-circle-chart-block`);const chartContainer=document.querySelector(`#${event.target.renderTo.id}`);if(itemToMove!==null&&chartContainer!==null){itemToMove.style.height=`${event.target.chartHeight}px`;itemToMove.style.width=`${event.target.chartWidth}px`;if(chartContainer.firstChild!==null){chartContainer.firstChild.before(itemToMove)}}};const CircleChart=({align:align="center",aria:aria={},rounded:rounded=false,borderColor:borderColor=(rounded?null:""),borderWidth:borderWidth=(rounded?20:null),chartData:chartData,children:children,className:className,colors:colors2=[],customOptions:customOptions={},dark:dark=false,data:data={},dataLabelHtml:dataLabelHtml="<div>{point.name}</div>",dataLabels:dataLabels=false,height:height,htmlOptions:htmlOptions={},id:id,innerSize:innerSize="md",legend:legend=false,maxPointSize:maxPointSize=null,minPointSize:minPointSize=null,startAngle:startAngle=null,style:style="pie",title:title,tooltipHtml:tooltipHtml,useHtml:useHtml=false,zMin:zMin=null,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);HighchartsMore(Highcharts);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();Highcharts.setOptions({tooltip:{headerFormat:null,pointFormat:tooltipHtml?tooltipHtml:'<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.y}</b>',useHTML:useHtml}});const innerSizes={sm:"35%",md:"50%",lg:"85%",none:"0%"};const innerSizeFormat=size=>innerSizes[size];const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{const formattedChartData=chartData.map((obj=>{obj.y=obj.value;delete obj.value;return obj}));const staticOptions={title:{text:title},chart:{height:height,type:style,events:{render:event=>alignBlockElement(event),redraw:event=>alignBlockElement(event)}},legend:{align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},plotOptions:{pie:{colors:colors2.length>0?mapColors(colors2):highchartsTheme.colors,dataLabels:{enabled:dataLabels,connectorShape:"straight",connectorWidth:3,format:dataLabelHtml},showInLegend:legend}},series:[{minPointSize:minPointSize,maxPointSize:maxPointSize,innerSize:borderWidth==20?"100%":innerSizeFormat(innerSize),data:formattedChartData,zMin:zMin,startAngle:startAngle,borderWidth:borderWidth,borderColor:borderColor}],credits:false};setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(Fragment,{children:children?jsxs("div",{id:`wrapper-circle-chart-${id}`,children:[jsx(HighchartsReact,{containerProps:{className:classnames("pb_circle_chart",globalProps(filteredProps)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options}),jsx("div",{className:"pb-circle-chart-block",children:children})]}):jsx(HighchartsReact,{containerProps:{className:classnames("pb_circle_chart",globalProps(filteredProps)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})})};const Gauge=({aria:aria={},chartData:chartData,customOptions:customOptions={},dark:dark=false,data:data={},disableAnimation:disableAnimation=false,fullCircle:fullCircle=false,height:height=null,htmlOptions:htmlOptions={},id:id,max:max=100,min:min=0,prefix:prefix="",showLabels:showLabels=false,style:style="solidgauge",suffix:suffix="",title:title="",tooltipHtml:tooltipHtml='<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.y}</b>',colors:colors$1=[],minorTickInterval:minorTickInterval=null,circumference:circumference=(fullCircle?[0,360]:[-100,100]),...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);HighchartsMore(Highcharts);SolidGauge(Highcharts);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();Highcharts.setOptions({tooltip:{pointFormat:tooltipHtml,followPointer:true}});const css=buildCss({pb_gauge_kit:true});const[options,setOptions]=useState({});useEffect((()=>{const formattedChartData=chartData.map((obj=>{obj.y=obj.value;delete obj.value;return obj}));const staticOptions={chart:{events:{load(){setTimeout(this.reflow.bind(this),0)}},type:style,height:height},title:{text:title},yAxis:{min:min,max:max,lineWidth:0,tickWidth:0,minorTickInterval:minorTickInterval,tickAmount:2,tickPositions:[min,max],labels:{y:26,enabled:showLabels}},credits:false,series:[{data:formattedChartData}],pane:{center:["50%","50%"],size:"90%",startAngle:circumference[0],endAngle:circumference[1],background:{borderWidth:20,innerRadius:"90%",outerRadius:"90%",shape:"arc",className:"gauge-pane"}},colors:colors$1!==void 0&&colors$1.length>0?mapColors(colors$1):highchartsTheme.colors,plotOptions:{series:{animation:!disableAnimation},solidgauge:{borderColor:colors$1!==void 0&&colors$1.length===1?mapColors(colors$1).join():highchartsTheme.colors[0],borderWidth:20,radius:90,innerRadius:"90%",dataLabels:{borderWidth:0,color:colors.text_lt_default,enabled:true,format:`<span class="prefix${dark?" dark":""}">${prefix}</span><span class="fix${dark?" dark":""}">{y:,f}</span><span class="suffix${dark?" dark":""}">${suffix}</span>`,style:{fontFamily:typography.font_family_base,fontWeight:typography.regular,fontSize:typography.heading_2},y:-26}}}};setOptions(merge(staticOptions,customOptions));if(document.querySelector(".prefix")){document.querySelectorAll(".prefix").forEach((prefix2=>{prefix2.setAttribute("y","28")}));document.querySelectorAll(".fix").forEach((fix=>fix.setAttribute("y","38")))}}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(css,globalProps(props)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};const LineGraph=({aria:aria={},data:data={},align:align="center",className:className="pb_bar_graph",customOptions:customOptions={},dark:dark=false,gradient:gradient=false,type:type="line",htmlOptions:htmlOptions={},id:id,legend:legend=false,toggleLegendClick:toggleLegendClick=true,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,axisTitle:axisTitle,xAxisCategories:xAxisCategories,yAxisMin:yAxisMin,yAxisMax:yAxisMax,chartData:chartData,pointStart:pointStart,subTitle:subTitle,title:title,height:height,colors:colors2=[],...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();const staticOptions={title:{text:title},chart:{height:height,type:type},subtitle:{text:subTitle},yAxis:{min:yAxisMin,max:yAxisMax,title:{text:axisTitle}},xAxis:{categories:xAxisCategories},legend:{enabled:legend,align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},colors:colors2!==void 0&&colors2.length>0?mapColors(colors2):highchartsTheme.colors,plotOptions:{series:{pointStart:pointStart,events:{},dataLabels:{enabled:false}}},series:chartData,credits:false};if(!toggleLegendClick){staticOptions.plotOptions.series.events={legendItemClick:()=>false}}const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(globalProps(filteredProps),className),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};export{BarGraph as B,CircleChart as C,Gauge as G,LineGraph as L};
1
+ import{jsx,Fragment,jsxs}from"react/jsx-runtime";import{useState,useEffect}from"react";import{f as buildAriaProps,g as buildDataProps,h as buildHtmlProps,H as HighchartsReact,i as Highcharts,j as classnames,k as globalProps,l as HighchartsMore,S as SolidGauge,m as buildCss}from"./_typeahead-D2PJbkOa.js";import{c as colors,h as highchartsTheme,m as merge,a as highchartsDarkTheme,t as typography}from"./lib-DAV78mo-.js";const mapColors=array=>{const regex=/(data)\-[1-8]/;const newArray=array.map((item=>regex.test(item)?`${colors[`data_${item[item.length-1]}`]}`:item));return newArray};const BarGraph=({aria:aria={},data:data={},align:align="center",axisTitle:axisTitle,dark:dark=false,chartData:chartData,className:className="pb_bar_graph",colors:colors2,htmlOptions:htmlOptions={},customOptions:customOptions={},axisFormat:axisFormat,id:id,pointStart:pointStart,stacking:stacking,subTitle:subTitle,type:type="column",title:title="Title",xAxisCategories:xAxisCategories,yAxisMin:yAxisMin,yAxisMax:yAxisMax,legend:legend=false,toggleLegendClick:toggleLegendClick=true,height:height,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();const staticOptions={title:{text:title},chart:{height:height,type:type},subtitle:{text:subTitle},yAxis:[{labels:{format:typeof axisFormat==="string"?axisFormat:axisFormat&&axisFormat[0]?axisFormat[0].format:""},min:yAxisMin,max:yAxisMax,opposite:false,title:{text:Array.isArray(axisTitle)?axisTitle.length>0?axisTitle[0].name:null:axisTitle},plotLines:typeof yAxisMin!=="undefined"&&yAxisMin!==null?[]:[{value:0,zIndex:10,color:"#E4E8F0"}]}],xAxis:{categories:xAxisCategories},legend:{enabled:legend,align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},colors:colors2!==void 0&&colors2.length>0?mapColors(colors2):highchartsTheme.colors,plotOptions:{series:{stacking:stacking,pointStart:pointStart,borderWidth:stacking?0:"",events:{},dataLabels:{enabled:false}}},series:chartData,credits:false};if(Array.isArray(axisTitle)&&axisTitle.length>1&&axisTitle[1].name){staticOptions.yAxis.push({labels:{format:typeof axisFormat==="string"?axisFormat:axisFormat[1].format},min:yAxisMin,max:yAxisMax,opposite:true,title:{text:axisTitle[1].name},plotLines:typeof yAxisMin!=="undefined"&&yAxisMin!==null?[]:[{value:0,zIndex:10,color:"#E4E8F0"}]})}if(!toggleLegendClick){staticOptions.plotOptions.series.events={legendItemClick:()=>false}}const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(globalProps(filteredProps),className),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};const alignBlockElement=event=>{const itemToMove=document.querySelector(`#wrapper-circle-chart-${event.target.renderTo.id} .pb-circle-chart-block`);const chartContainer=document.querySelector(`#${event.target.renderTo.id}`);if(itemToMove!==null&&chartContainer!==null){itemToMove.style.height=`${event.target.chartHeight}px`;itemToMove.style.width=`${event.target.chartWidth}px`;if(chartContainer.firstChild!==null){chartContainer.firstChild.before(itemToMove)}}};const CircleChart=({align:align="center",aria:aria={},rounded:rounded=false,borderColor:borderColor=(rounded?null:""),borderWidth:borderWidth=(rounded?20:null),chartData:chartData,children:children,className:className,colors:colors2=[],customOptions:customOptions={},dark:dark=false,data:data={},dataLabelHtml:dataLabelHtml="<div>{point.name}</div>",dataLabels:dataLabels=false,height:height,htmlOptions:htmlOptions={},id:id,innerSize:innerSize="md",legend:legend=false,maxPointSize:maxPointSize=null,minPointSize:minPointSize=null,startAngle:startAngle=null,style:style="pie",title:title,tooltipHtml:tooltipHtml,useHtml:useHtml=false,zMin:zMin=null,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);HighchartsMore(Highcharts);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();Highcharts.setOptions({tooltip:{headerFormat:null,pointFormat:tooltipHtml?tooltipHtml:'<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.y}</b>',useHTML:useHtml}});const innerSizes={sm:"35%",md:"50%",lg:"85%",none:"0%"};const innerSizeFormat=size=>innerSizes[size];const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{const formattedChartData=chartData.map((obj=>{obj.y=obj.value;delete obj.value;return obj}));const staticOptions={title:{text:title},chart:{height:height,type:style,events:{render:event=>alignBlockElement(event),redraw:event=>alignBlockElement(event)}},legend:{align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},plotOptions:{pie:{colors:colors2.length>0?mapColors(colors2):highchartsTheme.colors,dataLabels:{enabled:dataLabels,connectorShape:"straight",connectorWidth:3,format:dataLabelHtml},showInLegend:legend}},series:[{minPointSize:minPointSize,maxPointSize:maxPointSize,innerSize:borderWidth==20?"100%":innerSizeFormat(innerSize),data:formattedChartData,zMin:zMin,startAngle:startAngle,borderWidth:borderWidth,borderColor:borderColor}],credits:false};setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(Fragment,{children:children?jsxs("div",{id:`wrapper-circle-chart-${id}`,children:[jsx(HighchartsReact,{containerProps:{className:classnames("pb_circle_chart",globalProps(filteredProps)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options}),jsx("div",{className:"pb-circle-chart-block",children:children})]}):jsx(HighchartsReact,{containerProps:{className:classnames("pb_circle_chart",globalProps(filteredProps)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})})};const Gauge=({aria:aria={},chartData:chartData,customOptions:customOptions={},dark:dark=false,data:data={},disableAnimation:disableAnimation=false,fullCircle:fullCircle=false,height:height=null,htmlOptions:htmlOptions={},id:id,max:max=100,min:min=0,prefix:prefix="",showLabels:showLabels=false,style:style="solidgauge",suffix:suffix="",title:title="",tooltipHtml:tooltipHtml='<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.y}</b>',colors:colors$1=[],minorTickInterval:minorTickInterval=null,circumference:circumference=(fullCircle?[0,360]:[-100,100]),...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);HighchartsMore(Highcharts);SolidGauge(Highcharts);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();Highcharts.setOptions({tooltip:{pointFormat:tooltipHtml,followPointer:true}});const css=buildCss({pb_gauge_kit:true});const[options,setOptions]=useState({});useEffect((()=>{const formattedChartData=chartData.map((obj=>{obj.y=obj.value;delete obj.value;return obj}));const staticOptions={chart:{events:{load(){setTimeout(this.reflow.bind(this),0)}},type:style,height:height},title:{text:title},yAxis:{min:min,max:max,lineWidth:0,tickWidth:0,minorTickInterval:minorTickInterval,tickAmount:2,tickPositions:[min,max],labels:{y:26,enabled:showLabels}},credits:false,series:[{data:formattedChartData}],pane:{center:["50%","50%"],size:"90%",startAngle:circumference[0],endAngle:circumference[1],background:{borderWidth:20,innerRadius:"90%",outerRadius:"90%",shape:"arc",className:"gauge-pane"}},colors:colors$1!==void 0&&colors$1.length>0?mapColors(colors$1):highchartsTheme.colors,plotOptions:{series:{animation:!disableAnimation},solidgauge:{borderColor:colors$1!==void 0&&colors$1.length===1?mapColors(colors$1).join():highchartsTheme.colors[0],borderWidth:20,radius:90,innerRadius:"90%",dataLabels:{borderWidth:0,color:colors.text_lt_default,enabled:true,format:`<span class="prefix${dark?" dark":""}">${prefix}</span><span class="fix${dark?" dark":""}">{y:,f}</span><span class="suffix${dark?" dark":""}">${suffix}</span>`,style:{fontFamily:typography.font_family_base,fontWeight:typography.regular,fontSize:typography.heading_2},y:-26}}}};setOptions(merge(staticOptions,customOptions));if(document.querySelector(".prefix")){document.querySelectorAll(".prefix").forEach((prefix2=>{prefix2.setAttribute("y","28")}));document.querySelectorAll(".fix").forEach((fix=>fix.setAttribute("y","38")))}}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(css,globalProps(props)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};const LineGraph=({aria:aria={},data:data={},align:align="center",className:className="pb_bar_graph",customOptions:customOptions={},dark:dark=false,gradient:gradient=false,type:type="line",htmlOptions:htmlOptions={},id:id,legend:legend=false,toggleLegendClick:toggleLegendClick=true,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,axisTitle:axisTitle,xAxisCategories:xAxisCategories,yAxisMin:yAxisMin,yAxisMax:yAxisMax,chartData:chartData,pointStart:pointStart,subTitle:subTitle,title:title,height:height,colors:colors2=[],...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();const staticOptions={title:{text:title},chart:{height:height,type:type},subtitle:{text:subTitle},yAxis:{min:yAxisMin,max:yAxisMax,title:{text:axisTitle}},xAxis:{categories:xAxisCategories},legend:{enabled:legend,align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},colors:colors2!==void 0&&colors2.length>0?mapColors(colors2):highchartsTheme.colors,plotOptions:{series:{pointStart:pointStart,events:{},dataLabels:{enabled:false}}},series:chartData,credits:false};if(!toggleLegendClick){staticOptions.plotOptions.series.events={legendItemClick:()=>false}}const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(globalProps(filteredProps),className),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};export{BarGraph as B,CircleChart as C,Gauge as G,LineGraph as L};