'how to add custom icon in quill toolbar

I am using quill in my react native app as a text editor. I want to add a custom toolbar icon in the quill toolbar, any solution? my code is:

quill.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <style>
      html,body {
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
        background-color:rgba(0, 0, 0, 0);
      }
      #editor {
        height: calc(100% - 72px);
        background-color:rgba(0, 0, 0, 0);
      }
    </style>
    <link rel="stylesheet" type="text/css" href="https://cdn.quilljs.com/1.3.7/quill.snow.css"></link>
  </head>
  <body>
    <div id="editor"></div>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.min.js"
      integrity="sha512-P2W2rr8ikUPfa31PLBo5bcBQrsa+TNj8jiKadtaIrHQGMo6hQM6RdPjQYxlNguwHz8AwSQ28VkBK6kHBLgd/8g=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    ></script>
    <script>
      const quill = new Quill('#editor', window.options);
      quill.on('text-change', function (delta, oldDelta, source) {
        const html = document.querySelector('#editor').children[0].innerHTML;
        const message = {
          type: 'onChange',
          message: html,
        };
        window.ReactNativeWebView.postMessage(JSON.stringify(message));
      });
    </script>
  </body>
</html>

QuillEditor.tsx

import React from 'react'
import { Dimensions, Platform, ViewStyle } from 'react-native'
import { WebView, WebViewMessageEvent } from 'react-native-webview'

type Props = {
  style?: ViewStyle
  defaultValue?: string
  options?: any
  onChange?: (html: string) => void
}

const defaultValue = [[{ header: [1, 2, false] }], ['bold', 'italic', 'underline'], ['image', 'code-block']];

const Quill = (props: Props) => {
  const options = JSON.stringify({
    placeholder: 'Type here...',
    modules: {
      toolbar: defaultValue,
    },
    ...props.options,
    theme: 'snow',
  })
  const injectedJavaScriptBeforeContentLoaded = `window.options=${options}`
  const injectedJavaScript = `document.querySelector('#editor').children[0].innerHTML="${props.defaultValue}"`

  const onMessage = (e: WebViewMessageEvent) => {
    const data = JSON.parse(e.nativeEvent.data)
    if (data.type === 'onChange') {
      props.onChange(data.message)
    }
  }

  return (
    <WebView
      onMessage={onMessage}
      source={Platform.OS === 'ios' ? require('../../assets/quill.html') : { uri: 'file:///android_asset/quill.html' }}
      javaScriptEnabled
      injectedJavaScriptBeforeContentLoaded={injectedJavaScriptBeforeContentLoaded}
      injectedJavaScript={injectedJavaScript}
      style={{ height: Dimensions.get('window').height - 42, width: Dimensions.get('window').width, ...props.style }}
    />
  )
}

Quill.defaultProps = {
  style: {},
  defaultValue: '',
  onChange: () => {},
  options: {},
}

export default Quill

app.js

import React from 'react';
import { SafeAreaView, StyleSheet } from 'react-native';
import QuillEditor from '../components/QuillEditor'
export default function App() {
    const onChange = (html) => {
        console.log(html)
    }
    return (
        <SafeAreaView style={styles.root}>
            <QuillEditor
                style={{ height: 300 }}
                options={{
                    placeholder: 'Type here...',
                }}
                onChange={onChange}
            />
        </SafeAreaView>
    );
}

const styles = StyleSheet.create({
    title: {
        fontWeight: 'bold',
        alignSelf: 'center',
        paddingVertical: 10,
    },
    root: {
        flex: 1,
    },
    editor: {
        flex: 1,
        padding: 0,
        borderColor: 'gray',
        borderWidth: 1,
        marginHorizontal: 30,
        marginVertical: 5,
        backgroundColor: 'white',
    },
});


Solution 1:[1]

I found the solution.

quill.html

<html>
<head>
  <script src="https://cdn.quilljs.com/1.3.7/quill.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.quilljs.com/1.3.7/quill.bubble.css"></link>
  <link rel="stylesheet" type="text/css" href="https://cdn.quilljs.com/1.3.7/quill.snow.css"></link>
  <script src="https://cdn.jsdelivr.net/gh/T-vK/DynamicQuillTools@master/DynamicQuillTools.js"></script>
</head>
<body>
  <div id="editor"></div>
  <script>
    // Create a Quill Editor instance with some built-in toolbar tools
    const quill = new Quill('#editor', {
        theme: 'snow',
        modules: {
            toolbar: {
                container: [
                    ['bold', 'italic', 'underline', 'strike'],
                    ['blockquote', 'code-block'],

                    [{ 'header': 1 }, { 'header': 2 }],
                    [{ 'list': 'ordered' }, { 'list': 'bullet' }],
                    [{ 'script': 'sub' }, { 'script': 'super' }],
                    [{ 'indent': '-1' }, { 'indent': '+1' }],
                    [{ 'direction': 'rtl' }],

                    [{ 'size': ['small', false, 'large', 'huge'] }],
                    [{ 'header': [1, 2, 3, 4, 5, 6, false] }],

                    [{ 'color': [] }, { 'background': [] }],
                    [{ 'font': [] }],
                    [{ 'align': [] }],
                    ['clean'],
                ]
            }
        }
    })

    // Add a custom Button to the Quill Editor's toolbar:
    const myButton = new QuillToolbarButton({
    icon: `<svg viewBox="0 0 18 18"> <path class="ql-stroke" d="M5,3V9a4.012,4.012,0,0,0,4,4H9a4.012,4.012,0,0,0,4-4V3"></path></svg>`
    })
   
    myButton.onClick = function(quill) {
        const { index, length } = quill.selection.savedRange
        const selectedText = quill.getText(index, length)
        const newText = selectedText.toUpperCase()
        quill.deleteText(index, length)
        quill.insertText(index, newText)
        quill.setSelection(index, newText.length)
    }
    myButton.attach(quill)

 </script>
</body>
</html>

Solution 2:[2]

The validated answer seems to use the following library

https://github.com/T-vK/DynamicQuillTools

The README provides clear examples

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shivam
Solution 2 Wasabi