feat(editor): Update UI with n8n rebrand (#40342)

Co-authored-by: Bob Hough <15361982+heymynameisrob@users.noreply.github.com>
Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
Co-authored-by: Sebastien Powell <sebpowell@users.noreply.github.com>
Co-authored-by: Tuukka Kantola <tuukka@n8n.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Rob Hough 2026-10-13 16:06:30 +00:00 committed by GitHub
parent d245b17b89
commit bffe7d8392
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
998 changed files with 3902 additions and 2112 deletions

View File

@ -1,6 +1,6 @@
@use '@n8n/design-system/css/_primitives' as primitives;
@use '@n8n/design-system/css/_tokens' as tokens;
@use '@n8n/design-system/css/fonts/inter';
@use '@n8n/design-system/css/fonts/geist';
:root {
color-scheme: light dark;
@ -22,13 +22,7 @@
body {
margin: 0;
font-family:
InterVariable,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
sans-serif;
font-family: var(--font-family);
-webkit-font-smoothing: antialiased;
background: transparent;
color: var(--color--text--shade-1);

View File

@ -6,11 +6,11 @@ import { useI18n } from '@mcp-apps/i18n';
withDefaults(
defineProps<{
label?: string;
variant?: 'solid' | 'subtle';
variant?: 'solid' | 'outline';
size?: 'small' | 'medium';
}>(),
{
variant: 'subtle',
variant: 'outline',
size: 'small',
},
);

View File

@ -1,14 +1,12 @@
@use '@n8n/design-system/css/_primitives' as primitives;
@use '@n8n/design-system/css/_tokens' as tokens;
@use '@n8n/design-system/css/fonts/inter';
@use '@n8n/design-system/css/fonts/geist';
:root {
color-scheme: light dark;
@include primitives.primitives;
@include tokens.theme;
// Shared icon column, so info rows and tab rows keep one text edge and one icon centre
--row-marker-size: 40px;
--row-marker-size: var(--height--xl);
}
@media (prefers-color-scheme: dark) {
@ -26,25 +24,19 @@
body {
margin: 0;
padding: 0;
font-family:
InterVariable,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
sans-serif;
font-family: var(--font-family);
-webkit-font-smoothing: antialiased;
background-color: var(--color--background);
color: var(--color--text--shade-1);
}
// Grouping box shared by the views and the allowed-instances list.
/** Keep the shared card layout for extension panels. */
.panel {
display: flex;
flex-direction: column;
gap: var(--spacing--lg);
background: var(--background--surface);
border: var(--border-width) var(--border-style) var(--color--foreground--tint-1);
border: var(--border);
border-radius: var(--radius--lg);
padding: var(--spacing--lg);
min-height: 0;

View File

@ -0,0 +1,93 @@
Copyright 2024 The Geist Project Authors (https://github.com/vercel/geist-font)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@ -557,7 +557,7 @@ defineExpose({
>
<N8nButton
v-if="opt.text"
variant="subtle"
variant="outline"
size="xsmall"
@click="() => onQuickReply(opt)"
>

View File

@ -289,7 +289,7 @@ exports[`AskAssistantChat > renders chat with messages correctly 1`] = `
icononly="false"
loading="false"
size="xsmall"
variant="subtle"
variant="outline"
/>
</div>
<div
@ -301,7 +301,7 @@ exports[`AskAssistantChat > renders chat with messages correctly 1`] = `
icononly="false"
loading="false"
size="xsmall"
variant="subtle"
variant="outline"
/>
</div>

View File

@ -0,0 +1,40 @@
import type { StoryFn } from '@storybook/vue3-vite';
import BlockMessage from './BlockMessage.vue';
export default {
title: 'Areas/Assistant/BlockMessage',
component: BlockMessage,
parameters: {
docs: {
description: {
component: 'A titled summary block in Assistant chat, with markdown body content.',
},
},
},
};
const Template: StoryFn = (args) => ({
setup: () => ({ args }),
components: { BlockMessage },
template: `
<div style="width: 380px;">
<BlockMessage v-bind="args" />
</div>
`,
});
export const Default = Template.bind({});
Default.args = {
isFirstOfRole: true,
user: { firstName: 'Max', lastName: 'Test' },
message: {
id: 'block-1',
role: 'assistant',
type: 'block',
title: "Credential doesn't have correct permissions to send a message",
content:
'### Solution steps\n1. Check the credential **scopes**\n2. Reconnect the account\n3. Retry the node\n\n- Unordered item 1\n- Unordered item 2',
read: false,
},
};

View File

@ -61,7 +61,7 @@ const { renderMarkdown } = useMarkdown();
.blockTitle {
border-bottom: var(--border);
padding: var(--spacing--2xs);
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
}
.blockBody {
@ -77,7 +77,7 @@ const { renderMarkdown } = useMarkdown();
h1,
h2,
h3 {
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
font-size: var(--font-size--xs);
margin: var(--spacing--xs) 0 var(--spacing--4xs);
}
@ -85,7 +85,7 @@ const { renderMarkdown } = useMarkdown();
h4,
h5,
h6 {
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
font-size: var(--font-size--2xs);
}

View File

@ -27,7 +27,7 @@ const { t } = useI18n();
</p>
<N8nButton
v-if="message.retry"
variant="subtle"
variant="outline"
size="xsmall"
:class="$style.retryButton"
data-test-id="error-retry-button"

View File

@ -70,7 +70,7 @@ function onCancelFeedback() {
<div v-if="showRatingButtons" :class="$style.buttons">
<template v-if="!minimal">
<N8nButton
variant="subtle"
variant="outline"
size="small"
:label="t('assistantChat.rating.thumbsUp')"
data-test-id="message-thumbs-up-button"
@ -78,7 +78,7 @@ function onCancelFeedback() {
@click="onRateButton('up')"
/>
<N8nButton
variant="subtle"
variant="outline"
size="small"
data-test-id="message-thumbs-down-button"
:label="t('assistantChat.rating.thumbsDown')"
@ -121,7 +121,7 @@ function onCancelFeedback() {
/>
<div :class="$style.feedbackActions">
<N8nButton
variant="subtle"
variant="outline"
size="small"
:label="t('generic.cancel')"
@click="onCancelFeedback"

View File

@ -0,0 +1,38 @@
import type { StoryFn } from '@storybook/vue3-vite';
import RestoreVersionConfirm from './RestoreVersionConfirm.vue';
export default {
title: 'Areas/Assistant/RestoreVersionConfirm',
component: RestoreVersionConfirm,
parameters: {
docs: {
description: {
component: 'Confirmation card for restoring a previous workflow version from Assistant.',
},
},
},
};
const Template: StoryFn = (args) => ({
setup: () => ({ args }),
components: { RestoreVersionConfirm },
template: '<RestoreVersionConfirm v-bind="args" />',
});
export const Default = Template.bind({});
Default.args = {
versionId: 'version-abc123',
};
export const WithHourLimit = Template.bind({});
WithHourLimit.args = {
versionId: 'version-abc123',
pruneTimeHours: 1,
};
export const WithDayLimit = Template.bind({});
WithDayLimit.args = {
versionId: 'version-abc123',
pruneTimeHours: 72,
};

View File

@ -109,7 +109,7 @@ function handleConfirm() {
.title {
margin: 0;
font-size: var(--font-size--md);
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
color: var(--color--text--shade-1);
}
@ -137,7 +137,7 @@ function handleConfirm() {
padding: 0;
color: var(--color--text--shade-1);
font-size: var(--font-size--sm);
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
cursor: pointer;
padding: var(--spacing--3xs) var(--spacing--sm);

View File

@ -0,0 +1,66 @@
import type { StoryFn } from '@storybook/vue3-vite';
import TextMessage from './TextMessage.vue';
export default {
title: 'Areas/Assistant/TextMessage',
component: TextMessage,
parameters: {
docs: {
description: {
component: 'A text message in Assistant chat, for both user and assistant roles.',
},
},
},
};
const Template: StoryFn = (args) => ({
setup: () => ({ args }),
components: { TextMessage },
template: `
<div style="width: 380px;">
<TextMessage v-bind="args" />
</div>
`,
});
export const Assistant = Template.bind({});
Assistant.args = {
isFirstOfRole: true,
user: { firstName: 'Max', lastName: 'Test' },
message: {
id: 'text-1',
role: 'assistant',
type: 'text',
content:
'Hi Max! Here is my top solution to fix the error in your **Transform data** node.\n\n### Next steps\n1. Open the node\n2. Update the expression',
read: false,
},
};
export const User = Template.bind({});
User.args = {
isFirstOfRole: true,
user: { firstName: 'Max', lastName: 'Test' },
message: {
id: 'text-2',
role: 'user',
type: 'text',
content: 'Give it to me **ignore this markdown**',
read: false,
},
};
export const WithCodeSnippet = Template.bind({});
WithCodeSnippet.args = {
isFirstOfRole: true,
user: { firstName: 'Max', lastName: 'Test' },
message: {
id: 'text-3',
role: 'assistant',
type: 'text',
content: 'Use this expression in the node:',
codeSnippet: '```js\n{{ $json.data }}\n```',
read: false,
},
};

View File

@ -256,7 +256,7 @@ async function onCopyButtonClick(content: string, e: MouseEvent) {
h1,
h2,
h3 {
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
font-size: var(--font-size--xs);
margin: var(--spacing--xs) 0 var(--spacing--4xs);
}
@ -264,7 +264,7 @@ async function onCopyButtonClick(content: string, e: MouseEvent) {
h4,
h5,
h6 {
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
font-size: var(--font-size--2xs);
}

View File

@ -0,0 +1,72 @@
import type { StoryFn } from '@storybook/vue3-vite';
import ToolMessage from './ToolMessage.vue';
import type { ChatUI } from '../../../types/assistant';
export default {
title: 'Areas/Assistant/ToolMessage',
component: ToolMessage,
parameters: {
docs: {
description: {
component: 'A tool-call status row in Assistant chat.',
},
},
},
};
const Template: StoryFn = (args) => ({
setup: () => ({ args }),
components: { ToolMessage },
template: `
<div style="width: 380px;">
<ToolMessage v-bind="args" />
</div>
`,
});
const toolMessage = (
overrides: Partial<ChatUI.ToolMessage> & { id?: string; read?: boolean } = {},
): ChatUI.ToolMessage & { id: string; read: boolean } => ({
id: 'tool-1',
role: 'assistant',
type: 'tool',
toolName: 'search_files',
toolCallId: 'call_456',
displayTitle: 'Search Files',
status: 'completed',
updates: [],
read: false,
...overrides,
});
export const Completed = Template.bind({});
Completed.args = {
isFirstOfRole: true,
user: { firstName: 'Max', lastName: 'Test' },
message: toolMessage({ status: 'completed' }),
};
export const Running = Template.bind({});
Running.args = {
isFirstOfRole: true,
user: { firstName: 'Max', lastName: 'Test' },
message: toolMessage({
id: 'tool-2',
status: 'running',
toolName: 'code_tool',
displayTitle: 'Code Tool',
}),
};
export const Error = Template.bind({});
Error.args = {
isFirstOfRole: true,
user: { firstName: 'Max', lastName: 'Test' },
message: toolMessage({
id: 'tool-3',
status: 'error',
toolName: 'database_query',
displayTitle: 'Database Query',
}),
};

View File

@ -134,7 +134,7 @@ const statusColor = computed(() => {
}
.sectionTitle {
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
font-size: var(--font-size--2xs);
color: var(--color--text--shade-1);
margin-bottom: var(--spacing--3xs);

View File

@ -3,8 +3,8 @@
exports[`MessageRating > should render correctly with default props 1`] = `
"<div class="rating">
<div class="buttons">
<n8n-button-stub label="assistantChat.rating.thumbsUp" icon="thumbs-up" variant="subtle" size="small" loading="false" icononly="false" disabled="false" class="" data-test-id="message-thumbs-up-button"></n8n-button-stub>
<n8n-button-stub label="assistantChat.rating.thumbsDown" icon="thumbs-down" variant="subtle" size="small" loading="false" icononly="false" disabled="false" class="" data-test-id="message-thumbs-down-button"></n8n-button-stub>
<n8n-button-stub label="assistantChat.rating.thumbsUp" icon="thumbs-up" variant="outline" size="small" loading="false" icononly="false" disabled="false" class="" data-test-id="message-thumbs-up-button"></n8n-button-stub>
<n8n-button-stub label="assistantChat.rating.thumbsDown" icon="thumbs-down" variant="outline" size="small" loading="false" icononly="false" disabled="false" class="" data-test-id="message-thumbs-down-button"></n8n-button-stub>
</div>
<!--v-if-->
<!--v-if-->

View File

@ -15,7 +15,7 @@ withDefaults(defineProps<{ text: string; size?: 'small' | 'medium' | 'large' | '
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
}
.small {

View File

@ -44,7 +44,7 @@ const handleButtonClick = () => {
</template>
<span :class="$style.content">
{{ message }}
<N8nButton v-if="isAnotherTab" variant="subtle" size="xsmall" @click="handleButtonClick">
<N8nButton v-if="isAnotherTab" variant="outline" size="xsmall" @click="handleButtonClick">
{{ t('collaboration.canvas.acquireEditing') }}
</N8nButton>
</span>

View File

@ -113,7 +113,7 @@ const diffs = computed(() => {
</div>
<div v-else-if="replaced">
<N8nButton
variant="subtle"
variant="outline"
size="xsmall"
icon="undo-2"
data-test-id="undo-replace-button"
@ -128,7 +128,7 @@ const diffs = computed(() => {
</div>
<N8nButton
v-else
:variant="replacing ? 'subtle' : 'solid'"
:variant="replacing ? 'outline' : 'solid'"
size="xsmall"
icon="refresh-cw"
data-test-id="replace-code-button"
@ -150,7 +150,7 @@ const diffs = computed(() => {
.title {
padding: var(--spacing--2xs);
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
font-size: var(--font-size--2xs);
// ensure consistent spacing even if title is empty
min-height: 32.5px;

View File

@ -854,7 +854,7 @@ exports[`CodeDiff > renders replaced code diff correctly 1`] = `
icononly="false"
loading="false"
size="xsmall"
variant="subtle"
variant="outline"
/>
<n8n-icon-stub
class="ml-xs"
@ -1147,7 +1147,7 @@ exports[`CodeDiff > renders replacing code diff correctly 1`] = `
icononly="false"
loading="true"
size="xsmall"
variant="subtle"
variant="outline"
/>
</div>
</div>

View File

@ -48,7 +48,7 @@ const forwarded = useForwardPropsEmits(props, emit);
<DateRangePickerRoot v-bind="forwarded">
<DateRangePickerTrigger as-child>
<slot name="trigger">
<IconButton variant="subtle" icon="calendar" aria-label="Open calendar" />
<IconButton variant="outline" icon="calendar" aria-label="Open calendar" />
</slot>
</DateRangePickerTrigger>
@ -63,11 +63,11 @@ const forwarded = useForwardPropsEmits(props, emit);
<div :class="$style.CalendarWrapper">
<DateRangePickerHeader :class="$style.CalendarHeader">
<DateRangePickerPrev as-child>
<IconButton icon="chevron-left" variant="subtle" />
<IconButton icon="chevron-left" variant="outline" />
</DateRangePickerPrev>
<DateRangePickerHeading :class="$style.CalendarHeading" />
<DateRangePickerNext as-child>
<IconButton icon="chevron-right" variant="subtle" />
<IconButton icon="chevron-right" variant="outline" />
</DateRangePickerNext>
</DateRangePickerHeader>
@ -116,7 +116,7 @@ const forwarded = useForwardPropsEmits(props, emit);
<slot name="footer" :close="closePopover">
<N8nButton
variant="subtle"
variant="outline"
label="Apply"
class="mt-2xs"
:class="$style.ApplyButton"

View File

@ -36,7 +36,7 @@ describe('N8nActionToggle', () => {
},
});
expect(getByRole('button').querySelector('svg')).toHaveAttribute('data-icon', 'ellipsis');
expect(getByRole('button').querySelector('svg')).toHaveAttribute('data-icon', 'ellipsis-12');
});
it('should have bottom-end as default placement', async function () {
const { container, getByRole } = render(ActionToggle, {

View File

@ -101,7 +101,7 @@ defineExpose({
<N8nIconButton
variant="ghost"
:class="$style[theme]"
:icon="iconOrientation === 'horizontal' ? 'ellipsis' : 'ellipsis-vertical'"
:icon="iconOrientation === 'horizontal' ? 'ellipsis-12' : 'ellipsis-vertical-12'"
size="small"
:disabled="disabled"
role="button"

View File

@ -228,7 +228,7 @@ const alertBoxClassNames = computed(() => {
.title {
font-size: var.$alert-title-font-size;
line-height: 18px;
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
}
.description {

View File

@ -109,7 +109,7 @@ const handleCancel = () => {
<slot />
<N8nDialogFooter>
<N8nButton variant="subtle" :label="cancelLabel" @click="handleCancel" />
<N8nButton variant="outline" :label="cancelLabel" @click="handleCancel" />
<N8nButton
:variant="actionVariant === 'destructive' ? 'destructive' : 'solid'"
:label="actionLabel"

View File

@ -75,7 +75,7 @@ const getSize = (size: AvatarSize): number => AVATAR_SIZES[size];
.initials {
position: absolute;
font-size: var(--font-size--2xs);
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
color: var(--avatar--color--text);
text-shadow: 0 1px 6px rgba(25, 11, 9, 0.3);
text-transform: uppercase;

View File

@ -99,16 +99,28 @@ export const Sizes: Story = {
},
components: { N8nBadge },
template: `
<div style="display: flex; align-items: center; flex-wrap: wrap; gap: var(--spacing--sm)">
<N8nBadge
v-for="size in sizes"
:key="size"
:size="size"
leading-icon="circle-check"
variant="success"
>
Active
</N8nBadge>
<div style="display: flex; flex-direction: column; gap: var(--spacing--sm)">
<div style="display: flex; align-items: center; flex-wrap: wrap; gap: var(--spacing--sm)">
<N8nBadge
v-for="size in sizes"
:key="size"
:size="size"
leading-icon="circle-check"
variant="success"
>
Active
</N8nBadge>
</div>
<div style="display: flex; align-items: center; flex-wrap: wrap; gap: var(--spacing--sm)">
<N8nBadge
v-for="size in sizes"
:key="size + '-text'"
:size="size"
variant="success"
>
Active
</N8nBadge>
</div>
</div>
`,
};

View File

@ -79,7 +79,6 @@ const effectiveTextSize = computed(function getEffectiveTextSize() {
display: inline-flex;
align-items: center;
white-space: nowrap;
border-radius: var(--radius--full);
user-select: none;
appearance: none;
width: fit-content;
@ -91,7 +90,10 @@ const effectiveTextSize = computed(function getEffectiveTextSize() {
--n8n-badge--padding-inline-start: var(--spacing--2xs);
--n8n-badge--padding-inline-end: var(--spacing--2xs);
--n8n-badge--gap: var(--spacing--4xs);
--n8n-badge--radius: var(--radius--xs);
--n8n-badge--label-shift: 0;
border-radius: var(--n8n-badge--radius);
gap: var(--n8n-badge--gap);
background-color: var(--n8n-badge--background);
border: 1px solid var(--n8n-badge--border-color);
@ -102,6 +104,7 @@ const effectiveTextSize = computed(function getEffectiveTextSize() {
.label {
@include utils.utils-ellipsis;
transform: translateY(var(--n8n-badge--label-shift));
}
.clickable {
@ -130,36 +133,45 @@ const effectiveTextSize = computed(function getEffectiveTextSize() {
--n8n-badge--height: var(--height--2xs);
--n8n-badge--padding-inline-start: var(--spacing--2xs);
--n8n-badge--padding-inline-end: var(--spacing--2xs);
--n8n-badge--radius: var(--radius--2xs);
--n8n-badge--label-shift: 1px;
}
.xsmall {
--n8n-badge--height: var(--height--xs);
--n8n-badge--padding-inline-start: var(--spacing--2xs);
--n8n-badge--padding-inline-end: var(--spacing--2xs);
--n8n-badge--radius: var(--radius--2xs);
--n8n-badge--label-shift: 1px;
}
.small {
--n8n-badge--height: var(--height--sm);
--n8n-badge--padding-inline-start: var(--spacing--2xs);
--n8n-badge--padding-inline-end: var(--spacing--2xs);
--n8n-badge--label-shift: 0;
}
.medium {
--n8n-badge--height: var(--height--md);
--n8n-badge--padding-inline-start: var(--spacing--xs);
--n8n-badge--padding-inline-end: var(--spacing--xs);
--n8n-badge--label-shift: 0;
}
.large {
--n8n-badge--height: var(--height--lg);
--n8n-badge--padding-inline-start: var(--spacing--sm);
--n8n-badge--padding-inline-end: var(--spacing--sm);
--n8n-badge--label-shift: 0;
}
.xlarge {
--n8n-badge--height: var(--height--xl);
--n8n-badge--padding-inline-start: var(--spacing--sm);
--n8n-badge--padding-inline-end: var(--spacing--sm);
--n8n-badge--radius: var(--radius--sm);
--n8n-badge--label-shift: 0;
}
.filled {

View File

@ -6,11 +6,11 @@ exports[`Breadcrumbs > does not highlight last item for "highlightLastItem = fal
<!--v-if-->
<!--v-if-->
<!--v-if-->
<li class="item" title="Folder 1" data-resourceid="1" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder1" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 1</span></span></a></li>
<li class="item" title="Folder 1" data-resourceid="1" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder1" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 1</span></span></a></li>
<li class="separator">/</li>
<li class="item" title="Folder 2" data-resourceid="2" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder2" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 2</span></span></a></li>
<li class="item" title="Folder 2" data-resourceid="2" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder2" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 2</span></span></a></li>
<li class="separator">/</li>
<li class="item" title="Folder 3" data-resourceid="3" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder3" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 3</span></span></a></li>
<li class="item" title="Folder 3" data-resourceid="3" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder3" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 3</span></span></a></li>
<li class="separator">/</li>
<li class="item" title="Current" data-resourceid="4" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><span class="n8n-text size-medium regular">Current</span></li>
<!--v-if-->
@ -24,11 +24,11 @@ exports[`Breadcrumbs > renders custom separator correctly 1`] = `
<!--v-if-->
<!--v-if-->
<!--v-if-->
<li class="item" title="Folder 1" data-resourceid="1" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder1" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 1</span></span></a></li>
<li class="item" title="Folder 1" data-resourceid="1" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder1" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 1</span></span></a></li>
<li class="separator">➮</li>
<li class="item" title="Folder 2" data-resourceid="2" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder2" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 2</span></span></a></li>
<li class="item" title="Folder 2" data-resourceid="2" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder2" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 2</span></span></a></li>
<li class="separator">➮</li>
<li class="item" title="Folder 3" data-resourceid="3" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder3" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 3</span></span></a></li>
<li class="item" title="Folder 3" data-resourceid="3" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder3" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 3</span></span></a></li>
<li class="separator">➮</li>
<li class="item current" title="Current" data-resourceid="4" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><span class="n8n-text size-medium regular">Current</span></li>
<!--v-if-->
@ -42,11 +42,11 @@ exports[`Breadcrumbs > renders default version correctly 1`] = `
<!--v-if-->
<!--v-if-->
<!--v-if-->
<li class="item" title="Folder 1" data-resourceid="1" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder1" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 1</span></span></a></li>
<li class="item" title="Folder 1" data-resourceid="1" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder1" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 1</span></span></a></li>
<li class="separator">/</li>
<li class="item" title="Folder 2" data-resourceid="2" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder2" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 2</span></span></a></li>
<li class="item" title="Folder 2" data-resourceid="2" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder2" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 2</span></span></a></li>
<li class="separator">/</li>
<li class="item" title="Folder 3" data-resourceid="3" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder3" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 3</span></span></a></li>
<li class="item" title="Folder 3" data-resourceid="3" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder3" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 3</span></span></a></li>
<li class="separator">/</li>
<li class="item current" title="Current" data-resourceid="4" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><span class="n8n-text size-medium regular">Current</span></li>
<!--v-if-->
@ -61,11 +61,11 @@ exports[`Breadcrumbs > renders slots correctly 1`] = `
<li class="separator">/</li>
<!--v-if-->
<!--v-if-->
<li class="item" title="Folder 1" data-resourceid="1" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder1" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 1</span></span></a></li>
<li class="item" title="Folder 1" data-resourceid="1" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder1" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 1</span></span></a></li>
<li class="separator">/</li>
<li class="item" title="Folder 2" data-resourceid="2" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder2" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 2</span></span></a></li>
<li class="item" title="Folder 2" data-resourceid="2" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder2" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 2</span></span></a></li>
<li class="separator">/</li>
<li class="item" title="Folder 3" data-resourceid="3" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder3" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 3</span></span></a></li>
<li class="item" title="Folder 3" data-resourceid="3" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder3" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 3</span></span></a></li>
<li class="separator">/</li>
<li class="item current" title="Current" data-resourceid="4" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><span class="n8n-text size-medium regular">Current</span></li>
<!--v-if-->
@ -80,11 +80,11 @@ exports[`Breadcrumbs > renders small version correctly 1`] = `
<!--v-if-->
<!--v-if-->
<!--v-if-->
<li class="item" title="Folder 1" data-resourceid="1" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder1" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 1</span></span></a></li>
<li class="item" title="Folder 1" data-resourceid="1" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder1" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 1</span></span></a></li>
<li class="separator">/</li>
<li class="item" title="Folder 2" data-resourceid="2" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder2" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 2</span></span></a></li>
<li class="item" title="Folder 2" data-resourceid="2" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder2" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 2</span></span></a></li>
<li class="separator">/</li>
<li class="item" title="Folder 3" data-resourceid="3" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder3" class="n8n-link" role="link"><span class="text"><span class="n8n-text size-medium regular">Folder 3</span></span></a></li>
<li class="item" title="Folder 3" data-resourceid="3" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><a href="/folder3" class="n8n-link" role="link"><span class="text-underline"><span class="n8n-text size-medium regular">Folder 3</span></span></a></li>
<li class="separator">/</li>
<li class="item current" title="Current" data-resourceid="4" data-test-id="breadcrumbs-item" data-target="folder-breadcrumb-item"><span class="n8n-text size-medium regular">Current</span></li>
<!--v-if-->

View File

@ -11,7 +11,7 @@ const meta = {
argTypes: {
variant: {
control: 'select',
options: ['solid', 'subtle', 'ghost', 'outline', 'destructive', 'success'],
options: ['solid', 'brand', 'ghost', 'outline', 'destructive', 'success'],
},
size: {
control: 'select',
@ -73,7 +73,7 @@ export const Variants: Story = {
template: `
<div style="display: flex; gap: 12px; align-items: center;">
<N8nButton variant="solid" size="medium">Solid</N8nButton>
<N8nButton variant="subtle" size="medium">Subtle</N8nButton>
<N8nButton variant="brand" size="medium">Brand</N8nButton>
<N8nButton variant="outline" size="medium">Outline</N8nButton>
<N8nButton variant="ghost" size="medium">Ghost</N8nButton>
<N8nButton variant="destructive" size="medium">Destructive</N8nButton>
@ -130,7 +130,7 @@ export const Loading: Story = {
template: `
<div style="display: flex; gap: 12px; align-items: center;">
<N8nButton variant="solid" size="medium" loading>Solid</N8nButton>
<N8nButton variant="subtle" size="medium" loading>Subtle</N8nButton>
<N8nButton variant="brand" size="medium" loading>Brand</N8nButton>
<N8nButton variant="outline" size="medium" loading>Outline</N8nButton>
<N8nButton variant="ghost" size="medium" loading>Ghost</N8nButton>
<N8nButton variant="destructive" size="medium" loading>Destructive</N8nButton>
@ -147,7 +147,7 @@ export const Link: Story = {
template: `
<div style="display: flex; gap: 12px; align-items: center;">
<N8nButton variant="solid" size="medium" href="https://n8n.io">Link</N8nButton>
<N8nButton variant="subtle" size="medium" href="https://n8n.io">Link</N8nButton>
<N8nButton variant="brand" size="medium" href="https://n8n.io">Link</N8nButton>
<N8nButton variant="outline" size="medium" href="https://n8n.io">Link</N8nButton>
<N8nButton variant="ghost" size="medium" href="https://n8n.io">Link</N8nButton>
<N8nButton variant="destructive" size="medium" href="https://n8n.io">Link</N8nButton>
@ -181,7 +181,7 @@ export const Disabled: Story = {
template: `
<div style="display: flex; gap: 12px; align-items: center;">
<N8nButton variant="solid" size="medium" disabled>Solid</N8nButton>
<N8nButton variant="subtle" size="medium" disabled>Subtle</N8nButton>
<N8nButton variant="brand" size="medium" disabled>Brand</N8nButton>
<N8nButton variant="outline" size="medium" disabled>Outline</N8nButton>
<N8nButton variant="ghost" size="medium" disabled>Ghost</N8nButton>
<N8nButton variant="destructive" size="medium" disabled>Destructive</N8nButton>
@ -200,7 +200,7 @@ export const Disabled: Story = {
* | Legacy `type` | Current `variant` |
* |---------------|-------------------|
* | `primary` | `solid` |
* | `secondary` | `subtle` |
* | `secondary` | `outline` |
* | `tertiary` | `ghost` |
* | `danger` | `destructive` |
* | `success` | `success` |
@ -224,8 +224,8 @@ export const TypeToVariantMapping: Story = {
<N8nButton variant="solid">Solid</N8nButton>
<code>type="secondary"</code>
<code>variant="subtle"</code>
<N8nButton variant="subtle">Subtle</N8nButton>
<code>variant="outline"</code>
<N8nButton variant="outline">Outline</N8nButton>
<code>type="tertiary"</code>
<code>variant="ghost"</code>
@ -261,7 +261,6 @@ export const IconButtonPatterns: Story = {
<N8nIconButton icon="plus" title="Create" variant="solid" size="xlarge" />
<N8nIconButton icon="plus" title="Create" variant="solid" size="large" />
<N8nIconButton icon="plus" title="Create" variant="solid" size="medium" />
<N8nIconButton icon="plus" title="Create" variant="subtle" size="medium" />
<N8nIconButton icon="plus" title="Create" variant="ghost" size="medium" />
<N8nIconButton icon="plus" title="Create" variant="outline" size="medium" />
<N8nIconButton icon="plus" title="Create" variant="solid" :loading="true" size="medium" />

View File

@ -7,6 +7,11 @@ const stubs = ['N8nSpinner', 'N8nIcon'];
describe('components', () => {
describe('N8nButton', () => {
it('maps the legacy subtle variant to brand', () => {
const wrapper = render(N8nButton, { props: { variant: 'subtle' }, global: { stubs } });
expect(wrapper.getByRole('button').className).toContain('brand');
});
describe('rendering', () => {
it('should render correctly with default props', () => {
const wrapper = render(N8nButton, {
@ -82,7 +87,7 @@ describe('components', () => {
describe('props', () => {
describe('variant', () => {
it.each(['solid', 'subtle', 'ghost', 'outline', 'destructive', 'success'] as const)(
it.each(['solid', 'brand', 'ghost', 'outline', 'destructive', 'success'] as const)(
'should render %s variant',
(variant) => {
const wrapper = render(N8nButton, {

View File

@ -29,6 +29,7 @@ const effectiveSize = computed(() => {
// Map legacy variant values to current ones
const effectiveVariant = computed(() => {
if (props.variant === 'subtle') return 'brand';
if (props.variant === 'highlight') return 'ghost';
if (props.variant === 'highlight-fill') return 'ghost';
return props.variant;
@ -145,7 +146,7 @@ const handleClick = (event: MouseEvent) => {
height: var(--button--height);
padding: var(--button--padding);
border-radius: var(--button--radius);
border-radius: var(--radius--full);
font-size: var(--button--font-size);
--button--color--background: transparent;
@ -201,43 +202,72 @@ const handleClick = (event: MouseEvent) => {
&.xsmall {
--button--height: var(--height--xs);
--button--padding: 0 var(--spacing--2xs);
--button--radius: var(--radius--3xs);
--button--radius: var(--radius--xs);
--button--font-size: var(--font-size--2xs);
}
&.small {
--button--height: var(--height--sm);
--button--padding: 0 var(--spacing--xs);
--button--radius: var(--radius--3xs);
--button--radius: var(--radius--xs);
--button--font-size: var(--font-size--xs);
}
&.medium {
--button--height: var(--height--md);
--button--padding: 0 var(--spacing--xs);
--button--radius: var(--radius--3xs);
--button--radius: var(--radius--xs);
--button--font-size: var(--font-size--sm);
}
&.large {
--button--height: var(--height--lg);
--button--padding: 0 var(--spacing--sm);
--button--radius: var(--radius--2xs);
--button--radius: var(--radius--sm);
--button--font-size: var(--font-size--sm);
}
&.xlarge {
--button--height: var(--height--xl);
--button--padding: 0 var(--spacing--sm);
--button--radius: var(--radius--xs);
--button--radius: var(--radius--sm);
--button--font-size: var(--font-size--md);
}
&.solid {
--button--color--background: var(--color--primary);
--button--color--background-hover: color-mix(
in srgb,
var(--color--primary),
light-dark(var(--color--neutral-white), var(--color--neutral-black)) 10%
);
--button--color--background-active: color-mix(
in srgb,
var(--color--primary),
light-dark(var(--color--neutral-white), var(--color--neutral-black)) 12%
);
--button--color: var(--text-color--inverse);
--button--border-color: var(--color--primary);
--button--border-color--hover: color-mix(
in srgb,
var(--button--border-color),
light-dark(var(--color--neutral-white), var(--color--neutral-black)) 10%
);
--button--border-color--active: color-mix(
in srgb,
var(--button--border-color),
light-dark(var(--color--neutral-white), var(--color--neutral-black)) 12%
);
--button--border--shadow: 0 0 0 1px var(--button--border-color);
--button--border--shadow--hover: 0 0 0 1px var(--button--border-color--hover);
--button--border--shadow--active: 0 0 0 1px var(--button--border-color--active);
}
&.brand {
--button--color--background: var(--background--brand);
--button--color--background-hover: var(--background--brand--hover);
--button--color--background-active: var(--background--brand--active);
--button--color: var(--color--neutral-white);
--button--color: var(--color--neutral-black);
--button--shadow: var(--shadow--xs);
--button--shadow--hover: var(--shadow--xs);
--button--shadow--active: var(--shadow--xs);
@ -249,7 +279,7 @@ const handleClick = (event: MouseEvent) => {
--button--border--shadow--active: 0 0 0 1px var(--button--border-color--active);
}
&.subtle {
&.outline {
--button--color--background: var(--background--surface);
--button--color--background-hover: color-mix(
in srgb,
@ -261,34 +291,20 @@ const handleClick = (event: MouseEvent) => {
var(--button--color--background),
light-dark(var(--color--neutral-black), var(--color--neutral-white)) 10%
);
--button--border-color: var(--border-color);
--button--border-color--hover: color-mix(
in srgb,
var(--button--border-color),
light-dark(var(--color--neutral-black), var(--color--neutral-white)) 5%
);
--button--border-color--active: color-mix(
in srgb,
var(--button--border-color),
light-dark(var(--color--neutral-black), var(--color--neutral-white)) 10%
);
--button--shadow: var(--shadow--xs);
--button--shadow--hover: var(--shadow--xs);
--button--shadow--active: var(--shadow--xs);
--button--border-color: var(--border-color);
--button--border-color--hover: light-dark(
var(--color--black-alpha-200),
var(--color--white-alpha-200)
);
--button--border-color--active: light-dark(
var(--color--black-alpha-300),
var(--color--white-alpha-300)
);
--button--border--shadow: 0 0 0 1px var(--button--border-color);
--button--border--shadow--hover: 0 0 0 1px var(--button--border-color--hover);
--button--border--shadow--active: 0 0 0 1px var(--button--border-color--active);
}
&.outline {
--button--color--background: transparent;
--button--border-color: var(--border-color);
--button--border-color--hover: light-dark(
var(--color--black-alpha-200),
var(--color--white-alpha-200)
);
--button--border-color--active: light-dark(
var(--color--black-alpha-300),
var(--color--white-alpha-300)
);
--button--border--shadow: 0 0 0 1px var(--button--border-color);
--button--border--shadow--hover: 0 0 0 1px var(--button--border-color--hover);
--button--border--shadow--active: 0 0 0 1px var(--button--border-color--active);
@ -416,28 +432,11 @@ const handleClick = (event: MouseEvent) => {
@include motion.spin;
}
/* TODO: Move to global animations css library */
:global(.n8n-button-fade-enter-active),
:global(.n8n-button-fade-leave-active) {
--easing--ease-out: cubic-bezier(0.215, 0.61, 0.355, 1);
transition:
opacity 0.2s var(--easing--ease-out),
transform 0.2s var(--easing--ease-out);
@media (prefers-reduced-motion: reduce) {
transition: opacity 0.1s;
}
:global(.n8n-button-fade-enter-active) {
@include motion.fade-in-up;
}
:global(.n8n-button-fade-enter-from),
:global(.n8n-button-fade-leave-to) {
opacity: 0;
transform: translateY(4px);
filter: blur(2px);
@media (prefers-reduced-motion: reduce) {
transform: none;
filter: none;
}
:global(.n8n-button-fade-leave-active) {
@include motion.fade-out-down;
}
</style>

View File

@ -42,7 +42,7 @@ export const Default: Story = {
},
template: `
<N8nButtonList v-bind="args">
<N8nButton variant="subtle">Save</N8nButton>
<N8nButton variant="outline">Save</N8nButton>
<N8nButton variant="solid">Publish</N8nButton>
<N8nButton variant="ghost">More</N8nButton>
</N8nButtonList>
@ -61,9 +61,9 @@ export const IconButtons: Story = {
},
template: `
<N8nButtonList v-bind="args">
<N8nIconButton variant="subtle" size="large" icon="maximize" aria-label="Zoom to fit" />
<N8nIconButton variant="subtle" size="large" icon="zoom-in" aria-label="Zoom in" />
<N8nIconButton variant="subtle" size="large" icon="zoom-out" aria-label="Zoom out" />
<N8nIconButton variant="outline" size="large" icon="maximize" aria-label="Zoom to fit" />
<N8nIconButton variant="outline" size="large" icon="zoom-in" aria-label="Zoom in" />
<N8nIconButton variant="outline" size="large" icon="zoom-out" aria-label="Zoom out" />
</N8nButtonList>
`,
}),
@ -80,9 +80,9 @@ export const Vertical: Story = {
},
template: `
<N8nButtonList v-bind="args">
<N8nIconButton variant="subtle" size="large" icon="plus" aria-label="Add" />
<N8nIconButton variant="subtle" size="large" icon="search" aria-label="Search" />
<N8nIconButton variant="subtle" size="large" icon="sticky-note" aria-label="Sticky note" />
<N8nIconButton variant="outline" size="large" icon="plus" aria-label="Add" />
<N8nIconButton variant="outline" size="large" icon="search" aria-label="Search" />
<N8nIconButton variant="outline" size="large" icon="sticky-note" aria-label="Sticky note" />
</N8nButtonList>
`,
}),

View File

@ -170,11 +170,15 @@ const getIconSize = computed<IconSize>(() => {
.secondary {
font-size: var(--font-size--2xs);
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
border-color: var(--callout--border-color--secondary);
background-color: var(--callout--color--background--secondary);
color: var(--callout--color--text--secondary);
.messageSection > :global(.n8n-text) {
font-weight: inherit;
}
.icon {
color: var(--callout--icon-color--secondary);
}

View File

@ -1,9 +1,37 @@
import { render } from '@testing-library/vue';
import { mount } from '@vue/test-utils';
import { defineComponent, h, nextTick, ref } from 'vue';
import N8nCard from './Card.vue';
describe('components', () => {
describe('N8nCard', () => {
it('updates hover classes when the click listener changes', async () => {
const onClick = vi.fn();
const clickHandler = ref<typeof onClick>();
const hoverable = ref(false);
const wrapper = mount(
defineComponent({
setup: () => () =>
h(N8nCard, { onClick: clickHandler.value, hoverable: hoverable.value }),
}),
);
const card = wrapper.getComponent(N8nCard);
expect(card.classes()).not.toContain('hoverable');
clickHandler.value = onClick;
await nextTick();
expect(card.classes()).toContain('hoverable');
await card.trigger('click');
expect(onClick).toHaveBeenCalledOnce();
clickHandler.value = undefined;
await nextTick();
expect(card.classes()).not.toContain('hoverable');
hoverable.value = true;
await nextTick();
expect(card.classes()).toContain('hoverable');
wrapper.unmount();
});
it('should render correctly', () => {
const wrapper = render(N8nCard, {
slots: {

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { computed, useCssModule } from 'vue';
import { useAttrs, useCssModule } from 'vue';
interface CardProps {
hoverable?: boolean;
@ -10,16 +10,24 @@ const props = withDefaults(defineProps<CardProps>(), {
hoverable: false,
});
const attrs = useAttrs();
function hasClickHandler(): boolean {
return Boolean(attrs.onClick);
}
const $style = useCssModule();
const classes = computed(() => ({
card: true,
[$style.card]: true,
[$style.hoverable]: props.hoverable,
}));
function getClasses() {
return {
card: true,
[$style.card]: true,
[$style.hoverable]: props.hoverable || hasClickHandler(),
};
}
</script>
<template>
<div :class="classes" v-bind="$attrs">
<div :class="getClasses()" v-bind="$attrs">
<div v-if="$slots.prepend" data-test-id="card-prepend" :class="$style.icon">
<slot name="prepend" />
</div>
@ -46,9 +54,10 @@ const classes = computed(() => ({
<style lang="scss" module>
.card {
border-radius: var(--radius--lg);
border: 1px solid var(--border-color);
background-color: var(--color--background--light-3);
border-radius: var(--radius);
border: var(--border);
box-shadow: var(--shadow--xs);
background-color: var(--background--surface);
padding: var(--card--padding, var(--spacing--sm));
display: flex;
flex-direction: row;
@ -91,14 +100,11 @@ const classes = computed(() => ({
.hoverable {
cursor: pointer;
transition-property: border, color;
transition-duration: 0.3s;
transition-timing-function: ease;
transition: none;
&:hover,
&:focus {
color: var(--color--primary);
border-color: var(--color--primary);
border-color: var(--border-color--strong);
}
}

View File

@ -534,7 +534,7 @@ defineExpose({
.overLimit {
color: var(--color--danger);
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
}
}

View File

@ -34,7 +34,7 @@ exports[`N8nChatInput > rendering > should render correctly with default props 1
aria-disabled="true"
aria-label="Send"
aria-live="polite"
class="button button solid medium iconOnly disabled is-disabled"
class="button button brand medium iconOnly disabled is-disabled"
data-icon-only="true"
data-test-id="send-message-button"
disabled=""
@ -56,19 +56,16 @@ exports[`N8nChatInput > rendering > should render correctly with default props 1
aria-hidden="true"
class="n8n-icon"
data-icon="arrow-up"
fill="currentColor"
focusable="false"
height="16px"
height="14px"
role="img"
viewBox="0 0 24 24"
width="16px"
viewBox="0 0 16 16"
width="14px"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="m5 12l7-7l7 7m-7 7V5"
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15.56 8 14.5 9.06 8.75 3.31v11.94h-1.5V3.31L1.5 9.06.44 8 8 .44z"
/>
</svg>
@ -120,7 +117,7 @@ exports[`N8nChatInput > rendering > should render streaming state without disabl
<button
aria-label="Stop"
aria-live="polite"
class="button button solid medium iconOnly"
class="button button brand medium iconOnly"
data-icon-only="true"
data-test-id="send-message-button"
type="button"
@ -143,11 +140,11 @@ exports[`N8nChatInput > rendering > should render streaming state without disabl
data-icon="filled-square"
fill="currentColor"
focusable="false"
height="12px"
height="14px"
overflow="hidden"
role="img"
viewBox="0 0 10 10"
width="12px"
width="14px"
xmlns="http://www.w3.org/2000/svg"
>
<rect

View File

@ -148,7 +148,7 @@ function onHeightTransitionEnd(event: TransitionEvent) {
:icon="expandButtonIcon"
icon-only
icon-size="medium"
variant="subtle"
variant="outline"
:class="$style.expandButton"
:aria-label="expandButtonLabel"
@click="toggleCollapsed"

View File

@ -671,7 +671,7 @@ describe('N8nContextMenu', () => {
it('should render a submenu trigger with a chevron', async () => {
await renderOpen({ items: submenuItems });
expect(document.querySelector('[data-icon="chevron-right"]')).toBeInTheDocument();
expect(document.querySelector('[data-icon="chevron-right-12"]')).toBeInTheDocument();
expect(document.body.textContent).toContain('Export as…');
});

View File

@ -128,7 +128,7 @@ function handleSubmenuOpenChange(open: boolean) {
<slot name="item-trailing" v-bind="slotProps" />
</template>
</ContextMenuItemContent>
<Icon icon="chevron-right" :class="$style.subIndicator" :color="iconColor" size="large" />
<Icon icon="chevron-right-12" :class="$style.subIndicator" :color="iconColor" :size="12" />
</ContextMenuSubTrigger>
<ContextMenuPortal>
<ContextMenuSubContent

View File

@ -543,7 +543,7 @@ const table = useVueTable({
th {
position: relative;
color: var(--color--text);
font-weight: 600;
font-weight: var(--font-weight--medium);
font-size: 12px;
padding: 0 8px;
height: 36px;

View File

@ -216,7 +216,7 @@ export const AccessibilityFallback: Story = {
<N8nDialog v-model:open="isOpen" v-bind="args">
<div style="padding: var(--spacing--sm) 0;">
<p style="font-weight: var(--font-weight--bold); margin-bottom: var(--spacing--xs);">
<p style="font-weight: var(--font-weight--medium); margin-bottom: var(--spacing--xs);">
Custom Visual Title
</p>
<p>

View File

@ -165,10 +165,10 @@ function handleInteractOutside(e: Event) {
width: 100%;
padding: var(--n8n-dialog-content--padding, var(--spacing--lg));
border-radius: var(--radius--lg);
background-color: light-dark(var(--color--neutral-white), var(--color--neutral-800));
background-color: light-dark(var(--background--surface), var(--background--subtle));
outline: 1px solid var(--border-color);
box-shadow:
inset 0 1.5px 0 light-dark(transparent, var(--border-color)),
0 0 0 0.5px light-dark(var(--border-color), var(--color--black-alpha-300)),
0 0 0 0.5px light-dark(transparent, var(--color--black-alpha-500)),
0 8px 8px light-dark(var(--color--black-alpha-100), var(--color--black-alpha-300)),
0 32px 32px light-dark(var(--color--black-alpha-100), var(--color--black-alpha-200)),
0 64px 64px light-dark(rgba(0, 0, 0, 0.06), var(--color--black-alpha-100));

View File

@ -371,7 +371,7 @@ describe('N8nDropdownMenuItem', () => {
});
await waitFor(() => {
const chevron = document.querySelector('[data-icon="chevron-right"]');
const chevron = document.querySelector('[data-icon="chevron-right-12"]');
expect(chevron).toBeInTheDocument();
});
});
@ -384,7 +384,7 @@ describe('N8nDropdownMenuItem', () => {
});
await waitFor(() => {
const chevron = document.querySelector('[data-icon="chevron-right"]');
const chevron = document.querySelector('[data-icon="chevron-right-12"]');
expect(chevron).toBeInTheDocument();
});
});
@ -400,7 +400,7 @@ describe('N8nDropdownMenuItem', () => {
});
await waitFor(() => {
expect(document.querySelector('[data-icon="chevron-right"]')).toBeInTheDocument();
expect(document.querySelector('[data-icon="chevron-right-12"]')).toBeInTheDocument();
});
const trigger = document.querySelector('[role="menuitem"]')!;
@ -421,7 +421,7 @@ describe('N8nDropdownMenuItem', () => {
});
await waitFor(() => {
expect(document.querySelector('[data-icon="chevron-right"]')).toBeInTheDocument();
expect(document.querySelector('[data-icon="chevron-right-12"]')).toBeInTheDocument();
});
const trigger = document.querySelector('[role="menuitem"]')!;
@ -442,7 +442,7 @@ describe('N8nDropdownMenuItem', () => {
});
await waitFor(() => {
expect(document.querySelector('[data-icon="chevron-right"]')).toBeInTheDocument();
expect(document.querySelector('[data-icon="chevron-right-12"]')).toBeInTheDocument();
});
const trigger = document.querySelector('[role="menuitem"]')!;
@ -472,7 +472,7 @@ describe('N8nDropdownMenuItem', () => {
});
await waitFor(() => {
expect(document.querySelector('[data-icon="chevron-right"]')).toBeInTheDocument();
expect(document.querySelector('[data-icon="chevron-right-12"]')).toBeInTheDocument();
});
const trigger = document.querySelector('[role="menuitem"]')!;

View File

@ -329,27 +329,27 @@ onBeforeUnmount(() => {
:ui="trailingProps"
/>
<Icon
icon="chevron-right"
icon="chevron-right-12"
:class="$style['sub-indicator']"
:color="disabled ? 'text-xlight' : 'text-light'"
size="large"
:size="12"
/>
</span>
<span v-else-if="slots['item-trailing']" :class="$style['sub-indicator-action']">
<slot name="item-trailing" :item="props" :ui="trailingProps" />
<Icon
icon="chevron-right"
icon="chevron-right-12"
:class="$style['sub-indicator']"
:color="disabled ? 'text-xlight' : 'text-light'"
size="large"
:size="12"
/>
</span>
<Icon
v-else
icon="chevron-right"
icon="chevron-right-12"
:class="$style['sub-indicator']"
:color="disabled ? 'text-xlight' : 'text-light'"
size="large"
:size="12"
/>
</DropdownMenuSubTrigger>

View File

@ -30,35 +30,17 @@ exports[`N8nDropdownMenu > disabled state > should render trigger with disabled
aria-hidden="true"
class="n8n-icon"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="10px"
role="img"
viewBox="0 0 24 24"
viewBox="0 0 16 16"
width="10px"
xmlns="http://www.w3.org/2000/svg"
>
<g
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
>
<circle
cx="12"
cy="12"
r="1"
/>
<circle
cx="19"
cy="12"
r="1"
/>
<circle
cx="5"
cy="12"
r="1"
/>
</g>
<path
d="M3.2 6.5a1.3 1.3 0 0 1 1.3 1.3v.4a1.3 1.3 0 0 1-1.3 1.3h-.4a1.3 1.3 0 0 1-1.3-1.3v-.4a1.3 1.3 0 0 1 1.3-1.3zm5 0a1.3 1.3 0 0 1 1.3 1.3v.4a1.3 1.3 0 0 1-1.3 1.3h-.4a1.3 1.3 0 0 1-1.3-1.3v-.4a1.3 1.3 0 0 1 1.3-1.3zm5 0a1.3 1.3 0 0 1 1.3 1.3v.4a1.3 1.3 0 0 1-1.3 1.3h-.4a1.3 1.3 0 0 1-1.3-1.3v-.4a1.3 1.3 0 0 1 1.3-1.3z"
/>
</svg>
@ -94,35 +76,17 @@ exports[`N8nDropdownMenu > rendering > should render default trigger button 1`]
aria-hidden="true"
class="n8n-icon"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="10px"
role="img"
viewBox="0 0 24 24"
viewBox="0 0 16 16"
width="10px"
xmlns="http://www.w3.org/2000/svg"
>
<g
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
>
<circle
cx="12"
cy="12"
r="1"
/>
<circle
cx="19"
cy="12"
r="1"
/>
<circle
cx="5"
cy="12"
r="1"
/>
</g>
<path
d="M3.2 6.5a1.3 1.3 0 0 1 1.3 1.3v.4a1.3 1.3 0 0 1-1.3 1.3h-.4a1.3 1.3 0 0 1-1.3-1.3v-.4a1.3 1.3 0 0 1 1.3-1.3zm5 0a1.3 1.3 0 0 1 1.3 1.3v.4a1.3 1.3 0 0 1-1.3 1.3h-.4a1.3 1.3 0 0 1-1.3-1.3v-.4a1.3 1.3 0 0 1 1.3-1.3zm5 0a1.3 1.3 0 0 1 1.3 1.3v.4a1.3 1.3 0 0 1-1.3 1.3h-.4a1.3 1.3 0 0 1-1.3-1.3v-.4a1.3 1.3 0 0 1 1.3-1.3z"
/>
</svg>

View File

@ -28,19 +28,16 @@ exports[`N8nDropdownMenuItem > rendering > should render checked item with check
aria-hidden="true"
class="n8n-icon item-check"
data-icon="check"
fill="currentColor"
focusable="false"
height="16px"
role="img"
viewBox="0 0 24 24"
viewBox="0 0 16 16"
width="16px"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20 6L9 17l-5-5"
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15.56 3.25 6 12.81.44 7.25 1.5 6.19l4.5 4.5 8.5-8.5z"
/>
</svg>
@ -132,28 +129,17 @@ exports[`N8nDropdownMenuItem > rendering > should render item with icon 1`] = `
aria-hidden="true"
class="n8n-icon item-leading icon"
data-icon="user"
fill="currentColor"
focusable="false"
height="16px"
role="img"
viewBox="0 0 24 24"
viewBox="0 0 16 16"
width="16px"
xmlns="http://www.w3.org/2000/svg"
>
<g
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
>
<path
d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"
/>
<circle
cx="12"
cy="7"
r="4"
/>
</g>
<path
d="M11.25 1A3.75 3.75 0 0 1 15 4.75V15H3.25v-3.25H.393l.41-1.028 1.683-4.207A2.875 2.875 0 0 1 3.625 1zm-8.643 9.25H4.75v3.25h8.75v-3.25H8.25v-3a.5.5 0 0 0-.5-.5H4.008zM3.625 2.5a1.375 1.375 0 0 0 0 2.75H7.75a2 2 0 0 1 2 2v1.5h3.75v-4a2.25 2.25 0 0 0-2.25-2.25z"
/>
</svg>
@ -281,20 +267,17 @@ exports[`N8nDropdownMenuItem > rendering > should render sub-menu trigger when h
<svg
aria-hidden="true"
class="n8n-icon sub-indicator"
data-icon="chevron-right"
data-icon="chevron-right-12"
fill="currentColor"
focusable="false"
height="16px"
height="12px"
role="img"
viewBox="0 0 24 24"
width="16px"
viewBox="0 0 12 12"
width="12px"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="m9 18l6-6l-6-6"
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m4.424.576 5 5L9.849 6l-.425.424-5 5-.424.425L3.151 11l.425-.424L8.152 6 3.576 1.424 3.151 1 4 .151z"
/>
</svg>

View File

@ -12,6 +12,7 @@ interface FormBoxProps {
buttonText?: string;
buttonLoading?: boolean;
secondaryButtonText?: string;
submitButtonVariant?: 'solid' | 'brand';
redirectText?: string;
redirectLink?: string;
}
@ -23,6 +24,7 @@ withDefaults(defineProps<FormBoxProps>(), {
buttonLoading: false,
redirectText: '',
redirectLink: '',
submitButtonVariant: 'solid',
});
const formBus = createFormEventBus();
@ -66,6 +68,7 @@ const onSecondaryButtonClick = (event: Event) => emit('secondaryClick', event);
:loading="buttonLoading"
data-test-id="form-submit-button"
size="large"
:variant="submitButtonVariant"
@click="onButtonClick"
/>
</div>

View File

@ -59,7 +59,7 @@ const classes = computed(() => {
<style lang="scss" module>
.bold {
font-weight: var(--font-weight--bold);
font-weight: var(--font-weight--medium);
}
.regular {

View File

@ -1,37 +1,37 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Icon > should render correctly with a custom color 1`] = `
"<svg viewBox="0 0 24 24" width="1em" height="1em" class="n8n-icon" aria-hidden="true" focusable="false" role="img" data-icon="check">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 6L9 17l-5-5"></path>
"<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16" class="n8n-icon" aria-hidden="true" focusable="false" role="img" height="1em" width="1em" data-icon="check">
<path d="M15.56 3.25 6 12.81.44 7.25 1.5 6.19l4.5 4.5 8.5-8.5z"></path>
</svg>"
`;
exports[`Icon > should render correctly with a custom size 1`] = `
"<svg viewBox="0 0 24 24" width="24px" height="24px" class="n8n-icon" aria-hidden="true" focusable="false" role="img" data-icon="check">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 6L9 17l-5-5"></path>
"<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16" class="n8n-icon" aria-hidden="true" focusable="false" role="img" height="24px" width="24px" data-icon="check">
<path d="M15.56 3.25 6 12.81.44 7.25 1.5 6.19l4.5 4.5 8.5-8.5z"></path>
</svg>"
`;
exports[`Icon > should render correctly with a deprecated icon 1`] = `
"<svg viewBox="0 0 24 24" width="1em" height="1em" class="n8n-icon" aria-hidden="true" focusable="false" role="img" data-icon="variable">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 21s-4-3-4-9s4-9 4-9m8 0s4 3 4 9s-4 9-4 9M15 9l-6 6m0-6l6 6"></path>
"<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16" class="n8n-icon" aria-hidden="true" focusable="false" role="img" height="1em" width="1em" data-icon="variable">
<path d="M4.176 2.38A5.72 5.72 0 0 0 1.5 7.224v1.552c0 2.04 1.069 3.83 2.676 4.843L3.47 14.95A7.22 7.22 0 0 1 0 8.776V7.224A7.22 7.22 0 0 1 3.47 1.05zm8.351-1.33A7.22 7.22 0 0 1 16 7.224v1.552a7.22 7.22 0 0 1-3.473 6.174l-.704-1.33A5.72 5.72 0 0 0 14.5 8.775V7.224a5.72 5.72 0 0 0-2.677-4.844zM11.31 5.444l-.502.558L9.008 8l1.8 1.998.502.558-1.116 1.004-.502-.558L8 9.122l-1.692 1.88-.502.558-1.116-1.004.502-.558L6.99 8 5.192 6.002l-.502-.558L5.806 4.44l.502.558L8 6.878l1.692-1.88.502-.558z"></path>
</svg>"
`;
exports[`Icon > should render correctly with default props 1`] = `
"<svg viewBox="0 0 24 24" width="1em" height="1em" class="n8n-icon" aria-hidden="true" focusable="false" role="img" data-icon="check">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 6L9 17l-5-5"></path>
"<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16" class="n8n-icon" aria-hidden="true" focusable="false" role="img" height="1em" width="1em" data-icon="check">
<path d="M15.56 3.25 6 12.81.44 7.25 1.5 6.19l4.5 4.5 8.5-8.5z"></path>
</svg>"
`;
exports[`Icon > should render correctly with predefined size 1`] = `
"<svg viewBox="0 0 24 24" width="16px" height="16px" class="n8n-icon" aria-hidden="true" focusable="false" role="img" data-icon="check">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 6L9 17l-5-5"></path>
"<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16" class="n8n-icon" aria-hidden="true" focusable="false" role="img" height="16px" width="16px" data-icon="check">
<path d="M15.56 3.25 6 12.81.44 7.25 1.5 6.19l4.5 4.5 8.5-8.5z"></path>
</svg>"
`;
exports[`Icon > should render correctly with spin enabled 1`] = `
"<svg viewBox="0 0 24 24" width="1em" height="1em" class="n8n-icon spin" aria-hidden="true" focusable="false" role="img" data-icon="check">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 6L9 17l-5-5"></path>
"<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16" class="n8n-icon spin" aria-hidden="true" focusable="false" role="img" height="1em" width="1em" data-icon="check">
<path d="M15.56 3.25 6 12.81.44 7.25 1.5 6.19l4.5 4.5 8.5-8.5z"></path>
</svg>"
`;

View File

@ -0,0 +1,188 @@
export { default as Archive } from './custom/brand/archive--outline-16.svg';
export { default as ArrowDown } from './custom/brand/arrow-down--outline-16.svg';
export { default as ArrowLeft } from './custom/brand/arrow-left--outline-16.svg';
export { default as ArrowRight } from './custom/brand/arrow-right--outline-16.svg';
export { default as ArrowRightFromLine } from './custom/brand/arrow-right-from-line--outline-16.svg';
export { default as ArrowRightToLine } from './custom/brand/arrow-right-to-line--outline-16.svg';
export { default as ArrowUp } from './custom/brand/arrow-up--outline-16.svg';
export { default as ArrowUpRight } from './custom/brand/arrow-up-right--outline-16.svg';
export { default as AtSign } from './custom/brand/at--outline-16.svg';
export { default as BadgeCheck } from './custom/brand/check-seal--outline-16.svg';
export { default as Ban } from './custom/brand/slash-circle--outline-16.svg';
export { default as Bell } from './custom/brand/bell--outline-16.svg';
export { default as Blocks } from './custom/brand/blocks--outline-16.svg';
export { default as Bold } from './custom/brand/text-b--outline-16.svg';
export { default as Book } from './custom/brand/book--outline-16.svg';
export { default as BookOpen } from './custom/brand/book-open--outline-16.svg';
export { default as Bot } from './custom/brand/robot--outline-16.svg';
export { default as Box } from './custom/brand/cube--outline-16.svg';
export { default as Braces } from './custom/brand/brackets-curly--outline-16.svg';
export { default as Brain } from './custom/brand/brain--outline-16.svg';
export { default as Briefcase } from './custom/brand/briefcase--outline-16.svg';
export { default as Broom } from './custom/brand/broom--outline-16.svg';
export { default as Bug } from './custom/brand/bug--outline-16.svg';
export { default as Calendar } from './custom/brand/calendar--outline-16.svg';
export { default as ChartColumnDecreasing } from './custom/brand/chart-bars--outline-16.svg';
export { default as Check } from './custom/brand/check--outline-16.svg';
export { default as CheckCheck } from './custom/brand/checks--outline-16.svg';
export { default as ChevronDown } from './custom/brand/chevron-down--outline-16.svg';
export { default as ChevronLeft } from './custom/brand/chevron-left--outline-16.svg';
export { default as ChevronRight } from './custom/brand/chevron-right--outline-16.svg';
export { default as ChevronRight12 } from './custom/brand/chevron-right--outline-12.svg';
export { default as ChevronsDownUp } from './custom/brand/chevrons-down-up--outline-16.svg';
export { default as ChevronsLeft } from './custom/brand/chevrons-left--outline-16.svg';
export { default as ChevronsRight } from './custom/brand/chevrons-right--outline-16.svg';
export { default as ChevronsUpDown } from './custom/brand/chevrons-up-down--outline-16.svg';
export { default as ChevronUp } from './custom/brand/chevron-up--outline-16.svg';
export { default as Circle } from './custom/brand/circle--outline-16.svg';
export { default as CircleAlert } from './custom/brand/exclamation-circle--outline-16.svg';
export { default as CircleCheck } from './custom/brand/check-circle--outline-16.svg';
export { default as CircleDollarSign } from './custom/brand/currency-dollar-circle--outline-16.svg';
export { default as CircleEllipsis } from './custom/brand/dots-horizontal-circle--outline-16.svg';
export { default as CircleHelp } from './custom/brand/question-circle--outline-16.svg';
export { default as CircleMinus } from './custom/brand/minus-circle--outline-16.svg';
export { default as CirclePlay } from './custom/brand/play-circle--outline-16.svg';
export { default as CirclePlus } from './custom/brand/plus-circle--outline-16.svg';
export { default as CircleUserRound } from './custom/brand/person-circle--outline-16.svg';
export { default as CircleX } from './custom/brand/x-circle--outline-16.svg';
export { default as Clipboard } from './custom/brand/clipboard--outline-16.svg';
export { default as ClipboardList } from './custom/brand/clipboard--outline-16.svg';
export { default as Clock } from './custom/brand/clock--outline-16.svg';
export { default as Cloud } from './custom/brand/cloud--outline-16.svg';
export { default as Code } from './custom/brand/chevrons-left-right--outline-16.svg';
export { default as Cog } from './custom/brand/gear--outline-16.svg';
export { default as Copy } from './custom/brand/copy--outline-16.svg';
export { default as CornerDownRight } from './custom/brand/arrow-corner-down-right--outline-16.svg';
export { default as Corners } from './custom/brand/corners--outline-16.svg';
export { default as Crosshair } from './custom/brand/crosshair--outline-16.svg';
export { default as Database } from './custom/brand/database--outline-16.svg';
export { default as Ellipsis } from './custom/brand/dots-horizontal--outline-16.svg';
export { default as Ellipsis12 } from './custom/brand/dots-horizontal--outline-12.svg';
export { default as EllipsisVertical } from './custom/brand/dots-vertical--outline-16.svg';
export { default as EllipsisVertical12 } from './custom/brand/dots-vertical--outline-12.svg';
export { default as Expand } from './custom/brand/arrows-out--outline-16.svg';
export { default as ExternalLink } from './custom/brand/arrow-square-out--outline-16.svg';
export { default as Eye } from './custom/brand/eyes--outline-16.svg';
export { default as EyeOff } from './custom/brand/eyes-slash--outline-16.svg';
export { default as File } from './custom/brand/file--outline-16.svg';
export { default as FileCode } from './custom/brand/file-code--outline-16.svg';
export { default as FileDiff } from './custom/brand/file-diff--outline-16.svg';
export { default as FileDown } from './custom/brand/file-arrow-down--outline-16.svg';
export { default as FileInput } from './custom/brand/file-arrow-in--outline-16.svg';
export { default as Files } from './custom/brand/files--outline-16.svg';
export { default as FileText } from './custom/brand/file-text--outline-16.svg';
export { default as FlaskConical } from './custom/brand/flask--outline-16.svg';
export { default as Flow } from './custom/brand/flow--outline-16.svg';
export { default as Folder } from './custom/brand/folder--outline-16.svg';
export { default as FolderOpen } from './custom/brand/folder-open--outline-16.svg';
export { default as FolderPlus } from './custom/brand/folder-plus--outline-16.svg';
export { default as Funnel } from './custom/brand/filter--outline-16.svg';
export { default as Gauge } from './custom/brand/gauge--outline-16.svg';
export { default as Gift } from './custom/brand/gift--outline-16.svg';
export { default as GitBranch } from './custom/brand/git-branch--outline-16.svg';
export { default as Globe } from './custom/brand/globe--outline-16.svg';
export { default as GraduationCap } from './custom/brand/graduation-cap--outline-16.svg';
export { default as Grid2x2 } from './custom/brand/grid--outline-16.svg';
export { default as GripVertical } from './custom/brand/dots-grip--outline-16.svg';
export { default as Group } from './custom/brand/group--outline-16.svg';
export { default as HardDrive } from './custom/brand/hard-drive--outline-16.svg';
export { default as HardDriveDownload } from './custom/brand/arrow-to-bracket-down--outline-16.svg';
export { default as Hash } from './custom/brand/hash--outline-16.svg';
export { default as History } from './custom/brand/history--outline-16.svg';
export { default as Hourglass } from './custom/brand/hourglass--outline-16.svg';
export { default as House } from './custom/brand/home--outline-16.svg';
export { default as Info } from './custom/brand/info-circle--outline-16.svg';
export { default as Italic } from './custom/brand/text-italics--outline-16.svg';
export { default as KeyRound } from './custom/brand/key--outline-16.svg';
export { default as Layers } from './custom/brand/layers--outline-16.svg';
export { default as LayoutTemplate } from './custom/brand/template--outline-16.svg';
export { default as Lightbulb } from './custom/brand/lightbulb--outline-16.svg';
export { default as Link } from './custom/brand/link--outline-16.svg';
export { default as List } from './custom/brand/list-bullets--outline-16.svg';
export { default as ListChecks } from './custom/brand/list-checks--outline-16.svg';
export { default as ListPlus } from './custom/brand/list-plus--outline-16.svg';
export { default as ListTree } from './custom/brand/list-tree--outline-16.svg';
export { default as Lock } from './custom/brand/lock-locked--outline-16.svg';
export { default as LogIn } from './custom/brand/arrow-to-bracket-right--outline-16.svg';
export { default as LogOut } from './custom/brand/arrow-from-bracket-right--outline-16.svg';
export { default as Mail } from './custom/brand/envelope--outline-16.svg';
export { default as Maximize } from './custom/brand/arrows-out--outline-16.svg';
export { default as Maximize2 } from './custom/brand/arrows-down-left-up-right--outline-16.svg';
export { default as Menu } from './custom/brand/lines-horizontal-3--outline-16.svg';
export { default as MessageCircle } from './custom/brand/chat-bubble--outline-16.svg';
export { default as MessageCirclePlus } from './custom/brand/chat-bubble-plus--outline-16.svg';
export { default as MessageSquare } from './custom/brand/chat-bubble--outline-16.svg';
export { default as MessageSquarePlus } from './custom/brand/chat-bubble-plus--outline-16.svg';
export { default as MessagesSquare } from './custom/brand/chat-bubbles--outline-16.svg';
export { default as Mic } from './custom/brand/microphone--outline-16.svg';
export { default as Minimize2 } from './custom/brand/arrows-in--outline-16.svg';
export { default as Minus } from './custom/brand/minus--outline-16.svg';
export { default as MousePointer } from './custom/brand/mouse-pointer--outline-16.svg';
export { default as N8nAssistant } from './custom/brand/n8n-assistant--outline-16.svg';
export { default as PackageOpen } from './custom/brand/package--outline-16.svg';
export { default as Palette } from './custom/brand/palette--outline-16.svg';
export { default as PanelLeft } from './custom/brand/sidebar-left--outline-16.svg';
export { default as PanelRight } from './custom/brand/sidebar-right--outline-16.svg';
export { default as Paperclip } from './custom/brand/paperclip--outline-16.svg';
export { default as Pen } from './custom/brand/pencil--outline-16.svg';
export { default as Pencil } from './custom/brand/pencil--outline-16.svg';
export { default as PencilOff } from './custom/brand/pencil-slash--outline-16.svg';
export { default as Pin } from './custom/brand/thumbtack--outline-16.svg';
export { default as Play } from './custom/brand/play--outline-16.svg';
export { default as Plug } from './custom/brand/plug--outline-16.svg';
export { default as Plus } from './custom/brand/plus--outline-16.svg';
export { default as Power } from './custom/brand/power--outline-16.svg';
export { default as Quote } from './custom/brand/quotes--outline-16.svg';
export { default as Redo2 } from './custom/brand/arrow-u-up-right--outline-16.svg';
export { default as RefreshCw } from './custom/brand/arrows-cw--outline-16.svg';
export { default as Robot } from './custom/brand/robot--outline-16.svg';
export { default as Robot12 } from './custom/brand/robot--outline-12.svg';
export { default as Rss } from './custom/brand/rss--outline-16.svg';
export { default as SatelliteDish } from './custom/brand/satellite-dish--outline-16.svg';
export { default as Search } from './custom/brand/magnifying-glass--outline-16.svg';
export { default as Send } from './custom/brand/paperplane--outline-16.svg';
export { default as Settings } from './custom/brand/gear--outline-16.svg';
export { default as Share } from './custom/brand/arrow-from-bracket-up--outline-16.svg';
export { default as Shield } from './custom/brand/shield--outline-16.svg';
export { default as ShieldHalf } from './custom/brand/shield--outline-16.svg';
export { default as Smile } from './custom/brand/smiley-square--outline-16.svg';
export { default as Sparkle } from './custom/brand/sparkle--outline-16.svg';
export { default as Sparkles } from './custom/brand/sparkle-rays--outline-16.svg';
export { default as Split } from './custom/brand/arrows-split--outline-16.svg';
export { default as Square } from './custom/brand/square--outline-16.svg';
export { default as SquareArrowOutUpRight } from './custom/brand/arrow-square-out--outline-16.svg';
export { default as SquarePen } from './custom/brand/pencil-compose--outline-16.svg';
export { default as Squares } from './custom/brand/squares--outline-16.svg';
export { default as Star } from './custom/brand/star--outline-16.svg';
export { default as StickyNote } from './custom/brand/sticky-note--outline-16.svg';
export { default as Strikethrough } from './custom/brand/text-strikethrough--outline-16.svg';
export { default as Sun } from './custom/brand/sun--outline-16.svg';
export { default as Table } from './custom/brand/table--outline-16.svg';
export { default as Tags } from './custom/brand/tags--outline-16.svg';
export { default as Telescope } from './custom/brand/binoculars--outline-16.svg';
export { default as Terminal } from './custom/brand/terminal--outline-16.svg';
export { default as ThumbsDown } from './custom/brand/thumbs-down--outline-16.svg';
export { default as ThumbsUp } from './custom/brand/thumbs-up--outline-16.svg';
export { default as Trash2 } from './custom/brand/trash--outline-16.svg';
export { default as TriangleAlert } from './custom/brand/exclamation-triangle--outline-16.svg';
export { default as Underline } from './custom/brand/text-underline--outline-16.svg';
export { default as Undo2 } from './custom/brand/arrow-u-up-left--outline-16.svg';
export { default as Unlink } from './custom/brand/link-slash--outline-16.svg';
export { default as Upload } from './custom/brand/arrow-from-bracket-up--outline-16.svg';
export { default as User } from './custom/brand/person--outline-16.svg';
export { default as UserCheck } from './custom/brand/person-check--outline-16.svg';
export { default as UserPen } from './custom/brand/person-pencil--outline-16.svg';
export { default as UserRound } from './custom/brand/person--outline-16.svg';
export { default as Users } from './custom/brand/people--outline-16.svg';
export { default as Variable } from './custom/brand/variable--outline-16.svg';
export { default as Vault } from './custom/brand/vault--outline-16.svg';
export { default as Video } from './custom/brand/video-camera--outline-16.svg';
export { default as Volume2 } from './custom/brand/speaker-waves--outline-16.svg';
export { default as VolumeX } from './custom/brand/speaker-x--outline-16.svg';
export { default as WandSparkles } from './custom/brand/magic-wand--outline-16.svg';
export { default as Workflow } from './custom/brand/workflow--outline-16.svg';
export { default as Wrench } from './custom/brand/wrench--outline-16.svg';
export { default as X } from './custom/brand/x--outline-16.svg';
export { default as Zap } from './custom/brand/lightning--outline-16.svg';
export { default as ZoomIn } from './custom/brand/magnifying-glass-plus--outline-16.svg';
export { default as ZoomOut } from './custom/brand/magnifying-glass-minus--outline-16.svg';

View File

@ -1,3 +0,0 @@
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.2251 1.02271C13.5179 0.968554 13.8195 1.00233 14.0913 1.11939L14.2055 1.17506L14.3149 1.23951C14.5275 1.37763 14.7014 1.56758 14.8208 1.79127L14.8764 1.90553L14.9214 2.02467C15.0145 2.30522 15.0227 2.60793 14.9438 2.89478C14.9403 2.90772 14.9372 2.92106 14.9331 2.93385L13.0132 8.95338L12.9965 9.00025H19.9995C20.3769 8.99952 20.7471 9.10523 21.0669 9.30592C21.3874 9.50712 21.6437 9.79562 21.8071 10.137C21.9704 10.4783 22.0341 10.8588 21.9897 11.2346C21.9453 11.6105 21.7946 11.9661 21.5561 12.26C21.5375 12.2829 21.5181 12.3052 21.4975 12.3264L11.5971 22.5266L11.5962 22.5256C11.3774 22.7595 11.0907 22.9194 10.7749 22.9778C10.4403 23.0397 10.0944 22.9859 9.7944 22.8254C9.4944 22.665 9.25775 22.4066 9.1235 22.094C8.98941 21.7815 8.96593 21.4327 9.05612 21.1047L9.06686 21.0657L10.9868 15.0462L11.0034 15.0003H3.99948C3.62236 15.0008 3.25253 14.8941 2.93307 14.6936C2.61276 14.4925 2.35617 14.2047 2.19284 13.8635C2.02947 13.5221 1.96581 13.1408 2.01022 12.7649C2.05468 12.3892 2.20544 12.0333 2.44382 11.7395C2.46238 11.7167 2.4819 11.6942 2.50241 11.6731L12.4028 1.47389C12.6215 1.23984 12.9091 1.08117 13.2251 1.02271Z" fill="currentColor" fill-opacity="0.9" style="fill:currentColor;fill-opacity:0.9;"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M12.653 1.132 15 5.304v9.946H1V5.304l2.347-4.172.215-.382h8.877zM2.5 13.75h11v-7.5h-11zm8.25-4.5h-5.5v-1.5h5.5zm-7.718-4.5h9.936l-1.406-2.5H4.438z"/></svg>

After

Width:  |  Height:  |  Size: 245 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M15 15.25H1v-9.5h14zm-9.75-7.5v1.5h5.5v-1.5zm7.38-6.655 2.03 3.155H1.34l2.03-3.155.22-.345h8.82z"/></svg>

After

Width:  |  Height:  |  Size: 195 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="m8.75 12.94 1.75-1.75 1.06 1.06L8 15.81l-3.56-3.56 1.06-1.06 1.75 1.75V9h1.5zm6.5 1.31h-1.5v-11H2.25v11H.75V1.75h14.5zm-4.5-7.5h-5.5v-1.5h5.5z"/></svg>

After

Width:  |  Height:  |  Size: 241 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M15 14.5H8.784l2.024-2.248L11.934 11H8.75V8.5h-1.5V11H4.066l1.126 1.252L7.216 14.5H1v-13h14zm-9.75-10V6h5.5V4.5z"/></svg>

After

Width:  |  Height:  |  Size: 211 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M15.25 15.25h-1.5v-5.5H2.25v5.5H.75v-7h14.5zm-4.5-2h-5.5v-1.5h5.5zm.81-9.5L10.5 4.81 8.75 3.06V7h-1.5V3.06L5.5 4.81 4.44 3.75 8 .19z"/></svg>

After

Width:  |  Height:  |  Size: 231 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M15.25 15.25H.75v-7h14.5zm-10-3.75V13h5.5v-1.5zM8.558.748l2.25 2.5L11.934 4.5H9.25V7h-2.5V4.5H4.066l1.126-1.252 2.25-2.5L8 .128z"/></svg>

After

Width:  |  Height:  |  Size: 227 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M12.25 6.75h3.637l-1.069 1.24-6.25 7.25-.568.658-.568-.659-6.25-7.25L.113 6.75H3.75v-6h8.5zm-7 1.5H3.387L8 13.6l4.614-5.35H10.75v-6h-5.5z"/></svg>

After

Width:  |  Height:  |  Size: 236 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M12 6.75h3.887l-1.069 1.24-6.25 7.25-.568.658-.568-.659-6.25-7.25L.113 6.75H4v-6h8z"/></svg>

After

Width:  |  Height:  |  Size: 182 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M9.25 3.75h6v8.5h-6v3.637l-1.24-1.069-7.25-6.25L.103 8l.659-.568 7.25-6.25L9.25.113zM2.4 8l5.35 4.614V10.75h6v-5.5h-6V3.387z"/></svg>

After

Width:  |  Height:  |  Size: 223 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M9.25 4h6v8h-6v3.887l-1.24-1.069-7.25-6.25L.103 8l.659-.568 7.25-6.25L9.25.113z"/></svg>

After

Width:  |  Height:  |  Size: 178 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="m7.99 1.182 7.25 6.25.658.568-.659.568-7.25 6.25-1.239 1.069V12.25h-6v-8.5h6V.113zm.26 4.068h-6v5.5h6v1.863L13.6 8 8.25 3.386z"/></svg>

After

Width:  |  Height:  |  Size: 225 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="m7.99 1.182 7.25 6.25.658.568-.659.568-7.25 6.25-1.239 1.069V12h-6V4h6V.113z"/></svg>

After

Width:  |  Height:  |  Size: 175 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="m8.568.76 6.25 7.25 1.069 1.24H12.25v6h-8.5v-6H.113l1.069-1.24L7.432.76 8 .103zM3.386 7.75H5.25v6h5.5v-6h1.863L8 2.4z"/></svg>

After

Width:  |  Height:  |  Size: 216 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="m8.568.76 6.25 7.25 1.069 1.24H12v6H4v-6H.113l1.069-1.24L7.432.76 8 .103z"/></svg>

After

Width:  |  Height:  |  Size: 172 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M8.75.25a7 7 0 0 1 7 7v1.5a7 7 0 0 1-7 7h-1.5a7 7 0 0 1-7-7v-1.5a7 7 0 0 1 7-7zm-1.5 1.5a5.5 5.5 0 0 0-5.5 5.5v1.5a5.5 5.5 0 0 0 5.5 5.5h1.5a5.5 5.5 0 0 0 5.5-5.5v-1.5a5.5 5.5 0 0 0-5.5-5.5zm1.5 2.5v4.94L11 6.94 12.06 8 8 12.06 3.94 8 5 6.94l2.25 2.25V4.25z"/></svg>

After

Width:  |  Height:  |  Size: 356 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M8.75.25a7 7 0 0 1 7 7v1.5a7 7 0 0 1-7 7h-1.5a7 7 0 0 1-7-7v-1.5a7 7 0 0 1 7-7zm-1.5 9.19-2.5-2.5L3.69 8 8 12.31 12.31 8l-1.06-1.06-2.5 2.5V4h-1.5z"/></svg>

After

Width:  |  Height:  |  Size: 246 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M8.75.25a7 7 0 0 1 7 7v1.5a7 7 0 0 1-7 7h-1.5a7 7 0 0 1-7-7v-1.5a7 7 0 0 1 7-7zm-1.5 1.5a5.5 5.5 0 0 0-5.5 5.5v1.5a5.5 5.5 0 0 0 5.5 5.5h1.5a5.5 5.5 0 0 0 5.5-5.5v-1.5a5.5 5.5 0 0 0-5.5-5.5zM9.06 5 6.81 7.25h4.94v1.5H6.81L9.06 11 8 12.06 3.94 8 8 3.94z"/></svg>

After

Width:  |  Height:  |  Size: 351 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M8.75.25a7 7 0 0 1 7 7v1.5a7 7 0 0 1-7 7h-1.5a7 7 0 0 1-7-7v-1.5a7 7 0 0 1 7-7zM3.69 8 8 12.31l1.06-1.06-2.5-2.5H12v-1.5H6.56l2.5-2.5L8 3.69z"/></svg>

After

Width:  |  Height:  |  Size: 240 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M8.75.25a7 7 0 0 1 7 7v1.5a7 7 0 0 1-7 7h-1.5a7 7 0 0 1-7-7v-1.5a7 7 0 0 1 7-7zm-1.5 1.5a5.5 5.5 0 0 0-5.5 5.5v1.5a5.5 5.5 0 0 0 5.5 5.5h1.5a5.5 5.5 0 0 0 5.5-5.5v-1.5a5.5 5.5 0 0 0-5.5-5.5zM12.06 8 8 12.06 6.94 11l2.25-2.25H4.25v-1.5h4.94L6.94 5 8 3.94z"/></svg>

After

Width:  |  Height:  |  Size: 353 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M8.75.25a7 7 0 0 1 7 7v1.5a7 7 0 0 1-7 7h-1.5a7 7 0 0 1-7-7v-1.5a7 7 0 0 1 7-7zm-1.81 4.5 2.5 2.5H4v1.5h5.44l-2.5 2.5L8 12.31 12.31 8 8 3.69z"/></svg>

After

Width:  |  Height:  |  Size: 240 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M8.75.25a7 7 0 0 1 7 7v1.5a7 7 0 0 1-7 7h-1.5a7 7 0 0 1-7-7v-1.5a7 7 0 0 1 7-7zm-1.5 1.5a5.5 5.5 0 0 0-5.5 5.5v1.5a5.5 5.5 0 0 0 5.5 5.5h1.5a5.5 5.5 0 0 0 5.5-5.5v-1.5a5.5 5.5 0 0 0-5.5-5.5zM12.06 8 11 9.06 8.75 6.81v4.94h-1.5V6.81L5 9.06 3.94 8 8 3.94z"/></svg>

After

Width:  |  Height:  |  Size: 352 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M8.75.25a7 7 0 0 1 7 7v1.5a7 7 0 0 1-7 7h-1.5a7 7 0 0 1-7-7v-1.5a7 7 0 0 1 7-7zM3.69 8l1.06 1.06 2.5-2.5V12h1.5V6.56l2.5 2.5L12.31 8 8 3.69z"/></svg>

After

Width:  |  Height:  |  Size: 239 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M2.5 9.25h9.94l-4-4L9.5 4.19 15.31 10 9.5 15.81l-1.06-1.06 4-4H1V1h1.5z"/></svg>

After

Width:  |  Height:  |  Size: 170 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M3.5 8.25h7.232L7.482 5 9.25 3.232 15.518 9.5 9.25 15.768 7.482 14l3.25-3.25H1V1h2.5z"/></svg>

After

Width:  |  Height:  |  Size: 184 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="currentColor"><path d="m6.6 9.303 3.726-3.727.424-.425.849.849-.425.424-4.75 4.75-.424.425-.424-.425-4.75-4.75L.401 6l.849-.849.424.425L5.4 9.303V.65h1.2z"/></svg>

After

Width:  |  Height:  |  Size: 230 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="m8.75 12.69 5.75-5.75L15.56 8 8 15.56.44 8 1.5 6.94l5.75 5.75V.75h1.5z"/></svg>

After

Width:  |  Height:  |  Size: 169 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="currentColor"><path d="m6.9 8.076 2.713-2.713.637-.635L11.523 6l-.636.637-4.25 4.25-.637.636-.637-.636-4.25-4.25L.478 6 1.75 4.728l.637.635L5.1 8.076V.85h1.8z"/></svg>

After

Width:  |  Height:  |  Size: 234 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M9.25 10.982 14 6.232 15.768 8 8 15.768.232 8 2 6.232l4.75 4.75V.75h2.5z"/></svg>

After

Width:  |  Height:  |  Size: 171 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M14.31 2.75 4.56 12.5H14V14H2V2h1.5v9.44l9.75-9.75z"/></svg>

After

Width:  |  Height:  |  Size: 150 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="m14.518 3.25-8.25 8.25H14V14H2V2h2.5v7.732l8.25-8.25z"/></svg>

After

Width:  |  Height:  |  Size: 152 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M12.5 11.44V2H14v12H2v-1.5h9.44L1.69 2.75l1.06-1.06z"/></svg>

After

Width:  |  Height:  |  Size: 151 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M11.5 9.732V2H14v12H2v-2.5h7.732l-8.25-8.25L3.25 1.482z"/></svg>

After

Width:  |  Height:  |  Size: 154 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M6 2.25H4.5A2.25 2.25 0 0 0 2.25 4.5v7a2.25 2.25 0 0 0 2.25 2.25H6v1.5H4.5A3.75 3.75 0 0 1 .75 11.5v-7A3.75 3.75 0 0 1 4.5.75H6zM15.81 8l-5.56 5.56-1.06-1.06 3.75-3.75H6v-1.5h6.94L9.19 3.5l1.06-1.06z"/></svg>

After

Width:  |  Height:  |  Size: 298 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M6 3.25H4.5c-.69 0-1.25.56-1.25 1.25v7c0 .69.56 1.25 1.25 1.25H6v2.5H4.5A3.75 3.75 0 0 1 .75 11.5v-7A3.75 3.75 0 0 1 4.5.75H6zM15.768 8 9.75 14.018V9.25H6v-2.5h3.75V1.982z"/></svg>

After

Width:  |  Height:  |  Size: 270 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M2.25 11.5a2.25 2.25 0 0 0 2.25 2.25h7a2.25 2.25 0 0 0 2.25-2.25V10h1.5v1.5a3.75 3.75 0 0 1-3.75 3.75h-7A3.75 3.75 0 0 1 .75 11.5V10h1.5zm11.31-5.75L12.5 6.81 8.75 3.06V10h-1.5V3.06L3.5 6.81 2.44 5.75 8 .19z"/></svg>

After

Width:  |  Height:  |  Size: 306 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M3.25 11.5c0 .69.56 1.25 1.25 1.25h7c.69 0 1.25-.56 1.25-1.25V10h2.5v1.5a3.75 3.75 0 0 1-3.75 3.75h-7A3.75 3.75 0 0 1 .75 11.5V10h2.5zm10.768-5.25H9.25V10h-2.5V6.25H1.982L8 .232z"/></svg>

After

Width:  |  Height:  |  Size: 277 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="currentColor"><path d="m6.849 1.25-.425.424L2.697 5.4h8.653v1.2H2.697l3.727 3.726.425.424-.849.849-.424-.425-4.75-4.75L.401 6l.425-.424 4.75-4.75L6 .401z"/></svg>

After

Width:  |  Height:  |  Size: 229 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"><path d="M9.06 1.5 3.31 7.25h11.94v1.5H3.31l5.75 5.75L8 15.56.44 8 8 .44z"/></svg>

After

Width:  |  Height:  |  Size: 163 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="currentColor"><path d="m7.272 1.75-.635.637L3.924 5.1h7.226v1.8H3.924l2.713 2.713.635.637L6 11.523l-.637-.636-4.25-4.25L.478 6l.635-.637 4.25-4.25L6 .478z"/></svg>

After

Width:  |  Height:  |  Size: 230 B

Some files were not shown because too many files have changed in this diff Show More