giuseppelt / feelback-integrations

Feelback SDKs, integrations libraries and samples
https://www.feelback.dev
MIT License
33 stars 1 forks source link

Any way to use custom icons? #7

Closed scott-klaytn closed 1 week ago

scott-klaytn commented 2 weeks ago

The default icon files (e.g. icon_like.svg, icon_dislike.svg) are hard-coded or can be replaced with other custom svg files?

giuseppelt commented 2 weeks ago

Which framework are you working with?

scott-klaytn commented 2 weeks ago

Docusaurus. I swizzled the Footer instead of Docsidebar to make the feedback widget to appear in the end of every page (i.e. inside article class). I managed to get it to work, but one thing left to be done is applying custom icons.

src/theme/Footer/index.js

import React, { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom/client';
import Footer from '@theme-original/Footer';
import { FeelbackYesNo, PRESET_LIKE_DISLIKE } from "@feelback/react";
import { useLocation } from '@docusaurus/router';
import './custom.rating.css';

export default function FooterWrapper(props) {
    const location = useLocation();
    const rootsRef = useRef([]);

    useEffect(() => {
        if (typeof window !== 'undefined') {
            const articles = document.querySelectorAll('article');
            articles.forEach((article) => {
                if (!article.querySelector('.feelback-widget')) {
                    const widgetContainer = document.createElement('div');
                    widgetContainer.className = 'feelback-widget';
                    article.appendChild(widgetContainer);
                    const root = ReactDOM.createRoot(widgetContainer);
                    root.render(
                        <div className="feedback-container">
                            <hr className="feedback-divider" />
                            <div className="feedback-content">
                                <FeelbackYesNo
                                    contentSetId="my-content-set-id" // To be replaced with actual ContentSet ID
                                    textQuestion="Is this page helpful?"
                                    preset={PRESET_LIKE_DISLIKE}
                                    className={'feelback-buttons-custom'}
                                />
                            </div>
                        </div>
                    );
                    rootsRef.current.push(root);
                }
            });
        }

        return () => {
            rootsRef.current.forEach(root => {
                root.unmount();
            });
            rootsRef.current = [];
        };
    }, [location]);

    return <Footer {...props} />;
}

src/theme/Footer/custom.rating.css

.feelback-widget {
  margin-top: 2rem;
}

.feedback-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

.feedback-divider {
  width: 100%;
  border: 0;
  height: 1px;
  background-color: var(--ifm-color-emphasis-200);
  margin: 1rem 0;
}

.feedback-content {
  width: 100%;
  display: flex;
  justify-content: center;
}

.feelback-buttons-custom .feelback-btn {
  min-width: unset;
  height: unset;
  padding: 0.5rem 1rem;
  border: 1px solid var(--ifm-color-primary);
  border-radius: 4px;
  background-color: transparent;
  color: var(--ifm-color-primary);
  cursor: pointer;
  transition: background-color 0.3s, color 0.3s;
  display: flex;
  align-items: center;
}

.feelback-buttons-custom .feelback-btn:hover {
  background-color: var(--ifm-color-primary);
  color: white;
}

.feelback-buttons-custom .feelback-btn.active {
  background-color: var(--ifm-color-primary);
  color: white;
}

@media (max-width: 768px) {
  .feedback-divider {
      max-width: 100%;
  }

  .feedback-content {
      flex-direction: column;
      align-items: center;
  }

  .feelback-buttons-custom .feelback-btn {
      width: 100%;
      margin-bottom: 0.5rem;
  }

  .feelback-buttons-custom .feelback-btn .feelback-icon {
      margin-right: 0;
  }
}
giuseppelt commented 2 weeks ago

You can use a custom preset with your icons of choice.

Check https://github.com/giuseppelt/feelback-integrations/blob/master/packages/react/src/presets.ts#L45 , you need to pass the same object schema, but you can specify your custom icons. Icon must be a ReactElement, so you cannot use a raw svg file, you should import or transform it in a ReactElement first.

Make sure to keep the value property as you see in the original preset, otherwise it will not work.

scott-klaytn commented 1 week ago

With your help, I was able to integrate the custom icon into current feelback implementation successfully. Thank you for your support!