BUG: When you delete a component, duplicate classes between components will be deleted.
ihatov08 opened this issue · 3 comments
ihatov08 commented
GrapesJS version
- I confirm to use the latest version of GrapesJS
What browser are you using?
Chrome 126.0.6478.127(Windows)
Reproducible demo link
https://jsfiddle.net/t06s4oLb/8/
Describe the bug
How to reproduce the bug?
- Add section1 to canvas
- Add section2 to canvas under section1
- remove section2 from canvas.
- The style of section1 will be broken.
Video_2024_07_04-5.mp4
What is the expected behavior?
I would like it to not be deleted even if separate components have the same class.
What is the current behavior?
The reason is that both section1 and section2 have .flex classes, and if you delete section2 from canvas, the .flex css will be deleted from gjs-css-rules.
Code of Conduct
- I agree to follow this project's Code of Conduct
ihatov08 commented
As a temporary workaround, styles for each component are prefixed with id.
import { html as hero1html, css as hero1css } from './data/hero-1';
import { html as content1html, css as content1css } from './data/content-1';
const sources = [
{
id: 'hero-1',
name: 'Hero 1',
category: 'Hero',
html: hero1html,
css: hero1css,
class: 'bg-gray-100 p-5',
},
{
id: 'content-1',
name: 'Content 1',
category: 'Content',
html: content1html,
css: content1css,
class: 'p-5',
}
]
const escapeTailwindClasses = (str, id) => {
return str.replace(/(\.[a-z0-9_-]+)(:\w+)/gi, (match, p1, p2) => {
return `.${id}${p1.replace('.', '')}\\${p2}`;
});
};
export const importBlocks = (editor, options = {}) => {
const domc = editor.DomComponents;
const blockManager = editor.BlockManager;
sources.forEach(source => {
const prefix = source.id + '-';
const prefixedHtml = source.html.replace(/class="([^"]*)"/g, (match, className) => {
return `class="${className.split(' ').map(cn => prefix + cn).join(' ')}"`;
});
const prefixedCss = source.css.replace(/\.([a-z0-9_-]+)(?=\s*[{,])/gi, (match, className) => {
return '.' + prefix + className;
});
console.log(escapeTailwindClasses(prefixedCss, prefix))
const prefixedClasses = source.class.split(' ').map(cn => prefix + cn).join(' ');
domc.addType(source.id, {
model: {
defaults: {
attributes: { class: prefixedClasses },
components: prefixedHtml,
styles: escapeTailwindClasses(prefixedCss, prefix),
},
},
});
blockManager.add(source.id, {
category: source.category,
id: source.id,
label: source.name,
content: {
type: source.id,
},
});
});
}