flowbite-mcp 1.1.3 → 1.1.5

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 (72) hide show
  1. package/README.md +49 -74
  2. package/build/index.js +20 -36
  3. package/data/components/accordion.md +39 -53
  4. package/data/components/alerts.md +27 -44
  5. package/data/components/avatar.md +20 -33
  6. package/data/components/badge.md +34 -47
  7. package/data/components/banner.md +10 -29
  8. package/data/components/bottom-navigation.md +16 -29
  9. package/data/components/breadcrumb.md +12 -25
  10. package/data/components/button-group.md +26 -39
  11. package/data/components/buttons.md +41 -67
  12. package/data/components/card.md +34 -47
  13. package/data/components/carousel.md +25 -39
  14. package/data/components/chat-bubble.md +36 -50
  15. package/data/components/clipboard.md +256 -252
  16. package/data/components/datepicker.md +56 -70
  17. package/data/components/device-mockups.md +16 -29
  18. package/data/components/drawer.md +42 -56
  19. package/data/components/dropdowns.md +66 -80
  20. package/data/components/footer.md +16 -29
  21. package/data/components/forms.md +32 -50
  22. package/data/components/gallery.md +16 -33
  23. package/data/components/indicators.md +18 -31
  24. package/data/components/jumbotron.md +12 -25
  25. package/data/components/kbd.md +14 -27
  26. package/data/components/list-group.md +14 -27
  27. package/data/components/mega-menu.md +10 -24
  28. package/data/components/modal.md +37 -51
  29. package/data/components/navbar.md +41 -55
  30. package/data/components/pagination.md +22 -35
  31. package/data/components/popover.md +36 -51
  32. package/data/components/progress.md +10 -23
  33. package/data/components/qr-code.md +41 -133
  34. package/data/components/rating.md +16 -29
  35. package/data/components/sidebar.md +15 -30
  36. package/data/components/skeleton.md +16 -29
  37. package/data/components/speed-dial.md +40 -55
  38. package/data/components/spinner.md +14 -27
  39. package/data/components/stepper.md +14 -27
  40. package/data/components/tables.md +45 -64
  41. package/data/components/tabs.md +30 -45
  42. package/data/components/timeline.md +10 -23
  43. package/data/components/toast.md +25 -39
  44. package/data/components/tooltips.md +24 -39
  45. package/data/components/typography.md +22 -35
  46. package/data/components/video.md +14 -27
  47. package/data/forms/checkbox.md +27 -43
  48. package/data/forms/file-input.md +12 -26
  49. package/data/forms/floating-label.md +12 -25
  50. package/data/forms/input-field.md +17 -32
  51. package/data/forms/number-input.md +83 -93
  52. package/data/forms/phone-input.md +42 -54
  53. package/data/forms/radio.md +23 -39
  54. package/data/forms/range.md +12 -26
  55. package/data/forms/search-input.md +14 -31
  56. package/data/forms/select.md +15 -30
  57. package/data/forms/textarea.md +8 -21
  58. package/data/forms/timepicker.md +30 -42
  59. package/data/forms/toggle.md +18 -31
  60. package/data/plugins/charts.md +542 -526
  61. package/data/plugins/datatables.md +285 -286
  62. package/data/plugins/wysiwyg.md +658 -650
  63. package/data/quickstart.md +24 -24
  64. package/data/typography/blockquote.md +24 -37
  65. package/data/typography/headings.md +30 -43
  66. package/data/typography/hr.md +10 -23
  67. package/data/typography/images.md +32 -45
  68. package/data/typography/links.md +16 -29
  69. package/data/typography/lists.md +22 -35
  70. package/data/typography/paragraphs.md +30 -43
  71. package/data/typography/text.md +42 -55
  72. package/package.json +1 -1
