mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-23 11:44:06 -08:00
✨ Implement design system (#2050)
* split up main, sass imports, import new nds
* migrate most buttons
* update sizes based on feedback
* update copy buttons
* update executions list
* fix issues
* force message box buttons
* update warning color
* update more buttons
* wrap message box buttons
* update last component
* lint fixes
* add build report step
* breakout imports
* set package.json
* fix notification bug
* clean up imports
* use build directories directly
* update imports
* remove xl size
* update number inputs
* fix input width
* update line height, fix icon bug
* fix up editor
* fix spacing between buttons
* Reset line height
* revert changes to this
* revert changes
* clean up button sizes
* change to outline
* update select height
* update tooltip
* remove build report step
* clean up impl
* remove regenerator runtime
* add design system repo
* apply editorconfig
* apply editor config prettier
* lint issue
* switch to tabs
* switch to single space
* update eslintrc
* remove git modules
* update sass package
* support dart sass
* add build
* update dependency
* update contributing.md
* set repo
* update versions
* add tslint step
* update spacing to spaces, add dev step
* add test step
* add test step
* update browser lint rc
* remove .github
* delete .gitignore
* set comment for icons
* remove preview link
* update button interface
* update types
* set types
* clean up intro
* update intro
* remove assets
* move into preview
* remove headline comment
* reduce theme build
* loading executions
* match deps versions
* match deps versions
* fix lint issues
* fix lint issues
* update callback
* disable codacy for docs.css
* fix storybook issues
* add design system to docker image
* update spacing around delete sort button
* set line height to stop juggling headline
* update sizes
* clean up vars
* fix scss issues
* update button vars
* add shade color
* fix button without click
* fix buttons bug
* fix bug with executions list
* clean up theme
* update link styling
* fix typo
* run prettier
* 🎨 code format
* 🎨 code format
* 🔥 remove empty files
* ✨ N8n 2284 new inputs (#2075)
* implement inputs
* prettier fixes
* revert unnessary change
* move input components and tooltip
* remove form elements
* move select
* update input placements
* update sizes
* update credentails
* clean up select size
* fix caret issue
* update inputs
* clean up select
* fix tags dropdown border
* clean up tags input
* fix workflow name bug
* clean up select here
* add sizes template
* fix option caret
* fix input sizes
* update date input size
* remove tags input override
* update prop
* update input size
* center run data inputs
* update disabled colors
* update execution header
* update scrollbar
* update text area spacing
* fix items in header
* update run data tooltip
* remove popover
* update prefix positions
* add filterable demo
* address design issues
* fix input issues, flip boolean input to text
* update input sufffix colors
* remove override
* speed up switch, fix toggle spacing issue
* update icon
* remove icon classes
* clean up inputs
* clean up inputs with icons
* update input spacing again
* update suffix position
* build
* Add support for xlarge inputs
* fix input issues
* fix input issue
* update listeners
* update number inputs for settings
* update append/prepend spacing
* clean up inputs, set expression input as text
* fix type errors
* fix workflow number input
* fix tags dropdown bug
* fix bugs
* fix menu item bug
* remove font weight from link element
* remove default
* fix select option
* fix contrast issues
* allow overflow x for multi selects
* fix icon
* update options select
* fix issue that resolves expression to null
* update how actions are centered
* fix up selects
* update selects to support limiting size
* update option styles
* ⚡ Apply suggestions BHesseldieck
Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
* 🎨 code format
Co-authored-by: Jan <janober@users.noreply.github.com>
Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com>
* ⏪ Revert "🔥 remove empty files"
This reverts commit e91ace4e52
.
* ⚡ Remove private from n8n-design-system package
* 🎨 Change to spaces to stay consistent with editorconfig & others
package files
* ⚡ Fix year in license
Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com>
Co-authored-by: Jan <janober@users.noreply.github.com>
Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
parent
8dd0d547a2
commit
5bd8f7c93e
|
@ -37,6 +37,7 @@ The most important directories:
|
|||
- [/packages/core](/packages/core) - Core code which handles workflow
|
||||
execution, active webhooks and
|
||||
workflows
|
||||
- [/packages/design-system](/packages/design-system) - Vue frontend components
|
||||
- [/packages/editor-ui](/packages/editor-ui) - Vue frontend workflow editor
|
||||
- [/packages/node-dev](/packages/node-dev) - CLI to create new n8n-nodes
|
||||
- [/packages/nodes-base](/packages/nodes-base) - Base n8n nodes
|
||||
|
|
|
@ -14,6 +14,7 @@ COPY lerna.json .
|
|||
COPY package.json .
|
||||
COPY packages/cli/ ./packages/cli/
|
||||
COPY packages/core/ ./packages/core/
|
||||
COPY packages/design-system/ ./packages/design-system/
|
||||
COPY packages/editor-ui/ ./packages/editor-ui/
|
||||
COPY packages/nodes-base/ ./packages/nodes-base/
|
||||
COPY packages/workflow/ ./packages/workflow/
|
||||
|
|
3
packages/design-system/.browserslistrc
Normal file
3
packages/design-system/.browserslistrc
Normal file
|
@ -0,0 +1,3 @@
|
|||
> 1%
|
||||
last 2 versions
|
||||
not ie <= 8
|
15
packages/design-system/.editorconfig
Normal file
15
packages/design-system/.editorconfig
Normal file
|
@ -0,0 +1,15 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = tab
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[package.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.ts]
|
||||
quote_type = single
|
19
packages/design-system/.eslintrc.js
Normal file
19
packages/design-system/.eslintrc.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
extends: ['plugin:vue/essential', '@vue/typescript'],
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
semi: [2, 'always'],
|
||||
indent: ['error', 'tab'],
|
||||
'comma-dangle': ['error', 'always-multiline'],
|
||||
'no-tabs': 0,
|
||||
'no-labels': 0,
|
||||
},
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser',
|
||||
},
|
||||
};
|
26
packages/design-system/.npmignore
Normal file
26
packages/design-system/.npmignore
Normal file
|
@ -0,0 +1,26 @@
|
|||
.DS_Store
|
||||
storybook-static
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.md
|
||||
*.stories.js
|
||||
*.mdx
|
169
packages/design-system/.storybook/font-awesome-icons.js
Normal file
169
packages/design-system/.storybook/font-awesome-icons.js
Normal file
|
@ -0,0 +1,169 @@
|
|||
/**
|
||||
* These icons are only defined for storybook build
|
||||
* Editor icons are defined seperately
|
||||
*/
|
||||
import { library } from '@fortawesome/fontawesome-svg-core';
|
||||
import {
|
||||
faAngleDoubleLeft,
|
||||
faAngleDown,
|
||||
faAngleRight,
|
||||
faAngleUp,
|
||||
faArrowLeft,
|
||||
faArrowRight,
|
||||
faAt,
|
||||
faBook,
|
||||
faBug,
|
||||
faCalendar,
|
||||
faCheck,
|
||||
faChevronDown,
|
||||
faChevronUp,
|
||||
faCode,
|
||||
faCodeBranch,
|
||||
faCog,
|
||||
faCogs,
|
||||
faClone,
|
||||
faCloud,
|
||||
faCloudDownloadAlt,
|
||||
faCopy,
|
||||
faCut,
|
||||
faDotCircle,
|
||||
faEdit,
|
||||
faEnvelope,
|
||||
faEye,
|
||||
faExclamationTriangle,
|
||||
faExpand,
|
||||
faExternalLinkAlt,
|
||||
faExchangeAlt,
|
||||
faFile,
|
||||
faFileArchive,
|
||||
faFileCode,
|
||||
faFileDownload,
|
||||
faFileExport,
|
||||
faFileImport,
|
||||
faFilePdf,
|
||||
faFolderOpen,
|
||||
faGift,
|
||||
faHdd,
|
||||
faHome,
|
||||
faHourglass,
|
||||
faImage,
|
||||
faInbox,
|
||||
faInfo,
|
||||
faInfoCircle,
|
||||
faKey,
|
||||
faMapSigns,
|
||||
faNetworkWired,
|
||||
faPause,
|
||||
faPen,
|
||||
faPlay,
|
||||
faPlayCircle,
|
||||
faPlus,
|
||||
faPlusCircle,
|
||||
faQuestion,
|
||||
faQuestionCircle,
|
||||
faRedo,
|
||||
faRss,
|
||||
faSave,
|
||||
faSearch,
|
||||
faSearchMinus,
|
||||
faSearchPlus,
|
||||
faServer,
|
||||
faSignInAlt,
|
||||
faSlidersH,
|
||||
faSpinner,
|
||||
faStop,
|
||||
faSun,
|
||||
faSync,
|
||||
faSyncAlt,
|
||||
faTable,
|
||||
faTasks,
|
||||
faTerminal,
|
||||
faThLarge,
|
||||
faTimes,
|
||||
faTrash,
|
||||
faUndo,
|
||||
faUsers,
|
||||
faClock,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||
|
||||
library.add(faAngleDoubleLeft);
|
||||
library.add(faAngleDown);
|
||||
library.add(faAngleRight);
|
||||
library.add(faAngleUp);
|
||||
library.add(faArrowLeft);
|
||||
library.add(faArrowRight);
|
||||
library.add(faAt);
|
||||
library.add(faBook);
|
||||
library.add(faBug);
|
||||
library.add(faCalendar);
|
||||
library.add(faCheck);
|
||||
library.add(faChevronDown);
|
||||
library.add(faChevronUp);
|
||||
library.add(faCode);
|
||||
library.add(faCodeBranch);
|
||||
library.add(faCog);
|
||||
library.add(faCogs);
|
||||
library.add(faClone);
|
||||
library.add(faCloud);
|
||||
library.add(faCloudDownloadAlt);
|
||||
library.add(faCopy);
|
||||
library.add(faCut);
|
||||
library.add(faDotCircle);
|
||||
library.add(faEdit);
|
||||
library.add(faEnvelope);
|
||||
library.add(faEye);
|
||||
library.add(faExclamationTriangle);
|
||||
library.add(faExpand);
|
||||
library.add(faExternalLinkAlt);
|
||||
library.add(faExchangeAlt);
|
||||
library.add(faFile);
|
||||
library.add(faFileArchive);
|
||||
library.add(faFileCode);
|
||||
library.add(faFileDownload);
|
||||
library.add(faFileExport);
|
||||
library.add(faFileImport);
|
||||
library.add(faFilePdf);
|
||||
library.add(faFolderOpen);
|
||||
library.add(faGift);
|
||||
library.add(faHdd);
|
||||
library.add(faHome);
|
||||
library.add(faHourglass);
|
||||
library.add(faImage);
|
||||
library.add(faInbox);
|
||||
library.add(faInfo);
|
||||
library.add(faInfoCircle);
|
||||
library.add(faKey);
|
||||
library.add(faMapSigns);
|
||||
library.add(faNetworkWired);
|
||||
library.add(faPause);
|
||||
library.add(faPen);
|
||||
library.add(faPlay);
|
||||
library.add(faPlayCircle);
|
||||
library.add(faPlus);
|
||||
library.add(faPlusCircle);
|
||||
library.add(faQuestion);
|
||||
library.add(faQuestionCircle);
|
||||
library.add(faRedo);
|
||||
library.add(faRss);
|
||||
library.add(faSave);
|
||||
library.add(faSearch);
|
||||
library.add(faSearchMinus);
|
||||
library.add(faSearchPlus);
|
||||
library.add(faServer);
|
||||
library.add(faSignInAlt);
|
||||
library.add(faSlidersH);
|
||||
library.add(faSpinner);
|
||||
library.add(faStop);
|
||||
library.add(faSun);
|
||||
library.add(faSync);
|
||||
library.add(faSyncAlt);
|
||||
library.add(faTable);
|
||||
library.add(faTasks);
|
||||
library.add(faTerminal);
|
||||
library.add(faThLarge);
|
||||
library.add(faTimes);
|
||||
library.add(faTrash);
|
||||
library.add(faUndo);
|
||||
library.add(faUsers);
|
||||
library.add(faClock);
|
1
packages/design-system/.storybook/fonts.scss
Normal file
1
packages/design-system/.storybook/fonts.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');
|
38
packages/design-system/.storybook/main.js
Normal file
38
packages/design-system/.storybook/main.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
|
||||
addons: [
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'storybook-addon-designs',
|
||||
'storybook-addon-themes',
|
||||
],
|
||||
webpackFinal: async (config, { configType }) => {
|
||||
config.module.rules.push({
|
||||
test: /\.scss$/,
|
||||
oneOf: [
|
||||
{
|
||||
resourceQuery: /module/,
|
||||
use: [
|
||||
'vue-style-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
modules: true,
|
||||
},
|
||||
},
|
||||
'sass-loader',
|
||||
],
|
||||
include: path.resolve(__dirname, '../'),
|
||||
},
|
||||
{
|
||||
use: ['vue-style-loader', 'css-loader', 'sass-loader'],
|
||||
include: path.resolve(__dirname, '../'),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return config;
|
||||
},
|
||||
};
|
65
packages/design-system/.storybook/preview.js
Normal file
65
packages/design-system/.storybook/preview.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
import './font-awesome-icons';
|
||||
import './storybook.scss';
|
||||
|
||||
import lang from 'element-ui/lib/locale/lang/en';
|
||||
import locale from 'element-ui/lib/locale';
|
||||
|
||||
import Vue from 'vue';
|
||||
|
||||
locale.use(lang);
|
||||
|
||||
// https://github.com/storybookjs/storybook/issues/6153
|
||||
Vue.prototype.toJSON = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
export const parameters = {
|
||||
actions: {
|
||||
argTypesRegex: '^on[A-Z].*',
|
||||
},
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/,
|
||||
},
|
||||
},
|
||||
backgrounds: {
|
||||
default: '--color-background-xlight',
|
||||
values: [
|
||||
{
|
||||
name: '--color-background-dark',
|
||||
value: 'var(--color-background-dark)',
|
||||
},
|
||||
{
|
||||
name: '--color-background-base',
|
||||
value: 'var(--color-background-base)',
|
||||
},
|
||||
{
|
||||
name: '--color-background-light',
|
||||
value: 'var(--color-background-light)',
|
||||
},
|
||||
{
|
||||
name: '--color-background-lighter',
|
||||
value: 'var(--color-background-lighter)',
|
||||
},
|
||||
{
|
||||
name: '--color-background-xlight',
|
||||
value: 'var(--color-background-xlight)',
|
||||
},
|
||||
],
|
||||
},
|
||||
themes: {
|
||||
list: [
|
||||
{
|
||||
name: 'dark',
|
||||
class: 'theme-dark',
|
||||
color: '#000',
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
storySort: {
|
||||
order: ['Docs', 'Styleguide', 'Atoms'],
|
||||
},
|
||||
},
|
||||
};
|
12
packages/design-system/.storybook/storybook.scss
Normal file
12
packages/design-system/.storybook/storybook.scss
Normal file
|
@ -0,0 +1,12 @@
|
|||
@use "./fonts.scss";
|
||||
|
||||
@use "~/theme/src/base.scss" with (
|
||||
$font-path: '~element-ui/lib/theme-chalk/fonts',
|
||||
);
|
||||
|
||||
@use "~/theme/src/reset.scss";
|
||||
@use "~/theme/src/index.scss";
|
||||
|
||||
.multi-container > * {
|
||||
margin-bottom: 10px;
|
||||
}
|
228
packages/design-system/LICENSE.md
Normal file
228
packages/design-system/LICENSE.md
Normal file
|
@ -0,0 +1,228 @@
|
|||
“Commons Clause” License Condition v1.0
|
||||
|
||||
The Software is provided to you by the Licensor under the
|
||||
License, as defined below, subject to the following condition.
|
||||
|
||||
Without limiting other conditions in the License, the grant
|
||||
of rights under the License will not include, and the License
|
||||
does not grant to you, the right to Sell the Software.
|
||||
|
||||
For purposes of the foregoing, “Sell” means practicing any or
|
||||
all of the rights granted to you under the License to provide
|
||||
to third parties, for a fee or other consideration (including
|
||||
without limitation fees for hosting or consulting/ support
|
||||
services related to the Software), a product or service whose
|
||||
value derives, entirely or substantially, from the functionality
|
||||
of the Software. Any license notice or attribution required by
|
||||
the License must also include this Commons Clause License
|
||||
Condition notice.
|
||||
|
||||
Software: n8n
|
||||
|
||||
License: Apache 2.0 with Commons Clause
|
||||
|
||||
Licensor: n8n GmbH
|
||||
|
||||
---
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2021 n8n GmbH
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
45
packages/design-system/README.md
Normal file
45
packages/design-system/README.md
Normal file
|
@ -0,0 +1,45 @@
|
|||
# n8n-design-system
|
||||
|
||||
A component system for [n8n](https://n8n.io) using Storybook to preview.
|
||||
|
||||
## Project setup
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
|
||||
```
|
||||
npm run storybook
|
||||
```
|
||||
|
||||
### Build static pages
|
||||
|
||||
```
|
||||
npm run build:storybook
|
||||
```
|
||||
|
||||
### Run your unit tests
|
||||
|
||||
```
|
||||
npm run test:unit
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Build css files
|
||||
|
||||
```
|
||||
npm run build:theme
|
||||
```
|
||||
|
||||
### Monitor theme files and build any changes
|
||||
|
||||
```
|
||||
npm run watch:theme
|
||||
```
|
6
packages/design-system/babel.config.js
Normal file
6
packages/design-system/babel.config.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
presets: ['@vue/cli-plugin-babel/preset'],
|
||||
plugins: [
|
||||
['@babel/plugin-proposal-private-property-in-object', { loose: true }],
|
||||
],
|
||||
};
|
36
packages/design-system/gulpfile.js
Normal file
36
packages/design-system/gulpfile.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
'use strict';
|
||||
|
||||
const gulp = require('gulp');
|
||||
const sass = require('gulp-dart-sass');
|
||||
const autoprefixer = require('gulp-autoprefixer');
|
||||
const cleanCSS = require('gulp-clean-css');
|
||||
|
||||
gulp.task('build:theme', gulp.series([compileTheme, copyThemeFonts]));
|
||||
|
||||
gulp.task(
|
||||
'watch:theme',
|
||||
gulp.series([
|
||||
'build:theme',
|
||||
() => {
|
||||
gulp.watch('./theme/src/**/*.scss', gulp.series(['build:theme']));
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
function compileTheme() {
|
||||
return gulp
|
||||
.src('./theme/src/index.scss')
|
||||
.pipe(sass.sync())
|
||||
.pipe(
|
||||
autoprefixer({
|
||||
browsers: ['ie > 9', 'last 2 versions'],
|
||||
cascade: false,
|
||||
}),
|
||||
)
|
||||
.pipe(cleanCSS())
|
||||
.pipe(gulp.dest('./theme/dist'));
|
||||
}
|
||||
|
||||
function copyThemeFonts() {
|
||||
return gulp.src('./theme/src/fonts/**').pipe(gulp.dest('./theme/dist/fonts'));
|
||||
}
|
3
packages/design-system/jest.config.js
Normal file
3
packages/design-system/jest.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
|
||||
};
|
81
packages/design-system/package.json
Normal file
81
packages/design-system/package.json
Normal file
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"name": "n8n-design-system",
|
||||
"version": "0.1.0",
|
||||
"license": "SEE LICENSE IN LICENSE.md",
|
||||
"homepage": "https://n8n.io",
|
||||
"author": {
|
||||
"name": "Mutasem Aldmour",
|
||||
"email": "mutasem@n8n.io"
|
||||
},
|
||||
"main": "src/main.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/n8n-io/n8n.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run build:theme",
|
||||
"build:vue": "vue-cli-service build --target lib ./src/main.js --report",
|
||||
"dev": "npm run watch:theme",
|
||||
"test": "npm run test:unit",
|
||||
"build:storybook": "build-storybook",
|
||||
"storybook": "start-storybook -p 6006",
|
||||
"test:unit": "vue-cli-service test:unit --passWithNoTests",
|
||||
"lint": "vue-cli-service lint",
|
||||
"build:theme": "gulp build:theme",
|
||||
"watch:theme": "gulp watch:theme",
|
||||
"tslint": "tslint -p tsconfig.json -c tslint.json",
|
||||
"tslintfix": "tslint --fix -p tsconfig.json -c tslint.json"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "1.x",
|
||||
"@fortawesome/free-solid-svg-icons": "5.x",
|
||||
"@fortawesome/vue-fontawesome": "2.x",
|
||||
"core-js": "3.x",
|
||||
"element-ui": "2.13.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.3",
|
||||
"@fortawesome/vue-fontawesome": "^2.0.2",
|
||||
"core-js": "^3.6.5",
|
||||
"element-ui": "~2.13.0",
|
||||
"storybook-addon-themes": "^6.1.0",
|
||||
"vue": "^2.6.11",
|
||||
"vue-class-component": "^7.2.3",
|
||||
"vue-property-decorator": "^9.1.2",
|
||||
"@babel/core": "^7.14.6",
|
||||
"@storybook/addon-actions": "^6.3.6",
|
||||
"@storybook/addon-essentials": "^6.3.6",
|
||||
"@storybook/addon-links": "^6.3.6",
|
||||
"@storybook/vue": "^6.3.6",
|
||||
"@types/jest": "^26.0.13",
|
||||
"@typescript-eslint/eslint-plugin": "^4.18.0",
|
||||
"@typescript-eslint/parser": "^4.18.0",
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-plugin-typescript": "~4.5.0",
|
||||
"@vue/cli-plugin-unit-jest": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"@vue/eslint-config-prettier": "^6.0.0",
|
||||
"@vue/eslint-config-typescript": "^7.0.0",
|
||||
"@vue/test-utils": "^1.0.3",
|
||||
"babel-loader": "^8.2.2",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"fibers": "^5.0.0",
|
||||
"gulp": "^4.0.0",
|
||||
"prettier": "^2.2.1",
|
||||
"sass": "^1.26.5",
|
||||
"sass-loader": "^8.0.2",
|
||||
"storybook-addon-designs": "^6.0.1",
|
||||
"typescript": "~3.9.7",
|
||||
"vue-loader": "^15.9.7",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"gulp-autoprefixer": "^4.0.0",
|
||||
"gulp-clean-css": "^4.3.0",
|
||||
"gulp-dart-sass": "^1.0.2",
|
||||
"node-notifier": ">=8.0.1",
|
||||
"trim": ">=0.0.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
import N8nButton from './Button.vue';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
export default {
|
||||
title: 'Atoms/Button',
|
||||
component: N8nButton,
|
||||
argTypes: {
|
||||
label: {
|
||||
control: 'text',
|
||||
},
|
||||
title: {
|
||||
control: 'text',
|
||||
},
|
||||
type: {
|
||||
control: 'select',
|
||||
options: ['primary', 'outline', 'light', 'text'],
|
||||
},
|
||||
size: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['small', 'medium', 'large'],
|
||||
},
|
||||
},
|
||||
loading: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
control: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
iconSize: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['small', 'medium', 'large'],
|
||||
},
|
||||
},
|
||||
circle: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
fullWidth: {
|
||||
type: 'boolean',
|
||||
},
|
||||
theme: {
|
||||
type: 'select',
|
||||
options: ['success', 'danger', 'warning'],
|
||||
},
|
||||
float: {
|
||||
type: 'select',
|
||||
options: ['left', 'right'],
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
design: {
|
||||
type: 'figma',
|
||||
url: 'https://www.figma.com/file/DxLbnIyMK8X0uLkUguFV4n/n8n-design-system_v1?node-id=5%3A1147',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const methods = {
|
||||
onClick: action('click'),
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nButton,
|
||||
},
|
||||
template: '<n8n-button v-bind="$props" @click="onClick" />',
|
||||
methods,
|
||||
});
|
||||
|
||||
export const Button = Template.bind({});
|
||||
Button.args = {
|
||||
label: 'Button',
|
||||
};
|
||||
|
||||
const ManyTemplate = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nButton,
|
||||
},
|
||||
template:
|
||||
'<div> <n8n-button v-bind="$props" size="large" @click="onClick" /> <n8n-button v-bind="$props" size="medium" @click="onClick" /> <n8n-button v-bind="$props" size="small" @click="onClick" /> <n8n-button v-bind="$props" :loading="true" @click="onClick" /> <n8n-button v-bind="$props" :disabled="true" @click="onClick" /></div>',
|
||||
methods,
|
||||
});
|
||||
|
||||
export const Primary = ManyTemplate.bind({});
|
||||
Primary.args = {
|
||||
type: 'primary',
|
||||
label: 'Button',
|
||||
};
|
||||
|
||||
export const Outline = ManyTemplate.bind({});
|
||||
Outline.args = {
|
||||
type: 'outline',
|
||||
label: 'Button',
|
||||
};
|
||||
|
||||
export const Light = ManyTemplate.bind({});
|
||||
Light.args = {
|
||||
type: 'light',
|
||||
label: 'Button',
|
||||
};
|
||||
|
||||
export const WithIcon = ManyTemplate.bind({});
|
||||
WithIcon.args = {
|
||||
label: 'Button',
|
||||
icon: 'plus-circle',
|
||||
};
|
||||
|
||||
export const Text = ManyTemplate.bind({});
|
||||
Text.args = {
|
||||
type: 'text',
|
||||
label: 'Button',
|
||||
icon: 'plus-circle',
|
||||
};
|
299
packages/design-system/src/components/N8nButton/Button.vue
Normal file
299
packages/design-system/src/components/N8nButton/Button.vue
Normal file
|
@ -0,0 +1,299 @@
|
|||
<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="$style[$options.getClass(props)]"
|
||||
:round="!props.circle && props.round"
|
||||
:circle="props.circle"
|
||||
:style="$options.styles(props)"
|
||||
@click="(e) => listeners.click && listeners.click(e)"
|
||||
>
|
||||
<span :class="$style.icon" v-if="props.loading || props.icon">
|
||||
<component
|
||||
:is="$options.components.N8nSpinner"
|
||||
v-if="props.loading"
|
||||
:size="props.iconSize"
|
||||
/>
|
||||
<component
|
||||
:is="$options.components.N8nIcon"
|
||||
v-else-if="props.icon"
|
||||
:icon="props.icon"
|
||||
:size="props.iconSize"
|
||||
/>
|
||||
</span>
|
||||
<span v-if="props.label">{{ props.label }}</span>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import N8nIcon from '../N8nIcon';
|
||||
import N8nSpinner from '../N8nSpinner';
|
||||
import ElButton from 'element-ui/lib/button';
|
||||
|
||||
export default {
|
||||
name: 'n8n-button',
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'primary',
|
||||
validator: (value: string): boolean =>
|
||||
['primary', 'outline', 'light', 'text'].indexOf(value) !== -1,
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
validator: (value: string): boolean =>
|
||||
['success', 'warning', 'danger'].indexOf(value) !== -1,
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium',
|
||||
validator: (value: string): boolean =>
|
||||
['small', 'medium', 'large'].indexOf(value) !== -1,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
},
|
||||
iconSize: {
|
||||
type: String,
|
||||
},
|
||||
round: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
circle: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
float: {
|
||||
type: String,
|
||||
validator: (value: string): boolean =>
|
||||
['left', 'right'].indexOf(value) !== -1,
|
||||
},
|
||||
fullWidth: {
|
||||
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%' } : {}),
|
||||
};
|
||||
},
|
||||
getClass(props: { type: string; theme?: string }): string {
|
||||
return props.type === 'text'
|
||||
? 'text'
|
||||
: `${props.type}-${props.theme || 'primary'}`;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
@function lightness($h, $s, $l, $lightness) {
|
||||
@return hsl(var(#{$h}), var(#{$s}), calc(var(#{$l}) + #{$lightness}));
|
||||
}
|
||||
|
||||
.button {
|
||||
> i {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> span {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
span + span {
|
||||
margin-left: var(--spacing-3xs);
|
||||
}
|
||||
}
|
||||
|
||||
$active-shade-percent: 10%;
|
||||
$color-primary-shade: lightness(
|
||||
--color-primary-h,
|
||||
--color-primary-s,
|
||||
--color-primary-l,
|
||||
-($active-shade-percent)
|
||||
);
|
||||
|
||||
$color-success-shade: lightness(
|
||||
--color-success-h,
|
||||
--color-success-s,
|
||||
--color-success-l,
|
||||
-($active-shade-percent)
|
||||
);
|
||||
|
||||
$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;
|
||||
--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;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-flex;
|
||||
|
||||
svg {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
46
packages/design-system/src/components/N8nButton/index.d.ts
vendored
Normal file
46
packages/design-system/src/components/N8nButton/index.d.ts
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { N8nComponent, N8nComponentSize } from '../component';
|
||||
|
||||
/** Button type */
|
||||
export type ButtonType = 'primary' | 'outline' | 'light' | 'text';
|
||||
|
||||
/** Button themes */
|
||||
export type ButtonTheme = 'success' | 'warning' | 'danger';
|
||||
|
||||
/** Button Component */
|
||||
export declare class N8nButton extends N8nComponent {
|
||||
/** Button text */
|
||||
label: string;
|
||||
|
||||
/** Button title on hover */
|
||||
title: string;
|
||||
|
||||
/** Color scheme */
|
||||
theme: ButtonTheme;
|
||||
|
||||
/** Button size */
|
||||
size: N8nComponentSize;
|
||||
|
||||
/** Button type */
|
||||
type: ButtonType;
|
||||
|
||||
/** Determine whether it's a circular button */
|
||||
circle: boolean;
|
||||
|
||||
/** Determine whether it's loading */
|
||||
loading: boolean;
|
||||
|
||||
/** Disable the button */
|
||||
disabled: boolean;
|
||||
|
||||
/** Button icon, accepts an icon name of font awesome icon component */
|
||||
icon: string;
|
||||
|
||||
/** Size of icon */
|
||||
iconSize: N8nComponentSize;
|
||||
|
||||
/** Full width */
|
||||
fullWidth: boolean;
|
||||
|
||||
/** Float left or right */
|
||||
float: boolean;
|
||||
}
|
3
packages/design-system/src/components/N8nButton/index.js
Normal file
3
packages/design-system/src/components/N8nButton/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import N8nButton from './Button.vue';
|
||||
|
||||
export default N8nButton;
|
|
@ -0,0 +1,45 @@
|
|||
import N8nIcon from './Icon.vue';
|
||||
|
||||
export default {
|
||||
title: 'Atoms/Icon',
|
||||
component: N8nIcon,
|
||||
argTypes: {
|
||||
icon: {
|
||||
control: 'text',
|
||||
},
|
||||
size: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['small', 'medium', 'large'],
|
||||
},
|
||||
},
|
||||
spin: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nIcon,
|
||||
},
|
||||
template: '<n8n-icon v-bind="$props" />',
|
||||
});
|
||||
|
||||
export const Clock = Template.bind({});
|
||||
Clock.args = {
|
||||
icon: 'clock',
|
||||
};
|
||||
|
||||
export const Plus = Template.bind({});
|
||||
Plus.args = {
|
||||
icon: 'plus',
|
||||
};
|
||||
|
||||
export const Stop = Template.bind({});
|
||||
Stop.args = {
|
||||
icon: 'stop',
|
||||
};
|
56
packages/design-system/src/components/N8nIcon/Icon.vue
Normal file
56
packages/design-system/src/components/N8nIcon/Icon.vue
Normal file
|
@ -0,0 +1,56 @@
|
|||
<template functional>
|
||||
<component
|
||||
:is="$options.components.FontAwesomeIcon"
|
||||
:class="$style[`_${props.size}`]"
|
||||
:icon="props.icon"
|
||||
:spin="props.spin"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||
|
||||
export default {
|
||||
name: 'n8n-icon',
|
||||
components: {
|
||||
FontAwesomeIcon,
|
||||
},
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium',
|
||||
validator: function (value: string): boolean {
|
||||
return ['small', 'medium', 'large'].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
spin: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
._small {
|
||||
font-size: 0.85em;
|
||||
height: 0.85em;
|
||||
width: 0.85em !important;
|
||||
}
|
||||
|
||||
._medium {
|
||||
font-size: 0.95em;
|
||||
height: 0.95em;
|
||||
width: 0.95em !important;
|
||||
}
|
||||
|
||||
._large {
|
||||
font-size: 1.22em;
|
||||
height: 1.22em;
|
||||
width: 1.22em !important;
|
||||
}
|
||||
</style>
|
13
packages/design-system/src/components/N8nIcon/index.d.ts
vendored
Normal file
13
packages/design-system/src/components/N8nIcon/index.d.ts
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { N8nComponent, N8nComponentSize } from '../component';
|
||||
|
||||
/** Button Component */
|
||||
export declare class N8nIcon extends N8nComponent {
|
||||
/** icon name, accepts an icon name of font awesome icon component */
|
||||
icon: string;
|
||||
|
||||
/** Size of icon */
|
||||
size: N8nComponentSize;
|
||||
|
||||
/** Whether icon should be spinning */
|
||||
spin: boolean;
|
||||
}
|
3
packages/design-system/src/components/N8nIcon/index.js
Normal file
3
packages/design-system/src/components/N8nIcon/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import Icon from './Icon.vue';
|
||||
|
||||
export default Icon;
|
|
@ -0,0 +1,98 @@
|
|||
import N8nIconButton from './IconButton.vue';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
export default {
|
||||
title: 'Atoms/Icon Button',
|
||||
component: N8nIconButton,
|
||||
argTypes: {
|
||||
type: {
|
||||
control: 'select',
|
||||
options: ['primary', 'outline', 'light', 'text'],
|
||||
},
|
||||
title: {
|
||||
control: 'text',
|
||||
},
|
||||
size: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['small', 'medium', 'large', 'xlarge'],
|
||||
},
|
||||
},
|
||||
loading: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
control: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
theme: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['success', 'warning', 'danger'],
|
||||
},
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
backgrounds: { default: '--color-background-light' },
|
||||
},
|
||||
};
|
||||
|
||||
const methods = {
|
||||
onClick: action('click'),
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nIconButton,
|
||||
},
|
||||
template: '<n8n-icon-button v-bind="$props" @click="onClick" />',
|
||||
methods,
|
||||
});
|
||||
|
||||
export const Button = Template.bind({});
|
||||
Button.args = {
|
||||
icon: 'plus',
|
||||
title: 'my title',
|
||||
};
|
||||
|
||||
const ManyTemplate = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nIconButton,
|
||||
},
|
||||
template:
|
||||
'<div> <n8n-icon-button v-bind="$props" size="xlarge" @click="onClick" /> <n8n-icon-button v-bind="$props" size="large" @click="onClick" /> <n8n-icon-button v-bind="$props" size="medium" @click="onClick" /> <n8n-icon-button v-bind="$props" size="small" @click="onClick" /> <n8n-icon-button v-bind="$props" :loading="true" @click="onClick" /> <n8n-icon-button v-bind="$props" :disabled="true" @click="onClick" /></div>',
|
||||
methods,
|
||||
});
|
||||
|
||||
export const Primary = ManyTemplate.bind({});
|
||||
Primary.args = {
|
||||
icon: 'plus',
|
||||
title: 'my title',
|
||||
type: 'primary',
|
||||
};
|
||||
|
||||
export const Outline = ManyTemplate.bind({});
|
||||
Outline.args = {
|
||||
icon: 'plus',
|
||||
title: 'my title',
|
||||
type: 'outline',
|
||||
};
|
||||
|
||||
export const Light = ManyTemplate.bind({});
|
||||
Light.args = {
|
||||
icon: 'plus',
|
||||
title: 'my title',
|
||||
type: 'light',
|
||||
};
|
||||
|
||||
export const Text = ManyTemplate.bind({});
|
||||
Text.args = {
|
||||
icon: 'plus',
|
||||
title: 'my title',
|
||||
type: 'text',
|
||||
};
|
|
@ -0,0 +1,60 @@
|
|||
<template functional>
|
||||
<n8n-button
|
||||
:type="props.type"
|
||||
:disabled="props.disabled"
|
||||
:size="props.size === 'xlarge' ? 'large' : props.size"
|
||||
:loading="props.loading"
|
||||
:title="props.title"
|
||||
:icon="props.icon"
|
||||
:iconSize="$options.iconSizeMap[props.size] || props.size"
|
||||
:theme="props.theme"
|
||||
@click="(e) => listeners.click && listeners.click(e)"
|
||||
circle
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import N8nButton from '../N8nButton';
|
||||
|
||||
const iconSizeMap = {
|
||||
large: 'medium',
|
||||
xlarge: 'large',
|
||||
};
|
||||
|
||||
Vue.component('N8nButton', N8nButton);
|
||||
|
||||
export default {
|
||||
name: 'n8n-icon-button',
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium',
|
||||
validator: (value: string): boolean =>
|
||||
['small', 'medium', 'large', 'xlarge'].indexOf(value) !== -1,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
iconSizeMap,
|
||||
};
|
||||
</script>
|
29
packages/design-system/src/components/N8nIconButton/index.d.ts
vendored
Normal file
29
packages/design-system/src/components/N8nIconButton/index.d.ts
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { N8nComponent, N8nComponentSize } from '../component';
|
||||
import { ButtonTheme, ButtonType } from '../N8nButton';
|
||||
|
||||
/** Icon Button Component */
|
||||
export declare class N8nIconButton extends N8nComponent {
|
||||
/** Button type */
|
||||
type: ButtonType;
|
||||
|
||||
/** Button title on hover */
|
||||
title: string;
|
||||
|
||||
/** Button size */
|
||||
size: N8nComponentSize | 'xlarge';
|
||||
|
||||
/** icon size */
|
||||
iconSize: N8nComponentSize;
|
||||
|
||||
/** Determine whether it's loading */
|
||||
loading: boolean;
|
||||
|
||||
/** Disable the button */
|
||||
disabled: boolean;
|
||||
|
||||
/** Button icon, accepts an icon name of font awesome icon component */
|
||||
icon: string;
|
||||
|
||||
/** Button theme */
|
||||
theme: ButtonTheme;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
import IconButton from './IconButton.vue';
|
||||
|
||||
export default IconButton;
|
122
packages/design-system/src/components/N8nInput/Input.stories.js
Normal file
122
packages/design-system/src/components/N8nInput/Input.stories.js
Normal file
|
@ -0,0 +1,122 @@
|
|||
import N8nInput from './Input.vue';
|
||||
import N8nIcon from '../N8nIcon';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
export default {
|
||||
title: 'Atoms/Input',
|
||||
component: N8nInput,
|
||||
argTypes: {
|
||||
type: {
|
||||
control: 'select',
|
||||
options: ['text', 'textarea'],
|
||||
},
|
||||
placeholder: {
|
||||
control: 'text',
|
||||
},
|
||||
disabled: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['xlarge', 'large', 'medium', 'small', 'mini'],
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
backgrounds: { default: '--color-background-light' },
|
||||
},
|
||||
};
|
||||
|
||||
const methods = {
|
||||
onInput: action('input'),
|
||||
onFocus: action('input'),
|
||||
onChange: action('input'),
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nInput,
|
||||
},
|
||||
template: '<n8n-input v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" />',
|
||||
data() {
|
||||
return {
|
||||
val: '',
|
||||
};
|
||||
},
|
||||
methods,
|
||||
});
|
||||
|
||||
export const Input = Template.bind({});
|
||||
Input.args = {
|
||||
placeholder: 'placeholder...',
|
||||
};
|
||||
|
||||
const ManyTemplate = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nInput,
|
||||
},
|
||||
template:
|
||||
'<div class="multi-container"> <n8n-input size="xlarge" v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="$props" size="medium" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="$props" size="small" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="$props" v-model="val" size="mini" @input="onInput" @change="onChange" @focus="onFocus" /> </div> ',
|
||||
methods,
|
||||
data() {
|
||||
return {
|
||||
val: '',
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const Text = ManyTemplate.bind({});
|
||||
Text.args = {
|
||||
type: 'text',
|
||||
placeholder: 'placeholder...',
|
||||
};
|
||||
|
||||
export const TextArea = ManyTemplate.bind({});
|
||||
TextArea.args = {
|
||||
type: 'textarea',
|
||||
placeholder: 'placeholder...',
|
||||
};
|
||||
|
||||
|
||||
const WithPrefix = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nIcon,
|
||||
N8nInput,
|
||||
},
|
||||
template: '<n8n-input v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus"><n8n-icon icon="clock" slot="prefix" /></n8n-input>',
|
||||
data() {
|
||||
return {
|
||||
val: '',
|
||||
};
|
||||
},
|
||||
methods,
|
||||
});
|
||||
|
||||
export const WithPrefixIcon = WithPrefix.bind({});
|
||||
WithPrefixIcon.args = {
|
||||
placeholder: 'placeholder...',
|
||||
};
|
||||
|
||||
const WithSuffix = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nIcon,
|
||||
N8nInput,
|
||||
},
|
||||
template: '<n8n-input v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus"><n8n-icon icon="clock" slot="suffix" /></n8n-input>',
|
||||
data() {
|
||||
return {
|
||||
val: '',
|
||||
};
|
||||
},
|
||||
methods,
|
||||
});
|
||||
|
||||
export const WithSuffixIcon = WithSuffix.bind({});
|
||||
WithSuffixIcon.args = {
|
||||
placeholder: 'placeholder...',
|
||||
};
|
92
packages/design-system/src/components/N8nInput/Input.vue
Normal file
92
packages/design-system/src/components/N8nInput/Input.vue
Normal file
|
@ -0,0 +1,92 @@
|
|||
<template functional>
|
||||
<component
|
||||
:is="$options.components.ElInput"
|
||||
v-bind="props"
|
||||
:size="$options.methods.getSize(props.size)"
|
||||
:class="$style[$options.methods.getClass(props)]"
|
||||
:ref="data.ref"
|
||||
v-on="listeners"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<slot name="prepend" />
|
||||
</template>
|
||||
<template v-slot:append>
|
||||
<slot name="append" />
|
||||
</template>
|
||||
<template v-slot:prefix>
|
||||
<slot name="prefix" />
|
||||
</template>
|
||||
<template v-slot:suffix>
|
||||
<slot name="suffix" />
|
||||
</template>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import ElInput from 'element-ui/lib/input';
|
||||
|
||||
export default {
|
||||
name: 'n8n-input',
|
||||
components: {
|
||||
ElInput,
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
validator: (value: string): boolean =>
|
||||
['text', 'textarea', 'number', 'password'].indexOf(value) !== -1,
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'large',
|
||||
validator: (value: string): boolean =>
|
||||
['mini', 'small', 'medium', 'large', 'xlarge'].indexOf(value) !== -1,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
},
|
||||
rows: {
|
||||
type: Number,
|
||||
},
|
||||
maxlength: {
|
||||
type: Number,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getSize(size: string): string | undefined {
|
||||
if (size === 'xlarge') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return size;
|
||||
},
|
||||
getClass(props: { size: string }): string {
|
||||
if (props.size === 'xlarge') {
|
||||
return 'xlarge';
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.xlarge {
|
||||
--input-font-size: var(--font-size-m);
|
||||
input {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
</style>
|
3
packages/design-system/src/components/N8nInput/index.js
Normal file
3
packages/design-system/src/components/N8nInput/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import N8nInput from './Input.vue';
|
||||
|
||||
export default N8nInput;
|
|
@ -0,0 +1,27 @@
|
|||
import N8nInputLabel from './InputLabel.vue';
|
||||
import N8nInput from '../N8nInput';
|
||||
|
||||
export default {
|
||||
title: 'Atoms/Input Label',
|
||||
component: N8nInputLabel,
|
||||
argTypes: {},
|
||||
parameters: {
|
||||
backgrounds: { default: '--color-background-light' },
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nInputLabel,
|
||||
N8nInput,
|
||||
},
|
||||
template:
|
||||
'<div style="margin-top:50px"><n8n-input-label v-bind="$props"><n8n-input /></n8n-input-label></div>',
|
||||
});
|
||||
|
||||
export const InputLabel = Template.bind({});
|
||||
InputLabel.args = {
|
||||
label: 'input label',
|
||||
tooltipText: 'more info...',
|
||||
};
|
|
@ -0,0 +1,57 @@
|
|||
<template functional>
|
||||
<div :class="$style.inputLabel">
|
||||
<label>
|
||||
<div :class="$style.label">
|
||||
<span>{{ props.label }}</span>
|
||||
<span v-if="props.tooltipText" :class="$style.infoIcon">
|
||||
<n8n-tooltip :content="props.tooltipText" placement="top">
|
||||
<n8n-icon icon="info-circle" />
|
||||
</n8n-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
import N8nTooltip from '../N8nTooltip';
|
||||
import N8nIcon from '../N8nIcon';
|
||||
|
||||
Vue.component('N8nIcon', N8nIcon);
|
||||
Vue.component('N8nTooltip', N8nTooltip);
|
||||
|
||||
export default {
|
||||
name: 'n8n-input-label',
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
tooltipText: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.inputLabel {
|
||||
&:hover {
|
||||
--info-icon-display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: var(--font-weight-bold);
|
||||
font-size: var(--font-size-s);
|
||||
margin-bottom: var(--spacing-2xs);
|
||||
}
|
||||
|
||||
.infoIcon {
|
||||
color: var(--color-text-light);
|
||||
display: var(--info-icon-display, none);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,3 @@
|
|||
import N8nInputLabel from './InputLabel.vue';
|
||||
|
||||
export default N8nInputLabel;
|
|
@ -0,0 +1,94 @@
|
|||
import N8nInputNumber from './InputNumber.vue';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
export default {
|
||||
title: 'Atoms/Input Number',
|
||||
component: N8nInputNumber,
|
||||
argTypes: {
|
||||
placeholder: {
|
||||
control: 'text',
|
||||
},
|
||||
disabled: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
controls: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
precision: {
|
||||
control: {
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
min: {
|
||||
control: {
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
max: {
|
||||
control: {
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
step: {
|
||||
control: {
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
title: {
|
||||
control: 'text',
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
backgrounds: { default: '--color-background-light' },
|
||||
},
|
||||
};
|
||||
|
||||
const methods = {
|
||||
onInput: action('input'),
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nInputNumber,
|
||||
},
|
||||
template: '<n8n-input-number v-bind="$props" v-model="val" @input="onInput" />',
|
||||
data() {
|
||||
return {
|
||||
val: null,
|
||||
};
|
||||
},
|
||||
methods,
|
||||
});
|
||||
|
||||
export const Input = Template.bind({});
|
||||
Input.args = {
|
||||
placeholder: 'placeholder...',
|
||||
controls: false,
|
||||
};
|
||||
|
||||
const ManyTemplate = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nInputNumber,
|
||||
},
|
||||
template:
|
||||
'<div> <n8n-input-number style="margin-bottom:10px" v-bind="$props" v-model="val" @input="onInput" /> <n8n-input-number style="margin-bottom:10px" v-bind="$props" size="medium" v-model="val" @input="onInput" /> <n8n-input-number style="margin-bottom:10px" v-bind="$props" size="small" v-model="val" @input="onInput" /> <n8n-input-number style="margin-bottom:10px" v-bind="$props" v-model="val" size="mini" @input="onInput" /> </div>',
|
||||
methods,
|
||||
data() {
|
||||
return {
|
||||
val: '',
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const Sizes = ManyTemplate.bind({});
|
||||
Sizes.args = {
|
||||
placeholder: 'placeholder...',
|
||||
controls: false,
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<script lang="ts">
|
||||
import N8nInputNumber from 'element-ui/lib/input-number';
|
||||
|
||||
N8nInputNumber.name = 'n8n-input-number';
|
||||
|
||||
export default N8nInputNumber;
|
||||
</script>
|
|
@ -0,0 +1,3 @@
|
|||
import N8nInputNumber from './InputNumber.vue';
|
||||
|
||||
export default N8nInputNumber;
|
|
@ -0,0 +1,7 @@
|
|||
<script lang="ts">
|
||||
import ElOption from 'element-ui/lib/option';
|
||||
|
||||
ElOption.name = 'n8n-option';
|
||||
|
||||
export default ElOption;
|
||||
</script>
|
3
packages/design-system/src/components/N8nOption/index.js
Normal file
3
packages/design-system/src/components/N8nOption/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import N8nOption from './Option.vue';
|
||||
|
||||
export default N8nOption;
|
|
@ -0,0 +1,138 @@
|
|||
import N8nSelect from './Select.vue';
|
||||
import N8nOption from '../N8nOption';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
export default {
|
||||
title: 'Atoms/Select',
|
||||
component: N8nSelect,
|
||||
argTypes: {
|
||||
disabled: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
size: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['large', 'medium', 'small', 'mini'],
|
||||
},
|
||||
},
|
||||
loading: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
filterable: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
defaultFirstOption: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
backgrounds: { default: '--color-background-light' },
|
||||
},
|
||||
};
|
||||
|
||||
const methods = {
|
||||
onInput: action('input'),
|
||||
onChange: action('change'),
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nSelect,
|
||||
N8nOption,
|
||||
},
|
||||
template: '<n8n-select v-bind="$props" v-model="val" @input="onInput" @change="onChange"><n8n-option value="1">op1</n8n-option><n8n-option value="2">op2</n8n-option></n8n-select>',
|
||||
data() {
|
||||
return {
|
||||
val: '',
|
||||
};
|
||||
},
|
||||
methods,
|
||||
});
|
||||
|
||||
export const Input = Template.bind({});
|
||||
|
||||
export const Filterable = Template.bind({});
|
||||
Filterable.args = {
|
||||
filterable: true,
|
||||
defaultFirstOption: true,
|
||||
};
|
||||
|
||||
const selects = ['large', 'medium', 'small', 'mini'].map((size) => `<n8n-select v-bind="$props" v-model="val" @input="onInput" @change="onChange" size="${size}"><n8n-option value="1">op1</n8n-option><n8n-option value="2">op2</n8n-option></n8n-select>`).join('');
|
||||
|
||||
const ManyTemplate = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nSelect,
|
||||
N8nOption,
|
||||
},
|
||||
template: `<div class="multi-container">${selects}</div>`,
|
||||
methods,
|
||||
data() {
|
||||
return {
|
||||
val: '',
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const Sizes = ManyTemplate.bind({});
|
||||
Sizes.args = {
|
||||
type: 'text',
|
||||
label: 'text input:',
|
||||
placeholder: 'placeholder...',
|
||||
};
|
||||
|
||||
const selectsWithIcon = ['xlarge', 'large', 'medium', 'small', 'mini'].map((size) => `<n8n-select v-bind="$props" v-model="val" @input="onInput" size="${size}"><n8n-icon icon="search" slot="prefix" /><n8n-option value="1">op1</n8n-option><n8n-option value="2">op2</n8n-option></n8n-select>`).join('');
|
||||
|
||||
const ManyTemplateWithIcon = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nSelect,
|
||||
N8nOption,
|
||||
},
|
||||
template: `<div class="multi-container">${selectsWithIcon}</div>`,
|
||||
methods,
|
||||
data() {
|
||||
return {
|
||||
val: '',
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const WithIcon = ManyTemplateWithIcon.bind({});
|
||||
WithIcon.args = {
|
||||
type: 'text',
|
||||
label: 'text input:',
|
||||
placeholder: 'placeholder...',
|
||||
};
|
||||
|
||||
|
||||
const LimitedWidthTemplate = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nSelect,
|
||||
N8nOption,
|
||||
},
|
||||
template: '<div style="width:100px;"><n8n-select v-bind="$props" v-model="val" @input="onInput" @change="onChange"><n8n-option value="1">op1</n8n-option><n8n-option value="2">op2 test very long ipsum lipsum test jskdfjsld kjfdslk jfdslkfj lksdjf</n8n-option></n8n-select></div>',
|
||||
data() {
|
||||
return {
|
||||
val: '',
|
||||
};
|
||||
},
|
||||
methods,
|
||||
});
|
||||
|
||||
export const LimitedWidth = LimitedWidthTemplate.bind({});
|
||||
LimitedWidth.args = {
|
||||
type: 'text',
|
||||
label: 'text input:',
|
||||
placeholder: 'placeholder...',
|
||||
};
|
124
packages/design-system/src/components/N8nSelect/Select.vue
Normal file
124
packages/design-system/src/components/N8nSelect/Select.vue
Normal file
|
@ -0,0 +1,124 @@
|
|||
<template functional>
|
||||
<component
|
||||
:is="$options.components.ElSelect"
|
||||
v-bind="props"
|
||||
:value="props.value"
|
||||
:size="$options.methods.getSize(props.size)"
|
||||
:class="$style[$options.methods.getClass(props)]"
|
||||
:popper-class="$options.methods.getPopperClass(props, $style)"
|
||||
v-on="listeners"
|
||||
:ref="data.ref"
|
||||
>
|
||||
<template v-slot:prefix>
|
||||
<slot name="prefix" />
|
||||
</template>
|
||||
<template v-slot:suffix>
|
||||
<slot name="suffix" />
|
||||
</template>
|
||||
<template v-slot:default>
|
||||
<slot></slot>
|
||||
</template>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import ElSelect from 'element-ui/lib/select';
|
||||
|
||||
interface IProps {
|
||||
size?: string;
|
||||
limitPopperWidth?: string;
|
||||
popperClass?: string;
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'n8n-select',
|
||||
components: {
|
||||
ElSelect,
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'large',
|
||||
validator: (value: string): boolean =>
|
||||
['mini', 'small', 'medium', 'large', 'xlarge'].indexOf(value) !== -1,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
},
|
||||
filterable: {
|
||||
type: Boolean,
|
||||
},
|
||||
defaultFirstOption: {
|
||||
type: Boolean,
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
},
|
||||
filterMethod: {
|
||||
type: Function,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
},
|
||||
loadingText: {
|
||||
type: String,
|
||||
},
|
||||
popperClass: {
|
||||
type: String,
|
||||
},
|
||||
popperAppendToBody: {
|
||||
type: Boolean,
|
||||
},
|
||||
limitPopperWidth: {
|
||||
type: Boolean,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getSize(size: string): string | undefined {
|
||||
if (size === 'xlarge') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return size;
|
||||
},
|
||||
getClass(props: IProps): string {
|
||||
if (props.size === 'xlarge') {
|
||||
return 'xlarge';
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
getPopperClass(props: IProps, $style: any): string {
|
||||
let classes = props.popperClass || '';
|
||||
if (props.limitPopperWidth) {
|
||||
classes = `${classes} ${$style.limitPopperWidth}`;
|
||||
}
|
||||
|
||||
return classes;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.xlarge {
|
||||
--input-font-size: var(--font-size-m);
|
||||
input {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.limitPopperWidth {
|
||||
width: 0;
|
||||
|
||||
li > span {
|
||||
text-overflow: ellipsis;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
3
packages/design-system/src/components/N8nSelect/index.js
Normal file
3
packages/design-system/src/components/N8nSelect/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import N8nSelect from './Select.vue';
|
||||
|
||||
export default N8nSelect;
|
|
@ -0,0 +1,24 @@
|
|||
import N8nSpinner from './Spinner.vue';
|
||||
|
||||
export default {
|
||||
title: 'Atoms/Spinner',
|
||||
component: N8nSpinner,
|
||||
argTypes: {
|
||||
size: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['small', 'medium', 'large'],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nSpinner,
|
||||
},
|
||||
template: '<n8n-spinner v-bind="$props" />',
|
||||
});
|
||||
|
||||
export const Spinner = Template.bind({});
|
27
packages/design-system/src/components/N8nSpinner/Spinner.vue
Normal file
27
packages/design-system/src/components/N8nSpinner/Spinner.vue
Normal file
|
@ -0,0 +1,27 @@
|
|||
<template functional>
|
||||
<component
|
||||
:is="$options.components.N8nIcon"
|
||||
icon="spinner"
|
||||
:size="props.size"
|
||||
spin
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import N8nIcon from '../N8nIcon';
|
||||
|
||||
export default {
|
||||
name: 'n8n-spinner',
|
||||
components: {
|
||||
N8nIcon,
|
||||
},
|
||||
props: {
|
||||
size: {
|
||||
type: String,
|
||||
validator: function (value: string): boolean {
|
||||
return ['small', 'medium', 'large'].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
7
packages/design-system/src/components/N8nSpinner/index.d.ts
vendored
Normal file
7
packages/design-system/src/components/N8nSpinner/index.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { N8nComponent, N8nComponentSize } from '../component';
|
||||
|
||||
/** Spinner Component */
|
||||
export declare class N8nSpinner extends N8nComponent {
|
||||
/** Icon size */
|
||||
size: N8nComponentSize;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
import Spinner from './Spinner.vue';
|
||||
|
||||
export default Spinner;
|
|
@ -0,0 +1,49 @@
|
|||
import N8nTooltip from './Tooltip.vue';
|
||||
|
||||
export default {
|
||||
title: 'Atoms/Tooltip',
|
||||
component: N8nTooltip,
|
||||
argTypes: {
|
||||
effect: {
|
||||
control: 'select',
|
||||
options: ['dark', 'light'],
|
||||
},
|
||||
placement: {
|
||||
control: 'select',
|
||||
options: [
|
||||
'top',
|
||||
'top-start',
|
||||
'top-end',
|
||||
'bottom',
|
||||
'bottom-start',
|
||||
'bottom-end',
|
||||
'left',
|
||||
'left-start',
|
||||
'left-end',
|
||||
'right',
|
||||
'right-start',
|
||||
'right-end',
|
||||
],
|
||||
},
|
||||
disabled: {
|
||||
control: { type: 'boolean' },
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
backgrounds: { default: '--color-background-light' },
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nTooltip,
|
||||
},
|
||||
template:
|
||||
'<n8n-tooltip v-bind="$props"><div style="margin:50px; display: inline-block;"><span>yo</span></div></n8n-tooltip>',
|
||||
});
|
||||
|
||||
export const Tooltip = Template.bind({});
|
||||
Tooltip.args = {
|
||||
content: '...',
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
<script lang="ts">
|
||||
import ElTooltip from 'element-ui/lib/tooltip';
|
||||
|
||||
ElTooltip.name = 'n8n-tooltip';
|
||||
|
||||
export default ElTooltip;
|
||||
</script>
|
|
@ -0,0 +1,3 @@
|
|||
import N8nTooltip from './Tooltip.vue';
|
||||
|
||||
export default N8nTooltip;
|
10
packages/design-system/src/components/component.d.ts
vendored
Normal file
10
packages/design-system/src/components/component.d.ts
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
import Vue from 'vue';
|
||||
|
||||
/** N8n component common definition */
|
||||
export declare class N8nComponent extends Vue {
|
||||
/** Install component into Vue */
|
||||
static install(vue: typeof Vue): void;
|
||||
}
|
||||
|
||||
/** Component size definition for button, input, etc */
|
||||
export type N8nComponentSize = 'large' | 'medium' | 'small';
|
1
packages/design-system/src/components/index.d.ts
vendored
Normal file
1
packages/design-system/src/components/index.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
declare module './N8nButton';
|
23
packages/design-system/src/components/index.js
Normal file
23
packages/design-system/src/components/index.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import N8nButton from './N8nButton';
|
||||
import N8nIcon from './N8nIcon';
|
||||
import N8nIconButton from './N8nIconButton';
|
||||
import N8nInput from './N8nInput';
|
||||
import N8nInputLabel from './N8nInputLabel';
|
||||
import N8nInputNumber from './N8nInputNumber';
|
||||
import N8nOption from './N8nOption';
|
||||
import N8nSelect from './N8nSelect';
|
||||
import N8nSpinner from './N8nSpinner';
|
||||
import N8nTooltip from './N8nTooltip';
|
||||
|
||||
export {
|
||||
N8nButton,
|
||||
N8nIcon,
|
||||
N8nIconButton,
|
||||
N8nInput,
|
||||
N8nInputLabel,
|
||||
N8nInputNumber,
|
||||
N8nOption,
|
||||
N8nSelect,
|
||||
N8nSpinner,
|
||||
N8nTooltip,
|
||||
};
|
5
packages/design-system/src/docs/Introduction.stories.mdx
Normal file
5
packages/design-system/src/docs/Introduction.stories.mdx
Normal file
|
@ -0,0 +1,5 @@
|
|||
<Meta title="Docs/Introduction" />
|
||||
|
||||
# Welcome to n8n Storybook
|
||||
|
||||
This project includes components that make up n8n editor.
|
1
packages/design-system/src/main.d.ts
vendored
Normal file
1
packages/design-system/src/main.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
declare module 'n8n-design-system';
|
10
packages/design-system/src/main.js
Normal file
10
packages/design-system/src/main.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import * as components from './components';
|
||||
|
||||
for (const key in components) {
|
||||
const component = components[key];
|
||||
component.install = function (Vue) {
|
||||
Vue.component(component.name, component);
|
||||
};
|
||||
}
|
||||
|
||||
export * from './components';
|
7
packages/design-system/src/shims-element-ui.d.ts
vendored
Normal file
7
packages/design-system/src/shims-element-ui.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
declare module 'element-ui/lib/button';
|
||||
declare module 'element-ui/lib/input';
|
||||
declare module 'element-ui/lib/tooltip';
|
||||
declare module 'element-ui/lib/input-number';
|
||||
declare module 'element-ui/lib/select';
|
||||
declare module 'element-ui/lib/option';
|
||||
|
13
packages/design-system/src/shims-tsx.d.ts
vendored
Normal file
13
packages/design-system/src/shims-tsx.d.ts
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
import Vue, { VNode } from 'vue';
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
// tslint:disable no-empty-interface
|
||||
interface Element extends VNode {}
|
||||
// tslint:disable no-empty-interface
|
||||
interface ElementClass extends Vue {}
|
||||
interface IntrinsicElements {
|
||||
[elem: string]: any;
|
||||
}
|
||||
}
|
||||
}
|
4
packages/design-system/src/shims-vue.d.ts
vendored
Normal file
4
packages/design-system/src/shims-vue.d.ts
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
declare module '*.vue' {
|
||||
import Vue from 'vue';
|
||||
export default Vue;
|
||||
}
|
129
packages/design-system/src/styleguide/ColorCircles.vue
Normal file
129
packages/design-system/src/styleguide/ColorCircles.vue
Normal file
|
@ -0,0 +1,129 @@
|
|||
<template>
|
||||
<div :class="$style.section">
|
||||
<div v-for="color in colors" :key="color" :class="$style.container">
|
||||
<div
|
||||
:class="$style.circle"
|
||||
:style="{ backgroundColor: `var(${color})` }"
|
||||
></div>
|
||||
<span>{{ color }}</span>
|
||||
<span :class="$style.hsl">{{ hsl[color] }}</span>
|
||||
<span :class="$style.color">{{ getHexValue(color) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
function hslToHex(h: number, s: number, l: number): string {
|
||||
l /= 100;
|
||||
const a = (s * Math.min(l, 1 - l)) / 100;
|
||||
const f = (n: number) => {
|
||||
const k = (n + h / 30) % 12;
|
||||
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
||||
return Math.round(255 * color)
|
||||
.toString(16)
|
||||
.padStart(2, '0'); // convert to Hex and prefix "0" if needed
|
||||
};
|
||||
return `#${f(0)}${f(8)}${f(4)}`;
|
||||
}
|
||||
|
||||
function getHex(hsl: string): string {
|
||||
const colors = hsl
|
||||
.replace('hsl(', '')
|
||||
.replace(')', '')
|
||||
.replace(/%/g, '')
|
||||
.split(',')
|
||||
.map((n: string) => parseFloat(n));
|
||||
|
||||
return hslToHex(colors[0], colors[1], colors[2]);
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'color-circles',
|
||||
data() {
|
||||
return {
|
||||
observer: null as null | MutationObserver,
|
||||
hsl: {} as { [color: string]: string },
|
||||
};
|
||||
},
|
||||
props: {
|
||||
colors: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const setColors = () => {
|
||||
(this.colors as string[]).forEach((color: string) => {
|
||||
const style = getComputedStyle(document.body);
|
||||
|
||||
Vue.set(this.hsl, color, style.getPropertyValue(color));
|
||||
});
|
||||
};
|
||||
|
||||
setColors();
|
||||
|
||||
// when theme class is added or removed, reset color values
|
||||
this.observer = new MutationObserver((mutationsList) => {
|
||||
for (const mutation of mutationsList) {
|
||||
if (mutation.type === 'attributes') {
|
||||
setColors();
|
||||
}
|
||||
}
|
||||
});
|
||||
const body = document.querySelector('body');
|
||||
if (body) {
|
||||
this.observer.observe(body, { attributes: true });
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
if (this.observer) {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getHexValue(color: string) {
|
||||
return getHex(this.hsl[color]);
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.section {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.name {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 140px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
align-self: flex-start;
|
||||
padding: 5px;
|
||||
color: var(--color-text-dark);
|
||||
}
|
||||
|
||||
.circle {
|
||||
border-radius: 50%;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
margin-bottom: 5px;
|
||||
border: 1px solid lightgray;
|
||||
}
|
||||
|
||||
.color {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.hsl {
|
||||
composes: color;
|
||||
content: var(--color-primary);
|
||||
}
|
||||
</style>
|
83
packages/design-system/src/styleguide/Sizes.vue
Normal file
83
packages/design-system/src/styleguide/Sizes.vue
Normal file
|
@ -0,0 +1,83 @@
|
|||
<template>
|
||||
<table :class="$style.table">
|
||||
<tr>
|
||||
<th :class="$style.row">Name</th>
|
||||
<th :class="$style.row">rem</th>
|
||||
<th :class="$style.row">px</th>
|
||||
</tr>
|
||||
<tr
|
||||
v-for="variable in variables"
|
||||
:key="variable"
|
||||
:style="attr ? { [attr]: `var(${variable})` } : {}"
|
||||
>
|
||||
<td>{{ variable }}</td>
|
||||
<td>{{ sizes[variable].rem }}</td>
|
||||
<td>{{ sizes[variable].px }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'sizes',
|
||||
data() {
|
||||
return {
|
||||
observer: null as null | MutationObserver,
|
||||
sizes: {},
|
||||
};
|
||||
},
|
||||
props: {
|
||||
variables: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
attr: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const setSizes = () => {
|
||||
(this.variables as string[]).forEach((variable: string) => {
|
||||
const style = getComputedStyle(document.body);
|
||||
const rem = style.getPropertyValue(variable);
|
||||
const px = parseFloat(rem.replace('rem', '')) * 16;
|
||||
|
||||
Vue.set(this.sizes, variable, { rem, px });
|
||||
});
|
||||
};
|
||||
|
||||
setSizes();
|
||||
|
||||
// when theme class is added or removed, reset color values
|
||||
this.observer = new MutationObserver((mutationsList) => {
|
||||
for (const mutation of mutationsList) {
|
||||
if (mutation.type === 'attributes') {
|
||||
setSizes();
|
||||
}
|
||||
}
|
||||
});
|
||||
const body = document.querySelector('body');
|
||||
if (body) {
|
||||
this.observer.observe(body, { attributes: true });
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
if (this.observer) {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.table {
|
||||
text-align: center;
|
||||
color: var(--color-text-dark);
|
||||
}
|
||||
|
||||
.row {
|
||||
min-width: 150px;
|
||||
}
|
||||
</style>
|
49
packages/design-system/src/styleguide/TextClasses.vue
Normal file
49
packages/design-system/src/styleguide/TextClasses.vue
Normal file
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<table :class="$style.table">
|
||||
<tr v-for="c in classes" :key="c">
|
||||
<td>.{{ c }}{{ postfix ? postfix : '' }}</td>
|
||||
<td :class="$style[`${c}${postfix ? postfix : ''}`]">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse in
|
||||
luctus sapien, a suscipit neque.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'text-classes',
|
||||
data(): { observer: null | MutationObserver; classes: string[] } {
|
||||
return {
|
||||
observer: null as null | MutationObserver,
|
||||
classes: [
|
||||
'heading1',
|
||||
'heading2',
|
||||
'heading3',
|
||||
'heading4',
|
||||
'body-large',
|
||||
'body-medium',
|
||||
'body-small',
|
||||
],
|
||||
};
|
||||
},
|
||||
props: {
|
||||
postfix: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
@use "~/theme/src/common/typography.scss";
|
||||
|
||||
.table {
|
||||
text-align: center;
|
||||
color: var(--color-text-dark);
|
||||
|
||||
* {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
}
|
||||
</style>
|
80
packages/design-system/src/styleguide/VariableTable.vue
Normal file
80
packages/design-system/src/styleguide/VariableTable.vue
Normal file
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<table :class="$style.table">
|
||||
<tr>
|
||||
<th :class="$style.row">Name</th>
|
||||
<th :class="$style.row">Value</th>
|
||||
</tr>
|
||||
<tr
|
||||
v-for="variable in variables"
|
||||
:key="variable"
|
||||
:style="attr ? { [attr]: `var(${variable})` } : {}"
|
||||
>
|
||||
<td>{{ variable }}</td>
|
||||
<td>{{ values[variable] }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'variable-table',
|
||||
data() {
|
||||
return {
|
||||
observer: null as null | MutationObserver,
|
||||
values: {},
|
||||
};
|
||||
},
|
||||
props: {
|
||||
variables: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
attr: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const setValues = () => {
|
||||
(this.variables as string[]).forEach((variable: string) => {
|
||||
const style = getComputedStyle(document.body);
|
||||
const value = style.getPropertyValue(variable);
|
||||
|
||||
Vue.set(this.values, variable, value);
|
||||
});
|
||||
};
|
||||
|
||||
setValues();
|
||||
|
||||
// when theme class is added or removed, reset color values
|
||||
this.observer = new MutationObserver((mutationsList) => {
|
||||
for (const mutation of mutationsList) {
|
||||
if (mutation.type === 'attributes') {
|
||||
setValues();
|
||||
}
|
||||
}
|
||||
});
|
||||
const body = document.querySelector('body');
|
||||
if (body) {
|
||||
this.observer.observe(body, { attributes: true });
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
if (this.observer) {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.table {
|
||||
text-align: center;
|
||||
color: var(--color-text-dark);
|
||||
}
|
||||
|
||||
.row {
|
||||
min-width: 150px;
|
||||
}
|
||||
</style>
|
49
packages/design-system/src/styleguide/border.stories.mdx
Normal file
49
packages/design-system/src/styleguide/border.stories.mdx
Normal file
|
@ -0,0 +1,49 @@
|
|||
import { Meta, Story, Canvas } from '@storybook/addon-docs';
|
||||
import VariableTable from './VariableTable.vue';
|
||||
|
||||
<Meta
|
||||
title="Styleguide/Border"
|
||||
parameters={{
|
||||
design: {
|
||||
type: 'figma',
|
||||
url: 'https://www.figma.com/file/DxLbnIyMK8X0uLkUguFV4n/n8n-design-system_v1?node-id=79%3A6898',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
# Border Radius
|
||||
|
||||
<Canvas>
|
||||
<Story name="border-radius">
|
||||
{{
|
||||
template: `<variable-table :variables="['--border-radius-small','--border-radius-base']" />`,
|
||||
components: {
|
||||
VariableTable,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
# Border Width
|
||||
|
||||
<Canvas>
|
||||
<Story name="border-width">
|
||||
{{
|
||||
template: `<variable-table :variables="['--border-width-base']" />`,
|
||||
components: {
|
||||
VariableTable,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
<Canvas>
|
||||
<Story name="border-style">
|
||||
{{
|
||||
template: `<variable-table :variables="['--border-style-base']" />`,
|
||||
components: {
|
||||
VariableTable,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
131
packages/design-system/src/styleguide/colors.stories.mdx
Normal file
131
packages/design-system/src/styleguide/colors.stories.mdx
Normal file
|
@ -0,0 +1,131 @@
|
|||
import { Meta, Story, Canvas } from '@storybook/addon-docs';
|
||||
import ColorCircles from './ColorCircles.vue';
|
||||
|
||||
<Meta
|
||||
title="Styleguide/Colors"
|
||||
parameters={{
|
||||
design: {
|
||||
type: 'figma',
|
||||
url: 'https://www.figma.com/file/DxLbnIyMK8X0uLkUguFV4n/n8n-design-system_v1?node-id=2%3A23',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
# Colors
|
||||
|
||||
## Primary
|
||||
|
||||
<Canvas>
|
||||
<Story name="primary">
|
||||
{{
|
||||
template: `<color-circles :colors="['--color-primary-shade-1', '--color-primary', '--color-primary-tint-1', '--color-primary-tint-2', '--color-primary-tint-3']" />`,
|
||||
components: {
|
||||
ColorCircles,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Outline
|
||||
|
||||
<Canvas>
|
||||
<Story name="secondary">
|
||||
{{
|
||||
template: `<color-circles :colors="['--color-secondary']" />`,
|
||||
components: {
|
||||
ColorCircles,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Success
|
||||
|
||||
<Canvas>
|
||||
<Story name="success">
|
||||
{{
|
||||
template: `<color-circles :colors="['--color-success', '--color-success-tint-1', '--color-success-tint-2']" />`,
|
||||
components: {
|
||||
ColorCircles,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Warning
|
||||
|
||||
<Canvas>
|
||||
<Story name="warning">
|
||||
{{
|
||||
template: `<color-circles :colors="['--color-warning', '--color-warning-tint-1', '--color-warning-tint-2']" />`,
|
||||
components: {
|
||||
ColorCircles,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Danger
|
||||
|
||||
<Canvas>
|
||||
<Story name="danger">
|
||||
{{
|
||||
template: `<color-circles :colors="['--color-danger', '--color-danger-tint-1', '--color-danger-tint-2']" />`,
|
||||
components: {
|
||||
ColorCircles,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Info
|
||||
|
||||
<Canvas>
|
||||
<Story name="info">
|
||||
{{
|
||||
template: `<color-circles :colors="['--color-info', '--color-info-tint-1', '--color-info-tint-2']" />`,
|
||||
components: {
|
||||
ColorCircles,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Text
|
||||
|
||||
<Canvas>
|
||||
<Story name="text">
|
||||
{{
|
||||
template: `<color-circles :colors="['--color-text-dark', '--color-text-base', '--color-text-light', '--color-text-lighter', '--color-text-xlight']" />`,
|
||||
components: {
|
||||
ColorCircles,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Foreground
|
||||
|
||||
<Canvas>
|
||||
<Story name="foreground">
|
||||
{{
|
||||
template: `<color-circles :colors="['--color-foreground-base', '--color-foreground-light', '--color-foreground-xlight']" />`,
|
||||
components: {
|
||||
ColorCircles,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Background
|
||||
|
||||
<Canvas>
|
||||
<Story name="background">
|
||||
{{
|
||||
template: `<color-circles :colors="['--color-background-dark', '--color-background-base', '--color-background-light', '--color-background-lighter', '--color-background-xlight']" />`,
|
||||
components: {
|
||||
ColorCircles,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
59
packages/design-system/src/styleguide/fonts.stories.mdx
Normal file
59
packages/design-system/src/styleguide/fonts.stories.mdx
Normal file
|
@ -0,0 +1,59 @@
|
|||
import { Meta, Story, Canvas } from '@storybook/addon-docs';
|
||||
import Sizes from './Sizes.vue';
|
||||
import VariableTable from './VariableTable.vue';
|
||||
|
||||
<Meta title="Styleguide/Font" />
|
||||
|
||||
# Font
|
||||
|
||||
## Font Sizes
|
||||
|
||||
<Canvas>
|
||||
<Story name="font-size">
|
||||
{{
|
||||
template: `<sizes :variables="['--font-size-2xs','--font-size-xs','--font-size-s','--font-size-m','--font-size-l','--font-size-xl','--font-size-2xl']" attr="font-size" />`,
|
||||
components: {
|
||||
Sizes,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Line Heights
|
||||
|
||||
<Canvas>
|
||||
<Story name="line-height">
|
||||
{{
|
||||
template: `<variable-table :variables="['--font-line-height-compact','--font-line-height-regular','--font-line-height-loose','--font-line-height-xloose']" />`,
|
||||
components: {
|
||||
VariableTable,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Font Weights
|
||||
|
||||
<Canvas>
|
||||
<Story name="font-weight">
|
||||
{{
|
||||
template: `<variable-table :variables="['--font-weight-regular','--font-weight-bold']" attr="font-weight" />`,
|
||||
components: {
|
||||
VariableTable,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
## Font Family
|
||||
|
||||
<Canvas>
|
||||
<Story name="font-family">
|
||||
{{
|
||||
template: `<variable-table :variables="['--font-family']" attr="font-family" />`,
|
||||
components: {
|
||||
VariableTable,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
26
packages/design-system/src/styleguide/spacing.stories.mdx
Normal file
26
packages/design-system/src/styleguide/spacing.stories.mdx
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { Meta, Story, Canvas } from '@storybook/addon-docs';
|
||||
import Sizes from './Sizes.vue';
|
||||
import TextClasses from './TextClasses.vue';
|
||||
|
||||
<Meta
|
||||
title="Styleguide/Spacing"
|
||||
parameters={{
|
||||
design: {
|
||||
type: 'figma',
|
||||
url: 'https://www.figma.com/file/DxLbnIyMK8X0uLkUguFV4n/n8n-design-system_v1?node-id=79%3A6898',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
# Spacing
|
||||
|
||||
<Canvas>
|
||||
<Story name="spacing">
|
||||
{{
|
||||
template: `<sizes :variables="['--spacing-5xs','--spacing-4xs','--spacing-3xs','--spacing-2xs','--spacing-xs','--spacing-s','--spacing-m','--spacing-l','--spacing-xl','--spacing-2xl','--spacing-3xl','--spacing-4xl','--spacing-5xl']" />`,
|
||||
components: {
|
||||
Sizes,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
38
packages/design-system/src/styleguide/text.stories.mdx
Normal file
38
packages/design-system/src/styleguide/text.stories.mdx
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { Meta, Story, Canvas } from '@storybook/addon-docs';
|
||||
import TextClasses from './TextClasses.vue';
|
||||
|
||||
<Meta
|
||||
title="Styleguide/Text"
|
||||
parameters={{
|
||||
design: {
|
||||
type: 'figma',
|
||||
url: 'https://www.figma.com/file/DxLbnIyMK8X0uLkUguFV4n/n8n-design-system_v1?node-id=79%3A6898',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
# Regular
|
||||
|
||||
<Canvas>
|
||||
<Story name="regular">
|
||||
{{
|
||||
template: `<text-classes />`,
|
||||
components: {
|
||||
TextClasses,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
# Bold
|
||||
|
||||
<Canvas>
|
||||
<Story name="bold">
|
||||
{{
|
||||
template: `<text-classes postfix="-bold" />`,
|
||||
components: {
|
||||
TextClasses,
|
||||
},
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
2373
packages/design-system/theme/preview/docs.min.css
vendored
Normal file
2373
packages/design-system/theme/preview/docs.min.css
vendored
Normal file
File diff suppressed because it is too large
Load diff
1525
packages/design-system/theme/preview/index.html
Normal file
1525
packages/design-system/theme/preview/index.html
Normal file
File diff suppressed because it is too large
Load diff
260
packages/design-system/theme/src/_tokens.dark.scss
Normal file
260
packages/design-system/theme/src/_tokens.dark.scss
Normal file
|
@ -0,0 +1,260 @@
|
|||
@mixin theme {
|
||||
--color-primary-h: 7;
|
||||
--color-primary-s: 100%;
|
||||
--color-primary-l: 68%;
|
||||
--color-primary: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-l)
|
||||
);
|
||||
|
||||
--color-primary-tint-1-l: 18%;
|
||||
--color-primary-tint-1: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-tint-1-l)
|
||||
);
|
||||
|
||||
--color-primary-tint-2-l: 9%;
|
||||
--color-primary-tint-2: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-tint-2-l)
|
||||
);
|
||||
|
||||
--color-primary-tint-3-l: 3%;
|
||||
--color-primary-tint-3: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-tint-3-l)
|
||||
);
|
||||
|
||||
--color-primary-shade-1-l: 89%;
|
||||
--color-primary-shade-1: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-shade-1-l)
|
||||
);
|
||||
|
||||
--color-secondary-h: 247;
|
||||
--color-secondary-s: 100%;
|
||||
--color-secondary-l: 35%;
|
||||
--color-secondary: hsl(
|
||||
var(--color-secondary-h),
|
||||
var(--color-secondary-s),
|
||||
var(--color-secondary-l)
|
||||
);
|
||||
|
||||
--color-success-h: 150;
|
||||
--color-success-s: 74%;
|
||||
--color-success-l: 60%;
|
||||
--color-success: hsl(
|
||||
var(--color-success-h),
|
||||
var(--color-success-s),
|
||||
var(--color-success-l)
|
||||
);
|
||||
|
||||
--color-success-tint-1-l: 12%;
|
||||
--color-success-tint-1: hsl(
|
||||
var(--color-success-h),
|
||||
var(--color-success-s),
|
||||
var(--color-success-tint-1-l)
|
||||
);
|
||||
|
||||
--color-success-tint-2-l: 3%;
|
||||
--color-success-tint-2: hsl(
|
||||
var(--color-success-h),
|
||||
var(--color-success-s),
|
||||
var(--color-success-tint-2-l)
|
||||
);
|
||||
|
||||
--color-warning-h: 36;
|
||||
--color-warning-s: 77%;
|
||||
--color-warning-l: 43%;
|
||||
--color-warning: hsl(
|
||||
var(--color-warning-h),
|
||||
var(--color-warning-s),
|
||||
var(--color-warning-l)
|
||||
);
|
||||
|
||||
--color-warning-tint-1-l: 12%;
|
||||
--color-warning-tint-1: hsl(
|
||||
var(--color-warning-h),
|
||||
var(--color-warning-s),
|
||||
var(--color-warning-tint-1-l)
|
||||
);
|
||||
|
||||
--color-warning-tint-2-l: 4%;
|
||||
--color-warning-tint-2: hsl(
|
||||
var(--color-warning-h),
|
||||
var(--color-warning-s),
|
||||
var(--color-warning-tint-2-l)
|
||||
);
|
||||
|
||||
--color-danger-h: 0;
|
||||
--color-danger-s: 88%;
|
||||
--color-danger-l: 35%;
|
||||
--color-danger: hsl(
|
||||
var(--color-danger-h),
|
||||
var(--color-danger-s),
|
||||
var(--color-danger-l)
|
||||
);
|
||||
|
||||
--color-danger-tint-1-l: 8%;
|
||||
--color-danger-tint-1: hsl(
|
||||
var(--color-danger-h),
|
||||
var(--color-danger-s),
|
||||
var(--color-danger-tint-1-l)
|
||||
);
|
||||
|
||||
--color-danger-tint-2-l: 3%;
|
||||
--color-danger-tint-2: hsl(
|
||||
var(--color-danger-h),
|
||||
var(--color-danger-s),
|
||||
var(--color-danger-tint-2-l)
|
||||
);
|
||||
|
||||
--color-info-h: 220;
|
||||
--color-info-s: 4%;
|
||||
--color-info-l: 42%;
|
||||
--color-info: hsl(
|
||||
var(--color-info-h),
|
||||
var(--color-info-s),
|
||||
var(--color-info-l)
|
||||
);
|
||||
|
||||
--color-info-tint-1-l: 12%;
|
||||
--color-info-tint-1: hsl(
|
||||
var(--color-info-h),
|
||||
var(--color-info-s),
|
||||
var(--color-info-tint-1-l)
|
||||
);
|
||||
|
||||
--color-info-tint-2-l: 4%;
|
||||
--color-info-tint-2: hsl(
|
||||
var(--color-info-h),
|
||||
var(--color-info-s),
|
||||
var(--color-info-tint-2-l)
|
||||
);
|
||||
|
||||
--color-text-dark-h: 0;
|
||||
--color-text-dark-s: 0%;
|
||||
--color-text-dark-l: 100%;
|
||||
--color-text-dark: hsl(
|
||||
var(--color-text-dark-h),
|
||||
var(--color-text-dark-s),
|
||||
var(--color-text-dark-l)
|
||||
);
|
||||
|
||||
--color-text-base-h: 240;
|
||||
--color-text-base-s: 4%;
|
||||
--color-text-base-l: 49%;
|
||||
--color-text-base: hsl(
|
||||
var(--color-text-base-h),
|
||||
var(--color-text-base-s),
|
||||
var(--color-text-base-l)
|
||||
);
|
||||
|
||||
--color-text-light-h: 220;
|
||||
--color-text-light-s: 4%;
|
||||
--color-text-light-l: 42%;
|
||||
--color-text-light: hsl(
|
||||
var(--color-text-light-h),
|
||||
var(--color-text-light-s),
|
||||
var(--color-text-light-l)
|
||||
);
|
||||
|
||||
--color-text-lighter-h: 222;
|
||||
--color-text-lighter-s: 17%;
|
||||
--color-text-lighter-l: 12%;
|
||||
--color-text-lighter: hsl(
|
||||
var(--color-text-lighter-h),
|
||||
var(--color-text-lighter-s),
|
||||
var(--color-text-lighter-l)
|
||||
);
|
||||
|
||||
--color-text-xlight-h: 0;
|
||||
--color-text-xlight-s: 0%;
|
||||
--color-text-xlight-l: 100%;
|
||||
--color-text-xlight: hsl(
|
||||
var(--color-text-xlight-h),
|
||||
var(--color-text-xlight-s),
|
||||
var(--color-text-xlight-l)
|
||||
);
|
||||
|
||||
--color-foreground-base-h: 220;
|
||||
--color-foreground-base-s: 20%;
|
||||
--color-foreground-base-l: 12%;
|
||||
--color-foreground-base: hsl(
|
||||
var(--color-foreground-base-h),
|
||||
var(--color-foreground-base-s),
|
||||
var(--color-foreground-base-l)
|
||||
);
|
||||
|
||||
--color-foreground-light-h: 0;
|
||||
--color-foreground-light-s: 0%;
|
||||
--color-foreground-light-l: 7%;
|
||||
--color-foreground-light: hsl(
|
||||
var(--color-foreground-light-h),
|
||||
var(--color-foreground-light-s),
|
||||
var(--color-foreground-light-l)
|
||||
);
|
||||
|
||||
--color-foreground-xlight-h: 0;
|
||||
--color-foreground-xlight-s: 0%;
|
||||
--color-foreground-xlight-l: 0%;
|
||||
--color-foreground-xlight: hsl(
|
||||
var(--color-foreground-xlight-h),
|
||||
var(--color-foreground-xlight-s),
|
||||
var(--color-foreground-xlight-l)
|
||||
);
|
||||
|
||||
--color-background-dark-h: 0;
|
||||
--color-background-dark-s: 0%;
|
||||
--color-background-dark-l: 100%;
|
||||
--color-background-dark: hsl(
|
||||
var(--color-background-dark-h),
|
||||
var(--color-background-dark-s),
|
||||
var(--color-background-dark-l)
|
||||
);
|
||||
|
||||
--color-background-base-h: 252;
|
||||
--color-background-base-s: 71%;
|
||||
--color-background-base-l: 99%;
|
||||
--color-background-base: hsl(
|
||||
var(--color-background-base-h),
|
||||
var(--color-background-base-s),
|
||||
var(--color-background-base-l)
|
||||
);
|
||||
|
||||
--color-background-light-h: 220;
|
||||
--color-background-light-s: 27%;
|
||||
--color-background-light-l: 98%;
|
||||
--color-background-light: hsl(
|
||||
var(--color-background-light-h),
|
||||
var(--color-background-light-s),
|
||||
var(--color-background-light-l)
|
||||
);
|
||||
|
||||
--color-background-lighter-h: 220;
|
||||
--color-background-lighter-s: 30%;
|
||||
--color-background-lighter-l: 96%;
|
||||
--color-background-lighter: hsl(
|
||||
var(--color-background-lighter-h),
|
||||
var(--color-background-lighter-s),
|
||||
var(--color-background-lighter-l)
|
||||
);
|
||||
|
||||
--color-background-xlight-h: 240;
|
||||
--color-background-xlight-s: 4%;
|
||||
--color-background-xlight-l: 19%;
|
||||
--color-background-xlight: hsl(
|
||||
var(--color-background-xlight-h),
|
||||
var(--color-background-xlight-s),
|
||||
var(--color-background-xlight-l)
|
||||
);
|
||||
}
|
||||
|
||||
body.theme-dark {
|
||||
@include theme;
|
||||
}
|
307
packages/design-system/theme/src/_tokens.scss
Normal file
307
packages/design-system/theme/src/_tokens.scss
Normal file
|
@ -0,0 +1,307 @@
|
|||
@mixin theme {
|
||||
--color-primary-h: 6.9;
|
||||
--color-primary-s: 100%;
|
||||
--color-primary-l: 67.6%;
|
||||
--color-primary: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-l)
|
||||
);
|
||||
|
||||
--color-primary-tint-1-l: 88%;
|
||||
--color-primary-tint-1: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-tint-1-l)
|
||||
);
|
||||
|
||||
--color-primary-tint-2-l: 94.5%;
|
||||
--color-primary-tint-2: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-tint-2-l)
|
||||
);
|
||||
|
||||
--color-primary-tint-3-l: 96.9%;
|
||||
--color-primary-tint-3: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-tint-3-l)
|
||||
);
|
||||
|
||||
--color-primary-shade-1-l: 57.6%;
|
||||
--color-primary-shade-1: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-shade-1-l)
|
||||
);
|
||||
|
||||
--color-primary-shade-2-l: 23%;
|
||||
--color-primary-shade-2: hsl(
|
||||
var(--color-primary-h),
|
||||
var(--color-primary-s),
|
||||
var(--color-primary-shade-2-l)
|
||||
);
|
||||
|
||||
--color-secondary-h: 247;
|
||||
--color-secondary-s: 49%;
|
||||
--color-secondary-l: 53%;
|
||||
--color-secondary: hsl(
|
||||
var(--color-secondary-h),
|
||||
var(--color-secondary-s),
|
||||
var(--color-secondary-l)
|
||||
);
|
||||
|
||||
--color-success-h: 150.4;
|
||||
--color-success-s: 73.8%;
|
||||
--color-success-l: 40.4%;
|
||||
--color-success: hsl(
|
||||
var(--color-success-h),
|
||||
var(--color-success-s),
|
||||
var(--color-success-l)
|
||||
);
|
||||
|
||||
--color-success-tint-1-l: 90%;
|
||||
--color-success-tint-1: hsl(
|
||||
var(--color-success-h),
|
||||
var(--color-success-s),
|
||||
var(--color-success-tint-1-l)
|
||||
);
|
||||
|
||||
--color-success-tint-2-l: 94.9%;
|
||||
--color-success-tint-2: hsl(
|
||||
var(--color-success-h),
|
||||
var(--color-success-s),
|
||||
var(--color-success-tint-2-l)
|
||||
);
|
||||
|
||||
--color-warning-h: 36;
|
||||
--color-warning-s: 77%;
|
||||
--color-warning-l: 57%;
|
||||
--color-warning: hsl(
|
||||
var(--color-warning-h),
|
||||
var(--color-warning-s),
|
||||
var(--color-warning-l)
|
||||
);
|
||||
|
||||
--color-warning-tint-1-l: 88%;
|
||||
--color-warning-tint-1: hsl(
|
||||
var(--color-warning-h),
|
||||
var(--color-warning-s),
|
||||
var(--color-warning-tint-1-l)
|
||||
);
|
||||
|
||||
--color-warning-tint-2-l: 96%;
|
||||
--color-warning-tint-2: hsl(
|
||||
var(--color-warning-h),
|
||||
var(--color-warning-s),
|
||||
var(--color-warning-tint-2-l)
|
||||
);
|
||||
|
||||
--color-danger-h: 0;
|
||||
--color-danger-s: 87.6%;
|
||||
--color-danger-l: 65.3%;
|
||||
--color-danger: hsl(
|
||||
var(--color-danger-h),
|
||||
var(--color-danger-s),
|
||||
var(--color-danger-l)
|
||||
);
|
||||
|
||||
--color-danger-tint-1-l: 93.9%;
|
||||
--color-danger-tint-1: hsl(
|
||||
var(--color-danger-h),
|
||||
var(--color-danger-s),
|
||||
var(--color-danger-tint-1-l)
|
||||
);
|
||||
--color-danger-tint-2-l: 96.9%;
|
||||
--color-danger-tint-2: hsl(
|
||||
var(--color-danger-h),
|
||||
var(--color-danger-s),
|
||||
var(--color-danger-tint-2-l)
|
||||
);
|
||||
|
||||
--color-info-h: 220;
|
||||
--color-info-s: 4%;
|
||||
--color-info-l: 58%;
|
||||
--color-info: hsl(
|
||||
var(--color-info-h),
|
||||
var(--color-info-s),
|
||||
var(--color-info-l)
|
||||
);
|
||||
|
||||
--color-info-tint-1-l: 88%;
|
||||
--color-info-tint-1: hsl(
|
||||
var(--color-info-h),
|
||||
var(--color-info-s),
|
||||
var(--color-info-tint-1-l)
|
||||
);
|
||||
--color-info-tint-2-l: 96%;
|
||||
--color-info-tint-2: hsl(
|
||||
var(--color-info-h),
|
||||
var(--color-info-s),
|
||||
var(--color-info-tint-2-l)
|
||||
);
|
||||
|
||||
--color-text-dark-h: 0;
|
||||
--color-text-dark-s: 0%;
|
||||
--color-text-dark-l: 33.3%;
|
||||
--color-text-dark: hsl(
|
||||
var(--color-text-dark-h),
|
||||
var(--color-text-dark-s),
|
||||
var(--color-text-dark-l)
|
||||
);
|
||||
|
||||
--color-text-base-h: 240;
|
||||
--color-text-base-s: 4%;
|
||||
--color-text-base-l: 51%;
|
||||
--color-text-base: hsl(
|
||||
var(--color-text-base-h),
|
||||
var(--color-text-base-s),
|
||||
var(--color-text-base-l)
|
||||
);
|
||||
|
||||
--color-text-light-h: 220;
|
||||
--color-text-light-s: 4.2%;
|
||||
--color-text-light-l: 58.2%;
|
||||
--color-text-light: hsl(
|
||||
var(--color-text-light-h),
|
||||
var(--color-text-light-s),
|
||||
var(--color-text-light-l)
|
||||
);
|
||||
|
||||
--color-text-lighter-h: 222;
|
||||
--color-text-lighter-s: 16.7%;
|
||||
--color-text-lighter-l: 88.2%;
|
||||
--color-text-lighter: hsl(
|
||||
var(--color-text-lighter-h),
|
||||
var(--color-text-lighter-s),
|
||||
var(--color-text-lighter-l)
|
||||
);
|
||||
|
||||
--color-text-xlight-h: 0;
|
||||
--color-text-xlight-s: 0%;
|
||||
--color-text-xlight-l: 100%;
|
||||
--color-text-xlight: hsl(
|
||||
var(--color-text-xlight-h),
|
||||
var(--color-text-xlight-s),
|
||||
var(--color-text-xlight-l)
|
||||
);
|
||||
|
||||
--color-foreground-base-h: 220;
|
||||
--color-foreground-base-s: 20%;
|
||||
--color-foreground-base-l: 88.2%;
|
||||
--color-foreground-base: hsl(
|
||||
var(--color-foreground-base-h),
|
||||
var(--color-foreground-base-s),
|
||||
var(--color-foreground-base-l)
|
||||
);
|
||||
|
||||
--color-foreground-light-h: 0;
|
||||
--color-foreground-light-s: 0%;
|
||||
--color-foreground-light-l: 93.3%;
|
||||
--color-foreground-light: hsl(
|
||||
var(--color-foreground-light-h),
|
||||
var(--color-foreground-light-s),
|
||||
var(--color-foreground-light-l)
|
||||
);
|
||||
|
||||
--color-foreground-xlight-h: 0;
|
||||
--color-foreground-xlight-s: 0%;
|
||||
--color-foreground-xlight-l: 100%;
|
||||
--color-foreground-xlight: hsl(
|
||||
var(--color-foreground-xlight-h),
|
||||
var(--color-foreground-xlight-s),
|
||||
var(--color-foreground-xlight-l)
|
||||
);
|
||||
|
||||
--color-background-dark-h: 240;
|
||||
--color-background-dark-s: 4.2%;
|
||||
--color-background-dark-l: 18.8%;
|
||||
--color-background-dark: hsl(
|
||||
var(--color-background-dark-h),
|
||||
var(--color-background-dark-s),
|
||||
var(--color-background-dark-l)
|
||||
);
|
||||
|
||||
--color-background-base-h: 220;
|
||||
--color-background-base-s: 30%;
|
||||
--color-background-base-l: 96.1%;
|
||||
--color-background-base: hsl(
|
||||
var(--color-background-base-h),
|
||||
var(--color-background-base-s),
|
||||
var(--color-background-base-l)
|
||||
);
|
||||
|
||||
--color-background-light-h: 220;
|
||||
--color-background-light-s: 27.3%;
|
||||
--color-background-light-l: 97.8%;
|
||||
--color-background-light: hsl(
|
||||
var(--color-background-light-h),
|
||||
var(--color-background-light-s),
|
||||
var(--color-background-light-l)
|
||||
);
|
||||
|
||||
--color-background-lighter-h: 252;
|
||||
--color-background-lighter-s: 71.4%;
|
||||
--color-background-lighter-l: 98.6%;
|
||||
--color-background-lighter: hsl(
|
||||
var(--color-background-lighter-h),
|
||||
var(--color-background-lighter-s),
|
||||
var(--color-background-lighter-l)
|
||||
);
|
||||
|
||||
--color-background-xlight-h: 0;
|
||||
--color-background-xlight-s: 0%;
|
||||
--color-background-xlight-l: 100%;
|
||||
--color-background-xlight: hsl(
|
||||
var(--color-background-xlight-h),
|
||||
var(--color-background-xlight-s),
|
||||
var(--color-background-xlight-l)
|
||||
);
|
||||
|
||||
--border-radius-base: 4px;
|
||||
--border-radius-small: 2px;
|
||||
--border-color-base: var(--color-foreground-base);
|
||||
--border-color-light: var(--color-foreground-light);
|
||||
|
||||
--border-style-base: solid;
|
||||
--border-width-base: 1px;
|
||||
--border-base: var(--border-width-base) var(--border-style-base)
|
||||
var(--color-foreground-base);
|
||||
|
||||
--font-size-2xs: 0.75rem;
|
||||
--font-size-xs: 0.8125rem;
|
||||
--font-size-s: 0.875rem;
|
||||
--font-size-m: 1rem;
|
||||
--font-size-l: 1.125rem;
|
||||
--font-size-xl: 1.25rem;
|
||||
--font-size-2xl: 1.75rem;
|
||||
|
||||
--font-line-height-compact: 1.25;
|
||||
--font-line-height-regular: 1.3;
|
||||
--font-line-height-loose: 1.35;
|
||||
--font-line-height-xloose: 1.5;
|
||||
|
||||
--font-weight-regular: 400;
|
||||
--font-weight-semi-bold: 500;
|
||||
--font-weight-bold: 600;
|
||||
--font-family: 'Open Sans', sans-serif;
|
||||
|
||||
--spacing-5xs: 0.125rem;
|
||||
--spacing-4xs: 0.25rem;
|
||||
--spacing-3xs: 0.375rem;
|
||||
--spacing-2xs: 0.5rem;
|
||||
--spacing-xs: 0.75rem;
|
||||
--spacing-s: 1rem;
|
||||
--spacing-m: 1.25rem;
|
||||
--spacing-l: 1.5rem;
|
||||
--spacing-xl: 2rem;
|
||||
--spacing-2xl: 3rem;
|
||||
--spacing-3xl: 4rem;
|
||||
--spacing-4xl: 8rem;
|
||||
--spacing-5xl: 16rem;
|
||||
}
|
||||
|
||||
:root {
|
||||
@include theme;
|
||||
}
|
147
packages/design-system/theme/src/alert.scss
Normal file
147
packages/design-system/theme/src/alert.scss
Normal file
|
@ -0,0 +1,147 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
|
||||
@include mixins.b(alert) {
|
||||
width: 100%;
|
||||
padding: var.$alert-padding;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
border-radius: var.$alert-border-radius;
|
||||
position: relative;
|
||||
background-color: var.$color-white;
|
||||
overflow: hidden;
|
||||
opacity: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: opacity 0.2s;
|
||||
|
||||
@include mixins.when(light) {
|
||||
.el-alert__closebtn {
|
||||
color: var(--color-text-lighter);
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.when(dark) {
|
||||
.el-alert__closebtn {
|
||||
color: var.$color-white;
|
||||
}
|
||||
.el-alert__description {
|
||||
color: var.$color-white;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.when(center) {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@include mixins.m(success) {
|
||||
&.is-light {
|
||||
background-color: var.$alert-success-color;
|
||||
color: var(--color-success);
|
||||
|
||||
.el-alert__description {
|
||||
color: var(--color-success);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-dark {
|
||||
background-color: var(--color-success);
|
||||
color: var.$color-white;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.m(info) {
|
||||
&.is-light {
|
||||
background-color: var.$alert-info-color;
|
||||
color: var(--color-info);
|
||||
}
|
||||
|
||||
&.is-dark {
|
||||
background-color: var(--color-info);
|
||||
color: var.$color-white;
|
||||
}
|
||||
|
||||
.el-alert__description {
|
||||
color: var(--color-info);
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.m(warning) {
|
||||
&.is-light {
|
||||
background-color: var.$alert-warning-color;
|
||||
color: var(--color-warning);
|
||||
|
||||
.el-alert__description {
|
||||
color: var(--color-warning);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-dark {
|
||||
background-color: var(--color-warning);
|
||||
color: var.$color-white;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.m(error) {
|
||||
&.is-light {
|
||||
background-color: var.$alert-danger-color;
|
||||
color: var(--color-danger);
|
||||
|
||||
.el-alert__description {
|
||||
color: var(--color-danger);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-dark {
|
||||
background-color: var(--color-danger);
|
||||
color: var.$color-white;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(content) {
|
||||
display: table-cell;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
@include mixins.e(icon) {
|
||||
font-size: var.$alert-icon-size;
|
||||
width: var.$alert-icon-size;
|
||||
@include mixins.when(big) {
|
||||
font-size: var.$alert-icon-large-size;
|
||||
width: var.$alert-icon-large-size;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(title) {
|
||||
font-size: var.$alert-title-font-size;
|
||||
line-height: 18px;
|
||||
@include mixins.when(bold) {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
& .el-alert__description {
|
||||
font-size: var.$alert-description-font-size;
|
||||
margin: 5px 0 0 0;
|
||||
}
|
||||
|
||||
@include mixins.e(closebtn) {
|
||||
font-size: var.$alert-close-font-size;
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 15px;
|
||||
cursor: pointer;
|
||||
|
||||
@include mixins.when(customed) {
|
||||
font-style: normal;
|
||||
font-size: var.$alert-close-customed-font-size;
|
||||
top: 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-alert-fade-enter,
|
||||
.el-alert-fade-leave-active {
|
||||
opacity: 0;
|
||||
}
|
7
packages/design-system/theme/src/aside.scss
Normal file
7
packages/design-system/theme/src/aside.scss
Normal file
|
@ -0,0 +1,7 @@
|
|||
@use "mixins/mixins";
|
||||
|
||||
@include mixins.b(aside) {
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
}
|
80
packages/design-system/theme/src/autocomplete.scss
Normal file
80
packages/design-system/theme/src/autocomplete.scss
Normal file
|
@ -0,0 +1,80 @@
|
|||
@use "mixins/mixins";
|
||||
@use "mixins/utils";
|
||||
@use "./common/var";
|
||||
@use "./input.scss";
|
||||
@use "./scrollbar.scss";
|
||||
@use "./popper";
|
||||
|
||||
@include mixins.b(autocomplete) {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@include mixins.b(autocomplete-suggestion) {
|
||||
margin: 5px 0;
|
||||
box-shadow: var.$box-shadow-light;
|
||||
border-radius: var(--border-radius-base);
|
||||
border: 1px solid var(--border-color-base);
|
||||
box-sizing: border-box;
|
||||
background-color: var.$color-white;
|
||||
|
||||
@include mixins.e(wrap) {
|
||||
max-height: 280px;
|
||||
padding: 10px 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@include mixins.e(list) {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
& li {
|
||||
padding: 0 20px;
|
||||
margin: 0;
|
||||
line-height: 34px;
|
||||
cursor: pointer;
|
||||
color: var(--color-text-dark);
|
||||
font-size: var.$font-size-base;
|
||||
list-style: none;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:hover {
|
||||
background-color: var.$select-option-hover-background;
|
||||
}
|
||||
|
||||
&.highlighted {
|
||||
background-color: var.$select-option-hover-background;
|
||||
}
|
||||
|
||||
&.divider {
|
||||
margin-top: 6px;
|
||||
border-top: 1px solid var.$color-black;
|
||||
}
|
||||
|
||||
&.divider:last-child {
|
||||
margin-bottom: -6px;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.when(loading) {
|
||||
li {
|
||||
text-align: center;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
font-size: 20px;
|
||||
color: #999;
|
||||
@include utils.utils-vertical-center;
|
||||
|
||||
&:hover {
|
||||
background-color: var.$color-white;
|
||||
}
|
||||
}
|
||||
|
||||
& .el-icon-loading {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
51
packages/design-system/theme/src/avatar.scss
Normal file
51
packages/design-system/theme/src/avatar.scss
Normal file
|
@ -0,0 +1,51 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
|
||||
@include mixins.b(avatar) {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
color: var.$avatar-font-color;
|
||||
background: var.$avatar-background-color;
|
||||
width: var.$avatar-large-size;
|
||||
height: var.$avatar-large-size;
|
||||
line-height: var.$avatar-large-size;
|
||||
font-size: var.$avatar-text-font-size;
|
||||
|
||||
> img {
|
||||
display: block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@include mixins.m(circle) {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@include mixins.m(square) {
|
||||
border-radius: var.$avatar-border-radius;
|
||||
}
|
||||
|
||||
@include mixins.m(icon) {
|
||||
font-size: var.$avatar-icon-font-size;
|
||||
}
|
||||
|
||||
@include mixins.m(large) {
|
||||
width: var.$avatar-large-size;
|
||||
height: var.$avatar-large-size;
|
||||
line-height: var.$avatar-large-size;
|
||||
}
|
||||
|
||||
@include mixins.m(medium) {
|
||||
width: var.$avatar-medium-size;
|
||||
height: var.$avatar-medium-size;
|
||||
line-height: var.$avatar-medium-size;
|
||||
}
|
||||
|
||||
@include mixins.m(small) {
|
||||
width: var.$avatar-small-size;
|
||||
height: var.$avatar-small-size;
|
||||
line-height: var.$avatar-small-size;
|
||||
}
|
||||
}
|
22
packages/design-system/theme/src/backtop.scss
Normal file
22
packages/design-system/theme/src/backtop.scss
Normal file
|
@ -0,0 +1,22 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
|
||||
@include mixins.b(backtop) {
|
||||
position: fixed;
|
||||
background-color: var.$backtop-background-color;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
color: var.$backtop-font-color;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, 0.12);
|
||||
cursor: pointer;
|
||||
z-index: 5;
|
||||
|
||||
&:hover {
|
||||
background-color: var.$backtop-hover-background-color;
|
||||
}
|
||||
}
|
58
packages/design-system/theme/src/badge.scss
Normal file
58
packages/design-system/theme/src/badge.scss
Normal file
|
@ -0,0 +1,58 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
|
||||
@include mixins.b(badge) {
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
|
||||
@include mixins.e(content) {
|
||||
background-color: var.$badge-background-color;
|
||||
border-radius: var.$badge-radius;
|
||||
color: var.$color-white;
|
||||
display: inline-block;
|
||||
font-size: var.$badge-font-size;
|
||||
height: var.$badge-size;
|
||||
line-height: var.$badge-size;
|
||||
padding: 0 var.$badge-padding;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
border: 1px solid var.$color-white;
|
||||
box-sizing: content-box;
|
||||
|
||||
@include mixins.when(fixed) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: #{1 + var.$badge-size * 0.5};
|
||||
transform: translateY(-50%) translateX(100%);
|
||||
|
||||
@include mixins.when(dot) {
|
||||
right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.when(dot) {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
padding: 0;
|
||||
right: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@each $type in (primary, success, warning, info, danger) {
|
||||
@include mixins.m($type) {
|
||||
@if $type == primary {
|
||||
background-color: var(--color-primary);
|
||||
} @else if $type == success {
|
||||
background-color: var(--color-success);
|
||||
} @else if $type == warning {
|
||||
background-color: var(--color-warning);
|
||||
} @else if $type == info {
|
||||
background-color: var(--color-info);
|
||||
} @else {
|
||||
background-color: var(--color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
packages/design-system/theme/src/base.scss
Normal file
3
packages/design-system/theme/src/base.scss
Normal file
|
@ -0,0 +1,3 @@
|
|||
@forward "common/var.scss";
|
||||
@use "common/transition.scss";
|
||||
@use "icon.scss";
|
57
packages/design-system/theme/src/breadcrumb.scss
Normal file
57
packages/design-system/theme/src/breadcrumb.scss
Normal file
|
@ -0,0 +1,57 @@
|
|||
@use "mixins/mixins";
|
||||
@use "mixins/utils";
|
||||
@use "./common/var";
|
||||
|
||||
@include mixins.b(breadcrumb) {
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
@include utils.utils-clearfix;
|
||||
|
||||
@include mixins.e(separator) {
|
||||
margin: 0 9px;
|
||||
font-weight: bold;
|
||||
color: var(--color-text-lighter);
|
||||
|
||||
&[class*='icon'] {
|
||||
margin: 0 6px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(item) {
|
||||
float: left;
|
||||
|
||||
@include mixins.e(inner) {
|
||||
color: var(--color-text-dark);
|
||||
|
||||
&.is-link,
|
||||
& a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
transition: var.$color-transition-base;
|
||||
color: var(--color-text-dark);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.el-breadcrumb__inner,
|
||||
.el-breadcrumb__inner a {
|
||||
&,
|
||||
&:hover {
|
||||
font-weight: normal;
|
||||
color: var(--color-text-dark);
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
|
||||
.el-breadcrumb__separator {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
84
packages/design-system/theme/src/button-group.scss
Normal file
84
packages/design-system/theme/src/button-group.scss
Normal file
|
@ -0,0 +1,84 @@
|
|||
@charset "UTF-8";
|
||||
@use 'common/var';
|
||||
@use 'mixins/button';
|
||||
@use 'mixins/mixins';
|
||||
@use 'mixins/utils';
|
||||
@use 'mixins/function';
|
||||
|
||||
@include mixins.b(button-group) {
|
||||
@include utils.utils-clearfix;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
& > .el-button {
|
||||
float: left;
|
||||
position: relative;
|
||||
& + .el-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
&.is-disabled {
|
||||
z-index: 1;
|
||||
}
|
||||
&:first-child {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
&:last-child {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
&:first-child:last-child {
|
||||
border-top-right-radius: var(--border-radius-base);
|
||||
border-bottom-right-radius: var(--border-radius-base);
|
||||
border-top-left-radius: var(--border-radius-base);
|
||||
border-bottom-left-radius: var(--border-radius-base);
|
||||
|
||||
&.is-round {
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
&.is-circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
&:not(:first-child):not(:last-child) {
|
||||
border-radius: 0;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@include mixins.when(active) {
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
& > .el-dropdown {
|
||||
& > .el-button {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-left-color: rgba(var.$color-white, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
@each $type in (primary, success, warning, danger, info) {
|
||||
.el-button--#{$type} {
|
||||
&:first-child {
|
||||
border-right-color: rgba(var.$color-white, 0.5);
|
||||
}
|
||||
&:last-child {
|
||||
border-left-color: rgba(var.$color-white, 0.5);
|
||||
}
|
||||
&:not(:first-child):not(:last-child) {
|
||||
border-left-color: rgba(var.$color-white, 0.5);
|
||||
border-right-color: rgba(var.$color-white, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
107
packages/design-system/theme/src/button.scss
Normal file
107
packages/design-system/theme/src/button.scss
Normal file
|
@ -0,0 +1,107 @@
|
|||
@charset "UTF-8";
|
||||
@use 'mixins/mixins';
|
||||
@use 'mixins/utils';
|
||||
@use 'mixins/function';
|
||||
@use 'common/var';
|
||||
|
||||
$disabled-border-color: var(--color-foreground-base);
|
||||
|
||||
$loading-overlay-background-color: rgba(255, 255, 255, 0.35);
|
||||
|
||||
@include mixins.b(button) {
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
|
||||
border: var(--border-width-base) var.$button-border-color
|
||||
var(--border-style-base);
|
||||
color: var.$button-font-color;
|
||||
background-color: var.$button-background-color;
|
||||
font-weight: var(--font-weight-bold);
|
||||
border-radius: var.$button-border-radius;
|
||||
padding: var.$button-padding-vertical var.$button-padding-horizontal;
|
||||
font-size: var.$button-font-size;
|
||||
|
||||
-webkit-appearance: none;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
margin: 0;
|
||||
transition: 0.1s;
|
||||
|
||||
@include utils.utils-user-select(none);
|
||||
|
||||
&:active {
|
||||
color: var.$button-active-color;
|
||||
border-color: var.$button-active-border-color;
|
||||
background-color: var.$button-active-background-color;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
@include mixins.when(loading) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.when(disabled) {
|
||||
&,
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
cursor: not-allowed;
|
||||
background-image: none;
|
||||
color: var.$button-disabled-font-color;
|
||||
background-color: var.$button-disabled-background-color;
|
||||
border-color: var.$button-disabled-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.when(round) {
|
||||
--button-border-radius: 20px;
|
||||
}
|
||||
|
||||
@include mixins.when(circle) {
|
||||
--button-padding-vertical: var(--spacing-xs);
|
||||
--button-padding-horizontal: var(--spacing-xs);
|
||||
--button-border-radius: 50%;
|
||||
}
|
||||
|
||||
@include mixins.m(small) {
|
||||
--button-padding-vertical: var(--spacing-3xs);
|
||||
--button-padding-horizontal: var(--spacing-xs);
|
||||
--button-font-size: var(--font-size-2xs);
|
||||
|
||||
@include mixins.when(circle) {
|
||||
--button-padding-vertical: var(--spacing-3xs);
|
||||
--button-padding-horizontal: var(--spacing-3xs);
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.m(medium) {
|
||||
--button-padding-vertical: var(--spacing-2xs);
|
||||
--button-padding-horizontal: var(--spacing-xs);
|
||||
--button-font-size: var(--font-size-2xs);
|
||||
|
||||
@include mixins.when(circle) {
|
||||
--button-padding-vertical: var(--spacing-2xs);
|
||||
--button-padding-horizontal: var(--spacing-2xs);
|
||||
}
|
||||
}
|
||||
}
|
79
packages/design-system/theme/src/calendar.scss
Normal file
79
packages/design-system/theme/src/calendar.scss
Normal file
|
@ -0,0 +1,79 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
@use "button";
|
||||
@use "button-group";
|
||||
|
||||
@include mixins.b(calendar) {
|
||||
background-color: #fff;
|
||||
|
||||
@include mixins.e(header) {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 12px 20px;
|
||||
border-bottom: var.$table-border;
|
||||
}
|
||||
|
||||
@include mixins.e(title) {
|
||||
color: #000000;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
@include mixins.e(body) {
|
||||
padding: 12px 20px 35px;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.b(calendar-table) {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
|
||||
thead th {
|
||||
padding: 12px 0;
|
||||
color: var(--color-text-dark);
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
&:not(.is-range) {
|
||||
td.prev,
|
||||
td.next {
|
||||
color: var(--color-text-lighter);
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
border-bottom: var.$calendar-border;
|
||||
border-right: var.$calendar-border;
|
||||
vertical-align: top;
|
||||
transition: background-color 0.2s ease;
|
||||
|
||||
@include mixins.when(selected) {
|
||||
background-color: var.$calendar-selected-background-color;
|
||||
}
|
||||
|
||||
@include mixins.when(today) {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
tr:first-child td {
|
||||
border-top: var.$calendar-border;
|
||||
}
|
||||
|
||||
tr td:first-child {
|
||||
border-left: var.$calendar-border;
|
||||
}
|
||||
|
||||
tr.el-calendar-table__row--hide-border td {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
@include mixins.b(calendar-day) {
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
height: var.$calendar-cell-width;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: var.$calendar-selected-background-color;
|
||||
}
|
||||
}
|
||||
}
|
32
packages/design-system/theme/src/card.scss
Normal file
32
packages/design-system/theme/src/card.scss
Normal file
|
@ -0,0 +1,32 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
|
||||
@include mixins.b(card) {
|
||||
border-radius: var.$card-border-radius;
|
||||
border: 1px solid var.$card-border-color;
|
||||
background-color: var.$color-white;
|
||||
overflow: hidden;
|
||||
color: var(--color-text-dark);
|
||||
transition: 0.3s;
|
||||
|
||||
@include mixins.when(always-shadow) {
|
||||
box-shadow: var.$box-shadow-light;
|
||||
}
|
||||
|
||||
@include mixins.when(hover-shadow) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
box-shadow: var.$box-shadow-light;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(header) {
|
||||
padding: #{var.$card-padding - 2 var.$card-padding};
|
||||
border-bottom: 1px solid var.$card-border-color;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@include mixins.e(body) {
|
||||
padding: var.$card-padding;
|
||||
}
|
||||
}
|
50
packages/design-system/theme/src/carousel-item.scss
Normal file
50
packages/design-system/theme/src/carousel-item.scss
Normal file
|
@ -0,0 +1,50 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
|
||||
@include mixins.b(carousel) {
|
||||
@include mixins.e(item) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
z-index: #{var.$index-normal - 1};
|
||||
|
||||
@include mixins.when(active) {
|
||||
z-index: #{var.$index-normal + 1};
|
||||
}
|
||||
|
||||
@include mixins.when(animating) {
|
||||
transition: transform 0.4s ease-in-out;
|
||||
}
|
||||
|
||||
@include mixins.m(card) {
|
||||
width: 50%;
|
||||
transition: transform 0.4s ease-in-out;
|
||||
&.is-in-stage {
|
||||
cursor: pointer;
|
||||
z-index: var.$index-normal;
|
||||
&:hover .el-carousel__mask,
|
||||
&.is-hover .el-carousel__mask {
|
||||
opacity: 0.12;
|
||||
}
|
||||
}
|
||||
&.is-active {
|
||||
z-index: #{var.$index-normal + 1};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(mask) {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: var.$color-white;
|
||||
opacity: 0.24;
|
||||
transition: 0.2s;
|
||||
}
|
||||
}
|
164
packages/design-system/theme/src/carousel.scss
Normal file
164
packages/design-system/theme/src/carousel.scss
Normal file
|
@ -0,0 +1,164 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
|
||||
@include mixins.b(carousel) {
|
||||
position: relative;
|
||||
|
||||
@include mixins.m(horizontal) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
@include mixins.m(vertical) {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
@include mixins.e(container) {
|
||||
position: relative;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
@include mixins.e(arrow) {
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: var.$carousel-arrow-size;
|
||||
width: var.$carousel-arrow-size;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
border-radius: 50%;
|
||||
background-color: var.$carousel-arrow-background;
|
||||
color: var.$color-white;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
z-index: 10;
|
||||
transform: translateY(-50%);
|
||||
text-align: center;
|
||||
font-size: var.$carousel-arrow-font-size;
|
||||
|
||||
@include mixins.m(left) {
|
||||
left: 16px;
|
||||
}
|
||||
|
||||
@include mixins.m(right) {
|
||||
right: 16px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var.$carousel-arrow-hover-background;
|
||||
}
|
||||
|
||||
& i {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(indicators) {
|
||||
position: absolute;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
z-index: #{var.$index-normal + 1};
|
||||
|
||||
@include mixins.m(horizontal) {
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
@include mixins.m(vertical) {
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
@include mixins.m(outside) {
|
||||
bottom: #{var.$carousel-indicator-height +
|
||||
var.$carousel-indicator-padding-vertical * 2};
|
||||
text-align: center;
|
||||
position: static;
|
||||
transform: none;
|
||||
.el-carousel__indicator:hover button {
|
||||
opacity: 0.64;
|
||||
}
|
||||
button {
|
||||
background-color: var.$carousel-indicator-out-color;
|
||||
opacity: 0.24;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.m(labels) {
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: none;
|
||||
text-align: center;
|
||||
|
||||
.el-carousel__button {
|
||||
height: auto;
|
||||
width: auto;
|
||||
padding: 2px 18px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.el-carousel__indicator {
|
||||
padding: 6px 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(indicator) {
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover button {
|
||||
opacity: 0.72;
|
||||
}
|
||||
|
||||
@include mixins.m(horizontal) {
|
||||
display: inline-block;
|
||||
padding: var.$carousel-indicator-padding-vertical
|
||||
var.$carousel-indicator-padding-horizontal;
|
||||
}
|
||||
|
||||
@include mixins.m(vertical) {
|
||||
padding: var.$carousel-indicator-padding-horizontal
|
||||
var.$carousel-indicator-padding-vertical;
|
||||
.el-carousel__button {
|
||||
width: var.$carousel-indicator-height;
|
||||
height: #{var.$carousel-indicator-width * 0.5};
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.when(active) {
|
||||
button {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(button) {
|
||||
display: block;
|
||||
opacity: 0.48;
|
||||
width: var.$carousel-indicator-width;
|
||||
height: var.$carousel-indicator-height;
|
||||
background-color: var.$color-white;
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-arrow-left-enter,
|
||||
.carousel-arrow-left-leave-active {
|
||||
transform: translateY(-50%) translateX(-10px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.carousel-arrow-right-enter,
|
||||
.carousel-arrow-right-leave-active {
|
||||
transform: translateY(-50%) translateX(10px);
|
||||
opacity: 0;
|
||||
}
|
121
packages/design-system/theme/src/cascader-panel.scss
Normal file
121
packages/design-system/theme/src/cascader-panel.scss
Normal file
|
@ -0,0 +1,121 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
@use "./checkbox";
|
||||
@use "./radio";
|
||||
@use "./scrollbar";
|
||||
|
||||
@include mixins.b(cascader-panel) {
|
||||
display: flex;
|
||||
border-radius: var.$cascader-menu-radius;
|
||||
font-size: var.$cascader-menu-font-size;
|
||||
|
||||
@include mixins.when(bordered) {
|
||||
border: var.$cascader-menu-border;
|
||||
border-radius: var.$cascader-menu-radius;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.b(cascader-menu) {
|
||||
min-width: 180px;
|
||||
box-sizing: border-box;
|
||||
color: var.$cascader-menu-font-color;
|
||||
border-right: var.$cascader-menu-border;
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
.el-cascader-node {
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(wrap) {
|
||||
height: 204px;
|
||||
}
|
||||
|
||||
@include mixins.e(list) {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
margin: 0;
|
||||
padding: 6px 0;
|
||||
list-style: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@include mixins.e(hover-zone) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@include mixins.e(empty-text) {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
color: var.$cascader-color-empty;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.b(cascader-node) {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 30px 0 20px;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
outline: none;
|
||||
|
||||
&.is-selectable.in-active-path {
|
||||
color: var.$cascader-menu-font-color;
|
||||
}
|
||||
|
||||
&.in-active-path,
|
||||
&.is-selectable.in-checked-path,
|
||||
&.is-active {
|
||||
color: var.$cascader-menu-selected-font-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&:not(.is-disabled) {
|
||||
cursor: pointer;
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: var.$cascader-node-background-hover;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.when(disabled) {
|
||||
color: var.$cascader-node-color-disabled;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@include mixins.e(prefix) {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
@include mixins.e(postfix) {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
@include mixins.e(label) {
|
||||
flex: 1;
|
||||
padding: 0 10px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
> .el-radio {
|
||||
margin-right: 0;
|
||||
|
||||
.el-radio__label {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
183
packages/design-system/theme/src/cascader.scss
Normal file
183
packages/design-system/theme/src/cascader.scss
Normal file
|
@ -0,0 +1,183 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
@use "./input";
|
||||
@use "./popper";
|
||||
@use "./tag";
|
||||
@use "./cascader-panel";
|
||||
|
||||
@include mixins.b(cascader) {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
font-size: var.$font-size-base;
|
||||
line-height: var.$input-height;
|
||||
|
||||
&:not(.is-disabled):hover {
|
||||
.el-input__inner {
|
||||
cursor: pointer;
|
||||
border-color: var.$input-hover-border;
|
||||
}
|
||||
}
|
||||
|
||||
.el-input {
|
||||
cursor: pointer;
|
||||
|
||||
.el-input__inner {
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:focus {
|
||||
border-color: var.$input-focus-border;
|
||||
}
|
||||
}
|
||||
|
||||
.el-icon-arrow-down {
|
||||
transition: transform 0.3s;
|
||||
font-size: 14px;
|
||||
|
||||
@include mixins.when(reverse) {
|
||||
transform: rotateZ(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
.el-icon-circle-close:hover {
|
||||
color: var.$input-clear-hover-color;
|
||||
}
|
||||
|
||||
@include mixins.when(focus) {
|
||||
.el-input__inner {
|
||||
border-color: var.$input-focus-border;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.m(medium) {
|
||||
font-size: var.$input-medium-font-size;
|
||||
line-height: var.$input-medium-height;
|
||||
}
|
||||
|
||||
@include mixins.m(small) {
|
||||
font-size: var.$input-small-font-size;
|
||||
line-height: var.$input-small-height;
|
||||
}
|
||||
|
||||
@include mixins.m(mini) {
|
||||
font-size: var.$input-mini-font-size;
|
||||
line-height: var.$input-mini-height;
|
||||
}
|
||||
|
||||
@include mixins.when(disabled) {
|
||||
.el-cascader__label {
|
||||
z-index: #{var.$index-normal + 1};
|
||||
color: var.$disabled-color-base;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(dropdown) {
|
||||
margin: 5px 0;
|
||||
font-size: var.$cascader-menu-font-size;
|
||||
background: var.$cascader-menu-fill;
|
||||
border: var.$cascader-menu-border;
|
||||
border-radius: var.$cascader-menu-radius;
|
||||
box-shadow: var.$cascader-menu-shadow;
|
||||
}
|
||||
|
||||
@include mixins.e(tags) {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 30px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
line-height: normal;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
|
||||
.el-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
max-width: 100%;
|
||||
margin: 2px 0 2px 6px;
|
||||
text-overflow: ellipsis;
|
||||
background: var.$cascader-tag-background;
|
||||
|
||||
&:not(.is-hit) {
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
> span {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.el-icon-close {
|
||||
flex: none;
|
||||
background-color: var(--color-text-lighter);
|
||||
color: var.$color-white;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-text-light);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(suggestion-panel) {
|
||||
border-radius: var.$cascader-menu-radius;
|
||||
}
|
||||
|
||||
@include mixins.e(suggestion-list) {
|
||||
max-height: 204px;
|
||||
margin: 0;
|
||||
padding: 6px 0;
|
||||
font-size: var.$font-size-base;
|
||||
color: var.$cascader-menu-font-color;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@include mixins.e(suggestion-item) {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 34px;
|
||||
padding: 0 15px;
|
||||
text-align: left;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: var.$cascader-node-background-hover;
|
||||
}
|
||||
|
||||
&.is-checked {
|
||||
color: var.$cascader-menu-selected-font-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
> span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(empty-text) {
|
||||
margin: 10px 0;
|
||||
color: var.$cascader-color-empty;
|
||||
}
|
||||
|
||||
@include mixins.e(search-input) {
|
||||
flex: 1;
|
||||
height: 24px;
|
||||
min-width: 60px;
|
||||
margin: 2px 0 2px 15px;
|
||||
padding: 0;
|
||||
color: var.$cascader-menu-font-color;
|
||||
border: none;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--color-text-lighter);
|
||||
}
|
||||
}
|
||||
}
|
380
packages/design-system/theme/src/checkbox.scss
Normal file
380
packages/design-system/theme/src/checkbox.scss
Normal file
|
@ -0,0 +1,380 @@
|
|||
@use "./common/var";
|
||||
@use "mixins/mixins";
|
||||
@use "mixins/_button";
|
||||
@use "mixins/utils";
|
||||
|
||||
@include mixins.b(checkbox) {
|
||||
color: var.$checkbox-font-color;
|
||||
font-weight: var.$checkbox-font-weight;
|
||||
font-size: var.$font-size-base;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
margin-right: 30px;
|
||||
|
||||
@include mixins.when(bordered) {
|
||||
padding: var.$checkbox-bordered-padding;
|
||||
border-radius: var(--border-radius-base);
|
||||
border: var(--border-base);
|
||||
box-sizing: border-box;
|
||||
line-height: normal;
|
||||
height: var.$checkbox-bordered-height;
|
||||
|
||||
&.is-checked {
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
border-color: var(--border-color-light);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
& + .el-checkbox.is-bordered {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
&.el-checkbox--medium {
|
||||
padding: var.$checkbox-bordered-medium-padding;
|
||||
border-radius: var.$button-medium-border-radius;
|
||||
height: var.$checkbox-bordered-medium-height;
|
||||
|
||||
.el-checkbox__label {
|
||||
line-height: 17px;
|
||||
font-size: var.$button-medium-font-size;
|
||||
}
|
||||
|
||||
.el-checkbox__inner {
|
||||
height: var.$checkbox-bordered-medium-input-height;
|
||||
width: var.$checkbox-bordered-medium-input-width;
|
||||
}
|
||||
}
|
||||
|
||||
&.el-checkbox--small {
|
||||
padding: var.$checkbox-bordered-small-padding;
|
||||
border-radius: var.$button-small-border-radius;
|
||||
height: var.$checkbox-bordered-small-height;
|
||||
|
||||
.el-checkbox__label {
|
||||
line-height: 15px;
|
||||
font-size: var.$button-small-font-size;
|
||||
}
|
||||
|
||||
.el-checkbox__inner {
|
||||
height: var.$checkbox-bordered-small-input-height;
|
||||
width: var.$checkbox-bordered-small-input-width;
|
||||
|
||||
&::after {
|
||||
height: 6px;
|
||||
width: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.el-checkbox--mini {
|
||||
padding: var.$checkbox-bordered-mini-padding;
|
||||
border-radius: var.$button-mini-border-radius;
|
||||
height: var.$checkbox-bordered-mini-height;
|
||||
|
||||
.el-checkbox__label {
|
||||
line-height: 12px;
|
||||
font-size: var.$button-mini-font-size;
|
||||
}
|
||||
|
||||
.el-checkbox__inner {
|
||||
height: var.$checkbox-bordered-mini-input-height;
|
||||
width: var.$checkbox-bordered-mini-input-width;
|
||||
&::after {
|
||||
height: 6px;
|
||||
width: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(input) {
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
|
||||
@include mixins.when(disabled) {
|
||||
.el-checkbox__inner {
|
||||
background-color: var.$checkbox-disabled-input-fill;
|
||||
border-color: var.$checkbox-disabled-border-color;
|
||||
cursor: not-allowed;
|
||||
|
||||
&::after {
|
||||
cursor: not-allowed;
|
||||
border-color: var.$checkbox-disabled-icon-color;
|
||||
}
|
||||
|
||||
& + .el-checkbox__label {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-checked {
|
||||
.el-checkbox__inner {
|
||||
background-color: var.$checkbox-disabled-checked-input-fill;
|
||||
border-color: var.$checkbox-disabled-checked-input-border-color;
|
||||
|
||||
&::after {
|
||||
border-color: var.$checkbox-disabled-checked-icon-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-indeterminate {
|
||||
.el-checkbox__inner {
|
||||
background-color: var.$checkbox-disabled-checked-input-fill;
|
||||
border-color: var.$checkbox-disabled-checked-input-border-color;
|
||||
|
||||
&::before {
|
||||
background-color: var.$checkbox-disabled-checked-icon-color;
|
||||
border-color: var.$checkbox-disabled-checked-icon-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& + span.el-checkbox__label {
|
||||
color: var.$disabled-color-base;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.when(checked) {
|
||||
.el-checkbox__inner {
|
||||
background-color: var.$checkbox-checked-background-color;
|
||||
border-color: var.$checkbox-checked-input-border-color;
|
||||
|
||||
&::after {
|
||||
transform: rotate(45deg) scaleY(1);
|
||||
}
|
||||
}
|
||||
|
||||
& + .el-checkbox__label {
|
||||
color: var.$checkbox-checked-font-color;
|
||||
}
|
||||
}
|
||||
@include mixins.when(focus) {
|
||||
/*focus时 视觉上区分*/
|
||||
.el-checkbox__inner {
|
||||
border-color: var.$checkbox-input-border-color-hover;
|
||||
}
|
||||
}
|
||||
@include mixins.when(indeterminate) {
|
||||
.el-checkbox__inner {
|
||||
background-color: var.$checkbox-checked-background-color;
|
||||
border-color: var.$checkbox-checked-input-border-color;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: block;
|
||||
background-color: var.$checkbox-checked-icon-color;
|
||||
height: 2px;
|
||||
transform: scale(0.5);
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@include mixins.e(inner) {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
border: var.$checkbox-input-border;
|
||||
border-radius: var.$checkbox-border-radius;
|
||||
box-sizing: border-box;
|
||||
width: var.$checkbox-input-width;
|
||||
height: var.$checkbox-input-height;
|
||||
background-color: var.$checkbox-background-color;
|
||||
z-index: var.$index-normal;
|
||||
transition: border-color 0.25s cubic-bezier(0.71, -0.46, 0.29, 1.46),
|
||||
background-color 0.25s cubic-bezier(0.71, -0.46, 0.29, 1.46);
|
||||
|
||||
&:hover {
|
||||
border-color: var.$checkbox-input-border-color-hover;
|
||||
}
|
||||
|
||||
&::after {
|
||||
box-sizing: content-box;
|
||||
content: '';
|
||||
border: 1px solid var.$checkbox-checked-icon-color;
|
||||
border-left: 0;
|
||||
border-top: 0;
|
||||
height: 7px;
|
||||
left: 4px;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
transform: rotate(45deg) scaleY(0);
|
||||
width: 3px;
|
||||
transition: transform 0.15s ease-in 0.05s;
|
||||
transform-origin: center;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(original) {
|
||||
opacity: 0;
|
||||
outline: none;
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@include mixins.e(label) {
|
||||
display: inline-block;
|
||||
padding-left: 10px;
|
||||
line-height: 19px;
|
||||
font-size: var.$checkbox-font-size;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.b(checkbox-button) {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
@include mixins.e(inner) {
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
font-weight: var.$checkbox-font-weight;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
background: var.$button-default-background-color;
|
||||
border: var(--border-base);
|
||||
border-left: 0;
|
||||
color: var.$button-default-font-color;
|
||||
-webkit-appearance: none;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
transition: var.$all-transition;
|
||||
border-radius: 0;
|
||||
@include utils.utils-user-select(none);
|
||||
|
||||
@include button.button-size(
|
||||
var.$button-padding-vertical,
|
||||
var.$button-padding-horizontal,
|
||||
var.$button-font-size
|
||||
);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
& [class*='el-icon-'] {
|
||||
line-height: 0.9;
|
||||
|
||||
& + span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(original) {
|
||||
opacity: 0;
|
||||
outline: none;
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
&.is-checked {
|
||||
& .el-checkbox-button__inner {
|
||||
color: var.$checkbox-button-checked-font-color;
|
||||
background-color: var.$checkbox-button-checked-background-color;
|
||||
border-color: var.$checkbox-button-checked-border-color;
|
||||
box-shadow: -1px 0 0 0 var.$color-primary-light-4;
|
||||
}
|
||||
&:first-child .el-checkbox-button__inner {
|
||||
border-left-color: var.$checkbox-button-checked-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
& .el-checkbox-button__inner {
|
||||
color: var.$button-disabled-font-color;
|
||||
cursor: not-allowed;
|
||||
background-image: none;
|
||||
background-color: var.$button-disabled-background-color;
|
||||
border-color: var.$button-disabled-border-color;
|
||||
box-shadow: none;
|
||||
}
|
||||
&:first-child .el-checkbox-button__inner {
|
||||
border-left-color: var.$button-disabled-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
.el-checkbox-button__inner {
|
||||
border-left: var(--border-base);
|
||||
border-radius: var(--border-radius-base) 0 0 var(--border-radius-base);
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-focus {
|
||||
& .el-checkbox-button__inner {
|
||||
border-color: var.$checkbox-button-checked-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.el-checkbox-button__inner {
|
||||
border-radius: 0 var(--border-radius-base) var(--border-radius-base) 0;
|
||||
}
|
||||
}
|
||||
@include mixins.m(medium) {
|
||||
.el-checkbox-button__inner {
|
||||
border-radius: 0;
|
||||
@include button.button-size(
|
||||
var.$button-medium-padding-vertical,
|
||||
var.$button-medium-padding-horizontal,
|
||||
var.$button-medium-font-size
|
||||
);
|
||||
}
|
||||
}
|
||||
@include mixins.m(small) {
|
||||
.el-checkbox-button__inner {
|
||||
border-radius: 0;
|
||||
@include button.button-size(
|
||||
var.$button-small-padding-vertical,
|
||||
var.$button-small-padding-horizontal,
|
||||
var.$button-small-font-size
|
||||
);
|
||||
}
|
||||
}
|
||||
@include mixins.m(mini) {
|
||||
.el-checkbox-button__inner {
|
||||
border-radius: 0;
|
||||
@include button.button-size(
|
||||
var.$button-mini-padding-vertical,
|
||||
var.$button-mini-padding-horizontal,
|
||||
var.$button-mini-font-size
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.b(checkbox-group) {
|
||||
font-size: 0;
|
||||
}
|
158
packages/design-system/theme/src/col.scss
Normal file
158
packages/design-system/theme/src/col.scss
Normal file
|
@ -0,0 +1,158 @@
|
|||
@use "sass:math";
|
||||
|
||||
@use "./common/var.scss";
|
||||
@use "./mixins/mixins.scss";
|
||||
|
||||
[class*='el-col-'] {
|
||||
float: left;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.el-col-0 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@for $i from 0 through 24 {
|
||||
.el-col-#{$i} {
|
||||
width: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-offset-#{$i} {
|
||||
margin-left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-pull-#{$i} {
|
||||
position: relative;
|
||||
right: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-push-#{$i} {
|
||||
position: relative;
|
||||
left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.res(xs) {
|
||||
.el-col-xs-0 {
|
||||
display: none;
|
||||
}
|
||||
@for $i from 0 through 24 {
|
||||
.el-col-xs-#{$i} {
|
||||
width: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-xs-offset-#{$i} {
|
||||
margin-left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-xs-pull-#{$i} {
|
||||
position: relative;
|
||||
right: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-xs-push-#{$i} {
|
||||
position: relative;
|
||||
left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.res(sm) {
|
||||
.el-col-sm-0 {
|
||||
display: none;
|
||||
}
|
||||
@for $i from 0 through 24 {
|
||||
.el-col-sm-#{$i} {
|
||||
width: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-sm-offset-#{$i} {
|
||||
margin-left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-sm-pull-#{$i} {
|
||||
position: relative;
|
||||
right: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-sm-push-#{$i} {
|
||||
position: relative;
|
||||
left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.res(md) {
|
||||
.el-col-md-0 {
|
||||
display: none;
|
||||
}
|
||||
@for $i from 0 through 24 {
|
||||
.el-col-md-#{$i} {
|
||||
width: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-md-offset-#{$i} {
|
||||
margin-left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-md-pull-#{$i} {
|
||||
position: relative;
|
||||
right: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-md-push-#{$i} {
|
||||
position: relative;
|
||||
left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.res(lg) {
|
||||
.el-col-lg-0 {
|
||||
display: none;
|
||||
}
|
||||
@for $i from 0 through 24 {
|
||||
.el-col-lg-#{$i} {
|
||||
width: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-lg-offset-#{$i} {
|
||||
margin-left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-lg-pull-#{$i} {
|
||||
position: relative;
|
||||
right: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-lg-push-#{$i} {
|
||||
position: relative;
|
||||
left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.res(xl) {
|
||||
.el-col-xl-0 {
|
||||
display: none;
|
||||
}
|
||||
@for $i from 0 through 24 {
|
||||
.el-col-xl-#{$i} {
|
||||
width: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-xl-offset-#{$i} {
|
||||
margin-left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-xl-pull-#{$i} {
|
||||
position: relative;
|
||||
right: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
|
||||
.el-col-xl-push-#{$i} {
|
||||
position: relative;
|
||||
left: (math.div(1, 24) * $i * 100) * 1%;
|
||||
}
|
||||
}
|
||||
}
|
0
packages/design-system/theme/src/collapse-item.scss
Normal file
0
packages/design-system/theme/src/collapse-item.scss
Normal file
63
packages/design-system/theme/src/collapse.scss
Normal file
63
packages/design-system/theme/src/collapse.scss
Normal file
|
@ -0,0 +1,63 @@
|
|||
@use "mixins/mixins";
|
||||
@use "./common/var";
|
||||
@use "common/transition";
|
||||
|
||||
@include mixins.b(collapse) {
|
||||
border-top: 1px solid var.$collapse-border-color;
|
||||
border-bottom: 1px solid var.$collapse-border-color;
|
||||
}
|
||||
@include mixins.b(collapse-item) {
|
||||
@include mixins.when(disabled) {
|
||||
.el-collapse-item__header {
|
||||
color: var.$font-color-disabled-base;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
@include mixins.e(header) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: var.$collapse-header-height;
|
||||
line-height: var.$collapse-header-height;
|
||||
background-color: var.$collapse-header-background-color;
|
||||
color: var.$collapse-header-font-color;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid var.$collapse-border-color;
|
||||
font-size: var.$collapse-header-font-size;
|
||||
font-weight: 500;
|
||||
transition: border-bottom-color 0.3s;
|
||||
outline: none;
|
||||
@include mixins.e(arrow) {
|
||||
margin: 0 8px 0 auto;
|
||||
transition: transform 0.3s;
|
||||
font-weight: 300;
|
||||
@include mixins.when(active) {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
&.focusing:focus:not(:hover) {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
@include mixins.when(active) {
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(wrap) {
|
||||
will-change: height;
|
||||
background-color: var.$collapse-content-background-color;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid var.$collapse-border-color;
|
||||
}
|
||||
|
||||
@include mixins.e(content) {
|
||||
padding-bottom: 25px;
|
||||
font-size: var.$collapse-content-font-size;
|
||||
color: var.$collapse-content-font-color;
|
||||
line-height: 1.769230769230769;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
}
|
382
packages/design-system/theme/src/color-picker.scss
Normal file
382
packages/design-system/theme/src/color-picker.scss
Normal file
|
@ -0,0 +1,382 @@
|
|||
@use "mixins/mixins";
|
||||
@use "mixins/button";
|
||||
@use "./common/var";
|
||||
|
||||
@include mixins.b(color-predefine) {
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
margin-top: 8px;
|
||||
width: 280px;
|
||||
|
||||
@include mixins.e(colors) {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@include mixins.e(color-selector) {
|
||||
margin: 0 0 8px 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
&:nth-child(10n + 1) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
box-shadow: 0 0 3px 2px var(--color-primary);
|
||||
}
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
@include mixins.when(alpha) {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.b(color-hue-slider) {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: 280px;
|
||||
height: 12px;
|
||||
background-color: #f00;
|
||||
padding: 0 2px;
|
||||
|
||||
@include mixins.e(bar) {
|
||||
position: relative;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
#f00 0%,
|
||||
#ff0 17%,
|
||||
#0f0 33%,
|
||||
#0ff 50%,
|
||||
#00f 67%,
|
||||
#f0f 83%,
|
||||
#f00 100%
|
||||
);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@include mixins.e(thumb) {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
border-radius: 1px;
|
||||
background: #fff;
|
||||
border: 1px solid #f0f0f0;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@include mixins.when(vertical) {
|
||||
width: 12px;
|
||||
height: 180px;
|
||||
padding: 2px 0;
|
||||
|
||||
.el-color-hue-slider__bar {
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
#f00 0%,
|
||||
#ff0 17%,
|
||||
#0f0 33%,
|
||||
#0ff 50%,
|
||||
#00f 67%,
|
||||
#f0f 83%,
|
||||
#f00 100%
|
||||
);
|
||||
}
|
||||
|
||||
.el-color-hue-slider__thumb {
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.b(color-svpanel) {
|
||||
position: relative;
|
||||
width: 280px;
|
||||
height: 180px;
|
||||
|
||||
@include mixins.e(('white', 'black')) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
@include mixins.e('white') {
|
||||
background: linear-gradient(to right, #fff, rgba(255, 255, 255, 0));
|
||||
}
|
||||
|
||||
@include mixins.e('black') {
|
||||
background: linear-gradient(to top, #000, rgba(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
@include mixins.e(cursor) {
|
||||
position: absolute;
|
||||
|
||||
> div {
|
||||
cursor: head;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
box-shadow: 0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0, 0, 0, 0.3),
|
||||
0 0 1px 2px rgba(0, 0, 0, 0.4);
|
||||
border-radius: 50%;
|
||||
transform: translate(-2px, -2px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.b(color-alpha-slider) {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: 280px;
|
||||
height: 12px;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
|
||||
|
||||
@include mixins.e(bar) {
|
||||
position: relative;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
rgba(255, 255, 255, 0) 0%,
|
||||
rgba(255, 255, 255, 1) 100%
|
||||
);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@include mixins.e(thumb) {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
border-radius: 1px;
|
||||
background: #fff;
|
||||
border: 1px solid #f0f0f0;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@include mixins.when(vertical) {
|
||||
width: 20px;
|
||||
height: 180px;
|
||||
|
||||
.el-color-alpha-slider__bar {
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
rgba(255, 255, 255, 0) 0%,
|
||||
rgba(255, 255, 255, 1) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.el-color-alpha-slider__thumb {
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.b(color-dropdown) {
|
||||
width: 300px;
|
||||
|
||||
@include mixins.e(main-wrapper) {
|
||||
margin-bottom: 6px;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(btns) {
|
||||
margin-top: 6px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@include mixins.e(value) {
|
||||
float: left;
|
||||
line-height: 26px;
|
||||
font-size: 12px;
|
||||
color: var.$color-black;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
@include mixins.e(btn) {
|
||||
@include button.button-round();
|
||||
@include button.button-small();
|
||||
@include button.button-just-primary();
|
||||
}
|
||||
|
||||
@include mixins.e(link-btn) {
|
||||
@include button.button-round();
|
||||
@include button.button-outline();
|
||||
@include button.button-small();
|
||||
|
||||
margin-right: var(--spacing-2xs);
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.b(color-picker) {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
line-height: normal;
|
||||
height: 40px;
|
||||
|
||||
@include mixins.when(disabled) {
|
||||
.el-color-picker__trigger {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.m(medium) {
|
||||
height: 36px;
|
||||
|
||||
.el-color-picker__trigger {
|
||||
height: 36px;
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
.el-color-picker__mask {
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.m(small) {
|
||||
height: 32px;
|
||||
|
||||
.el-color-picker__trigger {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.el-color-picker__mask {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.el-color-picker__icon,
|
||||
.el-color-picker__empty {
|
||||
transform: translate3d(-50%, -50%, 0) scale(0.8);
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.m(mini) {
|
||||
height: 28px;
|
||||
|
||||
.el-color-picker__trigger {
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
.el-color-picker__mask {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
}
|
||||
|
||||
.el-color-picker__icon,
|
||||
.el-color-picker__empty {
|
||||
transform: translate3d(-50%, -50%, 0) scale(0.8);
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(mask) {
|
||||
height: 38px;
|
||||
width: 38px;
|
||||
border-radius: 4px;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 1px;
|
||||
z-index: 1;
|
||||
cursor: not-allowed;
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
@include mixins.e(trigger) {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
padding: 4px;
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 4px;
|
||||
font-size: 0;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@include mixins.e(color) {
|
||||
position: relative;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #999;
|
||||
border-radius: var(--border-radius-small);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
|
||||
@include mixins.when(alpha) {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.e(color-inner) {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
@include mixins.e(empty) {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
}
|
||||
|
||||
@include mixins.e(icon) {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
color: var.$color-white;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
@include mixins.e(panel) {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
padding: 6px;
|
||||
box-sizing: content-box;
|
||||
background-color: var.$color-white;
|
||||
border: 1px solid var(--border-color-light);
|
||||
border-radius: var(--border-radius-base);
|
||||
box-shadow: var.$dropdown-menu-box-shadow;
|
||||
}
|
||||
}
|
42
packages/design-system/theme/src/common/popup.scss
Normal file
42
packages/design-system/theme/src/common/popup.scss
Normal file
|
@ -0,0 +1,42 @@
|
|||
@use "./var.scss";
|
||||
@use "../mixins/mixins";
|
||||
|
||||
.v-modal-enter {
|
||||
animation: v-modal-in 0.2s ease;
|
||||
}
|
||||
|
||||
.v-modal-leave {
|
||||
animation: v-modal-out 0.2s ease forwards;
|
||||
}
|
||||
|
||||
@keyframes v-modal-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes v-modal-out {
|
||||
0% {
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.v-modal {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: var.$popup-modal-opacity;
|
||||
background: var.$popup-modal-background-color;
|
||||
}
|
||||
|
||||
@include mixins.b(popup-parent) {
|
||||
@include mixins.m(hidden) {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
102
packages/design-system/theme/src/common/transition.scss
Normal file
102
packages/design-system/theme/src/common/transition.scss
Normal file
|
@ -0,0 +1,102 @@
|
|||
@use "./var";
|
||||
|
||||
.fade-in-linear-enter-active,
|
||||
.fade-in-linear-leave-active {
|
||||
transition: var.$fade-linear-transition;
|
||||
}
|
||||
.fade-in-linear-enter,
|
||||
.fade-in-linear-leave,
|
||||
.fade-in-linear-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.el-fade-in-linear-enter-active,
|
||||
.el-fade-in-linear-leave-active {
|
||||
transition: var.$fade-linear-transition;
|
||||
}
|
||||
.el-fade-in-linear-enter,
|
||||
.el-fade-in-linear-leave,
|
||||
.el-fade-in-linear-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.el-fade-in-enter-active,
|
||||
.el-fade-in-leave-active {
|
||||
transition: all 0.3s cubic-bezier(0.55, 0, 0.1, 1);
|
||||
}
|
||||
.el-fade-in-enter,
|
||||
.el-fade-in-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.el-zoom-in-center-enter-active,
|
||||
.el-zoom-in-center-leave-active {
|
||||
transition: all 0.3s cubic-bezier(0.55, 0, 0.1, 1);
|
||||
}
|
||||
.el-zoom-in-center-enter,
|
||||
.el-zoom-in-center-leave-active {
|
||||
opacity: 0;
|
||||
transform: scaleX(0);
|
||||
}
|
||||
|
||||
.el-zoom-in-top-enter-active,
|
||||
.el-zoom-in-top-leave-active {
|
||||
opacity: 1;
|
||||
transform: scaleY(1);
|
||||
transition: var.$md-fade-transition;
|
||||
transform-origin: center top;
|
||||
}
|
||||
.el-zoom-in-top-enter,
|
||||
.el-zoom-in-top-leave-active {
|
||||
opacity: 0;
|
||||
transform: scaleY(0);
|
||||
}
|
||||
|
||||
.el-zoom-in-bottom-enter-active,
|
||||
.el-zoom-in-bottom-leave-active {
|
||||
opacity: 1;
|
||||
transform: scaleY(1);
|
||||
transition: var.$md-fade-transition;
|
||||
transform-origin: center bottom;
|
||||
}
|
||||
.el-zoom-in-bottom-enter,
|
||||
.el-zoom-in-bottom-leave-active {
|
||||
opacity: 0;
|
||||
transform: scaleY(0);
|
||||
}
|
||||
|
||||
.el-zoom-in-left-enter-active,
|
||||
.el-zoom-in-left-leave-active {
|
||||
opacity: 1;
|
||||
transform: scale(1, 1);
|
||||
transition: var.$md-fade-transition;
|
||||
transform-origin: top left;
|
||||
}
|
||||
.el-zoom-in-left-enter,
|
||||
.el-zoom-in-left-leave-active {
|
||||
opacity: 0;
|
||||
transform: scale(0.45, 0.45);
|
||||
}
|
||||
|
||||
.collapse-transition {
|
||||
transition: 0.3s height ease-in-out, 0.3s padding-top ease-in-out,
|
||||
0.3s padding-bottom ease-in-out;
|
||||
}
|
||||
.horizontal-collapse-transition {
|
||||
transition: 0.3s width ease-in-out, 0.3s padding-left ease-in-out,
|
||||
0.3s padding-right ease-in-out;
|
||||
}
|
||||
|
||||
.el-list-enter-active,
|
||||
.el-list-leave-active {
|
||||
transition: all 1s;
|
||||
}
|
||||
.el-list-enter,
|
||||
.el-list-leave-active {
|
||||
opacity: 0;
|
||||
transform: translateY(-30px);
|
||||
}
|
||||
|
||||
.el-opacity-transition {
|
||||
transition: opacity 0.3s cubic-bezier(0.55, 0, 0.1, 1);
|
||||
}
|
66
packages/design-system/theme/src/common/typography.scss
Normal file
66
packages/design-system/theme/src/common/typography.scss
Normal file
|
@ -0,0 +1,66 @@
|
|||
%bold {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.heading1 {
|
||||
font-size: var(--font-size-2xl);
|
||||
line-height: var(--font-line-height-compact);
|
||||
}
|
||||
|
||||
.heading1-bold {
|
||||
@extend %bold, .heading1;
|
||||
}
|
||||
|
||||
.heading2 {
|
||||
font-size: var(--font-size-xl);
|
||||
line-height: var(--font-line-height-loose);
|
||||
}
|
||||
|
||||
.heading2-bold {
|
||||
@extend %bold, .heading2;
|
||||
}
|
||||
|
||||
.heading3 {
|
||||
font-size: var(--font-size-m);
|
||||
line-height: var(--font-line-height-loose);
|
||||
}
|
||||
|
||||
.heading3-bold {
|
||||
@extend %bold, .heading3;
|
||||
}
|
||||
|
||||
.heading4 {
|
||||
font-size: var(--font-size-s);
|
||||
line-height: var(--font-line-height-regular);
|
||||
}
|
||||
|
||||
.heading4-bold {
|
||||
@extend %bold, .heading4;
|
||||
}
|
||||
|
||||
.body-large {
|
||||
font-size: var(--font-size-m);
|
||||
line-height: var(--font-line-height-xloose);
|
||||
}
|
||||
|
||||
.body-large-bold {
|
||||
@extend %bold, .body-large;
|
||||
}
|
||||
|
||||
.body-medium {
|
||||
font-size: var(--font-size-s);
|
||||
line-height: var(--font-line-height-loose);
|
||||
}
|
||||
|
||||
.body-medium-bold {
|
||||
@extend %bold, .body-medium;
|
||||
}
|
||||
|
||||
.body-small {
|
||||
font-size: var(--font-size-2xs);
|
||||
line-height: var(--font-line-height-loose);
|
||||
}
|
||||
|
||||
.body-small-bold {
|
||||
@extend %bold, .body-small;
|
||||
}
|
1191
packages/design-system/theme/src/common/var.scss
Normal file
1191
packages/design-system/theme/src/common/var.scss
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue