### Install and Configure NodeMoverModule Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/node-mover.md Example of how to install and configure the NodeMoverModule in a Quill editor form. Customize selection and drop indicator colors. ```php use Ehyiah\QuillJsBundle\DTO\Modules\NodeMoverModule; use Ehyiah\QuillJsBundle\Form\QuillType; $builder->add('content', QuillType::class, [ 'modules' => [ new NodeMoverModule([ 'borderColor' => '#007bff', // Optional: customize the selection frame color 'dropIndicatorColor' => '#ff0000' // Optional: customize the drop line color ]), ], ]); ``` -------------------------------- ### Example: Rich Toolbar Configuration Source: https://context7.com/ehyiah/ux-quill/llms.txt This example demonstrates a comprehensive toolbar configuration using various QuillGroup::build instances for different functionalities. Ensure all necessary DTOs and modules are imported. ```php use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\AlignField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\BackgroundColorField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\ColorField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\DirectionField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\FontField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\HeaderField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\HeaderGroupField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\IndentField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\ListField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\ScriptField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\SizeField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\BlockQuoteField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\BoldField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\CleanField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\CodeBlockField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\CodeField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\DividerField; // auto-imports DividerModule use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\EmojiField; // auto-imports EmojiModule use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\FormulaField; // requires KaTeX use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\ImageField; // auto-imports ImageSelectionModule use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\ImageGalleryField; // auto-imports ImageGalleryModule use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\ItalicField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\LinkField; // auto-imports LinkAttributesModule use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\PageBreakField; // auto-imports PageBreakModule use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\StrikeField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\TableField; // auto-imports TableModule use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\UnderlineField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\VideoField; // Example: rich toolbar 'quill_options' => [ QuillGroup::build( new BoldField(), new ItalicField(), new UnderlineField(), new StrikeField(), new BlockQuoteField(), new CodeField(), ), QuillGroup::build( new HeaderField(HeaderField::HEADER_OPTION_1), new HeaderField(HeaderField::HEADER_OPTION_2), new SizeField(), new AlignField(AlignField::ALIGN_FIELD_OPTION_CENTER), ), QuillGroup::build( new ListField(ListField::LIST_FIELD_OPTION_ORDERED), new ListField(ListField::LIST_FIELD_OPTION_BULLET), new ListField(ListField::LIST_FIELD_OPTION_CHECK), new IndentField(IndentField::INDENT_FIELD_OPTION_PLUS), new IndentField(IndentField::INDENT_FIELD_OPTION_MINUS), ), QuillGroup::build( new LinkField(), new ImageField(), new VideoField(), new TableField(), new EmojiField(), new FormulaField(), new DividerField(), new PageBreakField(), new CleanField(), ), ], ``` -------------------------------- ### Install ehyiah/ux-quill Bundle Source: https://context7.com/ehyiah/ux-quill/llms.txt Steps to install the bundle using Composer and configure for AssetMapper or Webpack Encore. ```bash # Step 1 – require the PHP package composer require ehyiah/ux-quill # Step 2a – AssetMapper (no further steps needed) # The importmap is populated automatically. # Step 2b – Webpack Encore (recompile assets) yarn install --force && yarn watch # or npm install --force && npm run watch ``` -------------------------------- ### Configuration: JSON Upload Handler Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/configuration/image-upload.md Example configuration for setting up a JSON upload handler. This specifies the upload endpoint and how to extract the image URL from the JSON response. ```php 'quill_extra_options' => [ 'upload_handler' => [ 'type' => 'json', 'upload_endpoint' => '/my-custom-endpoint/upload', 'json_response_file_path' => 'file.url' ] ], ``` -------------------------------- ### Install Dependencies with NPM Source: https://github.com/ehyiah/ux-quill/blob/main/README.md If you are using webpack encore, run these commands after composer require. Not needed with AssetMapper. ```sh npm install --force npm run watch ``` -------------------------------- ### QuillJS Configuration with Image Gallery Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/image-gallery.md Example of how to configure the Quill editor to include the Image Gallery module and its toolbar button. ```APIDOC ## QuillJS Configuration with Image Gallery This example demonstrates how to add the Image Gallery module to your Quill editor configuration. ### Usage ```php use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\ImageGalleryField; use Ehyiah\QuillJsBundle\DTO\Modules\ImageGalleryModule; use Ehyiah\QuillJsBundle\Form\QuillType; $builder->add('content', QuillType::class, [ 'quill_options' => [ ['bold', 'italic'], [new ImageGalleryField()], // Position the button in the toolbar ], 'modules' => [ new ImageGalleryModule(options: [ 'listEndpoint' => '/api/media/list', 'searchEndpoint' => '/api/media/search', 'buttonTitle' => 'Browse Media Library', 'messageTitleOption' => 'Select an image for your article', ]), ], ]); ``` ### Parameters - **quill_options**: An array of toolbar options, including the `ImageGalleryField` to display the button. - **modules**: Configuration for the `ImageGalleryModule` with specific API endpoints and display options. ``` -------------------------------- ### Build Toolbar Group with Headers and Text Formatting Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/configuration/quill-options.md Create multiple toolbar groups to organize different types of fields. This example demonstrates a group for headers and another for bold and italic text. ```php QuillGroup::build( new HeaderField(HeaderField::HEADER_OPTION_1), new HeaderField(HeaderField::HEADER_OPTION_2), ) QuillGroup::build( new BoldField(), new ItalicField(), ) ``` -------------------------------- ### Configure ReadTimeModule with Custom Options Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/read-time.md Example of how to instantiate the ReadTimeModule with custom words per minute and a target element for displaying the reading time. Ensure this module is added to the 'modules' option. ```php 'modules' => [ new ReadTimeModule([ 'wpm' => '250', 'target' => '#reading-time-display', ]), ], ``` -------------------------------- ### Install Dependencies with Yarn Source: https://github.com/ehyiah/ux-quill/blob/main/README.md If you are using webpack encore, run these commands after composer require. Not needed with AssetMapper. ```sh yarn install --force yarn watch ``` -------------------------------- ### Install QuillJs Bundle with Composer Source: https://github.com/ehyiah/ux-quill/blob/main/README.md Use this command to require the bundle in your Symfony project. ```sh composer require ehyiah/ux-quill ``` -------------------------------- ### Configure SmartLinksModule with Custom Regex Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/smart-links.md Manually add the SmartLinksModule to your application's modules and provide a custom regular expression to detect links. This example shows how to configure the `linkRegex` option. ```php 'modules' => [ new SmartLinksModule(options: [ 'linkRegex' => '/https?:\]\[^\]\]+/', ]), ], ``` -------------------------------- ### Listening to Image Gallery Events Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/image-gallery.md Example of how to attach an event listener to the Quill container to react when an image is selected from the gallery. ```javascript document.querySelector('.ql-container').addEventListener('quill:gallery:image-inserted', (e) => { console.log('Image selected:', e.detail.image); }); ``` -------------------------------- ### Symfony Controller for Image Gallery API Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/image-gallery.md Example Symfony controller implementing the listing and search API endpoints required by the Image Gallery module. ```APIDOC ## Symfony Controller for Image Gallery API This controller provides the necessary API endpoints for the Image Gallery module to list and search media. ### Endpoints #### `GET /api/media/gallery/list` Lists media items with pagination. ##### Parameters - **page** (int) - Optional - The page number to retrieve. Defaults to 1. ##### Response (Success - 200) - **data** (array) - An array of media objects, each containing `url`, `thumbnail`, and `title`. - **links** (object) - Contains `next` and `prev` URLs for pagination. ##### Response Example ```json { "data": [ { "url": "https://picsum.photos/id/11/400/400", "thumbnail": "https://picsum.photos/id/11/200/200", "title": "Image #1" } ], "links": { "next": "/api/media/gallery/list?page=2", "prev": null } } ``` #### `GET /api/media/gallery/search` Searches for media items. In this example, it defaults to the list endpoint. ##### Parameters - **term** (string) - Optional - The search term. - **page** (int) - Optional - The page number to retrieve. Defaults to 1. ##### Response (Success - 200) Returns the same structure as the list endpoint. ``` -------------------------------- ### Extend Quill Controller with Custom Keyboard and Clipboard Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/advanced/extend-stimulus-controller.md Create a custom Stimulus controller that extends the default Quill controller. This example demonstrates adding a new keyboard binding for bold text and a custom clipboard matcher. ```javascript import { Controller } from '@hotwired/stimulus'; export default class extends Controller { connect() { this.element.addEventListener('quill:connect', this._onConnect); } disconnect() { this.element.removeEventListener('quill:connect', this._onConnect); } _onConnect(event) { // The quill instance has been created console.log(event.detail); // You can access the quill instance using the event detail let quill = event.detail; // e.g : if you want to add a new keyboard binding quill.keyboard.addBinding({ key: 'b', shortKey: true }, function(range, context) { this.quill.formatText(range, 'bold', true); }); // e.g if you want to add a custom clipboard quill.clipboard.addMatcher(Node.TEXT_NODE, (node, delta) => { return new Delta().insert(node.data); }); } } ``` -------------------------------- ### Build Toolbar Group with Headers Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/configuration/quill-options.md Use QuillGroup::build to create a toolbar group containing header fields. This example shows how to add two different header options side by side. ```php QuillGroup::build( new HeaderField(HeaderField::HEADER_OPTION_1), new HeaderField(HeaderField::HEADER_OPTION_2), ) ``` -------------------------------- ### Configure STTModule in Quill Editor Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/stt.md This example shows how to integrate the STTModule into a Quill editor form. It demonstrates setting various configuration options for language, continuous recognition, visualizer, and custom button/label texts. Ensure the Web Speech API is supported by the browser. ```php use Ehyiah\QuillJsBundle\Form\QuillType; use Ehyiah\QuillJsBundle\DTO\Modules\STTModule; public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('content', QuillType::class, [ 'quill_options' => [ QuillGroup::buildWithAllFields() ], 'modules' => [ new STTModule( language: 'fr-FR', // French language recognition continuous: true, // Auto-restart after pauses visualizer: true, // Show audio visualizer waveformColor: '#4285f4', // Blue gradient color histogramColor: '#25D366', // Green accent color debug: false, // Disable debug logs buttonTitleStart: 'Start voice dictation', buttonTitleStop: 'Stop voice dictation', titleInactive: 'Voice recognition inactive', titleStarting: 'Initializing...', titleActive: 'Listening to your voice...', ), ], ]) ; } ``` -------------------------------- ### Configure Quill Modules in PHP Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules.md Example of how to instantiate and configure Quill modules directly within a PHP form configuration array. This includes custom modules like SyntaxModules and parameterized modules like TableModule. ```php 'modules' => [ new SyntaxModules(), new TableModule( 'menus' => ['column', 'row', 'merge', 'table', 'cell', 'wrap', 'copy', 'delete'], 'toolbarTable' => 'true', // must be set to true to show the table toolbar options in TableModule 'language' => 'fr_FR', ), ], ``` -------------------------------- ### Configuration: JSON Upload Handler with JWT Security Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/configuration/image-upload.md Example configuration for a JSON upload handler that includes JWT authentication. This adds an 'Authorization: Bearer' header to the upload request. ```php 'quill_extra_options' => [ 'upload_handler' => [ 'type' => 'json', 'upload_endpoint' => '/my-custom-endpoint/upload', 'json_response_file_path' => 'file.url', 'security' => [ 'type' => 'jwt', 'jwt_token' => 'my_jwt_token', ], ] ], ``` -------------------------------- ### Configure AutosaveModule with Custom Options Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/autosave.md Example of how to add the AutosaveModule to Quill's modules with custom options for interval, restore type, and notification text. ```php 'modules' => [ new AutosaveModule(options: [ 'interval' => 3000, 'restore_type' => 'manual', 'notificationText' => 'Un texte non enregistré a été trouvé.', 'restoreButtonLabel' => 'Restaurer', 'ignoreButtonLabel' => 'Ignorer', ]), ], ``` -------------------------------- ### Configure LinkAttributeModule with Custom Labels Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/link-attributes.md This example shows how to configure the LinkAttributeModule with custom labels for the 'Open in new tab', 'No follow', and 'OK' buttons. This is useful for internationalization or specific UI requirements. ```php [ new LinkAttributesModule(options: [ 'openInNewTabLabel' => 'Ouvrir dans un nouvel onglet', 'noFollowLabel' => 'Lien No-follow (SEO)', 'saveButtonLabel' => 'Valider', ]), ], ?> ``` -------------------------------- ### PHP: Returning Simple JSON Response Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/configuration/image-upload.md Example of returning a simple JSON HTTP response containing only the image URL. This is used when 'json_response_file_path' is null and the response is a direct JSON string. ```php return new JsonResponse('https://my-website/public/assets/my-uploaded-image.jpg'); ``` -------------------------------- ### Multiple Mention Modules with Unique Names Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/mention.md Implement multiple Mention Modules for different purposes (e.g., users and tags) by providing unique names starting with 'mention-'. This allows distinct triggers and data sources for each. ```php 'modules' => [ new MentionModule(name: 'mention-users', options: [ 'trigger' => '@', 'remote_url' => '/api/users/search?q={query}', ]), new MentionModule(name: 'mention-tags', options: [ 'trigger' => '#', 'data' => [ ['id' => 'tech', 'value' => 'technology'], ['id' => 'news', 'value' => 'news'], ], ]), ], ``` -------------------------------- ### Enable Markdown Shortcuts with MarkdownModule Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules.md Integrate MarkdownModule to enable automatic formatting for headers, lists, and blockquotes as you type. ```php new MarkdownModule(), ``` -------------------------------- ### Configure QuillType in Symfony Form Source: https://context7.com/ehyiah/ux-quill/llms.txt Example of using QuillType in a Symfony form, defining toolbar options and editor-level settings. ```php use Ehyiah\QuillJsBundle\Form\QuillType; use Ehyiah\QuillJsBundle\DTO\QuillGroup; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\BoldField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\ItalicField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\LinkField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\ImageField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\HeaderField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\AlignField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\ListField; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; class ArticleFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('content', QuillType::class, [ // Toolbar: two groups separated by a visual divider 'quill_options' => [ QuillGroup::build( new BoldField(), new ItalicField(), new LinkField(), ), QuillGroup::build( new HeaderField(HeaderField::HEADER_OPTION_1), new HeaderField(HeaderField::HEADER_OPTION_2), new AlignField(), new ListField(ListField::LIST_FIELD_OPTION_ORDERED), new ListField(ListField::LIST_FIELD_OPTION_BULLET), ), QuillGroup::build(new ImageField()), ], // Editor-level settings 'quill_extra_options' => [ 'height' => '400px', 'theme' => 'snow', // 'snow' or 'bubble' 'placeholder' => 'Write your article here…', 'style' => 'class', // 'class' or 'inline' 'read_only' => false, ], ]); } } ``` -------------------------------- ### Configure ImageGalleryModule Source: https://context7.com/ehyiah/ux-quill/llms.txt Set up the ImageGalleryModule to open a modal for image selection and upload. Configure the list and search endpoints, and customize modal titles and placeholders. Requires ImageGalleryField in quill_options. ```php use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\ImageGalleryField; use Ehyiah\QuillJsBundle\DTO\Modules\ImageGalleryModule; $builder->add('content', QuillType::class, [ 'quill_options' => [ ['bold', 'italic'], [new ImageGalleryField()], ], 'modules' => [ new ImageGalleryModule(options: [ 'listEndpoint' => '/api/media/list', // mandatory 'searchEndpoint' => '/api/media/search', // optional 'messageTitleOption' => 'Media Library', 'messageSearchPlaceholderOption' => 'Search images…', 'buttonTitle' => 'Browse Media', ]), ], ]); // Required API response format for listEndpoint / searchEndpoint: // GET /api/media/list?page=1 // { // "data": [ // { "url": "https://…/full.jpg", "thumbnail": "https://…/thumb.jpg", "title": "Sunset" } // ], // "links": { "next": "/api/media/list?page=2", "prev": null } // } // Gallery events (JavaScript): // document.querySelector('.ql-container').addEventListener('quill:gallery:image-inserted', e => { // console.log('Inserted image:', e.detail.image); // }); ``` -------------------------------- ### Configure ReadTimeModule with Custom Options Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules.md Instantiate ReadTimeModule with custom words per minute and a target element for displaying the reading time. ```php new ReadTimeModule([ 'wpm' => '250', 'target' => '#reading-time-display', ]), ``` -------------------------------- ### Initialize Counter Module with Custom Labels Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/counter.md Configure the Counter module to display both word and character counts with custom labels. Ensure the module is added to the editor's modules option. ```php 'modules' => [ new CounterModule(options: [ 'words' => true, 'words_label' => 'Mots : ', 'characters' => true, 'characters_label' => 'Caractères : ', ]), ], ``` -------------------------------- ### Mention Module with Remote Search (AJAX) Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/mention.md Set up the Mention Module to fetch suggestions dynamically from a remote URL using AJAX. Configure the trigger character, remote URL with a {query} placeholder, minimum characters for triggering, and maximum results. ```php 'modules' => [ new MentionModule(options: [ 'trigger' => '#', 'remote_url' => '/api/tags/search?q={query}', 'min_chars' => 2, 'max_results' => 5, ]), ], ``` -------------------------------- ### Configure MentionModule with Multiple Triggers Source: https://context7.com/ehyiah/ux-quill/llms.txt Enable multiple mention triggers (e.g., '@' for users and '#' for tags) by instantiating MentionModule multiple times with distinct names and configurations. ```php use Ehyiah\QuillJsBundle\DTO\Modules\MentionModule; // Multiple triggers (@users and #tags) $builder->add('content', QuillType::class, [ 'modules' => [ new MentionModule(name: 'mention-users', options: [ 'trigger' => '@', 'remote_url' => '/api/users/search?q={query}', ]), new MentionModule(name: 'mention-tags', options: [ 'trigger' => '#', 'data' => [ ['id' => 'php', 'value' => 'PHP'], ['id' => 'ux', 'value' => 'Symfony UX'], ], ]), ], ]); ``` -------------------------------- ### QuillAdminField with Custom Options Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/easyadmin.md Demonstrates how to use QuillAdminField with custom options, building a specific Quill toolbar configuration using QuillGroup and various field types. ```php QuillAdminField::new('quill') ->setFormTypeOptions([ 'quill_options' => QuillGroup::build( new BoldField(), new ItalicField(), new HeaderField(HeaderField::HEADER_OPTION_1), new HeaderField(HeaderField::HEADER_OPTION_2), ) ]) ``` -------------------------------- ### Integrating Quill Modules in a Form Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/index.md Example of how to add custom and built-in modules to a Quill editor instance within a Symfony form. Ensure necessary module classes are imported. ```php use Ehyiah\QuillJsBundle\Form\QuillType; use Ehyiah\QuillJsBundle\DTO\Modules\STTModule; public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('content', QuillType::class, [ 'quill_options' => [ // ], 'modules' => [ new SyntaxModules(), new TableModule( 'menus' => ['column', 'row', 'merge', 'table', 'cell', 'wrap', 'copy', 'delete'], 'toolbarTable' => 'true', // must be set to true to show the table toolbar options in TableModule 'language' => 'fr_FR', ), ], // ]) ; } ``` -------------------------------- ### Basic Mention Module with Static Data Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/mention.md Configure the Mention Module to use a predefined list of items for suggestions. Ensure the data items have 'id' and 'value' properties. ```php 'modules' => [ new MentionModule(options: [ 'trigger' => '@', 'data' => [ ['id' => 1, 'value' => 'Matthieu'], ['id' => 2, 'value' => 'Gemini'], ['id' => 3, 'value' => 'Symfony'], ], ]), ], ``` -------------------------------- ### Configure CounterModule for Word and Character Counts Source: https://context7.com/ehyiah/ux-quill/llms.txt Use CounterModule to display real-time word and character counts. Configure which counts to display, their labels, and optionally, the DOM elements for display. Listen to count updates via JavaScript events. ```php $builder->add('content', QuillType::class, [ 'modules' => [ new CounterModule(options: [ 'words' => true, 'words_label' => 'Words: ', 'words_container' => 'word-count-display', // DOM element ID (optional) 'characters' => true, 'characters_label' => 'Characters: ', 'characters_container' => '', // empty = auto-created below editor ]), ], ]); ``` ```javascript // document.addEventListener('quill:counter:words-update', e => console.log(e.detail.value)); // document.addEventListener('quill:counter:characters-update', e => console.log(e.detail.value)); ``` -------------------------------- ### PHP: Returning JSON Response with Nested URL Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/configuration/image-upload.md Example of returning a JSON HTTP response where the image URL is nested within a JSON object. The 'json_response_file_path' option should be set to 'file.url' to extract the URL. ```php return new JsonResponse([ 'file' => [ 'url' => 'https://my-website/public/assets/my-uploaded-image.jpg', ] ]); ``` -------------------------------- ### Configure SmartLinksModule for Auto-Converting URLs Source: https://context7.com/ehyiah/ux-quill/llms.txt Automatically converts typed URLs into clickable links when the user presses Space, Enter, or Tab. Uses a default link pattern, which can be customized via 'linkRegex'. ```php use Ehyiah\QuillJsBundle\DTO\Modules\SmartLinksModule; $builder->add('content', QuillType::class, [ 'modules' => [ new SmartLinksModule(options: [ 'linkRegex' => '/https?:\[^\s]+/', // default pattern ]), ], ]); ``` -------------------------------- ### PHP: Returning Plain Text Response Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/configuration/image-upload.md Example of returning a plain text HTTP response containing the image URL. This is used when the upload endpoint directly returns the URL without a JSON structure. ```php return new Response('https://my-website/public/assets/my-uploaded-image.jpg'); ``` -------------------------------- ### Configure MentionModule for Static Data Source: https://context7.com/ehyiah/ux-quill/llms.txt Set up the MentionModule to trigger autocomplete suggestions with static data. Specify the trigger character, data, minimum characters to type, and maximum results. ```php use Ehyiah\QuillJsBundle\DTO\Modules\MentionModule; // Static data $builder->add('content', QuillType::class, [ 'modules' => [ new MentionModule(options: [ 'trigger' => '@', 'data' => [ ['id' => 1, 'value' => 'Alice'], ['id' => 2, 'value' => 'Bob'], ], 'min_chars' => 1, 'max_results' => 5, ]), ], ]); ``` -------------------------------- ### Configure FullScreenModule for Editor Maximization Source: https://context7.com/ehyiah/ux-quill/llms.txt Adds a fullscreen toggle button to the toolbar using the quill-toggle-fullscreen-button library. Customize the button title and optionally provide custom SVG HTML for the icon. ```php use Ehyiah\QuillJsBundle\DTO\Modules\FullScreenModule; $builder->add('content', QuillType::class, [ 'modules' => [ new FullScreenModule([ 'buttonTitle' => 'Maximize editor', 'buttonHTML' => '', // optional custom icon ]), ], ]); ``` -------------------------------- ### Use Legacy ResizeModule with ImageSelectionModule Disabled Source: https://context7.com/ehyiah/ux-quill/llms.txt Disable the default ImageSelectionModule and enable the legacy ResizeModule by setting ImageSelectionModule options to false and adding ResizeModule. ```php use Ehyiah\QuillJsBundle\DTO\Modules\ImageSelectionModule; use Ehyiah\QuillJsBundle\DTO\Modules\ResizeModule; // Use the legacy resize module instead $builder->add('content', QuillType::class, [ 'modules' => [ new ImageSelectionModule(['options' => false]), // disable new module new ResizeModule(), // enable old one ], ]); ``` -------------------------------- ### Customize Mention Appearance with CSS Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/mention.md Style the inserted mentions and the suggestion list using CSS. The default classes are `.ql-mention`, `.ql-mention-list`, `.ql-mention-item`, and `.ql-mention-item.selected`. ```css .ql-editor .ql-mention { background-color: #fce4ec; color: #c2185b; } ``` -------------------------------- ### Configure Quill Editor in a Form Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/configuration/quill-options.md Integrate Quill editor into a Symfony form by defining 'quill_options'. This example shows how to add multiple toolbar groups, including inline fields, header fields, and a custom image gallery field. ```php use Ehyiah\QuillJsBundle\Form\QuillType; use Ehyiah\QuillJsBundle\DTO\QuillGroup; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\BoldField; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\ItalicField; use Ehyiah\QuillJsBundle\DTO\Fields\BlockField\HeaderField; public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('myField', QuillType::class, [ 'quill_options' => [ QuillGroup::build( new BoldField(), new ItalicField(), ), QuillGroup::build( new HeaderField(HeaderField::HEADER_OPTION_1), new HeaderField(HeaderField::HEADER_OPTION_2), ), // Add all built-in available fields at once (includes Table, Emoji, etc.) QuillGroup::build( new ImageGalleryField(), ), ] ]) ; } ``` -------------------------------- ### Configure NodeMoverModule for Block Reordering Source: https://context7.com/ehyiah/ux-quill/llms.txt Provides a gutter toolbar for selected blocks, enabling drag-and-drop reordering, duplication, and deletion. Can be customized with colors and options, or disabled entirely. ```php use Ehyiah\QuillJsBundle\DTO\Modules\NodeMoverModule; // Default (always on) – no configuration needed. // Customise options: $builder->add('content', QuillType::class, [ 'modules' => [ new NodeMoverModule([ 'borderColor' => '#007bff', 'dropIndicatorColor'=> '#ff0000', 'duplicate' => true, ]), ], ]); // Disable entirely: $builder->add('content', QuillType::class, [ 'modules' => [ new NodeMoverModule(['active' => false]), ], ]); ``` -------------------------------- ### MentionModule with Remote Search and Custom Options Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules.md Configure MentionModule for remote data fetching via AJAX. Specify the remote URL, minimum characters for triggering, and maximum results. ```php new MentionModule(options: [ 'trigger' => '#', 'remote_url' => '/api/tags/search?q={query}', 'min_chars' => 2, 'max_results' => 5, ]), ``` -------------------------------- ### Initialize PasteSanitizerModule with plain_text option Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/paste-sanitizer.md Configure the PasteSanitizerModule to always paste content as plain text by setting the `plain_text` option to `true`. This module must be manually added to the `modules` array. ```php 'modules' => [ new PasteSanitizerModule(options: [ 'plain_text' => true, ]), ], ``` -------------------------------- ### Implement Custom Inline and Module Fields Source: https://context7.com/ehyiah/ux-quill/llms.txt Implement `QuillInlineFieldInterface` for custom toolbar buttons and `QuillFieldModuleInterface` to auto-register required modules. The `getOption()` method must return the Quill format/blot name. ```php namespace App\Quill\Fields; use Ehyiah\QuillJsBundle\DTO\Fields\Interfaces\QuillInlineFieldInterface; use Ehyiah\QuillJsBundle\DTO\Fields\Interfaces\QuillFieldModuleInterface; use App\Quill\Modules\CustomHighlightModule; // Simple inline field (no module dependency) class HighlightField implements QuillInlineFieldInterface { public function getOption(): string { return 'highlight'; // must match the Quill format/blot name } } // Field that auto-imports a module class CustomEmojiField implements QuillInlineFieldInterface, QuillFieldModuleInterface { public function getOption(): string { return 'custom-emoji'; } public static function importModules(): array { return [CustomHighlightModule::class]; // ModuleInterface implementations } } ``` ```php // Usage $builder->add('content', QuillType::class, [ 'quill_options' => [ QuillGroup::build( new HighlightField(), new CustomEmojiField(), ), ], ]); ``` ```javascript // Corresponding JavaScript (register the blot/module before Quill init): // import Quill from 'quill'; // Quill.register('formats/highlight', HighlightBlot); // Quill.register('modules/customHighlight', CustomHighlightModule); ``` -------------------------------- ### Configure HtmlEditModule with Custom Options Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/html-edit.md Instantiate the HtmlEditModule with custom options for button text and labels. This module must be manually added to the 'modules' option. ```php 'modules' => [ new HtmlEditModule(options: [ 'buttonTitle' => 'Source HTML', 'okText' => 'Enregistrer', 'cancelText' => 'Annuler', ]), ], ``` -------------------------------- ### Configure MentionModule for Remote AJAX Search Source: https://context7.com/ehyiah/ux-quill/llms.txt Integrate the MentionModule with a remote AJAX endpoint for dynamic suggestions. Define the trigger character, the URL for the search query, and the minimum characters required to initiate the search. ```php use Ehyiah\QuillJsBundle\DTO\Modules\MentionModule; // Remote AJAX search // GET /api/users/search?q={query} → [{"id":1,"value":"Alice"},…] $builder->add('content', QuillType::class, [ 'modules' => [ new MentionModule(options: [ 'trigger' => '@', 'remote_url' => '/api/users/search?q={query}', 'min_chars' => 2, ]), ], ]); ``` -------------------------------- ### Configure Quill Editor Options Source: https://context7.com/ehyiah/ux-quill/llms.txt Use 'quill_extra_options' to control the global appearance, behavior, and upload handler of a Quill editor instance. Options include theme, placeholder, read-only mode, custom icons, and asset injection. ```php use Ehyiah\QuillJsBundle\Form\QuillType; $builder->add('body', QuillType::class, [ 'quill_extra_options' => [ // Visual 'height' => '350px', // CSS height (px, em, %, etc.) 'theme' => 'snow', // 'snow' (toolbar) | 'bubble' (inline) 'placeholder' => 'Start typing…', 'style' => 'inline', // 'class' (default) | 'inline' (for emails/RSS) // Behavior 'debug' => 'error', // 'error' | 'warn' | 'log' | 'info' 'read_only' => false, 'use_semantic_html' => false, // use getSemanticHTML() instead of innerHTML // Custom toolbar icons (SVG strings, keyed by format name) 'custom_icons' => [ 'bold' => '', 'italic' => '', ], // Inject additional CSS/JS (avoid with Turbo — inject directly instead) 'assets' => [ 'styleSheets' => ['https://cdn.example.com/custom-quill.css'], 'scripts' => ['https://cdn.example.com/custom-quill.js'], ], // Image upload handler (see Image Upload section) 'upload_handler' => [ 'type' => 'json', 'upload_endpoint' => '/api/upload/image', 'json_response_file_path'=> 'file.url', ], ], ]); ``` -------------------------------- ### Inject Custom CSS and JS Assets Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/configuration/extra-options.md Configure custom stylesheets and scripts to be injected into the editor. Be cautious of race conditions with turbo. ```php 'quill_extra_options' => [ 'assets' => [ 'styleSheets' => [ "https://example.com/custom.css", ], 'scripts' => [ "https://example.com/custom.js", ] ], ] ``` -------------------------------- ### Configure ReadTimeModule Source: https://context7.com/ehyiah/ux-quill/llms.txt Use the ReadTimeModule to estimate and display reading time. Configure words per minute, labels, and thresholds for different read time statuses. ```php use Ehyiah\QuillJsBundle\DTO\Modules\ReadTimeModule; $builder->add('content', QuillType::class, [ 'modules' => [ new ReadTimeModule([ 'wpm' => 250, 'label' => '⏱ Est. read: ~ ', 'suffix' => ' min', 'readTimeOk' => 5, // ≤5 min → green 'readTimeMedium' => 8, // ≤8 min → orange, >8 min → red 'target' => '#reading-time-display', // DOM element ID ]), ], ]); ``` -------------------------------- ### Initialize Stimulus Application Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/easyadmin.md This JavaScript snippet initializes the Stimulus application. It's typically placed in a main admin JavaScript file. ```javascript // start the Stimulus application import './bootstrap'; ``` -------------------------------- ### Configure TableModule for Table Functionality Source: https://context7.com/ehyiah/ux-quill/llms.txt Provides full table support, auto-imported when TableField is used. Configure table menus, toolbar visibility, and language. Requires 'quill-table-better' and TableField in quill_options. ```php use Ehyiah\QuillJsBundle\DTO\Modules\TableModule; use Ehyiah\QuillJsBundle\DTO\Fields\InlineField\TableField; $builder->add('content', QuillType::class, [ 'quill_options' => [ QuillGroup::build(new TableField()), ], 'modules' => [ new TableModule(options: [ 'menus' => ['column', 'row', 'merge', 'table', 'cell', 'wrap', 'copy', 'delete'], 'toolbarTable' => true, // show table toolbar 'language' => 'en_US', ]), ], ]); ``` -------------------------------- ### Disable ImageSelectionModule and Enable ResizeModule Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/image-selection.md Disable the ImageSelectionModule by setting its options to false and enable the legacy ResizeModule if the old image resizing behavior is preferred. This allows for a fallback to previous functionality. ```php use Ehyiah\QuillJsBundle\DTO\Modules\ImageSelectionModule; use Ehyiah\QuillJsBundle\DTO\Modules\ResizeModule; // ... 'modules' => [ new ImageSelectionModule(['options' => false]), // Disable the new module new ResizeModule(), // Enable the old one ], ``` -------------------------------- ### Configure HistoryModule for Undo/Redo Behavior Source: https://context7.com/ehyiah/ux-quill/llms.txt Manages Quill's native undo/redo functionality. Options include setting the delay for grouping changes, the maximum number of undo steps, and whether to track only user-initiated changes. ```php use Ehyiah\QuillJsBundle\DTO\Modules\HistoryModule; $builder->add('content', QuillType::class, [ 'modules' => [ new HistoryModule(options: [ 'delay' => 1000, // ms to group changes into one undo step 'maxStack' => 100, // maximum undo steps 'userOnly' => true, // only track user-initiated changes ]), ], ]); ``` -------------------------------- ### Configure ImageSelectionModule with Custom Options Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/image-selection.md Manually configure the ImageSelectionModule with custom options for border color, button labels, and alignment tooltips. This is useful when the module is not auto-imported or when specific customizations are needed. ```php use Ehyiah\QuillJsBundle\DTO\Modules\ImageSelectionModule; // ... 'modules' => [ new ImageSelectionModule([ 'borderColor' => '#ff0000', 'buttonBeforeLabel' => 'Insert Before', 'alignLabels' => [ 'center' => 'Centrer l\'image', ], ]), ], ``` -------------------------------- ### Configure JSON Image Upload Handler Source: https://context7.com/ehyiah/ux-quill/llms.txt Set up a JSON upload handler for images, specifying the endpoint, the JSON path to the returned URL, and security details like JWT. This allows server-side image storage instead of base64 encoding. ```php $builder->add('content', QuillType::class, [ 'quill_extra_options' => [ 'upload_handler' => [ 'type' => 'json', // 'json' | 'form' 'upload_endpoint' => '/api/media/upload', 'json_response_file_path' => 'data.url', // JSON path to the returned URL 'security' => [ 'type' => 'jwt', // 'jwt' | 'basic' | 'custom_header' 'jwt_token' => 'eyJhbGciOiJIUz…', ], ], ], ]); ``` -------------------------------- ### Symfony Controller for Image Gallery API Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules/image-gallery.md Implement a Symfony controller to handle image listing and search requests for the Image Gallery module. Includes pagination logic for the list endpoint. ```php get('page', 1); $perPage = 10; $total = 30; // Total images in your database $images = []; for ($i = 0; $i < $perPage; $i++) { $id = (($page - 1) * $perPage) + $i + 1; if ($id > $total) break; $images[] = [ 'url' => sprintf('https://picsum.photos/id/%d/400/400', 10 + $id), 'thumbnail' => sprintf('https://picsum.photos/id/%d/200/200', 10 + $id), 'title' => "Image #$id", ]; } $baseUrl = '/api/media/gallery/list'; $hasNext = ($page * $perPage) < $total; $hasPrev = $page > 1; return new JsonResponse([ 'data' => $images, 'links' => [ 'next' => $hasNext ? "$baseUrl?page=" . ($page + 1) : null, 'prev' => $hasPrev ? "$baseUrl?page=" . ($page - 1) : null, ], ]); } #[Route('/search', name: 'api_media_search')] public function search(Request $request): JsonResponse { $term = $request->get('term', ''); $page = (int) $request->get('page', 1); // In a real application, you would filter your query with $term // and return the appropriate paginated results. // Example with mock data: return $this->list($request); } } ``` -------------------------------- ### Basic QuillAdminField Usage Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/easyadmin.md This is the basic usage of the QuillAdminField in your EasyAdmin configuration. It assumes the asset is correctly configured. ```php QuillAdminField::new('quill') ``` -------------------------------- ### Configure STTModule for Speech-to-Text Source: https://context7.com/ehyiah/ux-quill/llms.txt Adds a microphone button for real-time voice dictation using the Web Speech API. Requires Chrome, Edge, or Safari. Emits various JavaScript events for listening status and results. ```php use Ehyiah\QuillJsBundle\DTO\Modules\STTModule; $builder->add('content', QuillType::class, [ 'modules' => [ new STTModule( language: 'en-US', continuous: true, visualizer: true, waveformColor: '#4285f4', histogramColor: '#25D366', debug: false, buttonTitleStart: 'Start dictation', buttonTitleStop: 'Stop dictation', titleInactive: 'Voice: off', titleStarting: 'Initializing…', titleActive: 'Listening…', ), ], ]); // JavaScript events emitted: // quill:stt:result → { text: string, isFinal: bool } // quill:stt:listening-start → {} // quill:stt:listening-stop → {} // quill:stt:error → { error: any } ``` -------------------------------- ### Configure AutosaveModule Source: https://github.com/ehyiah/ux-quill/blob/main/docs/guide/modules.md Use AutosaveModule to automatically save editor content to localStorage. Configure the save interval and restoration behavior. ```php 'modules' => [ new AutosaveModule(options: [ 'interval' => 3000, 'restore_type' => 'manual', ]), ], ```