2

I need to specify custom icons on my Ag-Grid (React) sidebar for custom panels. My toolpanels looks like this:

toolPanels: [
    {
        id: "actions",
        labelDefault: "Actions",
        labelKey: "actions",
        iconKey: "entityActions",                  
        toolPanel: "blotterActionsPanel",
        toolPanelParams: {glEventHub: this.props.glEventHub}
    },
    {
        id: "columns",
        labelDefault: "Columns",
        labelKey: "columns",
        iconKey: "columns",
        toolPanel: "agColumnsToolPanel"
    },
    {
        id: "filters",
        labelDefault: "Filters",
        labelKey: "filters",
        iconKey: "filter",
        toolPanel: "agFiltersToolPanel"
    }
]

for the 'actions' toolpanel I have iconKey 'entityActions', so my icons looks like this:

icons: {
    entityActions: '<i class="fa fa-running" style="font-size: 12pt; color: darkgrey"/>',
}

That works for a font-awesome icon... but I don't want to use an FA icon. I need to use icons from BlueprintJS, which are SVG icons. BlueprintJS provides an tag which would be the easiest to use... but I've tried various things like this:

icons: {
    entityActions: "<Icon icon='add'/>"
}

Which doesn't work... I can also get the raw SVG paths from BlueprintJS so I've tried:

entityActions: '<span><svg fill="black" height="16" width="16"  viewBox={"0 0 16 16"}><path d=' + IconSvgPaths16.add[0] + '/></svg></span>',

and also I tried hard-coding the path... In all of these cases I just get a blank hole where I expect the icon to be. The Ag-Grid documentation (https://www.ag-grid.com/javascript-grid-icons/):

The icon can be any of the following: String: The string will be treated as html. Use to return just text, or HTML tags. Function: A function that returns either a String or a DOM node or element.

so, I tried a function... I cannot find an example of how to do this, but after a few hours of searching I came across examples that show it creating an element using document.createElement.. So I tried this:

entityActions: params => {
    let icon = document.createElement('svg');
    let path = document.createElement('path');
    icon.setAttribute('fill', "black");
    icon.setAttribute("height", "16");
    icon.setAttribute("width", "16");
    icon.setAttribute("viewBox", "0 0 16 16");
    path.setAttribute("d", IconSvgPaths16.add[0]);                    
    icon.appendChild(path);
    return icon;
}

Still with no luck... How can I use a BlueprintJS Icon with Ag-Grid? This icon is actually customizable by the user so it would be good if I could use a function and pass in the icon name to use and have it return the appropriate one...

Thankyou, Troy.

Argee
  • 1,216
  • 1
  • 12
  • 22
Troy Peterson
  • 461
  • 1
  • 5
  • 16

2 Answers2

1

I had similar requirements in my project too. This is how I solved it and hope it helps:

As The icon can be any of the following: String: The string will be treated as html. Use to return just text, or HTML tags. Function: A function that returns either a String or a DOM node or element.

So we can provide a function which will return a dom node. In the dom node, we can render a React component onto it.

e.g. You may render a MaterialUI Icon, or a Custom SVG Icon onto a dom node and then return it.

icons: {
    entityActions: () => {
        let domNode = document.createElement('div');
        ReactDOM.render(<YourOwnSVGIcon style={{color: 'yourColorCode'}}/>, domNode );
        return domNode ;
    }
}
Fengzmg
  • 710
  • 8
  • 9
0

Why not convert the BlueprintJS icon to a base64 string, and use that in a div with the base64 string as the background-image?

So your entityActions will look like this for the add icon:

`entityActions: `<div id="test" style='height: 20px; width: 20px; background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE3LjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAxNiAxNiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMTYgMTYiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8ZyBpZD0iYWRkXzNfIj4KCTxnPgoJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTAuOTksNi45OWgtMnYtMmMwLTAuNTUtMC40NS0xLTEtMXMtMSwwLjQ1LTEsMXYyaC0yYy0wLjU1LDAtMSwwLjQ1LTEsMQoJCQlzMC40NSwxLDEsMWgydjJjMCwwLjU1LDAuNDUsMSwxLDFzMS0wLjQ1LDEtMXYtMmgyYzAuNTUsMCwxLTAuNDUsMS0xUzExLjU0LDYuOTksMTAuOTksNi45OXogTTcuOTktMC4wMWMtNC40MiwwLTgsMy41OC04LDgKCQkJczMuNTgsOCw4LDhzOC0zLjU4LDgtOFMxMi40MS0wLjAxLDcuOTktMC4wMXogTTcuOTksMTMuOTljLTMuMzEsMC02LTIuNjktNi02czIuNjktNiw2LTZzNiwyLjY5LDYsNlMxMS4zMSwxMy45OSw3Ljk5LDEzLjk5eiIvPgoJPC9nPgo8L2c+Cjwvc3ZnPgo")'>`

Here's a StackBlitz of this working.

ViqMontana
  • 5,090
  • 3
  • 19
  • 54
  • That seems to be an overly complicated solution and would require me converting a few hundred icons... These icons are used all over the application. It's a very large desktop replacement application for financial analysis - it has configurable screens and the same icons are used all over the place. For example, an administrator can define custom menus that users see based on their function, and as part of that the admin can create custom commands, functions, and buttons that can each have an icon, and the set of icon choices is the same across the system. – Troy Peterson Jun 04 '20 at 10:12