@@ -1,15 +1,3 @@
1
- ---
2
- layout: docs
3
- title: Tailwind CSS WYSIWYG Text Editor - Flowbite
4
- description: Use the wysiwyg text editor component from Flowbite to create and modify content by manipulating paragraphs, headings, images and styling them using all available options
5
- group: plugins
6
- toc: true
7
- requires_js: true
8
-
9
- previous: Datatables
10
- previousLink: plugins/datatables/
11
- ---
12
-
13
1
  The WYSIWYG text editor from Flowbite is open-source under the MIT license based on the [Tip Tap library](https://github.com/ueberdosis/tiptap) and allows you to easily edit complex text data with typography styles, links, images, videos, and more.
14
2
 
15
3
  The markup and styles provided by Flowbite are all built with the utility classes from Tailwind CSS and the styles for the content inside the WYSIWYG text editor are based on the [Flowbite Typography](https://flowbite.com/docs/components/typography/) plugin.
@@ -24,19 +12,19 @@ Before continuing make sure that you have Tailwind CSS, Flowbite, and Tip Tap in
24
12
 
25
13
  2. Install the [Flowbite Typography](https://flowbite.com/docs/components/typography/) plugin to format the content of text inside the WYSYIWYG editor preview:
26
14
 
27
- {{< code lang="bash" >}}
15
+ ```bash
28
16
  npm i flowbite-typography
29
- {{< /code >}}
17
+ ```
30
18
 
31
19
  3. Import the `flowbite-typography` plugin inside your main Tailwind CSS file:
32
20
 
33
- {{< code lang="javascript" file="wysiwyg.js" icon="file" >}}
21
+ ```javascript
34
22
  @plugin "flowbite-typography";
35
- {{< /code >}}
23
+ ```
36
24
 
37
25
  Alternatively you can do the same but in your `tailwind.config.js` file:
38
26
 
39
- {{< code lang="javascript" file="wysiwyg.js" icon="file" >}}
27
+ ```javascript
40
28
  // import the tailwind.config.js file in your main CSS file if using Tailwind CSS v4
41
29
  module.exports = {
42
30
  theme: {
@@ -47,13 +35,13 @@ module.exports = {
47
35
  // ...
48
36
  ],
49
37
  }
50
- {{< /code >}}
38
+ ```
51
39
 
52
40
  4. Finally, install Tip Tap either via NPM or skip this step if you're using CDN:
53
41
 
54
- {{< code lang="bash" >}}
42
+ ```bash
55
43
  npm install @tiptap/core @tiptap/pm @tiptap/starter-kit
56
- {{< /code >}}
44
+ ```
57
45
 
58
46
  Now you're ready to use the examples below by copying the HTML markup and the JavaScript code.
59
47
 
@@ -61,228 +49,7 @@ Now you're ready to use the examples below by copying the HTML markup and the Ja
61
49
 
62
50
  Use this example of a WYSIWYG text editor to enable basic typography styling and formatting, adding lists, links, images, videos, code blocks, aligning text, blockquotes, setting headers and paragraphs and more.
63
51
 
64
- {{< example class="flex justify-center bg-neutral-primary" github="plugins/wysiwyg.md" show_dark=true wysiwyg=true script_module=true disable_init_js=true javascript=`
65
- import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
66
- import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
67
- import Highlight from 'https://esm.sh/@tiptap/extension-highlight@2.6.6';
68
- import Underline from 'https://esm.sh/@tiptap/extension-underline@2.6.6';
69
- import Link from 'https://esm.sh/@tiptap/extension-link@2.6.6';
70
- import TextAlign from 'https://esm.sh/@tiptap/extension-text-align@2.6.6';
71
- import Image from 'https://esm.sh/@tiptap/extension-image@2.6.6';
72
- import YouTube from 'https://esm.sh/@tiptap/extension-youtube@2.6.6';
73
- import TextStyle from 'https://esm.sh/@tiptap/extension-text-style@2.6.6';
74
- import FontFamily from 'https://esm.sh/@tiptap/extension-font-family@2.6.6';
75
- import { Color } from 'https://esm.sh/@tiptap/extension-color@2.6.6';
76
- import Bold from 'https://esm.sh/@tiptap/extension-bold@2.6.6'; // Import the Bold extension
77
-
78
-
79
- window.addEventListener('load', function() {
80
- if (document.getElementById("wysiwyg-example")) {
81
-
82
- const FontSizeTextStyle = TextStyle.extend({
83
- addAttributes() {
84
- return {
85
- fontSize: {
86
- default: null,
87
- parseHTML: element => element.style.fontSize,
88
- renderHTML: attributes => {
89
- if (!attributes.fontSize) {
90
- return {};
91
- }
92
- return { style: 'font-size: ' + attributes.fontSize };
93
- },
94
- },
95
- };
96
- },
97
- });
98
- const CustomBold = Bold.extend({
99
- // Override the renderHTML method
100
- renderHTML({ mark, HTMLAttributes }) {
101
- const { style, ...rest } = HTMLAttributes;
102
-
103
- // Merge existing styles with font-weight
104
- const newStyle = 'font-weight: bold;' + (style ? ' ' + style : '');
105
-
106
- return ['span', { ...rest, style: newStyle.trim() }, 0];
107
- },
108
- // Ensure it doesn't exclude other marks
109
- addOptions() {
110
- return {
111
- ...this.parent?.(),
112
- HTMLAttributes: {},
113
- };
114
- },
115
- });
116
- // tip tap editor setup
117
- const editor = new Editor({
118
- element: document.querySelector('#wysiwyg-example'),
119
- extensions: [
120
- StarterKit.configure({
121
- textStyle: false,
122
- bold: false,
123
- marks: {
124
- bold: false,
125
- },
126
- }),
127
- // Include the custom Bold extension
128
- CustomBold,
129
- TextStyle,
130
- Color,
131
- FontSizeTextStyle,
132
- FontFamily,
133
- Highlight,
134
- Underline,
135
- Link.configure({
136
- openOnClick: false,
137
- autolink: true,
138
- defaultProtocol: 'https',
139
- }),
140
- TextAlign.configure({
141
- types: ['heading', 'paragraph'],
142
- }),
143
- Image,
144
- YouTube,
145
- ],
146
- content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
147
- editorProps: {
148
- attributes: {
149
- class: 'format lg:format-lg dark:format-invert focus:outline-none format-blue max-w-none',
150
- },
151
- }
152
- });
153
-
154
- // set up custom event listeners for the buttons
155
- document.getElementById('toggleBoldButton').addEventListener('click', () => editor.chain().focus().toggleBold().run());
156
- document.getElementById('toggleItalicButton').addEventListener('click', () => editor.chain().focus().toggleItalic().run());
157
- document.getElementById('toggleUnderlineButton').addEventListener('click', () => editor.chain().focus().toggleUnderline().run());
158
- document.getElementById('toggleStrikeButton').addEventListener('click', () => editor.chain().focus().toggleStrike().run());
159
- document.getElementById('toggleHighlightButton').addEventListener('click', () => {
160
- const isHighlighted = editor.isActive('highlight');
161
- // when using toggleHighlight(), judge if is is already highlighted.
162
- editor.chain().focus().toggleHighlight({
163
- color: isHighlighted ? undefined : '#ffc078' // if is already highlighted,unset the highlight color
164
- }).run();
165
- });
166
-
167
- document.getElementById('toggleLinkButton').addEventListener('click', () => {
168
- const url = window.prompt('Enter image URL:', 'https://flowbite.com');
169
- editor.chain().focus().toggleLink({ href: url }).run();
170
- });
171
- document.getElementById('removeLinkButton').addEventListener('click', () => {
172
- editor.chain().focus().unsetLink().run()
173
- });
174
- document.getElementById('toggleCodeButton').addEventListener('click', () => {
175
- editor.chain().focus().toggleCode().run();
176
- })
177
-
178
- document.getElementById('toggleLeftAlignButton').addEventListener('click', () => {
179
- editor.chain().focus().setTextAlign('left').run();
180
- });
181
- document.getElementById('toggleCenterAlignButton').addEventListener('click', () => {
182
- editor.chain().focus().setTextAlign('center').run();
183
- });
184
- document.getElementById('toggleRightAlignButton').addEventListener('click', () => {
185
- editor.chain().focus().setTextAlign('right').run();
186
- });
187
- document.getElementById('toggleListButton').addEventListener('click', () => {
188
- editor.chain().focus().toggleBulletList().run();
189
- });
190
- document.getElementById('toggleOrderedListButton').addEventListener('click', () => {
191
- editor.chain().focus().toggleOrderedList().run();
192
- });
193
- document.getElementById('toggleBlockquoteButton').addEventListener('click', () => {
194
- editor.chain().focus().toggleBlockquote().run();
195
- });
196
- document.getElementById('toggleHRButton').addEventListener('click', () => {
197
- editor.chain().focus().setHorizontalRule().run();
198
- });
199
- document.getElementById('addImageButton').addEventListener('click', () => {
200
- const url = window.prompt('Enter image URL:', 'https://placehold.co/600x400');
201
- if (url) {
202
- editor.chain().focus().setImage({ src: url }).run();
203
- }
204
- });
205
- document.getElementById('addVideoButton').addEventListener('click', () => {
206
- const url = window.prompt('Enter YouTube URL:', 'https://www.youtube.com/watch?v=KaLxCiilHns');
207
- if (url) {
208
- editor.commands.setYoutubeVideo({
209
- src: url,
210
- width: 640,
211
- height: 480,
212
- })
213
- }
214
- });
215
-
216
- // typography dropdown
217
- const typographyDropdown = FlowbiteInstances.getInstance('Dropdown', 'typographyDropdown');
218
-
219
- document.getElementById('toggleParagraphButton').addEventListener('click', () => {
220
- editor.chain().focus().setParagraph().run();
221
- typographyDropdown.hide();
222
- });
223
-
224
- document.querySelectorAll('[data-heading-level]').forEach((button) => {
225
- button.addEventListener('click', () => {
226
- const level = button.getAttribute('data-heading-level');
227
- editor.chain().focus().toggleHeading({ level: parseInt(level) }).run()
228
- typographyDropdown.hide();
229
- });
230
- });
231
-
232
- const textSizeDropdown = FlowbiteInstances.getInstance('Dropdown', 'textSizeDropdown');
233
-
234
- // Loop through all elements with the data-text-size attribute
235
- document.querySelectorAll('[data-text-size]').forEach((button) => {
236
- button.addEventListener('click', () => {
237
- const fontSize = button.getAttribute('data-text-size');
238
-
239
- // Apply the selected font size via pixels using the TipTap editor chain
240
- editor.chain().focus().setMark('textStyle', { fontSize }).run();
241
-
242
- // Hide the dropdown after selection
243
- textSizeDropdown.hide();
244
- });
245
- });
246
-
247
- // Listen for color picker changes
248
- const colorPicker = document.getElementById('color');
249
- colorPicker.addEventListener('input', (event) => {
250
- const selectedColor = event.target.value;
251
-
252
- // Apply the selected color to the selected text
253
- editor.chain().focus().setColor(selectedColor).run();
254
- })
255
-
256
- document.querySelectorAll('[data-hex-color]').forEach((button) => {
257
- button.addEventListener('click', () => {
258
- const selectedColor = button.getAttribute('data-hex-color');
259
-
260
- // Apply the selected color to the selected text
261
- editor.chain().focus().setColor(selectedColor).run();
262
- });
263
- });
264
-
265
- document.getElementById('reset-color').addEventListener('click', () => {
266
- editor.commands.unsetColor();
267
- })
268
-
269
- const fontFamilyDropdown = FlowbiteInstances.getInstance('Dropdown', 'fontFamilyDropdown');
270
-
271
- // Loop through all elements with the data-font-family attribute
272
- document.querySelectorAll('[data-font-family]').forEach((button) => {
273
- button.addEventListener('click', () => {
274
- const fontFamily = button.getAttribute('data-font-family');
275
-
276
- // Apply the selected font size via pixels using the TipTap editor chain
277
- editor.chain().focus().setFontFamily(fontFamily).run();
278
-
279
- // Hide the dropdown after selection
280
- fontFamilyDropdown.hide();
281
- });
282
- });
283
- }
284
- })
285
- ` >}}
52
+ ```html
286
53
  <div class="w-full bg-neutral-secondary-medium border border-default-medium rounded-base">
287
54
  <div class="p-2 border-b border-default-medium">
288
55
  <div class="flex flex-wrap items-center">
@@ -649,55 +416,25 @@ window.addEventListener('load', function() {
649
416
  <div id="wysiwyg-example"class="block w-full px-0 text-sm text-body bg-neutral-primary border-0 focus:ring-0"></div>
650
417
  </div>
651
418
  </div>
652
- {{< /example >}}
653
-
654
- Notice: there is a <a href="https://github.com/ueberdosis/tiptap/issues/577" target="_blank" rel="nofollow noreferrer">known issue from TipTap</a> when splitting blocks (ie. using enter to create break lines) and using the bullet list item. A quickfix for `v2.6.6` when using CDN is to match the import statements:
655
-
656
- {{< code lang="html" file="wysiwyg.html" icon="file" >}}
657
- <script type="importmap">
658
- {
659
- "imports": {
660
- "https://esm.sh/v135/prosemirror-model@1.22.3/es2022/prosemirror-model.mjs": "https://esm.sh/v135/prosemirror-model@1.19.3/es2022/prosemirror-model.mjs",
661
- "https://esm.sh/v135/prosemirror-model@1.22.1/es2022/prosemirror-model.mjs": "https://esm.sh/v135/prosemirror-model@1.19.3/es2022/prosemirror-model.mjs"
662
- }
663
- }
664
- </script>
665
- {{< /code >}}
666
-
667
- If you're importing the package with Yarn or NPM then you need to add this in your `package.json` file:
668
-
669
- {{< code lang="javascript" file="wysiwyg.js" icon="file" >}}
670
- // when using Yarn
671
- "resolutions": {
672
- "prosemirror-model": "1.19.3"
673
- }
674
-
675
- // when using NPM
676
- "overrides": {
677
- "prosemirror-model": "1.19.3"
678
- }
679
- {{< /code >}}
680
-
681
- We recommend later checking the Tip Tap library for a proper update to prevent this quickfix in the future.
682
-
683
- ## Text formatting
419
+ ```
684
420
 
685
- Use this example of a WYSIWYG text editor to enable typography styling, formatting and marking such as underline, bold, italic, strikethrough, code, highlight and also selecting text size, color, font family and more using the utility classes from Tailwind CSS.
686
-
687
- {{< example class="flex justify-center bg-neutral-primary" github="plugins/wysiwyg.md" show_dark=true wysiwyg=true script_module=true disable_init_js=true javascript=`
421
+ ```javascript
688
422
  import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
689
423
  import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
690
424
  import Highlight from 'https://esm.sh/@tiptap/extension-highlight@2.6.6';
691
425
  import Underline from 'https://esm.sh/@tiptap/extension-underline@2.6.6';
692
- import Subscript from 'https://esm.sh/@tiptap/extension-subscript@2.6.6';
693
- import Superscript from 'https://esm.sh/@tiptap/extension-superscript@2.6.6';
426
+ import Link from 'https://esm.sh/@tiptap/extension-link@2.6.6';
427
+ import TextAlign from 'https://esm.sh/@tiptap/extension-text-align@2.6.6';
428
+ import Image from 'https://esm.sh/@tiptap/extension-image@2.6.6';
429
+ import YouTube from 'https://esm.sh/@tiptap/extension-youtube@2.6.6';
694
430
  import TextStyle from 'https://esm.sh/@tiptap/extension-text-style@2.6.6';
695
431
  import FontFamily from 'https://esm.sh/@tiptap/extension-font-family@2.6.6';
696
432
  import { Color } from 'https://esm.sh/@tiptap/extension-color@2.6.6';
697
- import Bold from 'https://esm.sh/@tiptap/extension-bold@2.6.6';
433
+ import Bold from 'https://esm.sh/@tiptap/extension-bold@2.6.6'; // Import the Bold extension
434
+
698
435
 
699
436
  window.addEventListener('load', function() {
700
- if (document.getElementById("wysiwyg-text-example")) {
437
+ if (document.getElementById("wysiwyg-example")) {
701
438
 
702
439
  const FontSizeTextStyle = TextStyle.extend({
703
440
  addAttributes() {
@@ -716,18 +453,27 @@ window.addEventListener('load', function() {
716
453
  },
717
454
  });
718
455
  const CustomBold = Bold.extend({
719
- // Override the renderHTML method
720
- renderHTML({ HTMLAttributes }) {
721
- return ['span', { ...HTMLAttributes, style: 'font-weight: bold;' }, 0];
722
- },
723
- // Ensure it doesn't exclude other marks
724
- excludes: '',
725
- });
456
+ // Override the renderHTML method
457
+ renderHTML({ mark, HTMLAttributes }) {
458
+ const { style, ...rest } = HTMLAttributes;
459
+
460
+ // Merge existing styles with font-weight
461
+ const newStyle = 'font-weight: bold;' + (style ? ' ' + style : '');
726
462
 
463
+ return ['span', { ...rest, style: newStyle.trim() }, 0];
464
+ },
465
+ // Ensure it doesn't exclude other marks
466
+ addOptions() {
467
+ return {
468
+ ...this.parent?.(),
469
+ HTMLAttributes: {},
470
+ };
471
+ },
472
+ });
727
473
  // tip tap editor setup
728
474
  const editor = new Editor({
729
- element: document.querySelector('#wysiwyg-text-example'),
730
- extensions: [
475
+ element: document.querySelector('#wysiwyg-example'),
476
+ extensions: [
731
477
  StarterKit.configure({
732
478
  textStyle: false,
733
479
  bold: false,
@@ -737,16 +483,24 @@ window.addEventListener('load', function() {
737
483
  }),
738
484
  // Include the custom Bold extension
739
485
  CustomBold,
740
- Highlight,
741
- Underline,
742
- Subscript,
743
- Superscript,
744
486
  TextStyle,
745
- FontSizeTextStyle,
746
487
  Color,
747
- FontFamily
488
+ FontSizeTextStyle,
489
+ FontFamily,
490
+ Highlight,
491
+ Underline,
492
+ Link.configure({
493
+ openOnClick: false,
494
+ autolink: true,
495
+ defaultProtocol: 'https',
496
+ }),
497
+ TextAlign.configure({
498
+ types: ['heading', 'paragraph'],
499
+ }),
500
+ Image,
501
+ YouTube,
748
502
  ],
749
- content: '<p>Flowbite React is an <strong>open-source library of UI components</strong> built using React and Tailwind CSS. It supports dark mode, a Figma design system, and more.</p><p>It includes essential components for web apps like buttons, dropdowns, navigation bars, modals, datepickers, and charts, all optimized for React.</p><p>Example button component in Flowbite React:</p><code>import &#123; Button &#125; from &#39;flowbite-react&#39;; &lt;Button color&#x3D;&quot;blue&quot;&gt;Default&lt;/Button&gt;</code><p>These components can also be easily customized using the theme props from the Flowbite Docs and allows you to add your own Tailwind CSS utility classes to override the default styles.</p><p>Explore more components and props values in the Flowbite Docs.</p>',
503
+ content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
750
504
  editorProps: {
751
505
  attributes: {
752
506
  class: 'format lg:format-lg dark:format-invert focus:outline-none format-blue max-w-none',
@@ -759,8 +513,6 @@ window.addEventListener('load', function() {
759
513
  document.getElementById('toggleItalicButton').addEventListener('click', () => editor.chain().focus().toggleItalic().run());
760
514
  document.getElementById('toggleUnderlineButton').addEventListener('click', () => editor.chain().focus().toggleUnderline().run());
761
515
  document.getElementById('toggleStrikeButton').addEventListener('click', () => editor.chain().focus().toggleStrike().run());
762
- document.getElementById('toggleSubscriptButton').addEventListener('click', () => editor.chain().focus().toggleSubscript().run());
763
- document.getElementById('toggleSuperscriptButton').addEventListener('click', () => editor.chain().focus().toggleSuperscript().run());
764
516
  document.getElementById('toggleHighlightButton').addEventListener('click', () => {
765
517
  const isHighlighted = editor.isActive('highlight');
766
518
  // when using toggleHighlight(), judge if is is already highlighted.
@@ -769,8 +521,69 @@ window.addEventListener('load', function() {
769
521
  }).run();
770
522
  });
771
523
 
524
+ document.getElementById('toggleLinkButton').addEventListener('click', () => {
525
+ const url = window.prompt('Enter image URL:', 'https://flowbite.com');
526
+ editor.chain().focus().toggleLink({ href: url }).run();
527
+ });
528
+ document.getElementById('removeLinkButton').addEventListener('click', () => {
529
+ editor.chain().focus().unsetLink().run()
530
+ });
772
531
  document.getElementById('toggleCodeButton').addEventListener('click', () => {
773
532
  editor.chain().focus().toggleCode().run();
533
+ })
534
+
535
+ document.getElementById('toggleLeftAlignButton').addEventListener('click', () => {
536
+ editor.chain().focus().setTextAlign('left').run();
537
+ });
538
+ document.getElementById('toggleCenterAlignButton').addEventListener('click', () => {
539
+ editor.chain().focus().setTextAlign('center').run();
540
+ });
541
+ document.getElementById('toggleRightAlignButton').addEventListener('click', () => {
542
+ editor.chain().focus().setTextAlign('right').run();
543
+ });
544
+ document.getElementById('toggleListButton').addEventListener('click', () => {
545
+ editor.chain().focus().toggleBulletList().run();
546
+ });
547
+ document.getElementById('toggleOrderedListButton').addEventListener('click', () => {
548
+ editor.chain().focus().toggleOrderedList().run();
549
+ });
550
+ document.getElementById('toggleBlockquoteButton').addEventListener('click', () => {
551
+ editor.chain().focus().toggleBlockquote().run();
552
+ });
553
+ document.getElementById('toggleHRButton').addEventListener('click', () => {
554
+ editor.chain().focus().setHorizontalRule().run();
555
+ });
556
+ document.getElementById('addImageButton').addEventListener('click', () => {
557
+ const url = window.prompt('Enter image URL:', 'https://placehold.co/600x400');
558
+ if (url) {
559
+ editor.chain().focus().setImage({ src: url }).run();
560
+ }
561
+ });
562
+ document.getElementById('addVideoButton').addEventListener('click', () => {
563
+ const url = window.prompt('Enter YouTube URL:', 'https://www.youtube.com/watch?v=KaLxCiilHns');
564
+ if (url) {
565
+ editor.commands.setYoutubeVideo({
566
+ src: url,
567
+ width: 640,
568
+ height: 480,
569
+ })
570
+ }
571
+ });
572
+
573
+ // typography dropdown
574
+ const typographyDropdown = FlowbiteInstances.getInstance('Dropdown', 'typographyDropdown');
575
+
576
+ document.getElementById('toggleParagraphButton').addEventListener('click', () => {
577
+ editor.chain().focus().setParagraph().run();
578
+ typographyDropdown.hide();
579
+ });
580
+
581
+ document.querySelectorAll('[data-heading-level]').forEach((button) => {
582
+ button.addEventListener('click', () => {
583
+ const level = button.getAttribute('data-heading-level');
584
+ editor.chain().focus().toggleHeading({ level: parseInt(level) }).run()
585
+ typographyDropdown.hide();
586
+ });
774
587
  });
775
588
 
776
589
  const textSizeDropdown = FlowbiteInstances.getInstance('Dropdown', 'textSizeDropdown');
@@ -824,10 +637,44 @@ window.addEventListener('load', function() {
824
637
  fontFamilyDropdown.hide();
825
638
  });
826
639
  });
640
+ }
641
+ })
642
+ ```
643
+
644
+ Notice: there is a <a href="https://github.com/ueberdosis/tiptap/issues/577" target="_blank" rel="nofollow noreferrer">known issue from TipTap</a> when splitting blocks (ie. using enter to create break lines) and using the bullet list item. A quickfix for `v2.6.6` when using CDN is to match the import statements:
827
645
 
646
+ ```html
647
+ <script type="importmap">
648
+ {
649
+ "imports": {
650
+ "https://esm.sh/v135/prosemirror-model@1.22.3/es2022/prosemirror-model.mjs": "https://esm.sh/v135/prosemirror-model@1.19.3/es2022/prosemirror-model.mjs",
651
+ "https://esm.sh/v135/prosemirror-model@1.22.1/es2022/prosemirror-model.mjs": "https://esm.sh/v135/prosemirror-model@1.19.3/es2022/prosemirror-model.mjs"
652
+ }
828
653
  }
829
- })
830
- ` >}}
654
+ </script>
655
+ ```
656
+
657
+ If you're importing the package with Yarn or NPM then you need to add this in your `package.json` file:
658
+
659
+ ```javascript
660
+ // when using Yarn
661
+ "resolutions": {
662
+ "prosemirror-model": "1.19.3"
663
+ }
664
+
665
+ // when using NPM
666
+ "overrides": {
667
+ "prosemirror-model": "1.19.3"
668
+ }
669
+ ```
670
+
671
+ We recommend later checking the Tip Tap library for a proper update to prevent this quickfix in the future.
672
+
673
+ ## Text formatting
674
+
675
+ Use this example of a WYSIWYG text editor to enable typography styling, formatting and marking such as underline, bold, italic, strikethrough, code, highlight and also selecting text size, color, font family and more using the utility classes from Tailwind CSS.
676
+
677
+ ```html
831
678
  <div class="w-full bg-neutral-secondary-medium border border-default-medium rounded-base">
832
679
  <div class="p-2 border-b border-default-medium">
833
680
  <div class="flex flex-wrap items-center">
@@ -1042,44 +889,71 @@ window.addEventListener('load', function() {
1042
889
  <div id="wysiwyg-text-example" class="block w-full px-0 text-sm text-body bg-neutral-primary border-0 focus:ring-0"></div>
1043
890
  </div>
1044
891
  </div>
1045
- {{< /example >}}
1046
-
1047
- ## Text alignment
1048
-
1049
- Enable text alignment to the left, center, right, and justify for the content inside of the WYSIWYG component.
892
+ ```
1050
893
 
1051
- {{< example class="flex justify-center bg-neutral-primary" github="plugins/wysiwyg.md" show_dark=true wysiwyg=true script_module=true disable_init_js=true javascript=`
894
+ ```javascript
1052
895
  import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
1053
896
  import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
1054
897
  import Highlight from 'https://esm.sh/@tiptap/extension-highlight@2.6.6';
1055
898
  import Underline from 'https://esm.sh/@tiptap/extension-underline@2.6.6';
1056
- import Link from 'https://esm.sh/@tiptap/extension-link@2.6.6';
1057
- import TextAlign from 'https://esm.sh/@tiptap/extension-text-align@2.6.6';
1058
- import Image from 'https://esm.sh/@tiptap/extension-image@2.6.6';
1059
- import YouTube from 'https://esm.sh/@tiptap/extension-youtube@2.6.6';
899
+ import Subscript from 'https://esm.sh/@tiptap/extension-subscript@2.6.6';
900
+ import Superscript from 'https://esm.sh/@tiptap/extension-superscript@2.6.6';
901
+ import TextStyle from 'https://esm.sh/@tiptap/extension-text-style@2.6.6';
902
+ import FontFamily from 'https://esm.sh/@tiptap/extension-font-family@2.6.6';
903
+ import { Color } from 'https://esm.sh/@tiptap/extension-color@2.6.6';
904
+ import Bold from 'https://esm.sh/@tiptap/extension-bold@2.6.6';
1060
905
 
1061
906
  window.addEventListener('load', function() {
1062
- if (document.getElementById("wysiwyg-alignment-example")) {
907
+ if (document.getElementById("wysiwyg-text-example")) {
908
+
909
+ const FontSizeTextStyle = TextStyle.extend({
910
+ addAttributes() {
911
+ return {
912
+ fontSize: {
913
+ default: null,
914
+ parseHTML: element => element.style.fontSize,
915
+ renderHTML: attributes => {
916
+ if (!attributes.fontSize) {
917
+ return {};
918
+ }
919
+ return { style: 'font-size: ' + attributes.fontSize };
920
+ },
921
+ },
922
+ };
923
+ },
924
+ });
925
+ const CustomBold = Bold.extend({
926
+ // Override the renderHTML method
927
+ renderHTML({ HTMLAttributes }) {
928
+ return ['span', { ...HTMLAttributes, style: 'font-weight: bold;' }, 0];
929
+ },
930
+ // Ensure it doesn't exclude other marks
931
+ excludes: '',
932
+ });
1063
933
 
1064
934
  // tip tap editor setup
1065
935
  const editor = new Editor({
1066
- element: document.querySelector('#wysiwyg-alignment-example'),
1067
- extensions: [
1068
- StarterKit,
936
+ element: document.querySelector('#wysiwyg-text-example'),
937
+ extensions: [
938
+ StarterKit.configure({
939
+ textStyle: false,
940
+ bold: false,
941
+ marks: {
942
+ bold: false,
943
+ },
944
+ }),
945
+ // Include the custom Bold extension
946
+ CustomBold,
1069
947
  Highlight,
1070
948
  Underline,
1071
- Link.configure({
1072
- openOnClick: false,
1073
- autolink: true,
1074
- defaultProtocol: 'https',
1075
- }),
1076
- TextAlign.configure({
1077
- types: ['heading', 'paragraph'],
1078
- }),
1079
- Image,
1080
- YouTube
949
+ Subscript,
950
+ Superscript,
951
+ TextStyle,
952
+ FontSizeTextStyle,
953
+ Color,
954
+ FontFamily
1081
955
  ],
1082
- content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
956
+ content: '<p>Flowbite React is an <strong>open-source library of UI components</strong> built using React and Tailwind CSS. It supports dark mode, a Figma design system, and more.</p><p>It includes essential components for web apps like buttons, dropdowns, navigation bars, modals, datepickers, and charts, all optimized for React.</p><p>Example button component in Flowbite React:</p><code>import &#123; Button &#125; from &#39;flowbite-react&#39;; &lt;Button color&#x3D;&quot;blue&quot;&gt;Default&lt;/Button&gt;</code><p>These components can also be easily customized using the theme props from the Flowbite Docs and allows you to add your own Tailwind CSS utility classes to override the default styles.</p><p>Explore more components and props values in the Flowbite Docs.</p>',
1083
957
  editorProps: {
1084
958
  attributes: {
1085
959
  class: 'format lg:format-lg dark:format-invert focus:outline-none format-blue max-w-none',
@@ -1088,21 +962,85 @@ window.addEventListener('load', function() {
1088
962
  });
1089
963
 
1090
964
  // set up custom event listeners for the buttons
1091
- document.getElementById('toggleLeftAlignButton').addEventListener('click', () => {
1092
- editor.chain().focus().setTextAlign('left').run();
965
+ document.getElementById('toggleBoldButton').addEventListener('click', () => editor.chain().focus().toggleBold().run());
966
+ document.getElementById('toggleItalicButton').addEventListener('click', () => editor.chain().focus().toggleItalic().run());
967
+ document.getElementById('toggleUnderlineButton').addEventListener('click', () => editor.chain().focus().toggleUnderline().run());
968
+ document.getElementById('toggleStrikeButton').addEventListener('click', () => editor.chain().focus().toggleStrike().run());
969
+ document.getElementById('toggleSubscriptButton').addEventListener('click', () => editor.chain().focus().toggleSubscript().run());
970
+ document.getElementById('toggleSuperscriptButton').addEventListener('click', () => editor.chain().focus().toggleSuperscript().run());
971
+ document.getElementById('toggleHighlightButton').addEventListener('click', () => {
972
+ const isHighlighted = editor.isActive('highlight');
973
+ // when using toggleHighlight(), judge if is is already highlighted.
974
+ editor.chain().focus().toggleHighlight({
975
+ color: isHighlighted ? undefined : '#ffc078' // if is already highlighted,unset the highlight color
976
+ }).run();
1093
977
  });
1094
- document.getElementById('toggleCenterAlignButton').addEventListener('click', () => {
1095
- editor.chain().focus().setTextAlign('center').run();
978
+
979
+ document.getElementById('toggleCodeButton').addEventListener('click', () => {
980
+ editor.chain().focus().toggleCode().run();
1096
981
  });
1097
- document.getElementById('toggleRightAlignButton').addEventListener('click', () => {
1098
- editor.chain().focus().setTextAlign('right').run();
982
+
983
+ const textSizeDropdown = FlowbiteInstances.getInstance('Dropdown', 'textSizeDropdown');
984
+
985
+ // Loop through all elements with the data-text-size attribute
986
+ document.querySelectorAll('[data-text-size]').forEach((button) => {
987
+ button.addEventListener('click', () => {
988
+ const fontSize = button.getAttribute('data-text-size');
989
+
990
+ // Apply the selected font size via pixels using the TipTap editor chain
991
+ editor.chain().focus().setMark('textStyle', { fontSize }).run();
992
+
993
+ // Hide the dropdown after selection
994
+ textSizeDropdown.hide();
995
+ });
1099
996
  });
1100
- document.getElementById('toggleJustifyButton').addEventListener('click', () => {
1101
- editor.chain().focus().setTextAlign('justify').run();
997
+
998
+ // Listen for color picker changes
999
+ const colorPicker = document.getElementById('color');
1000
+ colorPicker.addEventListener('input', (event) => {
1001
+ const selectedColor = event.target.value;
1002
+
1003
+ // Apply the selected color to the selected text
1004
+ editor.chain().focus().setColor(selectedColor).run();
1005
+ })
1006
+
1007
+ document.querySelectorAll('[data-hex-color]').forEach((button) => {
1008
+ button.addEventListener('click', () => {
1009
+ const selectedColor = button.getAttribute('data-hex-color');
1010
+
1011
+ // Apply the selected color to the selected text
1012
+ editor.chain().focus().setColor(selectedColor).run();
1013
+ });
1014
+ });
1015
+
1016
+ document.getElementById('reset-color').addEventListener('click', () => {
1017
+ editor.commands.unsetColor();
1018
+ })
1019
+
1020
+ const fontFamilyDropdown = FlowbiteInstances.getInstance('Dropdown', 'fontFamilyDropdown');
1021
+
1022
+ // Loop through all elements with the data-font-family attribute
1023
+ document.querySelectorAll('[data-font-family]').forEach((button) => {
1024
+ button.addEventListener('click', () => {
1025
+ const fontFamily = button.getAttribute('data-font-family');
1026
+
1027
+ // Apply the selected font size via pixels using the TipTap editor chain
1028
+ editor.chain().focus().setFontFamily(fontFamily).run();
1029
+
1030
+ // Hide the dropdown after selection
1031
+ fontFamilyDropdown.hide();
1032
+ });
1102
1033
  });
1034
+
1103
1035
  }
1104
1036
  })
1105
- ` >}}
1037
+ ```
1038
+
1039
+ ## Text alignment
1040
+
1041
+ Enable text alignment to the left, center, right, and justify for the content inside of the WYSIWYG component.
1042
+
1043
+ ```html
1106
1044
  <div class="w-full bg-neutral-secondary-medium border border-default-medium rounded-base">
1107
1045
  <div class="p-2 border-b border-default-medium">
1108
1046
  <div class="flex flex-wrap items-center">
@@ -1151,26 +1089,40 @@ window.addEventListener('load', function() {
1151
1089
  <div id="wysiwyg-alignment-example"class="block w-full px-0 text-sm text-body bg-neutral-primary border-0 focus:ring-0"></div>
1152
1090
  </div>
1153
1091
  </div>
1154
- {{< /example >}}
1155
-
1156
- ## Typography elements
1092
+ ```
1157
1093
 
1158
- Use this example to create typography elements like bullet lists, ordered lists, blockquotes, horizontal rules, paragraphs, headings, code blocks based on Tailwind CSS utility classees and the Flowbite API.
1159
-
1160
- {{< example class="flex justify-center bg-neutral-primary" github="plugins/wysiwyg.md" show_dark=true wysiwyg=true script_module=true disable_init_js=true javascript=`
1094
+ ```javascript
1161
1095
  import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
1162
1096
  import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
1097
+ import Highlight from 'https://esm.sh/@tiptap/extension-highlight@2.6.6';
1098
+ import Underline from 'https://esm.sh/@tiptap/extension-underline@2.6.6';
1099
+ import Link from 'https://esm.sh/@tiptap/extension-link@2.6.6';
1100
+ import TextAlign from 'https://esm.sh/@tiptap/extension-text-align@2.6.6';
1101
+ import Image from 'https://esm.sh/@tiptap/extension-image@2.6.6';
1102
+ import YouTube from 'https://esm.sh/@tiptap/extension-youtube@2.6.6';
1163
1103
 
1164
1104
  window.addEventListener('load', function() {
1165
- if (document.getElementById("wysiwyg-typography-example")) {
1105
+ if (document.getElementById("wysiwyg-alignment-example")) {
1166
1106
 
1167
1107
  // tip tap editor setup
1168
1108
  const editor = new Editor({
1169
- element: document.querySelector('#wysiwyg-typography-example'),
1109
+ element: document.querySelector('#wysiwyg-alignment-example'),
1170
1110
  extensions: [
1171
- StarterKit
1111
+ StarterKit,
1112
+ Highlight,
1113
+ Underline,
1114
+ Link.configure({
1115
+ openOnClick: false,
1116
+ autolink: true,
1117
+ defaultProtocol: 'https',
1118
+ }),
1119
+ TextAlign.configure({
1120
+ types: ['heading', 'paragraph'],
1121
+ }),
1122
+ Image,
1123
+ YouTube
1172
1124
  ],
1173
- content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><ul><li>Over 600+ open-source UI components</li><li>Supports dark mode and RTL</li><li>Available in React, Vue, Svelte frameworks</li></ul><p>Here is an example of a button component:</p><pre><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code></pre><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
1125
+ content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
1174
1126
  editorProps: {
1175
1127
  attributes: {
1176
1128
  class: 'format lg:format-lg dark:format-invert focus:outline-none format-blue max-w-none',
@@ -1179,40 +1131,27 @@ window.addEventListener('load', function() {
1179
1131
  });
1180
1132
 
1181
1133
  // set up custom event listeners for the buttons
1182
- document.getElementById('toggleListButton').addEventListener('click', () => {
1183
- editor.chain().focus().toggleBulletList().run();
1184
- });
1185
- document.getElementById('toggleOrderedListButton').addEventListener('click', () => {
1186
- editor.chain().focus().toggleOrderedList().run();
1134
+ document.getElementById('toggleLeftAlignButton').addEventListener('click', () => {
1135
+ editor.chain().focus().setTextAlign('left').run();
1187
1136
  });
1188
- document.getElementById('toggleBlockquoteButton').addEventListener('click', () => {
1189
- editor.chain().focus().toggleBlockquote().run();
1137
+ document.getElementById('toggleCenterAlignButton').addEventListener('click', () => {
1138
+ editor.chain().focus().setTextAlign('center').run();
1190
1139
  });
1191
- document.getElementById('toggleHRButton').addEventListener('click', () => {
1192
- editor.chain().focus().setHorizontalRule().run();
1140
+ document.getElementById('toggleRightAlignButton').addEventListener('click', () => {
1141
+ editor.chain().focus().setTextAlign('right').run();
1193
1142
  });
1194
- document.getElementById('toggleCodeBlockButton').addEventListener('click', () => {
1195
- editor.chain().focus().toggleCodeBlock().run();
1143
+ document.getElementById('toggleJustifyButton').addEventListener('click', () => {
1144
+ editor.chain().focus().setTextAlign('justify').run();
1196
1145
  });
1146
+ }
1147
+ })
1148
+ ```
1197
1149
 
1198
- // typography dropdown
1199
- const typographyDropdown = FlowbiteInstances.getInstance('Dropdown', 'typographyDropdown');
1150
+ ## Typography elements
1200
1151
 
1201
- document.getElementById('toggleParagraphButton').addEventListener('click', () => {
1202
- editor.chain().focus().setParagraph().run();
1203
- typographyDropdown.hide();
1204
- });
1205
-
1206
- document.querySelectorAll('[data-heading-level]').forEach((button) => {
1207
- button.addEventListener('click', () => {
1208
- const level = button.getAttribute('data-heading-level');
1209
- editor.chain().focus().toggleHeading({ level: parseInt(level) }).run()
1210
- typographyDropdown.hide();
1211
- });
1212
- });
1213
- }
1214
- })
1215
- ` >}}
1152
+ Use this example to create typography elements like bullet lists, ordered lists, blockquotes, horizontal rules, paragraphs, headings, code blocks based on Tailwind CSS utility classees and the Flowbite API.
1153
+
1154
+ ```html
1216
1155
  <div class="w-full bg-neutral-secondary-medium border border-default-medium rounded-base">
1217
1156
  <div class="p-2 border-b border-default-medium">
1218
1157
  <div class="flex items-center gap-2">
@@ -1351,32 +1290,22 @@ window.addEventListener('load', function() {
1351
1290
  <div id="wysiwyg-typography-example"class="block w-full px-0 text-sm text-body bg-neutral-primary border-0 focus:ring-0"></div>
1352
1291
  </div>
1353
1292
  </div>
1354
- {{< /example >}}
1355
-
1356
- ## Configuring links
1293
+ ```
1357
1294
 
1358
- Use this example to add and remove anchor links for the content inside of the WYSIWYG text editor.
1359
-
1360
- {{< example class="flex justify-center bg-neutral-primary" github="plugins/wysiwyg.md" show_dark=true wysiwyg=true script_module=true disable_init_js=true javascript=`
1295
+ ```javascript
1361
1296
  import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
1362
1297
  import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
1363
- import Link from 'https://esm.sh/@tiptap/extension-link@2.6.6';
1364
1298
 
1365
1299
  window.addEventListener('load', function() {
1366
- if (document.getElementById("wysiwyg-links-example")) {
1300
+ if (document.getElementById("wysiwyg-typography-example")) {
1367
1301
 
1368
1302
  // tip tap editor setup
1369
1303
  const editor = new Editor({
1370
- element: document.querySelector('#wysiwyg-links-example'),
1304
+ element: document.querySelector('#wysiwyg-typography-example'),
1371
1305
  extensions: [
1372
- StarterKit,
1373
- Link.configure({
1374
- openOnClick: false,
1375
- autolink: true,
1376
- defaultProtocol: 'https',
1377
- })
1306
+ StarterKit
1378
1307
  ],
1379
- content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
1308
+ content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><ul><li>Over 600+ open-source UI components</li><li>Supports dark mode and RTL</li><li>Available in React, Vue, Svelte frameworks</li></ul><p>Here is an example of a button component:</p><pre><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code></pre><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
1380
1309
  editorProps: {
1381
1310
  attributes: {
1382
1311
  class: 'format lg:format-lg dark:format-invert focus:outline-none format-blue max-w-none',
@@ -1385,16 +1314,46 @@ window.addEventListener('load', function() {
1385
1314
  });
1386
1315
 
1387
1316
  // set up custom event listeners for the buttons
1388
- document.getElementById('toggleLinkButton').addEventListener('click', () => {
1389
- const url = window.prompt('Enter image URL:', 'https://flowbite.com');
1390
- editor.chain().focus().toggleLink({ href: url }).run();
1317
+ document.getElementById('toggleListButton').addEventListener('click', () => {
1318
+ editor.chain().focus().toggleBulletList().run();
1391
1319
  });
1392
- document.getElementById('removeLinkButton').addEventListener('click', () => {
1393
- editor.chain().focus().unsetLink().run()
1320
+ document.getElementById('toggleOrderedListButton').addEventListener('click', () => {
1321
+ editor.chain().focus().toggleOrderedList().run();
1322
+ });
1323
+ document.getElementById('toggleBlockquoteButton').addEventListener('click', () => {
1324
+ editor.chain().focus().toggleBlockquote().run();
1325
+ });
1326
+ document.getElementById('toggleHRButton').addEventListener('click', () => {
1327
+ editor.chain().focus().setHorizontalRule().run();
1328
+ });
1329
+ document.getElementById('toggleCodeBlockButton').addEventListener('click', () => {
1330
+ editor.chain().focus().toggleCodeBlock().run();
1331
+ });
1332
+
1333
+ // typography dropdown
1334
+ const typographyDropdown = FlowbiteInstances.getInstance('Dropdown', 'typographyDropdown');
1335
+
1336
+ document.getElementById('toggleParagraphButton').addEventListener('click', () => {
1337
+ editor.chain().focus().setParagraph().run();
1338
+ typographyDropdown.hide();
1339
+ });
1340
+
1341
+ document.querySelectorAll('[data-heading-level]').forEach((button) => {
1342
+ button.addEventListener('click', () => {
1343
+ const level = button.getAttribute('data-heading-level');
1344
+ editor.chain().focus().toggleHeading({ level: parseInt(level) }).run()
1345
+ typographyDropdown.hide();
1346
+ });
1394
1347
  });
1395
1348
  }
1396
1349
  })
1397
- ` >}}
1350
+ ```
1351
+
1352
+ ## Configuring links
1353
+
1354
+ Use this example to add and remove anchor links for the content inside of the WYSIWYG text editor.
1355
+
1356
+ ```html
1398
1357
  <div class="w-full bg-neutral-secondary-medium border border-default-medium rounded-base">
1399
1358
  <div class="p-2 border-b border-default-medium">
1400
1359
  <div class="flex flex-wrap items-center">
@@ -1427,28 +1386,28 @@ window.addEventListener('load', function() {
1427
1386
  <div id="wysiwyg-links-example"class="block w-full px-0 text-sm text-body bg-neutral-primary border-0 focus:ring-0"></div>
1428
1387
  </div>
1429
1388
  </div>
1430
- {{< /example >}}
1431
-
1432
- ## Using images
1433
-
1434
- Use this example to learn how to add images inside of the WYSIWYG text editor and configure settings such as the image URL, image alt attribute which is important for SEO and accessibility and the image title.
1389
+ ```
1435
1390
 
1436
- {{< example class="flex justify-center bg-neutral-primary" github="plugins/wysiwyg.md" show_dark=true wysiwyg=true script_module=true disable_init_js=true javascript=`
1391
+ ```javascript
1437
1392
  import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
1438
1393
  import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
1439
- import Image from 'https://esm.sh/@tiptap/extension-image@2.6.6';
1394
+ import Link from 'https://esm.sh/@tiptap/extension-link@2.6.6';
1440
1395
 
1441
1396
  window.addEventListener('load', function() {
1442
- if (document.getElementById("wysiwyg-images-example")) {
1397
+ if (document.getElementById("wysiwyg-links-example")) {
1443
1398
 
1444
1399
  // tip tap editor setup
1445
1400
  const editor = new Editor({
1446
- element: document.querySelector('#wysiwyg-images-example'),
1401
+ element: document.querySelector('#wysiwyg-links-example'),
1447
1402
  extensions: [
1448
1403
  StarterKit,
1449
- Image
1404
+ Link.configure({
1405
+ openOnClick: false,
1406
+ autolink: true,
1407
+ defaultProtocol: 'https',
1408
+ })
1450
1409
  ],
1451
- content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><img src="https://placehold.co/600x400" contenteditable="false" draggable="true"><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
1410
+ content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
1452
1411
  editorProps: {
1453
1412
  attributes: {
1454
1413
  class: 'format lg:format-lg dark:format-invert focus:outline-none format-blue max-w-none',
@@ -1457,33 +1416,22 @@ window.addEventListener('load', function() {
1457
1416
  });
1458
1417
 
1459
1418
  // set up custom event listeners for the buttons
1460
- document.getElementById('addImageButton').addEventListener('click', () => {
1461
- const url = window.prompt('Enter image URL:', 'https://placehold.co/600x400');
1462
- if (url) {
1463
- editor.chain().focus().setImage({ src: url }).run();
1464
- }
1419
+ document.getElementById('toggleLinkButton').addEventListener('click', () => {
1420
+ const url = window.prompt('Enter image URL:', 'https://flowbite.com');
1421
+ editor.chain().focus().toggleLink({ href: url }).run();
1465
1422
  });
1466
-
1467
- const advancedImageModal = FlowbiteInstances.getInstance('Modal', 'advanced-image-modal');
1468
-
1469
- document.getElementById('advancedImageForm').addEventListener('submit', (e) => {
1470
-
1471
- e.preventDefault();
1472
-
1473
- const imageUrl = document.getElementById('URL').value;
1474
- const imageAlt = document.getElementById('alt').value;
1475
- const imageTitle = document.getElementById('title').value;
1476
-
1477
- if (imageUrl) {
1478
- editor.chain().focus().setImage({ src: imageUrl, alt: imageAlt ? imageAlt : '', title: imageTitle ? imageTitle: '' }).run();
1479
- document.getElementById('advancedImageForm').reset();
1480
- advancedImageModal.hide();
1481
- }
1423
+ document.getElementById('removeLinkButton').addEventListener('click', () => {
1424
+ editor.chain().focus().unsetLink().run()
1482
1425
  });
1483
-
1484
1426
  }
1485
1427
  })
1486
- ` >}}
1428
+ ```
1429
+
1430
+ ## Using images
1431
+
1432
+ Use this example to learn how to add images inside of the WYSIWYG text editor and configure settings such as the image URL, image alt attribute which is important for SEO and accessibility and the image title.
1433
+
1434
+ ```html
1487
1435
  <div class="w-full bg-neutral-secondary-medium border border-default-medium rounded-base">
1488
1436
  <div class="p-2 border-b border-default-medium">
1489
1437
  <div class="flex items-center gap-2">
@@ -1557,26 +1505,22 @@ window.addEventListener('load', function() {
1557
1505
  </div>
1558
1506
  </div>
1559
1507
  </div>
1560
- {{< /example >}}
1561
-
1562
- ## Adding videos
1508
+ ```
1563
1509
 
1564
- Use this example to embed videos inside the WYSIWYG text editor based on a YouTube URL source and set the width and height of the video by using the Flowbite modal component API.
1565
-
1566
- {{< example class="flex justify-center bg-neutral-primary" github="plugins/wysiwyg.md" show_dark=true wysiwyg=true script_module=true disable_init_js=true javascript=`
1510
+ ```javascript
1567
1511
  import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
1568
1512
  import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
1569
- import YouTube from 'https://esm.sh/@tiptap/extension-youtube@2.6.6';
1513
+ import Image from 'https://esm.sh/@tiptap/extension-image@2.6.6';
1570
1514
 
1571
1515
  window.addEventListener('load', function() {
1572
- if (document.getElementById("wysiwyg-video-example")) {
1516
+ if (document.getElementById("wysiwyg-images-example")) {
1573
1517
 
1574
1518
  // tip tap editor setup
1575
1519
  const editor = new Editor({
1576
- element: document.querySelector('#wysiwyg-video-example'),
1520
+ element: document.querySelector('#wysiwyg-images-example'),
1577
1521
  extensions: [
1578
1522
  StarterKit,
1579
- YouTube
1523
+ Image
1580
1524
  ],
1581
1525
  content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><img src="https://placehold.co/600x400" contenteditable="false" draggable="true"><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
1582
1526
  editorProps: {
@@ -1587,37 +1531,39 @@ window.addEventListener('load', function() {
1587
1531
  });
1588
1532
 
1589
1533
  // set up custom event listeners for the buttons
1590
- document.getElementById('addVideoButton').addEventListener('click', () => {
1591
- const url = window.prompt('Enter YouTube URL:', 'https://www.youtube.com/watch?v=KaLxCiilHns');
1534
+ document.getElementById('addImageButton').addEventListener('click', () => {
1535
+ const url = window.prompt('Enter image URL:', 'https://placehold.co/600x400');
1592
1536
  if (url) {
1593
- editor.commands.setYoutubeVideo({
1594
- src: url,
1595
- width: 640,
1596
- height: 480,
1597
- })
1537
+ editor.chain().focus().setImage({ src: url }).run();
1598
1538
  }
1599
1539
  });
1600
1540
 
1601
- const advancedVideoModal = FlowbiteInstances.getInstance('Modal', 'advanced-video-modal');
1541
+ const advancedImageModal = FlowbiteInstances.getInstance('Modal', 'advanced-image-modal');
1602
1542
 
1603
- document.getElementById('advancedVideoForm').addEventListener('submit', (e) => {
1543
+ document.getElementById('advancedImageForm').addEventListener('submit', (e) => {
1604
1544
 
1605
1545
  e.preventDefault();
1606
1546
 
1607
- const videoUrl = document.getElementById('URL').value;
1608
- const videoWidth = document.getElementById('width').value;
1609
- const videoHeight = document.getElementById('height').value;
1547
+ const imageUrl = document.getElementById('URL').value;
1548
+ const imageAlt = document.getElementById('alt').value;
1549
+ const imageTitle = document.getElementById('title').value;
1610
1550
 
1611
- if (videoUrl) {
1612
- editor.commands.setYoutubeVideo({ src: videoUrl, width: videoWidth ? videoWidth : 640, height: videoHeight ? videoHeight: 480 });
1613
- document.getElementById('advancedVideoForm').reset();
1614
- advancedVideoModal.hide();
1551
+ if (imageUrl) {
1552
+ editor.chain().focus().setImage({ src: imageUrl, alt: imageAlt ? imageAlt : '', title: imageTitle ? imageTitle: '' }).run();
1553
+ document.getElementById('advancedImageForm').reset();
1554
+ advancedImageModal.hide();
1615
1555
  }
1616
1556
  });
1617
1557
 
1618
1558
  }
1619
1559
  })
1620
- ` >}}
1560
+ ```
1561
+
1562
+ ## Adding videos
1563
+
1564
+ Use this example to embed videos inside the WYSIWYG text editor based on a YouTube URL source and set the width and height of the video by using the Flowbite modal component API.
1565
+
1566
+ ```html
1621
1567
  <div class="w-full bg-neutral-secondary-medium border border-default-medium rounded-base">
1622
1568
  <div class="p-2 border-b border-default-medium">
1623
1569
  <div class="flex items-center gap-2">
@@ -1686,60 +1632,24 @@ window.addEventListener('load', function() {
1686
1632
  </div>
1687
1633
  </div>
1688
1634
  </div>
1689
- {{< /example >}}
1690
-
1691
- ## Editing tables
1635
+ ```
1692
1636
 
1693
- Use this example to edit table data inside the WYSIWYG text editor by adding and removing table column, rows, and cells and use other features to navigate through the table data for a convenient editing process.
1694
-
1695
- {{< example class="flex justify-center bg-neutral-primary" github="plugins/wysiwyg.md" show_dark=true wysiwyg=true script_module=true disable_init_js=true javascript=`
1637
+ ```javascript
1696
1638
  import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
1697
1639
  import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
1698
- import Table from 'https://esm.sh/@tiptap/extension-table@2.6.6';
1699
- import TableCell from 'https://esm.sh/@tiptap/extension-table-cell@2.6.6';
1700
- import TableHeader from 'https://esm.sh/@tiptap/extension-table-header@2.6.6';
1701
- import TableRow from 'https://esm.sh/@tiptap/extension-table-row@2.6.6';
1702
-
1703
- const TipTapExtensionTableCell = TableCell.extend({
1704
- addAttributes() {
1705
- return {
1706
- ...this.parent?.(),
1707
- backgroundColor: {
1708
- default: null,
1709
- renderHTML: (attributes) => {
1710
- if (!attributes.backgroundColor) {
1711
- return {}
1712
- }
1713
-
1714
- return {
1715
- style: 'background-color: ' + attributes.backgroundColor,
1716
- }
1717
- },
1718
- parseHTML: (element) => {
1719
- return element.style.backgroundColor.replace(/['"]+/g, '')
1720
- },
1721
- },
1722
- }
1723
- },
1724
- });
1640
+ import YouTube from 'https://esm.sh/@tiptap/extension-youtube@2.6.6';
1725
1641
 
1726
1642
  window.addEventListener('load', function() {
1727
- if (document.getElementById("wysiwyg-tables-example")) {
1643
+ if (document.getElementById("wysiwyg-video-example")) {
1728
1644
 
1729
1645
  // tip tap editor setup
1730
1646
  const editor = new Editor({
1731
- element: document.querySelector('#wysiwyg-tables-example'),
1647
+ element: document.querySelector('#wysiwyg-video-example'),
1732
1648
  extensions: [
1733
1649
  StarterKit,
1734
- Table.configure({
1735
- resizable: true,
1736
- }),
1737
- TableRow,
1738
- TableHeader,
1739
- TableCell,
1740
- TipTapExtensionTableCell
1650
+ YouTube
1741
1651
  ],
1742
- content: '<p>Understanding global <strong>population growth trends</strong> is essential for analyzing the development and future of nations. Population growth rates provide insights into economic prospects, resource allocation, and potential challenges for countries worldwide.</p><p>Here is an example of population data:</p><div class=tableWrapper><table style=min-width:75px><col><col><col><tr><th colspan=1 rowspan=1><p>Country<th colspan=1 rowspan=1><p>Population<th colspan=1 rowspan=1><p>Growth rate<tr><td colspan=1 rowspan=1><p>United States<td colspan=1 rowspan=1><p>333 million<td colspan=1 rowspan=1><p>0.4%<tr><td colspan=1 rowspan=1><p>China<td colspan=1 rowspan=1><p>1.41 billion<td colspan=1 rowspan=1><p>0%<tr><td colspan=1 rowspan=1><p>Germany<td colspan=1 rowspan=1><p>83.8 million<td colspan=1 rowspan=1><p>0.7%<tr><td colspan=1 rowspan=1><p>India<td colspan=1 rowspan=1><p>1.42 billion<td colspan=1 rowspan=1><p>1.0%<tr><td colspan=1 rowspan=1><p>Brazil<td colspan=1 rowspan=1><p>214 million<td colspan=1 rowspan=1><p>0.6%<tr><td colspan=1 rowspan=1><p>Indonesia<td colspan=1 rowspan=1><p>273 million<td colspan=1 rowspan=1><p>1.1%<tr><td colspan=1 rowspan=1><p>Pakistan<td colspan=1 rowspan=1><p>231 million<td colspan=1 rowspan=1><p>2.0%<tr><td colspan=1 rowspan=1><p>Nigeria<td colspan=1 rowspan=1><p>223 million<td colspan=1 rowspan=1><p>2.5%</table></div><p>Learn more about global population trends from reliable sources like the <a href=https://www.worldpopulationreview.com>World Population Review</a>.</p>',
1652
+ content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><img src="https://placehold.co/600x400" contenteditable="false" draggable="true"><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
1743
1653
  editorProps: {
1744
1654
  attributes: {
1745
1655
  class: 'format lg:format-lg dark:format-invert focus:outline-none format-blue max-w-none',
@@ -1748,108 +1658,43 @@ window.addEventListener('load', function() {
1748
1658
  });
1749
1659
 
1750
1660
  // set up custom event listeners for the buttons
1751
- document.getElementById('addTableButton').addEventListener('click', () => {
1752
- editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
1753
- });
1754
-
1755
- // add column before
1756
- document.getElementById('addColumnBeforeButton').addEventListener('click', () => {
1757
- editor.chain().focus().addColumnBefore().run();
1758
- });
1759
-
1760
- // add column after
1761
- document.getElementById('addColumnAfterButton').addEventListener('click', () => {
1762
- editor.chain().focus().addColumnAfter().run();
1763
- });
1764
-
1765
- // remove column
1766
- document.getElementById('removeColumnButton').addEventListener('click', () => {
1767
- editor.chain().focus().deleteColumn().run();
1768
- });
1769
-
1770
- // add row before
1771
- document.getElementById('addRowBeforeButton').addEventListener('click', () => {
1772
- editor.chain().focus().addRowBefore().run();
1773
- });
1774
-
1775
- // add row after
1776
- document.getElementById('addRowAfterButton').addEventListener('click', () => {
1777
- editor.chain().focus().addRowAfter().run();
1778
- });
1779
-
1780
- // remove row
1781
- document.getElementById('removeRowButton').addEventListener('click', () => {
1782
- editor.chain().focus().deleteRow().run();
1783
- });
1784
-
1785
- // delete table
1786
- document.getElementById('deleteTableButton').addEventListener('click', () => {
1787
- editor.chain().focus().deleteTable().run();
1788
- });
1789
-
1790
- // merge cells
1791
- document.getElementById('mergeCellsButton').addEventListener('click', () => {
1792
- editor.chain().focus().mergeCells().run();
1793
- });
1794
-
1795
- // split cells
1796
- document.getElementById('splitCellsButton').addEventListener('click', () => {
1797
- editor.chain().focus().splitCell().run();
1798
- });
1799
-
1800
- // merge or split
1801
- document.getElementById('mergeOrSplitButton').addEventListener('click', () => {
1802
- editor.chain().focus().mergeOrSplit().run();
1803
- });
1804
-
1805
- // toggle header column
1806
- document.getElementById('toggleHeaderColumnButton').addEventListener('click', () => {
1807
- editor.chain().focus().toggleHeaderColumn().run();
1808
- });
1809
-
1810
- // toggle header row
1811
- document.getElementById('toggleHeaderRowButton').addEventListener('click', () => {
1812
- editor.chain().focus().toggleHeaderRow().run();
1813
- });
1814
-
1815
- // toggle header cell
1816
- document.getElementById('toggleHeaderCellButton').addEventListener('click', () => {
1817
- editor.chain().focus().toggleHeaderCell().run();
1661
+ document.getElementById('addVideoButton').addEventListener('click', () => {
1662
+ const url = window.prompt('Enter YouTube URL:', 'https://www.youtube.com/watch?v=KaLxCiilHns');
1663
+ if (url) {
1664
+ editor.commands.setYoutubeVideo({
1665
+ src: url,
1666
+ width: 640,
1667
+ height: 480,
1668
+ })
1669
+ }
1818
1670
  });
1819
1671
 
1820
- const cellAttributeModal = FlowbiteInstances.getInstance('Modal', 'cell-attribute-modal');
1672
+ const advancedVideoModal = FlowbiteInstances.getInstance('Modal', 'advanced-video-modal');
1821
1673
 
1822
- document.getElementById('addCellAttributeForm').addEventListener('submit', (e) => {
1674
+ document.getElementById('advancedVideoForm').addEventListener('submit', (e) => {
1823
1675
 
1824
1676
  e.preventDefault();
1825
1677
 
1826
- const attributeName = document.getElementById('attribute-name').value;
1827
- const attributeValue = document.getElementById('attribute-value').value;
1828
-
1829
- if (attributeName && attributeValue) {
1830
- const result = editor.commands.setCellAttribute(attributeName ? attributeName : '', attributeValue ? attributeValue : '');
1831
- document.getElementById('addCellAttributeForm').reset();
1832
- cellAttributeModal.hide();
1833
- }
1834
- });
1835
-
1836
- // fix tables
1837
- document.getElementById('fixTablesButton').addEventListener('click', () => {
1838
- editor.commands.fixTables();
1839
- });
1840
-
1841
- // go to previous cell
1842
- document.getElementById('previousCellButton').addEventListener('click', () => {
1843
- editor.chain().focus().goToPreviousCell().run();
1844
- });
1678
+ const videoUrl = document.getElementById('URL').value;
1679
+ const videoWidth = document.getElementById('width').value;
1680
+ const videoHeight = document.getElementById('height').value;
1845
1681
 
1846
- // go to the next cell
1847
- document.getElementById('nextCellButton').addEventListener('click', () => {
1848
- editor.chain().focus().goToNextCell().run();
1682
+ if (videoUrl) {
1683
+ editor.commands.setYoutubeVideo({ src: videoUrl, width: videoWidth ? videoWidth : 640, height: videoHeight ? videoHeight: 480 });
1684
+ document.getElementById('advancedVideoForm').reset();
1685
+ advancedVideoModal.hide();
1686
+ }
1849
1687
  });
1688
+
1850
1689
  }
1851
1690
  })
1852
- ` >}}
1691
+ ```
1692
+
1693
+ ## Editing tables
1694
+
1695
+ Use this example to edit table data inside the WYSIWYG text editor by adding and removing table column, rows, and cells and use other features to navigate through the table data for a convenient editing process.
1696
+
1697
+ ```html
1853
1698
  <div class="w-full bg-neutral-secondary-medium border border-default-medium rounded-base">
1854
1699
  <div class="p-2 border-b border-default-medium">
1855
1700
  <div class="flex items-center gap-2">
@@ -2092,26 +1937,56 @@ window.addEventListener('load', function() {
2092
1937
  </div>
2093
1938
  </div>
2094
1939
  </div>
2095
- {{< /example >}}
2096
-
2097
- ## Undo and redo
2098
-
2099
- Use the history functionality from the WYSIWYG text editor component to integrate undo and redo actions.
1940
+ ```
2100
1941
 
2101
- {{< example class="flex justify-center bg-neutral-primary" github="plugins/wysiwyg.md" show_dark=true wysiwyg=true script_module=true disable_init_js=true javascript=`
1942
+ ```javascript
2102
1943
  import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
2103
1944
  import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
1945
+ import Table from 'https://esm.sh/@tiptap/extension-table@2.6.6';
1946
+ import TableCell from 'https://esm.sh/@tiptap/extension-table-cell@2.6.6';
1947
+ import TableHeader from 'https://esm.sh/@tiptap/extension-table-header@2.6.6';
1948
+ import TableRow from 'https://esm.sh/@tiptap/extension-table-row@2.6.6';
1949
+
1950
+ const TipTapExtensionTableCell = TableCell.extend({
1951
+ addAttributes() {
1952
+ return {
1953
+ ...this.parent?.(),
1954
+ backgroundColor: {
1955
+ default: null,
1956
+ renderHTML: (attributes) => {
1957
+ if (!attributes.backgroundColor) {
1958
+ return {}
1959
+ }
1960
+
1961
+ return {
1962
+ style: 'background-color: ' + attributes.backgroundColor,
1963
+ }
1964
+ },
1965
+ parseHTML: (element) => {
1966
+ return element.style.backgroundColor.replace(/['"]+/g, '')
1967
+ },
1968
+ },
1969
+ }
1970
+ },
1971
+ });
2104
1972
 
2105
1973
  window.addEventListener('load', function() {
2106
- if (document.getElementById("wysiwyg-history-example")) {
1974
+ if (document.getElementById("wysiwyg-tables-example")) {
2107
1975
 
2108
1976
  // tip tap editor setup
2109
1977
  const editor = new Editor({
2110
- element: document.querySelector('#wysiwyg-history-example'),
1978
+ element: document.querySelector('#wysiwyg-tables-example'),
2111
1979
  extensions: [
2112
- StarterKit
1980
+ StarterKit,
1981
+ Table.configure({
1982
+ resizable: true,
1983
+ }),
1984
+ TableRow,
1985
+ TableHeader,
1986
+ TableCell,
1987
+ TipTapExtensionTableCell
2113
1988
  ],
2114
- content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
1989
+ content: '<p>Understanding global <strong>population growth trends</strong> is essential for analyzing the development and future of nations. Population growth rates provide insights into economic prospects, resource allocation, and potential challenges for countries worldwide.</p><p>Here is an example of population data:</p><div class=tableWrapper><table style=min-width:75px><col><col><col><tr><th colspan=1 rowspan=1><p>Country<th colspan=1 rowspan=1><p>Population<th colspan=1 rowspan=1><p>Growth rate<tr><td colspan=1 rowspan=1><p>United States<td colspan=1 rowspan=1><p>333 million<td colspan=1 rowspan=1><p>0.4%<tr><td colspan=1 rowspan=1><p>China<td colspan=1 rowspan=1><p>1.41 billion<td colspan=1 rowspan=1><p>0%<tr><td colspan=1 rowspan=1><p>Germany<td colspan=1 rowspan=1><p>83.8 million<td colspan=1 rowspan=1><p>0.7%<tr><td colspan=1 rowspan=1><p>India<td colspan=1 rowspan=1><p>1.42 billion<td colspan=1 rowspan=1><p>1.0%<tr><td colspan=1 rowspan=1><p>Brazil<td colspan=1 rowspan=1><p>214 million<td colspan=1 rowspan=1><p>0.6%<tr><td colspan=1 rowspan=1><p>Indonesia<td colspan=1 rowspan=1><p>273 million<td colspan=1 rowspan=1><p>1.1%<tr><td colspan=1 rowspan=1><p>Pakistan<td colspan=1 rowspan=1><p>231 million<td colspan=1 rowspan=1><p>2.0%<tr><td colspan=1 rowspan=1><p>Nigeria<td colspan=1 rowspan=1><p>223 million<td colspan=1 rowspan=1><p>2.5%</table></div><p>Learn more about global population trends from reliable sources like the <a href=https://www.worldpopulationreview.com>World Population Review</a>.</p>',
2115
1990
  editorProps: {
2116
1991
  attributes: {
2117
1992
  class: 'format lg:format-lg dark:format-invert focus:outline-none format-blue max-w-none',
@@ -2120,16 +1995,114 @@ window.addEventListener('load', function() {
2120
1995
  });
2121
1996
 
2122
1997
  // set up custom event listeners for the buttons
2123
- document.getElementById('toggleUndoButton').addEventListener('click', () => {
2124
- editor.chain().focus().undo().run();
1998
+ document.getElementById('addTableButton').addEventListener('click', () => {
1999
+ editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
2125
2000
  });
2126
- document.getElementById('toggleRedoButton').addEventListener('click', () => {
2127
- editor.chain().focus().redo().run()
2001
+
2002
+ // add column before
2003
+ document.getElementById('addColumnBeforeButton').addEventListener('click', () => {
2004
+ editor.chain().focus().addColumnBefore().run();
2005
+ });
2006
+
2007
+ // add column after
2008
+ document.getElementById('addColumnAfterButton').addEventListener('click', () => {
2009
+ editor.chain().focus().addColumnAfter().run();
2010
+ });
2011
+
2012
+ // remove column
2013
+ document.getElementById('removeColumnButton').addEventListener('click', () => {
2014
+ editor.chain().focus().deleteColumn().run();
2015
+ });
2016
+
2017
+ // add row before
2018
+ document.getElementById('addRowBeforeButton').addEventListener('click', () => {
2019
+ editor.chain().focus().addRowBefore().run();
2020
+ });
2021
+
2022
+ // add row after
2023
+ document.getElementById('addRowAfterButton').addEventListener('click', () => {
2024
+ editor.chain().focus().addRowAfter().run();
2025
+ });
2026
+
2027
+ // remove row
2028
+ document.getElementById('removeRowButton').addEventListener('click', () => {
2029
+ editor.chain().focus().deleteRow().run();
2030
+ });
2031
+
2032
+ // delete table
2033
+ document.getElementById('deleteTableButton').addEventListener('click', () => {
2034
+ editor.chain().focus().deleteTable().run();
2035
+ });
2036
+
2037
+ // merge cells
2038
+ document.getElementById('mergeCellsButton').addEventListener('click', () => {
2039
+ editor.chain().focus().mergeCells().run();
2040
+ });
2041
+
2042
+ // split cells
2043
+ document.getElementById('splitCellsButton').addEventListener('click', () => {
2044
+ editor.chain().focus().splitCell().run();
2045
+ });
2046
+
2047
+ // merge or split
2048
+ document.getElementById('mergeOrSplitButton').addEventListener('click', () => {
2049
+ editor.chain().focus().mergeOrSplit().run();
2050
+ });
2051
+
2052
+ // toggle header column
2053
+ document.getElementById('toggleHeaderColumnButton').addEventListener('click', () => {
2054
+ editor.chain().focus().toggleHeaderColumn().run();
2055
+ });
2056
+
2057
+ // toggle header row
2058
+ document.getElementById('toggleHeaderRowButton').addEventListener('click', () => {
2059
+ editor.chain().focus().toggleHeaderRow().run();
2128
2060
  });
2129
2061
 
2062
+ // toggle header cell
2063
+ document.getElementById('toggleHeaderCellButton').addEventListener('click', () => {
2064
+ editor.chain().focus().toggleHeaderCell().run();
2065
+ });
2066
+
2067
+ const cellAttributeModal = FlowbiteInstances.getInstance('Modal', 'cell-attribute-modal');
2068
+
2069
+ document.getElementById('addCellAttributeForm').addEventListener('submit', (e) => {
2070
+
2071
+ e.preventDefault();
2072
+
2073
+ const attributeName = document.getElementById('attribute-name').value;
2074
+ const attributeValue = document.getElementById('attribute-value').value;
2075
+
2076
+ if (attributeName && attributeValue) {
2077
+ const result = editor.commands.setCellAttribute(attributeName ? attributeName : '', attributeValue ? attributeValue : '');
2078
+ document.getElementById('addCellAttributeForm').reset();
2079
+ cellAttributeModal.hide();
2080
+ }
2081
+ });
2082
+
2083
+ // fix tables
2084
+ document.getElementById('fixTablesButton').addEventListener('click', () => {
2085
+ editor.commands.fixTables();
2086
+ });
2087
+
2088
+ // go to previous cell
2089
+ document.getElementById('previousCellButton').addEventListener('click', () => {
2090
+ editor.chain().focus().goToPreviousCell().run();
2091
+ });
2092
+
2093
+ // go to the next cell
2094
+ document.getElementById('nextCellButton').addEventListener('click', () => {
2095
+ editor.chain().focus().goToNextCell().run();
2096
+ });
2130
2097
  }
2131
2098
  })
2132
- ` >}}
2099
+ ```
2100
+
2101
+ ## Undo and redo
2102
+
2103
+ Use the history functionality from the WYSIWYG text editor component to integrate undo and redo actions.
2104
+
2105
+ ```html
2133
2106
  <div class="w-full bg-neutral-secondary-medium border border-default-medium rounded-base">
2134
2107
  <div class="p-2 border-b border-default-medium">
2135
2108
  <div class="flex flex-wrap items-center">
@@ -2162,22 +2135,18 @@ window.addEventListener('load', function() {
2162
2135
  <div id="wysiwyg-history-example"class="block w-full px-0 text-sm text-body bg-neutral-primary border-0 focus:ring-0"></div>
2163
2136
  </div>
2164
2137
  </div>
2165
- {{< /example >}}
2138
+ ```
2166
2139
 
2167
- ## Exporting data
2168
-
2169
- Use the `editor.getJSON()` and the `editor.getHTML()` functions to export the text content inside of the WYSIWYG text editor in JSON or raw HTML format to persist into your database or API structure.
2170
-
2171
- {{< example class="flex justify-center bg-neutral-primary" github="plugins/wysiwyg.md" show_dark=true wysiwyg=true script_module=true disable_init_js=true javascript=`
2140
+ ```javascript
2172
2141
  import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
2173
2142
  import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
2174
2143
 
2175
2144
  window.addEventListener('load', function() {
2176
- if (document.getElementById("wysiwyg-export-example")) {
2145
+ if (document.getElementById("wysiwyg-history-example")) {
2177
2146
 
2178
2147
  // tip tap editor setup
2179
2148
  const editor = new Editor({
2180
- element: document.querySelector('#wysiwyg-export-example'),
2149
+ element: document.querySelector('#wysiwyg-history-example'),
2181
2150
  extensions: [
2182
2151
  StarterKit
2183
2152
  ],
@@ -2189,34 +2158,23 @@ window.addEventListener('load', function() {
2189
2158
  }
2190
2159
  });
2191
2160
 
2192
- const sourceCodeModal = FlowbiteInstances.getInstance('Modal', 'source-code-modal');
2193
- const sourceCodeWrapper = document.getElementById('sourceCode');
2194
-
2195
2161
  // set up custom event listeners for the buttons
2196
- document.getElementById('toggleHTMLButton').addEventListener('click', () => {
2197
-
2198
- // basically just use editor.getHTML(); to get the raw html
2199
-
2200
- sourceCodeWrapper.innerHTML = editor.getHTML()
2201
- .replace(/&/g, "&amp;") // Escape & character
2202
- .replace(/</g, "&lt;") // Escape < character
2203
- .replace(/>/g, "&gt;") // Escape > character
2204
- .replace(/"/g, "&quot;") // Escape " character
2205
- .replace(/'/g, "&#039;"); // Escape ' character
2162
+ document.getElementById('toggleUndoButton').addEventListener('click', () => {
2163
+ editor.chain().focus().undo().run();
2206
2164
  });
2207
-
2208
- document.getElementById('toggleJSONButton').addEventListener('click', () => {
2209
-
2210
- // basically just use editor.getJSON(); to get the raw json
2211
-
2212
- sourceCode.innerHTML = JSON.stringify(editor.getJSON(), null, 2)
2213
- .replace(/&/g, "&amp;")
2214
- .replace(/</g, "&lt;")
2215
- .replace(/>/g, "&gt;");
2165
+ document.getElementById('toggleRedoButton').addEventListener('click', () => {
2166
+ editor.chain().focus().redo().run()
2216
2167
  });
2168
+
2217
2169
  }
2218
2170
  })
2219
- ` >}}
2171
+ ```
2172
+
2173
+ ## Exporting data
2174
+
2175
+ Use the `editor.getJSON()` and the `editor.getHTML()` functions to export the text content inside of the WYSIWYG text editor in JSON or raw HTML format to persist into your database or API structure.
2176
+
2177
+ ```html
2220
2178
  <div class="w-full bg-neutral-secondary-medium border border-default-medium rounded-base">
2221
2179
  <div class="p-2 border-b border-default-medium">
2222
2180
  <div class="flex flex-wrap items-center">
@@ -2273,7 +2231,57 @@ window.addEventListener('load', function() {
2273
2231
  </div>
2274
2232
  </div>
2275
2233
  </div>
2276
- {{< /example >}}
2234
+ ```
2235
+
2236
+ ```javascript
2237
+ import { Editor } from 'https://esm.sh/@tiptap/core@2.6.6';
2238
+ import StarterKit from 'https://esm.sh/@tiptap/starter-kit@2.6.6';
2239
+
2240
+ window.addEventListener('load', function() {
2241
+ if (document.getElementById("wysiwyg-export-example")) {
2242
+
2243
+ // tip tap editor setup
2244
+ const editor = new Editor({
2245
+ element: document.querySelector('#wysiwyg-export-example'),
2246
+ extensions: [
2247
+ StarterKit
2248
+ ],
2249
+ content: '<p>Flowbite is an <strong>open-source library of UI components</strong> based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, and more.</p><p>It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigation bars, modals, datepickers, advanced charts and the list goes on.</p><p>Here is an example of a button component:</p><code>&#x3C;button type=&#x22;button&#x22; class=&#x22;text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-base text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800&#x22;&#x3E;Default&#x3C;/button&#x3E;</code><p>Learn more about all components from the <a href="https://flowbite.com/docs/getting-started/introduction/">Flowbite Docs</a>.</p>',
2250
+ editorProps: {
2251
+ attributes: {
2252
+ class: 'format lg:format-lg dark:format-invert focus:outline-none format-blue max-w-none',
2253
+ },
2254
+ }
2255
+ });
2256
+
2257
+ const sourceCodeModal = FlowbiteInstances.getInstance('Modal', 'source-code-modal');
2258
+ const sourceCodeWrapper = document.getElementById('sourceCode');
2259
+
2260
+ // set up custom event listeners for the buttons
2261
+ document.getElementById('toggleHTMLButton').addEventListener('click', () => {
2262
+
2263
+ // basically just use editor.getHTML(); to get the raw html
2264
+
2265
+ sourceCodeWrapper.innerHTML = editor.getHTML()
2266
+ .replace(/&/g, "&amp;") // Escape & character
2267
+ .replace(/</g, "&lt;") // Escape < character
2268
+ .replace(/>/g, "&gt;") // Escape > character
2269
+ .replace(/"/g, "&quot;") // Escape " character
2270
+ .replace(/'/g, "&#039;"); // Escape ' character
2271
+ });
2272
+
2273
+ document.getElementById('toggleJSONButton').addEventListener('click', () => {
2274
+
2275
+ // basically just use editor.getJSON(); to get the raw json
2276
+
2277
+ sourceCode.innerHTML = JSON.stringify(editor.getJSON(), null, 2)
2278
+ .replace(/&/g, "&amp;")
2279
+ .replace(/</g, "&lt;")
2280
+ .replace(/>/g, "&gt;");
2281
+ });
2282
+ }
2283
+ })
2284
+ ```
2277
2285
 
2278
2286
  ## Javascript behaviour
2279
2287
 
@@ -2281,7 +2289,7 @@ Learn more about how you can programmatically use the WYSIWYG editor using Javas
2281
2289
 
2282
2290
  After you have installed Tip Tap via NPM or CDN you can create a new `Editor` object:
2283
2291
 
2284
- {{< code lang="javascript" file="wysiwyg.js" icon="file" >}}
2292
+ ```javascript
2285
2293
  import { Editor } from '@tiptap/core';
2286
2294
  import StarterKit from '@tiptap/starter-kit';
2287
2295
 
@@ -2290,13 +2298,13 @@ new Editor({
2290
2298
  extensions: [StarterKit],
2291
2299
  content: '<p>Welcome to Flowbite!</p>',
2292
2300
  })
2293
- {{< /code >}}
2301
+ ```
2294
2302
 
2295
2303
  Make sure that you also have an empty `div` element with the appropiate ID:
2296
2304
 
2297
- {{< code lang="html" file="wysiwyg.html" icon="file" >}}
2305
+ ```html
2298
2306
  <div id="wysiwyg"></div>
2299
- {{< /code >}}
2307
+ ```
2300
2308
 
2301
2309
  This code will automatically set up the markup needed inside of the WYSIWYG component. Please note the fact that the Tip Tap library is headless so you need to style the elements yourself, but you can copy-paste the examples from Flowbite on this page.
2302
2310
 
@@ -2304,7 +2312,7 @@ This code will automatically set up the markup needed inside of the WYSIWYG comp
2304
2312
 
2305
2313
  We also recommend adding custom typography classes from the [Flowbite Typography](https://flowbite.com/docs/components/typography/) package so that the content inside of the text editor will be correctly styled:
2306
2314
 
2307
- {{< code lang="javascript" file="wysiwyg.js" icon="file" >}}
2315
+ ```javascript
2308
2316
  new Editor({
2309
2317
  element: document.getElementById('wysiwyg'),
2310
2318
  extensions: [StarterKit],
@@ -2315,7 +2323,7 @@ new Editor({
2315
2323
  },
2316
2324
  }
2317
2325
  })
2318
- {{< /code >}}
2326
+ ```
2319
2327
 
2320
2328
  ### Extensions
2321
2329
 
@@ -2323,7 +2331,7 @@ Tip Tap is a modular library meaning that if you want to introduce images, video
2323
2331
 
2324
2332
  Here is one example where we add the link extension:
2325
2333
 
2326
- {{< code lang="javascript" file="wysiwyg.js" icon="file" >}}
2334
+ ```javascript
2327
2335
  import { Editor } from '@tiptap/core';
2328
2336
  import StarterKit from '@tiptap/starter-kit';
2329
2337
  import Link from '@tiptap/extension-link';
@@ -2345,7 +2353,7 @@ const editor = new Editor({
2345
2353
  },
2346
2354
  }
2347
2355
  });
2348
- {{< /code >}}
2356
+ ```
2349
2357
 
2350
2358
  Links will now be available inside the WYSIWYG component. Learn more about all of the <a href="https://tiptap.dev/docs/editor/extensions/overview" target="_blank" rel="nofollow">extensions API</a>.
2351
2359
 
@@ -2353,22 +2361,22 @@ Links will now be available inside the WYSIWYG component. Learn more about all o
2353
2361
 
2354
2362
  You can easily call the methods from the `Editor` object to set text styles, links, images, and more. Here is one example where based upon a click event on a button you will be prompted with the URL of the link and it will add it to the currently selected text:
2355
2363
 
2356
- {{< code lang="javascript" file="wysiwyg.js" icon="file" >}}
2364
+ ```javascript
2357
2365
  // set up custom event listeners for the buttons
2358
2366
  document.getElementById('toggleLinkButton').addEventListener('click', () => {
2359
2367
  const url = window.prompt('Enter image URL:', 'https://flowbite.com');
2360
2368
  editor.chain().focus().toggleLink({ href: url }).run();
2361
2369
  });
2362
- {{< /code >}}
2370
+ ```
2363
2371
 
2364
2372
  And here's another example where you can unset a link:
2365
2373
 
2366
- {{< code lang="javascript" file="wysiwyg.js" icon="file" >}}
2374
+ ```javascript
2367
2375
  // unset the links based on a button click
2368
2376
  document.getElementById('removeLinkButton').addEventListener('click', () => {
2369
2377
  editor.chain().focus().unsetLink().run()
2370
2378
  });
2371
- {{< /code >}}
2379
+ ```
2372
2380
 
2373
2381
  Examples from this page have functional elements so you can check the JavaScript tab for the source code.
2374
2382