title | category | order |
---|---|---|
Changelog |
Docs |
2 |
0.4.6 — 28-12-2017
ErrorBubble
component was reimplemented usingPopup
. While the API did not change, the implementation has changed drastically. If you were relying on the internals (to customize CSS, for example) please review your implementation.
0.4.0 — 18-12-2017
-
react-markdown
package was updated to version 3.0 which contains breaking changes. Since theMarkdown
component passes props toreact-markdown
, this constitutes a breaking change for Ring UI itself. See the details. -
dependencies.io was set up to help us keep dependencies up-to-date. Most dependencies were updated to latest versions.
0.3.8 — 29-11-2017
- Embedded login flow is now supported: instead of redirecting to and from Hub to perform authentication, a login form
can now be opened in a separate window. Upon successful authentication the service may choose to either reload the page
or to partially update the UI without reloading, which results in a more pleasant login experience for the users.
To enable the new mode, pass
embeddedLogin: true
to Auth configuration. There's also a newenableBackendStatusCheck
option that checks if Hub is up and running before opening the login window or making the redirect. This option is enabled by default.
0.3.0 — 20-11-2017
-
Release 0.3.0 is designed to work with React 16. Moreover,
react
andreact-dom
are no longerdependencies
butpeerDependencies
— make sure to include them in your project'sdependencies
, if you don't have them already. If your project'swebpack.config.js
includes aresolve
section for making sure only one copy of React is loaded, it can now be removed. -
RingComponent
, a base class for all Ring UI components is now gone. The components are now inherited directly fromPureComponent
. If you have your own components usingRingComponent
as the base class, please refactor them:// Before import React from 'react'; import RingComponent from '../ring-component/ring-component'; export default class MyComponent extends RingComponent { ... // RingComponent had its own lifecycle methods, matching the original ones didUpdate(prevProps, prevState) { } } // After import React, {PureComponent} from 'react'; export default class MyComponent extends PureComponent { ... componentDidUpdate(prevProps, prevState) { } }
-
If you were relying on the
rerender
method ofRingComponent
(for example, to trigger re-rendering ofdate-picker
orquery-assist
), special wrapped versions of those components should be used instead. Those wrapped versions include thererender
method for backward compatibility:// Before import DatePicker from "@jetbrains/ring-ui/components/date-picker/date-picker"; // After import {RerenderableDatePicker as DatePicker} from "@jetbrains/ring-ui/components/date-picker/date-picker";
- Hover mode was added to
Dropdown
. Review user-card
component was added. Review- Support for fuzzy search was added to
Select
, passprops.filter = { fuzzy: true }
to activate. Review data-list
component received a major rewrite. Review
React Ng
, a legacy Angular directive for proxying React components was removed.- An ability to import SVG icons as components (
import PencilIcon from '@jetbrains/icons/pencil.svg'
) deprecated earlier was removed.
- Updated lots of dependencies
mout
is no longer a dependency
0.2.10 — 22-08-2017
-
Icon
component now exports icons (@jetbrains/icons
package) and logos (@jetbrains/logos
) as React components. A previously introduced feature of importing them directly from packages is deprecated:// deprecated, will be removed in 0.3 import PencilIcon from '@jetbrains/icons/pencil.svg' import SearchIcon from '@jetbrains/icons/search.svg' import HubLogo from '@jetbrains/logos/hub/hub.svg' <PencilIcon/> <SearchIcon/> <HubLogo/> // Worked before, works now, and will work later import pencilIcon from '@jetbrains/icons/pencil.svg' import searchIcon from '@jetbrains/icons/search.svg' import hubLogo from '@jetbrains/logos/hub/hub.svg' import Icon from '@jetbrains/components/icon/icon' <Icon glyph={pencilIcon}/> <Icon glyph={searchIcon}/> <Icon glyph={hubLogo}/> // Works since 0.2.7. This allows to stop patching ring-ui's `svg-sprite-loader` rule in your webpack config. import {PencilIcon, SearchIcon} from '@jetbrains/components/icon' import {HubLogo} from '@jetbrains/components/icon/logos' // This can dramatically increase your bundle size, so you may want to keep using the above traditional method for logos <PencilIcon/> <SearchIcon/> <HubLogo/> // Also works import Icon, {PencilIcon, SearchIcon} from '@jetbrains/components/icon' import {HubLogo} from '@jetbrains/components/icon/logos' <Icon glyph={PencilIcon}/> <Icon glyph={SearchIcon}/> <Icon glyph={HubLogo}/>
-
Tag
:disabled
prop was added. Review -
Popup
: a custom container can be passed as a prop. Review -
Dialog
: focus is trapped inside dialog. Tabbing outside of the dialog is blocked. You can opt out of this behavior by passingtrapFocus={false}
. Review
Select
: after selecting a tag, the input is cleared. Review
- "Clear" icon on
Select
's button was not clickable in Firefox. Review svg-sprite-loader
was updated to fix rendering of logos in Firefox. Review
0.2.1 — 11-08-2017
- Include icon-runtime-generator.js into package
0.2.0 — 11-08-2017
-
SVG icons can be imported directly as React components. They pass props to the
Icon
component.// Before (and still fully supported) import pencilIcon from '@jetbrains/icons/pencil.svg' import Icon from '@jetbrains/components/icon/icon' <Icon glyph={pencilIcon} size={Icon.Size.Size12} title="edit" /> // After import PencilIcon from '@jetbrains/icons/pencil.svg' <PencilIcon size={PencilIcon.Size.Size12} title="edit" />
-
baseline
option forGrid
component. Review
-
Code
component now comes with a list of highlighed languages. Other languages supported byhighlight.js
can be enabled manually:import {highlight} from '@jetbrains/ring-ui/components/code/code' import lang1c from 'highlight.js/lib/languages/1c'; highlight.registerLanguage('1c', lang1c);
-
DataList
component: "show more / less" functionality was fully rewritten. Review
DataList
: fixed the issue with selection and focus being cleared when toggling a tree element. Review- Various optimizations were applied to reduce app bundle size. Review
@jetbrains/ring-ui
package should be used instead ofring-ui
.- Version was reset to
0.1.1
. To install the latest version, runnpm install --save-exact @jetbrains/ring-ui
. - You may remove the internal registry line from
.npmrc
. - Named imports can be used for importing components:
import {Button, Input} from '@jetbrains/ring-ui'; // You can still import components one by one to reduce bundle size import Button from '@jetbrains/ring-ui/components/button/button'; import Input from '@jetbrains/ring-ui/components/input/input';
- Change the webpack configuration import (if using one) from
require('ring-ui')
torequire('@jetbrains/ring-ui')
.
- The commit history has been rewritten. Please clone the repository anew from
ssh://github.com/JetBrains/ring-ui.git
. - Prepend your commit messages with
[Publish]
to trigger publishing of npm packages.
Private jetbrains-icons
package was replaced with a public one that is hosted on GitHub and available as @jetbrains/icons
in npm. Please update your projects accordingly.
This allows to put the underline right below the descenders, so that it doesn't cross them, and make it 1 physical pixel wide on retina displays.
If you use some non-textual content along with text inside Link
component, you may need to pass a function as a child to Link
, which would take one argument, WrapText
, and use it to wrap the text parts (see example with logo).
Note that WrapText
relies on the fact that it's an inline element, so if, for example, you use flexbox layout inside Link
, you may need an additional div around WrapText
.
The render optimisation logic in List component is delegated to react-virtualized library. Now it works even if the List doesn't have a maxHeight
prop. You may still opt out of the optimization by passing renderOptimization={false}
.
It's not possible to define should
property on null
and undefined
values, so here's a possible workaround:
// Before
expect(foo).to.not.exist;
expect(foo).to.be.null;
expect(foo).to.not.undefined;
// After
should.not.exist(foo);
// Or, if you want to be more specific
(foo === null).should.be.true;
(foo === undefined).should.be.true;
Run npm run bootstrap
to install all the packages' dependencies and link them between each other where needed.
Use header
component instead
Airbnb's enzyme was introduced as a tool for testing React output. Please refer to its API docs and to the list of chai-enzyme
assertions.
When using enzyme, a tough question is which of the shallow/mount/render
helpers to use. Here's a simple checklist for that.
- Use
shallow
by default. Basically, it just tests the output of yourrender
function and often this can be enough - Use
mount
when- some DOM APIs are involved
- testcase relies on
componentDidMount
or refs being called - testcase uses type and/or props of the component being tested (example)
- Use
render
when- the full html output tree is needed
- testing the text content of a node
- using some complex CSS selector, beyond the subset supported by other wrappers
One possible workflow is to start with shallow
, and if something doesn't work as expected, replace with mount
or render
based on the checklist.
Using context(this
) in testcases is discouraged in favour of local variables. This allows using arrow functions for all the testcases, which in turn helps to maintain uniformity.
- before:
/* eslint-disable func-names */ describe('Something', () => { beforeEach(function() { this.foo = makeFoo(); }); it('testcase using foo', function() { this.foo.should.equal(this.foo); }); it('testcase not using foo', () => { true.should.equal(true); }); })
- after:
describe('Something', () => { let foo; beforeEach(() => { foo = makeFoo(); }); it('testcase using foo', () => { foo.should.equal(foo); }); it('testcase not using foo', () => { true.should.equal(true); }); })
Sinon sandbox previously available as this.sinon
became a global variable sandbox
.
25-05-2017: auth parameters have been uniformly named in camelCase. Support for snake_case parameters has been dropped.
Attempting to pass client_id
, redirect_uri
, request_credentials
will throw an exception. Use clientId
, redirectUri
, requestCredentials
instead.
Use brand new Header component instead
The most widely used of them was transform-function-bind
.
- Before:
::this.handleClick
- After:
this.handleClick.bind(this)
Often it's better to declare an arrow property function instead of binding a method on each render.
- Before:
class MyComponent extends Component() { handleClick(e) { ... } render() { return <div onClick={::this.handleClick}/>; } }
- After:
class MyComponent extends Component() { handleClick = e => { ... } render() { return <div onClick={this.handleClick}/>; } }
This was necessary in order to enable tree-shaking.
This affects only CommonJS usages.
- Before:
const Button = require('ring-ui/components/button/button');
- After:
const Button = require('ring-ui/components/button/button').default;
- Even better:
import Button from 'ring-ui/components/button/button';
Use the brand new HTTP
component instead.
Before:
import Auth from 'ring-ui/components/auth/auth';
const auth = new Auth(authConfig);
const services = auth.requestToken().
then(token => auth.getApi('services/header', token));
After:
import Auth from 'ring-ui/components/auth/auth';
import HTTP from 'ring-ui/components/http/http';
const auth = new Auth(authConfig);
const http = new HTTP(auth, auth.getAPIPath());
const services = http.get('services/header');
13-02-2017: Checkbox + ReactNg connection does not support ngModel anymore. Use checkbox-ng instead.
In order to migrate to webpack 2, we have to keep webpack.config clean of properties that don't match the schema.
Since this change config moved to internal property config
, and loaders moved to loaders
properties:
Before:
require('webpack-config-merger')(require('ring-ui'), {
...
});
After:
require('webpack-config-merger')(require('ring-ui').config, {
...
});
Before:
import Header from 'ring-ui/components/header/header';
import HeaderHelper from 'ring-ui/components/header/header__helper';
After:
import Header from 'ring-ui/components/header-legacy/header-legacy';
import HeaderHelper from 'ring-ui/components/header-legacy/header-legacy__helper';
Popup
should now be rendered directly, as any other react childanchorElement
becomes optional, the parent DOM element is used as default anchorcontainer
prop isn't used anymore. Instead, for correct positioning inside scrollable containers, scroll events on anchor ancestors are listened to.- Imperative API is replaced with declarative
Before:
class TogglePopup extends Component {
renderPopup() {
this.popup = Popup.renderPopup(
<Popup
hidden={false}
anchorElement={this.refs.button}
onClose={::this.forceUpdate} // to keep button state in sync with popup
dontCloseOnAnchorClick={true}
autoRemove={false}
>
<div ref="popupContent" />
</Popup>
)
}
toggle() {
if (!this.popup) {
this.renderPopup()
} else if (this.popup.isVisible()) {
this.popup.hide()
} else {
this.popup.show()
}
}
render() {
return (
<Button
ref="button"
active={this.popup && this.popup.isVisible()}
onClick={::this.toggle}
>
Toggle
</Button>
)
}
}
After:
class TogglePopup extends Component {
state = {hidden: false};
toggle() {
this.setState(state => ({hidden: !state.hidden}));
}
render() {
return (
<Button
active={!this.state.hidden}
onClick={::this.toggle}
>
Toggle
// Button becomes anchor here
<Popup
hidden={this.state.hidden}
// This is called on Esc press or outside click. There are also separate handlers for those two events
onCloseAttempt={() => this.setState({hidden: true})}
dontCloseOnAnchorClick={true}
>
// String refs don't work inside Popup. Use functional refs instead:
<div
ref={el => { this.popupContent = el; }}
/>
</Popup>
</Button>
)
}
}
- There are now two ways to use alerts in React: 1) as a pure component with
custom management of alerts' stack (see Alert Container example),
and 2) a simple
alert-service
, which should cover most usages. - Alert now receives the message as its child, not as
caption
prop. - Alert is now closeable by default.
- Alert now has a
timeout
property to define timeout foronCloseRequest
call. - Alert doesn't remove itself anymore. It now calls the
onCloseRequest
callback if it should be removed with an animation. The host component should then set theisClosing={true}
prop which performs the closing animation and calls theonClose
callback after it finishes. - To remove an alert use
{remove, removeWithoutAnimation}
functions from alert-service. - [Angular]
alert-ng
component was removed –alert-service
should be used instead.
- dialog.scss was moved to dialog-ng component because dialog itself has been reimplemented.
- island header and island content now have 32px spacing to suit the most common use case.
18-11-2016: All buttons have type="button" by default. To set another type (e.g. "submit") you have to pass it explicitly
15-11-2016: Footer no longer supports the "ring-footer_floating" modifier, use "floating" prop instead
Before:
<Footer className="ring-footer_floating"/>
After:
<Footer floating={true}/>
Since React prohibits passing non-supported props to DOM elements we now have a whitelist of supported props declared in PropTypes.
Other props are no longer passed to ListItem
and ListCustom
.
29-08-2016: The long-deprecated .ring-input__error-bubble and .ring-form__footer styles were removed
Please migrate to .ring-error-bubble
and .ring-panel
infiniteScrollPackSize should match the value of $top
REST parameter.
Before:
<rg-select ...
with-infinite-scroll="true">
</rg-select>
After:
<rg-select ...
infinite-scroll-pack-size="50">
</rg-select>
To make Ring UI installable with npm install ring-ui
we have changed the versioning scheme.
Before:
2.4.0-4995 (major.minor.patch-build)
After:
2.4.4996 (major.minor.build)
Before:
$palette-array, $palette-white-text, $palette-grey-text
After:
$ring-palette-array, $ring-palette-white-text, $ring-palette-grey-text
Use rgba colors directly as we no longer support ancient IE versions.
Before:
@include rgba-attribute('border-color', rgba(0, 0, 0, 0.15));
After:
border-color: rgba(0, 0, 0, 0.15);
04-04-2016: Browser requirements for Autoprefixer should be specified in the target project (RG-963)
Place a browserslist
file in your project directory.
Default query is > 1%, last 2 versions, Firefox ESR
which currently resolves to:
and_chr 49
and_uc 9.9
android 4.4
chrome 49
chrome 48
edge 13
edge 12
firefox 45
firefox 44
firefox 38
ie 11
ie 10
ie_mob 11
ie_mob 10
ios_saf 9.3
ios_saf 9.0-9.2
ios_saf 8.1-8.4
op_mini 5.0-8.0
opera 36
opera 35
safari 9.1
safari 9
22-04-2016: Permissions: parameter "config" does not have property config.serviceId, use config.services instead
Before:
new Permissions(auth, {serviceId: auth.serviceId})
After:
new Permissions(auth, {services: [auth.serviceId]})
Before:
<Button modifier={Button.Modifiers.BLUE}>{'Button text'}</Button>
After:
<Button blue={true}>{'Button text'}</Button>
03-02-2016: in-space
parameter of rg-permission
and rg-permission-if
directives was renamed to in-project
(RG-750)
Before:
<div rg-permission="space-read" in-space="0-0-0-0-0">
Is visible if user has permission 'read-space' in space 0-0-0-0-0.
</div>
After:
<div rg-permission="project-read" in-project="0-0-0-0-0">
Is visible if user has permission 'read-project' in project 0-0-0-0-0.
</div>
To set the size of the form controls, use the ring-input-size_<size>
class, where <size>
can be "sx" (50px), "s" (100px), "md" (200px) or "l" (400px).
Before:
<div class="ring-form">
<input class="ring-input"/>
...
<input class="ring-input ring-input_long"/>
</div>
After:
<div class="ring-form">
<input class="ring-input ring-input-size_md"/>
...
<input class="ring-input ring-input-size_l"/>
</div>
The arcane bitwise API was replaced with a more straightforward direction specification. "Corner" and "Direction" properties were dropped, "Directions" array was introduced. Example: Before:
props: {
...
Corner: Popup.PopupProps.Corner.BOTTOM_LEFT,
Direction: Popup.PopupProps.Direction.DOWN | Popup.PopupProps.Direction.RIGHT
...
}
After:
props: {
...
Directions: Popup.PopupProps.Directions.BOTTOM_RIGHT
...
}
Please use the rg-save-field
component instead.
Please use ring-input
instead.
jetbrains-icons
(since 1.0.12) and jetbrains-logos
(since 1.0.5) packages now contain compressed SVG images, so there is no more RingSVGOConfig
in webpack.config.js
.
Migration path: update jetbrains-icons
and jetbrains-logos
.
07-12-2015: Changes in markup of ring-input, ring-textarea, error-bubble and ring-form__control (RG-965)
- If ring-input or ring-textarea is used outside of
ring-form__control
, it should have classring-input_medium
(ring-textarea_medium
), otherwise it will have a width of 100% - Class
ring-input_full-width
renamed toring-form__control_full-width
(asring-input
is now full-width by default)
Usages should be updated if you're not using the React component. (See example).
redirect
param in Auth is nowfalse
by defaultredirect
param in Auth doesn't have thebackground-unsafe
value anymore, so it should be removed from project's Auth configs- Background token refresh always uses
request_credentials
modesilent
30-10-2015: webpack.config.js does not provide loaders for applications' code anymore, you will need to set up all the necessary loaders in your project configuration.
30-10-2015: Icons are now loaded using svg-sprite-loader. They were also moved to a separate package (RG-550, RG-834)
Icon's glyph
property now accepts URL from loader instead of ID, e.g. <Icon glyph={require('jetbrains-icons/add.svg')}>
.
jQuery, when.js, and mout are not used anymore.
E.g. you should use import ring-ui/components/react-ng/react-ng
instead of react-ng/react-ng
.
LoaderInline is display: inline-block
by default and shouldn't be used as the main loader anymore.
filter
property doesn't make sense anymore
form-ng__update-text
should be required separately from form-ng
in consuming code
- Renamed
_island.scss
toisland.scss
- Removed
display: block
from the main class and dropped the.ring-island_inline
modifier completely
Use the guest
field of the user object instead. It is included by default in Auth.prototype.requestUser
response.
It's now required to set userFields
in the Auth
config if any fields other than guest, id, name, profile/avatar/url
are needed in auth.requestUser.
Please note that you need to explicitly specify profile
sub-fields to request them, specifying profile
won't do anything.
Example:
var auth = new Auth({
serverUri: 'http://localhost/',
userFields: ['login', 'profile/email']
});