Skip to content

Commit

Permalink
BUGFIX: Render table dropdowns with correct icons
Browse files Browse the repository at this point in the history
The icons were broken and the fallback title was not aligned pretty well. So the SVG markup string will be transformed now to an data-uri and this can be used as image sorce.
  • Loading branch information
markusguenther committed Dec 2, 2024
1 parent da8c62c commit b8ecc24
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';

import {neos} from '@neos-project/neos-ui-decorators';
import {svgToDataUri} from '@neos-project/utils-helpers';
import ckeIcons from './icons';

import style from './TableDropDown.module.css';
Expand Down Expand Up @@ -39,12 +40,14 @@ export default class TableDropDownButton extends PureComponent {
}

render() {
const iconDataUri = svgToDataUri(ckeIcons[this.props.icon]);
console.log({iconDataUri});
return (
<DropDown
padded={false}
>
<DropDown.Header title={this.props.i18nRegistry.translate(this.props.tooltip)}>
<img style={{verticalAlign: 'text-top'}} src={ckeIcons[this.props.icon]} alt={this.props.i18nRegistry.translate(this.props.tooltip)} />
<img style={{verticalAlign: 'text-top'}} src={iconDataUri} alt={this.props.i18nRegistry.translate(this.props.tooltip)} />
</DropDown.Header>
<DropDown.Contents className={style.contents} scrollable={false}>
{this.props.options.map(item => item.type === 'checkBox' ? (
Expand Down
2 changes: 2 additions & 0 deletions packages/utils-helpers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import isEmail from './isEmail';
import {isUri} from './isUri';
import isEqualSet from './isEqualSet';
import isNil from './isNil';
import svgToDataUri from './svgToDataUri';

export {
decodeHtml,
Expand All @@ -19,6 +20,7 @@ export {
isEqualSet,
stripTags,
stripTagsEncoded,
svgToDataUri,
cancelIdleCallback,
requestIdleCallback
};
47 changes: 47 additions & 0 deletions packages/utils-helpers/src/svgToDataUri.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const REGEX = {
whitespace: /\s+/g,
urlHexPairs: /%[\dA-F]{2}/g,
quotes: /"/g
};

// Function to collapse whitespace in a string
const collapseWhitespace = (str: string): string =>
str.trim().replace(REGEX.whitespace, ' ');

// Function to encode data for a URI payload
const dataURIPayload = (string: string): string =>
encodeURIComponent(string).replace(REGEX.urlHexPairs, specialHexEncode);

// Function to handle special hex encoding
const specialHexEncode = (match: string): string => {
switch (match) {
case '%20':
return ' ';
case '%3D':
return '=';
case '%3A':
return ':';
case '%2F':
return '/';
default:
return match.toLowerCase(); // Compresses better
}
};

// Function to convert an SVG string to a tiny data URI
const svgToDataUri = (svgString: string): string => {
// Strip the Byte-Order Mark if the SVG has one
if (svgString.charCodeAt(0) === 0xfeff) {
svgString = svgString.slice(1);
}

const body = collapseWhitespace(svgString);
return `data:image/svg+xml,${dataURIPayload(body)}`;
};

// Add a static method to handle srcset conversions
svgToDataUri.toSrcset = (svgString: string): string =>
svgToDataUri(svgString).replace(/ /g, '%20');

// Export the function as the default export
export default svgToDataUri;

0 comments on commit b8ecc24

Please sign in to comment.