diff --git a/.idea/runConfigurations/Gemini_test_single.xml b/.idea/runConfigurations/Gemini_test_single.xml
index a24b01fd4bc..fd3c8830eb2 100644
--- a/.idea/runConfigurations/Gemini_test_single.xml
+++ b/.idea/runConfigurations/Gemini_test_single.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/.idea/runConfigurations/Lint.xml b/.idea/runConfigurations/Lint.xml
new file mode 100644
index 00000000000..4331d4ad47a
--- /dev/null
+++ b/.idea/runConfigurations/Lint.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/button/button.examples.html b/components/button/button.examples.html
index 9f69573294c..702a9c9ddd7 100644
--- a/components/button/button.examples.html
+++ b/components/button/button.examples.html
@@ -8,17 +8,11 @@
:global(.dark) {
background: #000;
}
-
- :global(.inline) {
- display: inline-block;
- padding: 8px;
- }
-
@@ -47,6 +41,20 @@
href="/"
>Button link
+
+
+
+
+
+
{
[
'active', 'primary', 'danger', 'delayed', 'disabled'
@@ -88,6 +96,11 @@
href="/"
>Button link
+
+
{
[
'active', 'primary', 'danger', 'delayed', 'disabled'
@@ -104,37 +117,13 @@
render(dark, document.getElementById('dark'));
- const dynamic = (
-
-
-
-
-
-
-
-
- );
-
- render(dynamic, document.getElementById('dynamic'));
-
- :global(.icon) {
+ #example > :not(:first-child) {
margin-left: 8px;
}
@@ -147,6 +136,7 @@
import React, {Component, Fragment} from 'react';
import {render} from 'react-dom';
import Button from '@jetbrains/ring-ui/components/button/button';
+ import Loader from '@jetbrains/ring-ui/components/loader-inline/loader-inline';
import {HourglassIcon} from '@jetbrains/ring-ui/components/icon';
class Sleeper extends Component {
@@ -175,6 +165,7 @@
+ {loading && }
);
}
diff --git a/components/button/button.gemini.js b/components/button/button.gemini.js
index 103fd992d19..4d424efd615 100644
--- a/components/button/button.gemini.js
+++ b/components/button/button.gemini.js
@@ -2,7 +2,7 @@
gemini.suite('Button', suite => {
suite.
- setUrl('button/button.html').
+ setUrl('button/button.html?block-animations').
setCaptureElements('#buttons', '#dark').
capture('button');
});
diff --git a/components/global/conic-gradient.js b/components/global/conic-gradient.js
new file mode 100644
index 00000000000..29665a1a526
--- /dev/null
+++ b/components/global/conic-gradient.js
@@ -0,0 +1,18 @@
+/* global ConicGradient */
+import 'conic-gradient';
+
+import memoize from './memoize';
+
+const needsFallback = memoize(() => {
+ const div = document.createElement('div');
+ div.style.backgroundImage = 'conic-gradient(white, black)';
+ return !div.style.backgroundImage;
+});
+
+const conicGradient = memoize(stops => (
+ needsFallback()
+ ? new ConicGradient({stops}).toString()
+ : `conic-gradient(${stops})`
+));
+
+export default stops => conicGradient(stops.join(','));
diff --git a/components/global/inject-styles.js b/components/global/inject-styles.js
new file mode 100644
index 00000000000..047195bf78d
--- /dev/null
+++ b/components/global/inject-styles.js
@@ -0,0 +1,12 @@
+export const injectStyleSheet = styles => {
+ const styleTag = document.createElement('style');
+ styleTag.setAttribute('type', 'text/css');
+ styleTag.textContent = styles;
+ document.head.appendChild(styleTag);
+};
+
+export const injectRuleSet = (selector, declarations) =>
+ injectStyleSheet(`
+${selector} {${Object.entries(declarations).map(([property, value]) => `
+ ${property}: ${value};`)}
+}`);
diff --git a/components/global/memoize.js b/components/global/memoize.js
index c621782d76b..9ef91c9520e 100644
--- a/components/global/memoize.js
+++ b/components/global/memoize.js
@@ -1,7 +1,7 @@
export default function memoize(fn) {
const primitiveCache = new Map();
const objectCache = new WeakMap();
- return function memoized(arg) {
+ return function memoized(arg = '__singleValue__') {
const cache = arg instanceof Object ? objectCache : primitiveCache;
if (cache.has(arg)) {
return cache.get(arg);
diff --git a/components/loader-inline/loader-inline.css b/components/loader-inline/loader-inline.css
new file mode 100644
index 00000000000..ab1a0dbd6c1
--- /dev/null
+++ b/components/loader-inline/loader-inline.css
@@ -0,0 +1,62 @@
+@value unit, black-color, white-color from "../global/global.css";
+
+@keyframes spin {
+ 0% {
+ transform: rotate(0);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes pulse {
+ 0% {
+ transform: scale(calc(12 / 16));
+ }
+
+ 100% {
+ transform: scale(calc(17 / 16));
+ }
+}
+
+.loader {
+ position: relative;
+
+ display: inline-block;
+
+ width: calc(unit * 2);
+ height: calc(unit * 2);
+
+ animation: spin 1s linear infinite;
+ vertical-align: -3px;
+
+ &,
+ &::after {
+ transform-origin: center;
+
+ border-radius: unit;
+ }
+
+ &::after {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+
+ content: '';
+ transform: scale(calc(12 / 16));
+ animation: pulse 0.85s cubic-bezier(0.68, 0, 0.74, 0.74) infinite alternate;
+
+ background-color: inherit;
+ }
+}
+
+.light {
+ background-color: white-color;
+}
+
+.dark {
+ background-color: black-color;
+}
diff --git a/components/loader-inline/loader-inline.examples.html b/components/loader-inline/loader-inline.examples.html
new file mode 100644
index 00000000000..9331a0e5875
--- /dev/null
+++ b/components/loader-inline/loader-inline.examples.html
@@ -0,0 +1,85 @@
+
+
+ some text on top
+ before Some text after
+ some text under loader
+
+
+
+ import React from 'react';
+ import {render} from 'react-dom';
+ import Loader from '@jetbrains/ring-ui/components/loader-inline/loader-inline';
+
+ render(, document.getElementById('loader-inline'));
+
+
+
+
+
+
+
some text on top
+
before Some text after
+
some text under loader
+
+
+
+
+ body {
+ background-color: #000;
+ }
+
+ :global(.container) {
+ color: #fff;
+ }
+
+
+
+ import React from 'react';
+ import {render} from 'react-dom';
+ import Loader from '@jetbrains/ring-ui/components/loader-inline/loader-inline';
+
+ render(, document.getElementById('loader-inline'));
+
+
+
+
+
+
+
some text on top
+
before Some text after
+
some text under loader
+
+
+
+
+ body {
+ background-color: #E5F4FF;
+ }
+
+ :global(.loader) {
+ background-color: #E5F4FF;
+ }
+
+
+
+ import React from 'react';
+ import {render} from 'react-dom';
+ import Loader from '@jetbrains/ring-ui/components/loader-inline/loader-inline';
+
+ render(, document.getElementById('loader-inline'));
+
+
+
+
+
+
+
+
+
+ import '@jetbrains/ring-ui/components/loader-inline/loader-inline.scss';
+
+
diff --git a/components/loader-inline/loader-inline.gemini.js b/components/loader-inline/loader-inline.gemini.js
new file mode 100644
index 00000000000..2452d32b61a
--- /dev/null
+++ b/components/loader-inline/loader-inline.gemini.js
@@ -0,0 +1,24 @@
+/* global gemini: false */
+
+gemini.suite('Loader inline', () => {
+ gemini.suite('White background', suite => {
+ suite.
+ setUrl('loader-inline/inline-loader.html?block-animations').
+ setCaptureElements('body').
+ capture('loader');
+ });
+
+ gemini.suite('Black background', suite => {
+ suite.
+ setUrl('loader-inline/inline-loader-on-black-background.html?block-animations').
+ setCaptureElements('body').
+ capture('loader');
+ });
+
+ gemini.suite('Custom background', suite => {
+ suite.
+ setUrl('loader-inline/inline-loader-on-custom-background.html?block-animations').
+ setCaptureElements('body').
+ capture('loader');
+ });
+});
diff --git a/components/loader-inline/loader-inline.js b/components/loader-inline/loader-inline.js
index f0a17e81f99..4903d073a2b 100644
--- a/components/loader-inline/loader-inline.js
+++ b/components/loader-inline/loader-inline.js
@@ -2,64 +2,67 @@ import React, {PureComponent} from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
-import './loader-inline.scss';
+import conicGradient from '../global/conic-gradient';
+import {injectRuleSet} from '../global/inject-styles';
+import Theme from '../global/theme';
+
+import styles from './loader-inline.css';
+
+injectRuleSet(`.${styles[Theme.LIGHT]}`, {
+ 'background-image': conicGradient([
+ '#ff008c',
+ '#ac3cff',
+ '#008eff',
+ '#58ba00',
+ '#f48700',
+ '#ff008c'
+ ])
+});
+
+injectRuleSet(`.${styles[Theme.DARK]}`, {
+ 'background-image': conicGradient([
+ '#ff35a4',
+ '#cd89ff',
+ '#289fff',
+ '#88d444',
+ '#ffe000',
+ '#ff35a4'
+ ])
+});
/**
* @name Loader Inline
* @category Components
+ * @tags Ring UI Language
* @constructor
* @description Displays a small animated loader, shown inline with text. Use case: contextual loading animation.
* @extends {ReactComponent}
- * @example
-
-
- some text on top
- before some text after
- some text under loader
-
-
-
- import React from 'react';
- import {render} from 'react-dom';
- import Loader from '@jetbrains/ring-ui/components/loader-inline/loader-inline';
-
- render(, document.getElementById('loader-inline'));
-
-
-
-
-
-
-
- import '@jetbrains/ring-ui/components/loader-inline/loader-inline';
-
-
+ * @example-file ./loader-inline.examples.html
*/
export default class LoaderInline extends PureComponent {
+ static Theme = Theme;
static propTypes = {
+ theme: PropTypes.oneOf(Object.values(Theme)),
className: PropTypes.string
};
+ static defaultProps = {
+ theme: Theme.LIGHT
+ };
+
render() {
const classes = classNames(
- 'ring-loader-inline',
- this.props.className
+ styles.loader,
+ this.props.className,
+ styles[this.props.theme]
);
return (
+ />
);
}
}
diff --git a/package-lock.json b/package-lock.json
index 61240bea46d..0293da824a5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3649,6 +3649,14 @@
}
}
},
+ "conic-gradient": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/conic-gradient/-/conic-gradient-1.0.0.tgz",
+ "integrity": "sha512-TEmM3Ondx8nid2AN0Rsw6eQG7PgTUkL6gs90UqX1cNqO/bpt/H/Rw6DwbzoylQ9SSxqLG1SsteAr9/yBsAzdtw==",
+ "requires": {
+ "prefixfree": "1.0.0"
+ }
+ },
"connect": {
"version": "3.6.5",
"resolved": "https://registry.npmjs.org/connect/-/connect-3.6.5.tgz",
@@ -17582,6 +17590,11 @@
"posthtml-render": "1.1.1"
}
},
+ "prefixfree": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prefixfree/-/prefixfree-1.0.0.tgz",
+ "integrity": "sha1-grDtu6wQfyo+LcVp1sPfQDXNeRA="
+ },
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
@@ -22314,6 +22327,11 @@
"prepend-http": "1.0.4"
}
},
+ "url-search-params": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/url-search-params/-/url-search-params-0.10.0.tgz",
+ "integrity": "sha512-oFPzmbPAbdthStgffGq8alULe47skPDt1X3KW6NOQnKkcLHP4IS1NfdfHG/CBP5lGsr2gDzNp87pfWLx/eIxjw=="
+ },
"url-slug": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/url-slug/-/url-slug-2.0.0.tgz",
diff --git a/package.json b/package.json
index f3634a29d6e..18803dfe4d7 100644
--- a/package.json
+++ b/package.json
@@ -177,6 +177,7 @@
"classnames": "2.2.5",
"combokeys": "3.0.0",
"compile-code-loader": "0.2.0",
+ "conic-gradient": "^1.0.0",
"css-loader": "0.28.11",
"deep-equal": "1.0.1",
"dom4": "1.8.5",
@@ -208,7 +209,8 @@
"sniffr": "1.1.4",
"style-loader": "0.20.3",
"svg-sprite-loader": "3.7.3",
- "url-loader": "1.0.1"
+ "url-loader": "1.0.1",
+ "url-search-params": "^0.10.0"
},
"engines": {
"node": ">=7.4"
diff --git a/packages/docs/components/example-common.css b/packages/docs/components/example-common.css
index 7f54f2f3ec0..d0151420850 100644
--- a/packages/docs/components/example-common.css
+++ b/packages/docs/components/example-common.css
@@ -11,3 +11,10 @@ body {
font-size: font-size;
line-height: line-height;
}
+
+.blockAnimations *,
+.blockAnimations *::before,
+.blockAnimations *::after {
+ transition: none !important;
+ animation: none !important;
+}
diff --git a/packages/docs/components/example-common.js b/packages/docs/components/example-common.js
index 4fce70e026a..6c6307eca72 100644
--- a/packages/docs/components/example-common.js
+++ b/packages/docs/components/example-common.js
@@ -1,5 +1,10 @@
import 'iframe-resizer/js/iframeResizer.contentWindow';
+import classNames from 'classnames';
+import URLSearchParams from 'url-search-params'
import styles from './example-common.css';
-document.body.className = styles.body;
+const params = new URLSearchParams(location.search.slice(1));
+document.body.className = classNames(styles.body, {
+ [styles.blockAnimations]: params.has('block-animations')
+});
diff --git a/packages/gemini/gemini/screens/Button/button/chrome.png b/packages/gemini/gemini/screens/Button/button/chrome.png
index 621091d7b3e..86c552b6600 100644
Binary files a/packages/gemini/gemini/screens/Button/button/chrome.png and b/packages/gemini/gemini/screens/Button/button/chrome.png differ
diff --git a/packages/gemini/gemini/screens/Button/button/edge.png b/packages/gemini/gemini/screens/Button/button/edge.png
index c9808a78a09..5e6bde1cd50 100644
Binary files a/packages/gemini/gemini/screens/Button/button/edge.png and b/packages/gemini/gemini/screens/Button/button/edge.png differ
diff --git a/packages/gemini/gemini/screens/Button/button/firefox.png b/packages/gemini/gemini/screens/Button/button/firefox.png
index 5ab8f46adb0..97460f488c7 100644
Binary files a/packages/gemini/gemini/screens/Button/button/firefox.png and b/packages/gemini/gemini/screens/Button/button/firefox.png differ
diff --git a/packages/gemini/gemini/screens/Button/button/ie.png b/packages/gemini/gemini/screens/Button/button/ie.png
index 93229c80634..32b3d741071 100644
Binary files a/packages/gemini/gemini/screens/Button/button/ie.png and b/packages/gemini/gemini/screens/Button/button/ie.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/Black background/loader/chrome.png b/packages/gemini/gemini/screens/Loader inline/Black background/loader/chrome.png
new file mode 100644
index 00000000000..eab7f5775fe
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/Black background/loader/chrome.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/Black background/loader/edge.png b/packages/gemini/gemini/screens/Loader inline/Black background/loader/edge.png
new file mode 100644
index 00000000000..6aea5faa070
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/Black background/loader/edge.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/Black background/loader/firefox.png b/packages/gemini/gemini/screens/Loader inline/Black background/loader/firefox.png
new file mode 100644
index 00000000000..26f2a3a1f1b
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/Black background/loader/firefox.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/Black background/loader/ie.png b/packages/gemini/gemini/screens/Loader inline/Black background/loader/ie.png
new file mode 100644
index 00000000000..c2c62bebb76
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/Black background/loader/ie.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/Custom background/loader/chrome.png b/packages/gemini/gemini/screens/Loader inline/Custom background/loader/chrome.png
new file mode 100644
index 00000000000..d82f5d19fd1
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/Custom background/loader/chrome.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/Custom background/loader/edge.png b/packages/gemini/gemini/screens/Loader inline/Custom background/loader/edge.png
new file mode 100644
index 00000000000..0137f8dcb7b
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/Custom background/loader/edge.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/Custom background/loader/firefox.png b/packages/gemini/gemini/screens/Loader inline/Custom background/loader/firefox.png
new file mode 100644
index 00000000000..12b37f3a54c
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/Custom background/loader/firefox.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/Custom background/loader/ie.png b/packages/gemini/gemini/screens/Loader inline/Custom background/loader/ie.png
new file mode 100644
index 00000000000..7e81907eb5d
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/Custom background/loader/ie.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/White background/loader/chrome.png b/packages/gemini/gemini/screens/Loader inline/White background/loader/chrome.png
new file mode 100644
index 00000000000..e5dfdecfce5
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/White background/loader/chrome.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/White background/loader/edge.png b/packages/gemini/gemini/screens/Loader inline/White background/loader/edge.png
new file mode 100644
index 00000000000..32767264194
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/White background/loader/edge.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/White background/loader/firefox.png b/packages/gemini/gemini/screens/Loader inline/White background/loader/firefox.png
new file mode 100644
index 00000000000..f3eed2b9bf8
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/White background/loader/firefox.png differ
diff --git a/packages/gemini/gemini/screens/Loader inline/White background/loader/ie.png b/packages/gemini/gemini/screens/Loader inline/White background/loader/ie.png
new file mode 100644
index 00000000000..6b578d4f6bd
Binary files /dev/null and b/packages/gemini/gemini/screens/Loader inline/White background/loader/ie.png differ