mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 05:29:44 +02:00
fix(editor): Remove invalid :global() from shipped design-system CSS (no-changelog) (#35144)
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
b2eb04aca0
commit
953fd3165c
|
|
@ -3,7 +3,6 @@
|
|||
"name": "@n8n/design-system",
|
||||
"version": "2.32.0",
|
||||
"main": "src/index.ts",
|
||||
"import": "src/index.ts",
|
||||
"scripts": {
|
||||
"dev": "pnpm run --dir=../storybook dev",
|
||||
"clean": "rimraf dist .turbo",
|
||||
|
|
@ -46,6 +45,7 @@
|
|||
"autoprefixer": "^10.4.19",
|
||||
"emojibase-data": "^17.0.0",
|
||||
"eslint-plugin-storybook": "catalog:storybook",
|
||||
"pinia": "catalog:frontend",
|
||||
"postcss": "^8.4.38",
|
||||
"sass": "^1.71.1",
|
||||
"storybook": "catalog:storybook",
|
||||
|
|
@ -90,7 +90,6 @@
|
|||
"markdown-it-link-attributes": "catalog:",
|
||||
"markdown-it-task-lists": "^2.1.1",
|
||||
"parse-diff": "^0.11.1",
|
||||
"pinia": "catalog:frontend",
|
||||
"reka-ui": "^2.5.0",
|
||||
"sanitize-html": "catalog:",
|
||||
"vue": "catalog:frontend",
|
||||
|
|
|
|||
|
|
@ -11,10 +11,15 @@
|
|||
* Usage:
|
||||
* <N8nButton variant="solid" class="n8n-button--success">Save</N8nButton>
|
||||
* <N8nButton variant="ghost" class="n8n-button--highlight">Info</N8nButton>
|
||||
*
|
||||
* Do not wrap these selectors in `:global()`. This file is `@use`d from
|
||||
* Button.vue's plain (non-module) style block, where selectors are already
|
||||
* global, so `:global()` is never transformed away — it ships as an invalid
|
||||
* pseudo-class and browsers drop the whole rule.
|
||||
*/
|
||||
|
||||
/** @deprecated Use a semantic variant instead of success color */
|
||||
:global(.n8n-button--success) {
|
||||
.n8n-button--success {
|
||||
--button--color--background: var(--color--success);
|
||||
--button--color--background-hover: var(--color--success--shade-1);
|
||||
--button--color--background-active: var(--color--success--shade-1);
|
||||
|
|
@ -31,7 +36,7 @@
|
|||
}
|
||||
|
||||
/** @deprecated Use a semantic variant instead of warning color */
|
||||
:global(.n8n-button--warning) {
|
||||
.n8n-button--warning {
|
||||
--button--color--background: var(--color--warning);
|
||||
--button--color--background-hover: var(--color--warning--shade-1);
|
||||
--button--color--background-active: var(--color--warning--shade-1);
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ export { default as N8nResizeWrapper } from './N8nResizeWrapper';
|
|||
export { default as N8nSelect } from './N8nSelect';
|
||||
export { default as N8nSpinner } from './N8nSpinner';
|
||||
export { default as N8nStatusDot } from './N8nStatusDot';
|
||||
export { default as N8nStepper } from './N8nStepper/Stepper.vue';
|
||||
export { default as N8nSticky } from './N8nSticky';
|
||||
export { default as N8nResizeableSticky } from './N8nResizeableSticky';
|
||||
export { default as N8nSuggestedActions } from './N8nSuggestedActions';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
import { readdirSync, readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
/**
|
||||
* `:global()` is a CSS-Modules construct. It is only transformed away in a
|
||||
* `<style module>` or `<style scoped>` block; anywhere else it survives into
|
||||
* the emitted CSS as an invalid pseudo-class, which browsers respond to by
|
||||
* dropping the whole rule (and lightningcss by warning). A standalone `.scss`
|
||||
* can't know which kind of block will `@use` it, so it must not use `:global()`
|
||||
* at all — the caller decides, and getting it wrong fails silently.
|
||||
*/
|
||||
|
||||
const srcDir = resolve(process.cwd(), 'src');
|
||||
const styleBlock = /<style\b([^>]*)>([\s\S]*?)<\/style>/g;
|
||||
|
||||
/** Only selectors matter here, so comments explaining this very rule shouldn't trip it. */
|
||||
const usesGlobal = (source: string) =>
|
||||
source
|
||||
.replace(/\/\*[\s\S]*?\*\//g, '')
|
||||
.replace(/(^|\s)\/\/.*$/gm, '$1')
|
||||
.includes(':global(');
|
||||
|
||||
const allFiles = readdirSync(srcDir, { recursive: true, encoding: 'utf8' });
|
||||
|
||||
const collect = (extension: string) => {
|
||||
const files = allFiles.filter((file) => file.endsWith(extension));
|
||||
// A wrong srcDir would make the assertions below vacuously pass.
|
||||
expect(files.length).toBeGreaterThan(0);
|
||||
return files.map((file) => [file, readFileSync(resolve(srcDir, file), 'utf8')] as const);
|
||||
};
|
||||
|
||||
describe(':global() placement', () => {
|
||||
it('is not used in .vue style blocks that do not transform it', () => {
|
||||
const offenders: string[] = [];
|
||||
|
||||
for (const [file, source] of collect('.vue')) {
|
||||
for (const [, attrs, body] of source.matchAll(styleBlock)) {
|
||||
const transformed = /\bmodule\b/.test(attrs) || /\bscoped\b/.test(attrs);
|
||||
if (!transformed && usesGlobal(body)) {
|
||||
offenders.push(`${file} — <style${attrs}>`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect(offenders).toEqual([]);
|
||||
});
|
||||
|
||||
it('is not used in standalone .scss files', () => {
|
||||
const offenders = collect('.scss')
|
||||
.filter(([, source]) => usesGlobal(source))
|
||||
.map(([file]) => file);
|
||||
|
||||
expect(offenders).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref, shallowRef } from 'vue';
|
||||
import { N8nButton, N8nIconButton, N8nInput, N8nText } from '@n8n/design-system';
|
||||
import N8nStepper from '@n8n/design-system/components/N8nStepper/Stepper.vue';
|
||||
import { N8nButton, N8nIconButton, N8nInput, N8nStepper, N8nText } from '@n8n/design-system';
|
||||
import type { ChatIntegrationDescriptor, AgentIntegrationSettings } from '@n8n/api-types';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { useRootStore } from '@n8n/stores/useRootStore';
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import {
|
|||
N8nIcon,
|
||||
N8nIconButton,
|
||||
N8nInput,
|
||||
N8nStepper,
|
||||
N8nText,
|
||||
} from '@n8n/design-system';
|
||||
import N8nStepper from '@n8n/design-system/components/N8nStepper/Stepper.vue';
|
||||
import AgentChannelSlackSetupSnapshots from './AgentChannelSlackSetupSnapshots.vue';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { useRootStore } from '@n8n/stores/useRootStore';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { N8nButton, N8nText } from '@n8n/design-system';
|
||||
import N8nStepper from '@n8n/design-system/components/N8nStepper/Stepper.vue';
|
||||
import { N8nButton, N8nStepper, N8nText } from '@n8n/design-system';
|
||||
import type { ChatIntegrationDescriptor, AgentIntegrationSettings } from '@n8n/api-types';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import type { PermissionsRecord } from '@n8n/permissions';
|
||||
|
|
|
|||
|
|
@ -5181,9 +5181,6 @@ importers:
|
|||
parse-diff:
|
||||
specifier: ^0.11.1
|
||||
version: 0.11.1
|
||||
pinia:
|
||||
specifier: catalog:frontend
|
||||
version: 2.2.4(typescript@6.0.2)(vue@3.5.26(typescript@6.0.2))
|
||||
reka-ui:
|
||||
specifier: ^2.5.0
|
||||
version: 2.5.0(typescript@6.0.2)(vue@3.5.26(typescript@6.0.2))
|
||||
|
|
@ -5272,6 +5269,9 @@ importers:
|
|||
eslint-plugin-storybook:
|
||||
specifier: catalog:storybook
|
||||
version: 10.1.11(eslint@9.29.0(jiti@2.6.1))(storybook@10.1.11(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(utf-8-validate@5.0.10))(typescript@6.0.2)
|
||||
pinia:
|
||||
specifier: catalog:frontend
|
||||
version: 2.2.4(typescript@6.0.2)(vue@3.5.26(typescript@6.0.2))
|
||||
postcss:
|
||||
specifier: 8.5.10
|
||||
version: 8.5.10
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user