feat(editor): Add data pinning functionality (#3511)

* feat: Design system color improvements and button component redesign.

* feat: Added button focus state and unit tests.

* refactor: Aligned n8n-button usage inside of editor-ui.

* test: Updated snapshots.

* refactor: Extracted focus outline width into scss variable.

* fix: Fixed select input border-radius.

* refactor: Removed element-ui references in button.

* fix: Fixed scss variable imports.

* feat: Added color-neutral variable story.

* fix: Fixed color-secondary variable definition.

* feat: Added color-white story.

* test: Updated button snapshot.

* feat: Replaced zoom buttons with new n8n-icon-button.

* feat: Added stories for float utilities.

* chore: Updated color shades generation code for later use.

* chore: Removed color-white code.

* chore: Updated story properties for button components.

* fix: Added el-button fallback for places where el-button is not replaceable (messagebox).

* feat: Reverted to css modules. Replaced el-button with n8n-button at application level.

* test: Updated button snapshot.

* fix: Fixed element-ui locally referenced buttons (via components: {}).

* fix: Updated colors. Removed irrelevant validation. Added ElButton override component.

* test: Updated button override snapshot.

* fix: Various button adjustments and fixes.

* fix: Updated button disabled state.

* test: Updated snapshots.

* fix: Consolidated css variables changes.

* Data pinning (#3512)

* refactor: Aligned n8n-button usage inside of editor-ui.

* feat: Added edit data button on json hover.

* feat: Extracted code editor into separate form component.

* feat: Added edit data button on json hover.

* feat: Added pinData and edit mode methods.

* 🔥 Remove conflict markers

* ✏️ Update i18n keys

*  Add JSON validation

* 🗃️ Add `pinData` column to `workflow_entity`

* 📘 Tighten type

*  Make `pinData` column nullable

*  Adjust workflow endpoints for pin data

* 📘 Improve types

* ✏️ Improve wording

* Inject pindata into items flow (#3420)

*  Inject pin data - Second approach

* 🔥 Remove unneeded lint exception

* feat: Added edit data button on json hover.

* feat: Extracted code editor into separate form component.

* feat: Added edit data button on json hover.

* fix: Fixed rebase conflicts.

*  Undo button change

* 🐛 Fix runNode call

Adjust per update in bdb84130d6

* 🧪 Fix workflow tests

* 🐛 More merge conflict fixes

* feat: Added pin/unpin button and store mutations.

* feat: Size check. Various design and ux improvements.

*  Add transformer

*  Hoist pin data

*  Adjust endpoints for hoisted pin data

* 📘 Expand interface

* 🐛 Fix stray array

* 👕 Fix build

* 👕 Add lint exception

* 👕 Fix header

* 🎨 Add color secondary tints

*  Create `HeaderMessage` component

*  Adjust `InfoTip` component

*  Add `HeaderMessage` to `RunData`

* 🐛 Fix console error

* 👕 Fix lint

*  Consolidate `HeaderMessage` and `Callout`

*  Undo `InfoTip` changes

* 🔥 Remove duplicate icons

*  Simplify template

* 🎨 Change cursor for action text

* 👕 Fix lint

*  Add URL

* 🐛 Fix handler name

*  Use constant

* ♻️ Refactor per feedback

* fix: Various fixes after data pinning relocation.

* fix: Added store mutation for setting pinned data.

* feat: Added pinned state for workflow canvas node.

* fix: Fixed workflow saving.

* fix: Removed pinData hoisting (no longer necessary).

* feat: Added canPinData flag to hide for input pane and binary data. Fixed unpin and execute flow.

*  Fixes for canvas pin data (#3587)

*  Fixes for canvas pin data

* 📘 Rename type

* 🧪 Fix unrelated Public API test

* 🔥 Remove logging

* feat: Updated pinData mixin to no longer include extra fields.

*  Output same pindata for every run

* 🎨 Fix cropping

* 🔥 Remove unrelated logging

* feat: Moved edit button next to pin button.

* feat: Changed data to be inserted for empty state.

* chore: Changed invalid editor output translation.

* feat: Added error line reporting on JSON Validation.

* feat: Migrated pinData edit mode to store.

* chore: Merged duplicate node border color condition.

* feat: Moved pin data validation to mixin. Added check before closing ndv modal.

* fix: Changed pinned data size calculation to discard active node pin data.

* feat: Added support for rename and delete node with pin data.

* feat: Simplified editing state. Fixed edit mode in input panel after store migration.

* feat: Various data pinning improvements.

* fix: Fixed callout link underline.

* refactor: Added support for both string and objects for data size check.

* feat: Added disabled node check for input panel. Fixed monaco editor resizing.

* fix: Fixed edit mode footer size.

*  Fix pindata items per run

* 👕 Remove unneeded exception

* refactor: Added isValidPinData() helper method.

* refactor: Changed how string size in bytes in calculated.g

* refactor: Updated pinData mixin interface.

* refactor: Merged filter and reduce in pinDataSize calculation.

* fix: Changed code-editor to correct type.

* fix: Added insert test data message to trigger nodes.

* feat: Disabled data pinning for multiple output nodes.

* refactor: Updated ndv.input.disabled translation to include node name.

* refactor: Aligned n8n-button usage inside of editor-ui.

* feat: Added edit data button on json hover.

* feat: Extracted code editor into separate form component.

* feat: Added edit data button on json hover.

* feat: Added pinData and edit mode methods.

* 🔥 Remove conflict markers

* ✏️ Update i18n keys

*  Add JSON validation

* 🗃️ Add `pinData` column to `workflow_entity`

* 📘 Tighten type

*  Make `pinData` column nullable

*  Adjust workflow endpoints for pin data

* 📘 Improve types

* ✏️ Improve wording

* Inject pindata into items flow (#3420)

*  Inject pin data - Second approach

* 🔥 Remove unneeded lint exception

* feat: Added edit data button on json hover.

* feat: Extracted code editor into separate form component.

* feat: Added edit data button on json hover.

* fix: Fixed rebase conflicts.

*  Undo button change

* 🐛 Fix runNode call

Adjust per update in bdb84130d6

* 🧪 Fix workflow tests

* 🐛 More merge conflict fixes

* feat: Added pin/unpin button and store mutations.

* feat: Size check. Various design and ux improvements.

*  Add transformer

*  Hoist pin data

*  Adjust endpoints for hoisted pin data

* 📘 Expand interface

* 🐛 Fix stray array

* 👕 Fix build

* 🎨 Add color secondary tints

*  Create `HeaderMessage` component

*  Adjust `InfoTip` component

*  Add `HeaderMessage` to `RunData`

* 🐛 Fix console error

* 👕 Fix lint

*  Consolidate `HeaderMessage` and `Callout`

*  Undo `InfoTip` changes

* 🔥 Remove duplicate icons

*  Simplify template

* 🎨 Change cursor for action text

* 👕 Fix lint

*  Add URL

* 🐛 Fix handler name

*  Use constant

* ♻️ Refactor per feedback

* fix: Various fixes after data pinning relocation.

* fix: Added store mutation for setting pinned data.

* feat: Added pinned state for workflow canvas node.

*  Fixes for canvas pin data (#3587)

*  Fixes for canvas pin data

* 📘 Rename type

* 🧪 Fix unrelated Public API test

* 🔥 Remove logging

* feat: Updated pinData mixin to no longer include extra fields.

* fix: Removed pinData hoisting (no longer necessary).

* chore: Merged duplicate node border color condition.

*  Output same pindata for every run

* 🎨 Fix cropping

* 🐛 Fix excess closing template tag

* fix: Removed rogue template tag after merge.

* fix: Fixed code-editor resizing when moving ndv panel.

* feat: Added node duplication pin data.

*  Implement telemetry

* ♻️ Add clarifications from call

* fix: Fixed run data header height.

* feat: Removed border from pin data callout.

* feat: Added line-break before 'or insert pin data'.

* feat: Changed enterEditMode to always insert test data if there's no execution data.

* feat: Removed copy output tooltip.

* feat: Removed unpin tooltip.

* fix: Removed thumbtack icon rotation.

* fix: Removed run info from Edit Output title.

* feat: Hid edit and pin buttons when editing.

* feat: Updated monaco code-editor padding and borders.

* feat: Progress on pinData error message format

* feat: Updated copy feature to work without any selected value.

* feat: Moved save and cancel buttons. Cleared notifications on save.

* feat: Changed pin data beforeClosing confirm text.

* feat: Closing ndv when discarding or saving pindata on close.

* feat: Added split in batches node to pin data denylist.

* fix: Added missing margin-bottom to webhook node.

* feat: Moved thumbtack icon to the right, replacing the checkmark.

* fix: Hid pagination while editing.

* feat: Added pin data discovery flow.

* feat: Changed pin data discovery flow to avoid tooltip glitching.

* fix: Changed copy selection to copy all input data.

* feat: Updated pin data validation error message for unexpected single quotes.

* fix: Replaced :manual='true' prop with manual shorthand.

* fix: Removed unused variable.

* chore: Renamed translation key to node.discovery.pinData.

* refactor: Extracted isPinDataNodeType to pinData mixin.

* fix: Updated watch condition to improve performance.

* refactor: Renamed some pin data variables and methods as per review.

* fix: Added partial translation for JSON.parse pin data error messages.

* chore: Temporarily disabled failing unit test.

* 🧪 Fix data pinning workflow retrieval test

* 🔥 Remove unused imports

* 🔥 Remove leftover line

*  Skip pindata node issues on BE

*  Skip pindata node issues on FE

*  Hide `RunInfo` for pindata node

*  Hide purple banner in edit output mode

* feat: Updated data pinning discoverability flow.

* fix: Fixed paginated data pinning.

* fix: Disabled pin data in read only mode.

* 🐛 Fix runtime error with non-array

* fix: Loading pin data when opening execution.

*  Adjust stale data warning for pinned data

*  Skip auth in endpoint

*  Mark start node for pinned trigger

* ✏️ Comment on passthrough

* 🔥 Remove comment

* Final pindata metrics changes (#3673)

* 🐛 Fix `pinData` tracked as `0`

*  Add `is_pinned` to `nodesGraph`

* 📘 Extend `IWorkflowBase`

*  Handle `pinData` being `undefined`

*  Add `data_pinning_tooltip_presented`

* ♻️ Refactor to remove circular dependency

* fix: Added pin data handling when importing workflow. (#3698)

* 🔥 Remove helper from WorkflowExecute

*  Add logic for single pinned trigger

* 👕 Remove lint exception

* fix: Added pin data handling in importWorkflowExact.

* N8N-4077 data pinning discoverability part 2 (#3701)

* fix: Fixed pin data discovery tooltip position when moving canvas.

* feat: Updated data pinning discovery tooltip copy.

* Fix data pinning build (#3702)

*  Disable edit button for disabled node

*  Ensure disabled pinned nodes are passthrough

* 🐛 Fix JSON key unfurling in edit mode

*  Improve implementation

* 🐛 Fix console error

* fix: Fixed copying pinned output data. (#3715)

* Fix pinning for webhook responding with output from last node (#3719)

* fix: Fixed entering edit mode after refresh.

* fix: Fixed type error during build.

* fix: RunData import formatting.

* chore: Updated pin data types.

* fix: Added missing type to stringSizeInBytes.

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>

* fix: Showing pin data without executing the node only in output pane.

* fix: Updated no data message when previous node not executed.

* feat: Added expression input and evaluation for pin data nodes without execution.

* chore: Fixed linting issues and removed remnant console.log().

* chore: Undone package-lock changes.

* fix: Removed pin data store changes.

* fix: Created a new object using vuex runExecutionData.

* fix: Fixed bug appearing when adding a new node after executing.

* fix: Fix editor-ui build

* feat: Added green node connectors when having pin data output.

* chore: Fixed linting errors.

* fix: Added pin data eventBus unsubscribe.

* fix: Added pin data color check after adding a connection.

* 🎨 Add pindata styles

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
This commit is contained in:
Alex Grozav
2022-07-20 18:50:39 +03:00
committed by GitHub
parent fb67543b2f
commit 15693b0056
99 changed files with 4145 additions and 1868 deletions

View File

@@ -1,62 +1,45 @@
<template functional>
<component
:is="$options.components.ElButton"
:plain="props.type === 'outline'"
:disabled="props.disabled"
:size="props.size"
:loading="props.loading"
:title="props.title || props.label"
:class="$options.getClass(props, $style)"
:round="!props.circle && props.round"
:circle="props.circle"
:style="$options.styles(props)"
@click="(e) => listeners.click && listeners.click(e)"
<template>
<button
:class="classes"
:disabled="disabled || loading"
:aria-disabled="ariaDisabled"
:aria-busy="ariaBusy"
aria-live="polite"
v-on="$listeners"
>
<span :class="$style.icon" v-if="props.loading || props.icon">
<component
:is="$options.components.N8nSpinner"
v-if="props.loading"
:size="props.size"
<span :class="$style.icon" v-if="loading || icon">
<n8n-spinner
v-if="loading"
:size="size"
/>
<component
:is="$options.components.N8nIcon"
v-else-if="props.icon"
:icon="props.icon"
:size="props.size"
<n8n-icon
v-else-if="icon"
:icon="icon"
:size="size"
/>
</span>
<span v-if="props.label || $slots.default">
<slot>
{{ props.label }}
</slot>
<span v-if="label || $slots.default">
<slot>{{ label }}</slot>
</span>
</component>
</button>
</template>
<script lang="ts">
import Vue from 'vue';
import N8nIcon from '../N8nIcon';
import N8nSpinner from '../N8nSpinner';
import ElButton from 'element-ui/lib/button';
export default {
export default Vue.extend({
name: 'n8n-button',
props: {
label: {
type: String,
},
title: {
type: String,
},
type: {
type: String,
default: 'primary',
validator: (value: string): boolean =>
['primary', 'outline', 'light', 'text', 'tertiary'].includes(value),
},
theme: {
type: String,
validator: (value: string): boolean =>
['success', 'warning', 'danger'].includes(value),
['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger'].includes(value),
},
size: {
type: String,
@@ -72,13 +55,18 @@ export default {
type: Boolean,
default: false,
},
icon: {
},
round: {
outline: {
type: Boolean,
default: true,
default: false,
},
circle: {
text: {
type: Boolean,
default: false,
},
icon: {
type: [String, Array],
},
block: {
type: Boolean,
default: false,
},
@@ -87,47 +75,82 @@ export default {
validator: (value: string): boolean =>
['left', 'right'].includes(value),
},
fullWidth: {
type: Boolean,
default: false,
},
transparentBackground: {
type: Boolean,
default: false,
},
},
components: {
ElButton,
N8nSpinner,
N8nIcon,
},
styles: (props: {
fullWidth?: boolean;
float?: string;
}): { float?: string; width?: string } => {
return {
...(props.float ? { float: props.float } : {}),
...(props.fullWidth ? { width: '100%' } : {}),
};
computed: {
ariaBusy(): string {
return this.loading ? 'true' : 'false';
},
ariaDisabled(): string {
return this.disabled ? 'true' : 'false';
},
classes(): string {
return `button ${this.$style['button']} ${this.$style[this.type]}` +
`${this.size ? ` ${this.$style[this.size]}` : ''}` +
`${this.outline ? ` ${this.$style['outline']}` : ''}` +
`${this.loading ? ` ${this.$style['loading']}` : ''}` +
`${this.float ? ` ${this.$style[`float-${this.float}`]}` : ''}` +
`${this.text ? ` ${this.$style['text']}` : ''}` +
`${this.disabled ? ` ${this.$style['disabled']}` : ''}` +
`${this.block ? ` ${this.$style['block']}` : ''}` +
`${this.icon || this.loading ? ` ${this.$style['icon']}` : ''}`;
},
},
getClass(props: { type: string; theme?: string, transparentBackground: boolean }, $style: any): string {
const theme = props.type === 'text' || props.type === 'tertiary'
? props.type
: `${props.type}-${props.theme || 'primary'}`;
if (props.transparentBackground) {
return `${$style[theme]} ${$style['transparent']}`;
}
return $style[theme];
},
};
});
</script>
<style lang="scss" module>
@import "../../utils";
@import '../../../theme/src/mixins/utils';
@import '../../../theme/src/common/var';
.button {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
border: var(--border-width-base) $button-border-color var(--border-style-base);
color: $button-font-color;
background-color: $button-background-color;
font-weight: var(--font-weight-bold);
border-radius: $button-border-radius;
padding: $button-padding-vertical $button-padding-horizontal;
font-size: $button-font-size;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
outline: none;
margin: 0;
transition: 0.3s;
@include utils-user-select(none);
&:hover {
color: $button-hover-color;
border-color: $button-hover-border-color;
background-color: $button-hover-background-color;
}
&:focus {
border-color: $button-focus-outline-color;
outline: $focus-outline-width solid $button-focus-outline-color;
}
&:active {
color: $button-active-color;
border-color: $button-active-border-color;
background-color: $button-active-background-color;
outline: none;
}
&::-moz-focus-inner {
border: 0;
}
> i {
display: none;
}
@@ -143,172 +166,258 @@ export default {
}
}
$active-shade-percent: 10%;
$color-primary-shade: lightness(
--color-primary-h,
--color-primary-s,
--color-primary-l,
-($active-shade-percent)
);
$loading-overlay-background-color: rgba(255, 255, 255, 0);
$color-success-shade: lightness(
--color-success-h,
--color-success-s,
--color-success-l,
-($active-shade-percent)
);
/**
* Colors
*/
$color-warning-shade: lightness(
--color-warning-h,
--color-warning-s,
--color-warning-l,
-($active-shade-percent)
);
$color-danger-shade: lightness(
--color-danger-h,
--color-danger-s,
--color-danger-l,
-($active-shade-percent)
);
.primary-primary {
composes: button;
}
.primary-success {
composes: button;
--button-background-color: var(--color-success);
--button-color: var(--color-text-xlight);
--button-border-color: var(--color-success);
--button-active-color: var(--color-text-xlight);
--button-active-border-color: #{$color-success-shade};
--button-active-background-color: #{$color-success-shade};
}
.primary-warning {
composes: button;
--button-background-color: var(--color-warning);
--button-color: var(--color-text-xlight);
--button-border-color: var(--color-warning);
--button-active-color: var(--color-text-xlight);
--button-active-border-color: #{$color-warning-shade};
--button-active-background-color: #{$color-warning-shade};
}
.primary-danger {
composes: button;
--button-background-color: var(--color-danger);
--button-color: var(--color-text-xlight);
--button-border-color: var(--color-danger);
--button-active-color: var(--color-text-xlight);
--button-active-border-color: #{$color-danger-shade};
--button-active-background-color: #{$color-danger-shade};
}
.outline {
--button-background-color: var(--color-foreground-xlight);
--button-disabled-background-color: var(--color-foreground-xlight);
--button-active-background-color: var(--color-foreground-xlight);
}
.outline-primary {
composes: button;
composes: outline;
.secondary {
--button-color: var(--color-primary);
--button-active-border-color: #{$color-primary-shade};
--button-active-color: #{$color-primary-shade};
}
.outline-success {
composes: button;
composes: outline;
--button-color: var(--color-success);
--button-border-color: var(--color-success);
--button-active-color: #{$color-success-shade};
--button-active-border-color: #{$color-success-shade};
}
.outline-warning {
composes: button;
composes: outline;
--button-color: var(--color-warning);
--button-border-color: var(--color-warning);
--button-active-color: #{$color-warning-shade};
--button-active-border-color: #{$color-warning-shade};
}
.outline-danger {
composes: button;
composes: outline;
--button-color: var(--color-danger);
--button-border-color: var(--color-danger);
--button-active-color: #{$color-danger-shade};
--button-active-border-color: #{$color-danger-shade};
}
.light-primary {
composes: button;
--button-color: var(--color-primary);
--button-border-color: var(--color-primary-tint-2);
--button-background-color: var(--color-primary-tint-2);
--button-active-background-color: var(--color-primary-tint-2);
--button-active-color: #{$color-primary-shade};
--button-active-border-color: #{$color-primary-shade};
}
.light-success {
composes: button;
--button-color: var(--color-success);
--button-border-color: var(--color-success-tint-1);
--button-background-color: var(--color-success-tint-1);
--button-active-background-color: var(--color-success-tint-1);
--button-active-color: #{$color-success-shade};
--button-active-border-color: #{$color-success-shade};
}
.light-warning {
composes: button;
--button-color: var(--color-warning);
--button-border-color: var(--color-warning-tint-2);
--button-background-color: var(--color-warning-tint-2);
--button-active-background-color: var(--color-warning-tint-2);
--button-active-color: #{$color-warning-shade};
--button-active-border-color: #{$color-warning-shade};
}
.light-danger {
composes: button;
--button-color: var(--color-danger);
--button-border-color: var(--color-danger-tint-1);
--button-background-color: var(--color-danger-tint-1);
--button-active-background-color: var(--color-danger-tint-1);
--button-active-color: #{$color-danger-shade};
--button-active-border-color: #{$color-danger-shade};
}
.text {
composes: button;
--button-color: var(--color-text-light);
--button-border-color: transparent;
--button-background-color: transparent;
--button-active-background-color: transparent;
--button-active-color: var(--color-primary);
--button-active-border-color: transparent;
}
.tertiary {
composes: button;
font-weight: var(--font-weight-regular) !important;
--button-color: var(--color-text-dark);
--button-border-color: var(--color-foreground-base);
--button-background-color: var(--color-background-base);
--button-border-color: var(--color-primary);
--button-background-color: var(--color-background-xlight);
--button-active-background-color: var(--color-primary-tint-2);
--button-active-color: var(--color-primary);
--button-active-border-color: var(--color-primary);
--button-disabled-border-color: var(--color-foreground-xdark);
--button-hover-background-color: var(--color-primary-tint-3);
--button-hover-color: var(--color-primary);
--button-hover-border-color: var(--color-primary);
--button-focus-outline-color: var(--color-primary-tint-1);
}
.tertiary {
font-weight: var(--font-weight-regular) !important;
--button-background-color: var(--color-background-xlight);
--button-color: var(--color-text-dark);
--button-border-color: var(--color-neutral-850);
--button-active-background-color: var(--color-primary-tint-2);
--button-active-color: var(--color-primary);
--button-active-border-color: var(--color-primary);
--button-hover-background-color: var(--color-neutral-950);
--button-hover-color: var(--color-text-dark);
--button-hover-border-color: var(--color-neutral-800);
--button-focus-outline-color: hsla(var(--color-neutral-h), var(--color-neutral-s), var(--color-neutral-l), 0.2);
}
.success {
--button-background-color: var(--color-success);
--button-color: var(--color-text-xlight);
--button-border-color: var(--color-success);
--button-active-background-color: var(--color-success-350);
--button-active-border-color: var(--color-success-350);
--button-hover-background-color: var(--color-success-450);
--button-hover-border-color: var(--color-success-450);
--button-focus-outline-color: hsla(var(--color-success-h), var(--color-success-s), var(--color-success-l), 0.33);
}
.warning {
--button-background-color: var(--color-warning);
--button-color: var(--color-text-xlight);
--button-border-color: var(--color-warning);
--button-active-background-color: var(--color-warning-500);
--button-active-border-color: var(--color-warning-500);
--button-hover-background-color: var(--color-warning-650);
--button-hover-border-color: var(--color-warning-650);
--button-focus-outline-color: hsla(var(--color-warning-h), var(--color-warning-s), var(--color-warning-l), 0.33);
}
.danger {
--button-background-color: var(--color-danger);
--button-color: var(--color-text-xlight);
--button-border-color: var(--color-danger);
--button-active-color: var(--color-text-xlight);
--button-active-background-color: var(--color-danger-600);
--button-active-border-color: var(--color-danger-600);
--button-hover-background-color: var(--color-danger-700);
--button-hover-border-color: var(--color-danger-700);
--button-focus-outline-color: hsla(var(--color-danger-h), var(--color-danger-s), var(--color-danger-l), 0.33);
}
/**
* Sizes
*/
.mini {
--button-padding-vertical: var(--spacing-4xs);
--button-padding-horizontal: var(--spacing-2xs);
--button-font-size: var(--font-size-2xs);
&.icon-button {
height: 22px;
width: 22px;
}
}
.small {
--button-padding-vertical: var(--spacing-3xs);
--button-padding-horizontal: var(--spacing-xs);
--button-font-size: var(--font-size-2xs);
&.icon-button {
height: 26px;
width: 26px;
}
}
.medium {
--button-padding-vertical: var(--spacing-2xs);
--button-padding-horizontal: var(--spacing-xs);
--button-font-size: var(--font-size-2xs);
&.icon-button {
height: 32px;
width: 32px;
}
}
.large {
&.icon-button {
height: 42px;
width: 42px;
}
}
.xlarge {
--button-padding-vertical: var(--spacing-xs);
--button-padding-horizontal: var(--spacing-s);
--button-font-size: var(--font-size-m);
&.icon-button {
height: 46px;
width: 46px;
}
}
/**
* Modifiers
*/
.outline {
--button-color: var(--color-primary);
--button-background-color: transparent;
--button-disabled-background-color: transparent;
--button-active-background-color: transparent;
&.primary {
--button-color: var(--color-primary);
--button-border-color: var(--color-primary);
--button-active-background-color: var(--color-primary);
}
&.tertiary {
--button-color: var(--color-text-dark);
}
&.success {
--button-color: var(--color-success);
--button-border-color: var(--color-success);
--button-active-background-color: var(--color-success);
}
&.warning {
--button-color: var(--color-warning);
--button-border-color: var(--color-warning);
--button-active-background-color: var(--color-warning);
}
&.danger {
--button-color: var(--color-danger);
--button-border-color: var(--color-danger);
--button-active-background-color: var(--color-danger);
}
}
.text {
--button-color: var(--color-text-light);
--button-border-color: transparent;
--button-background-color: transparent;
--button-active-color: var(--color-text-light);
--button-active-background-color: transparent;
--button-active-border-color: transparent;
--button-hover-color: var(--color-text-light);
--button-hover-background-color: transparent;
--button-hover-border-color: transparent;
&.primary {
--button-color: var(--color-primary);
--button-active-color: var(--color-primary);
--button-hover-color: var(--color-primary);
}
&.secondary {
--button-color: var(--color-primary-tint-1);
--button-active-color: var(--color-primary-tint-1);
--button-hover-color: var(--color-primary-tint-1);
}
&.success {
--button-color: var(--color-success);
--button-active-color: var(--color-success);
--button-hover-color: var(--color-success);
}
&.warning {
--button-color: var(--color-warning);
--button-active-color: var(--color-warning);
--button-hover-color: var(--color-warning);
}
&.danger {
--button-color: var(--color-danger);
--button-active-color: var(--color-danger);
--button-hover-color: var(--color-danger);
}
&:hover {
text-decoration: underline;
}
}
.loading,
.active {
position: relative;
pointer-events: none;
&:before {
pointer-events: none;
content: '';
position: absolute;
left: -1px;
top: -1px;
right: -1px;
bottom: -1px;
border-radius: inherit;
background-color: $loading-overlay-background-color;
}
}
.disabled {
&,
&:hover,
&:active,
&:focus {
cursor: not-allowed;
background-image: none;
color: $button-disabled-font-color;
background-color: $button-disabled-background-color;
border-color: $button-disabled-border-color;
}
}
.transparent {
@@ -323,4 +432,16 @@ $color-danger-shade: lightness(
display: block;
}
}
.block {
width: 100%;
}
.float-left {
float: left;
}
.float-right {
float: right;
}
</style>