mirror of
https://github.com/qlik-oss/nebula.js.git
synced 2025-12-19 09:48:18 -05:00
chore: switch to react
This commit is contained in:
@@ -9,11 +9,6 @@
|
||||
"extends": [
|
||||
"airbnb"
|
||||
],
|
||||
"settings": {
|
||||
"react": {
|
||||
"pragma": "preact"
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"max-len": 0,
|
||||
"no-plusplus": 0,
|
||||
|
||||
@@ -5,7 +5,7 @@ module.exports = {
|
||||
['@babel/preset-env', { targets: { node: 'current' } }],
|
||||
],
|
||||
plugins: [
|
||||
['@babel/plugin-transform-react-jsx', { pragma: 'preact.h' }],
|
||||
['@babel/plugin-transform-react-jsx'],
|
||||
[
|
||||
'istanbul',
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import preact from 'preact';
|
||||
import render from 'preact-render-to-string';
|
||||
/* eslint object-property-newline:0 */
|
||||
import React from 'react';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
import { AppSelections } from '../../src/components/AppSelections';
|
||||
|
||||
@@ -60,17 +61,18 @@ describe('<AppSelections />', () => {
|
||||
['**/Grid.jsx', () => Grid],
|
||||
['**/Text.jsx', () => Button],
|
||||
], ['../../src/components/AppSelections']);
|
||||
const html = render.render(<AS api={api} />);
|
||||
expect(html).to.equal(`
|
||||
<t>
|
||||
<g>
|
||||
<g>
|
||||
<b d>Back</b>
|
||||
<b>Forward</b>
|
||||
<b>Clear</b>
|
||||
</g>
|
||||
<g></g>
|
||||
</g>
|
||||
</t>`.replace(/\n(\s+)/g, ''));
|
||||
const r = renderer.create(<AS api={api} />);
|
||||
|
||||
expect(r.toJSON()).to.eql({
|
||||
type: 't', props: {}, children: [{
|
||||
type: 'g', props: {}, children: [{
|
||||
type: 'g', props: {}, children: [
|
||||
{ type: 'b', props: { d: true }, children: ['Back'] },
|
||||
{ type: 'b', props: { d: false }, children: ['Forward'] },
|
||||
{ type: 'b', props: { d: false }, children: ['Clear'] },
|
||||
],
|
||||
}, { type: 'g', props: {}, children: null }],
|
||||
}],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,34 +1,67 @@
|
||||
import preact from 'preact';
|
||||
import render from 'preact-render-to-string';
|
||||
import looksLike from 'html-looks-like';
|
||||
import React from 'react';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
import Header from '../../src/components/Header';
|
||||
|
||||
describe('<Header />', () => {
|
||||
it('should be empty when input is falsy', () => {
|
||||
expect(render(<Header />)).to.equal('');
|
||||
expect(render(<Header layout={{ showTitles: true }} />)).to.equal('');
|
||||
expect(renderer.create(<Header />).toJSON()).to.equal(null);
|
||||
expect(renderer.create(<Header layout={{ showTitles: true }} />).toJSON()).to.equal(null);
|
||||
});
|
||||
|
||||
it('should render a title', () => {
|
||||
const layout = { showTitles: true, title: 'foo' };
|
||||
const html = render(<Header layout={layout} />);
|
||||
looksLike(html, `
|
||||
<div>
|
||||
<span>foo</span>
|
||||
<span></span>
|
||||
</div>
|
||||
`);
|
||||
const [{ default: MockedHeader }] = aw.mock([
|
||||
['**/Text.jsx', () => ({ children, ...p }) => <span {...p}>{children}</span>],
|
||||
], ['../../src/components/Header']);
|
||||
const tree = renderer.create(<MockedHeader layout={layout} />).toJSON();
|
||||
expect(tree).to.eql({
|
||||
type: 'div',
|
||||
props: {
|
||||
style: { background: 'transparent', padding: '0 8px' },
|
||||
},
|
||||
children: [{
|
||||
type: 'span',
|
||||
props: { block: true, nowrap: true, size: 'large' },
|
||||
children: ['foo'],
|
||||
}, {
|
||||
type: 'span',
|
||||
props: {
|
||||
faded: true,
|
||||
block: true,
|
||||
nowrap: true,
|
||||
size: 'small',
|
||||
},
|
||||
children: null,
|
||||
}],
|
||||
});
|
||||
});
|
||||
|
||||
it('should render a subtitle', () => {
|
||||
const layout = { showTitles: true, subtitle: 'foo' };
|
||||
const html = render(<Header layout={layout} />);
|
||||
looksLike(html, `
|
||||
<div>
|
||||
<span></span>
|
||||
<span>foo</span>
|
||||
</div>
|
||||
`);
|
||||
const [{ default: MockedHeader }] = aw.mock([
|
||||
['**/Text.jsx', () => ({ children, ...p }) => <span {...p}>{children}</span>],
|
||||
], ['../../src/components/Header']);
|
||||
const tree = renderer.create(<MockedHeader layout={layout} />).toJSON();
|
||||
expect(tree).to.eql({
|
||||
type: 'div',
|
||||
props: {
|
||||
style: { background: 'transparent', padding: '0 8px' },
|
||||
},
|
||||
children: [{
|
||||
type: 'span',
|
||||
props: { block: true, nowrap: true, size: 'large' },
|
||||
children: null,
|
||||
}, {
|
||||
type: 'span',
|
||||
props: {
|
||||
faded: true,
|
||||
block: true,
|
||||
nowrap: true,
|
||||
size: 'small',
|
||||
},
|
||||
children: ['foo'],
|
||||
}],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import preact from 'preact';
|
||||
import render from 'preact-render-to-string';
|
||||
import React from 'react';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
import SelectionToolbar from '../../src/components/SelectionToolbar';
|
||||
|
||||
@@ -25,7 +25,13 @@ describe('<SelectionToolbar />', () => {
|
||||
selectionToolbar: { items: [{ key: 'mine', type: 'random' }] },
|
||||
},
|
||||
};
|
||||
st = new SelectionToolbar(props);
|
||||
const STItem = () => '';
|
||||
const styled = () => ['classes'];
|
||||
const [{ default: STB }] = aw.mock([
|
||||
['**/SelectionToolbarItem.jsx', () => STItem],
|
||||
['**/styled.js', () => styled],
|
||||
], ['../../src/components/SelectionToolbar']);
|
||||
st = new STB(props);
|
||||
});
|
||||
|
||||
it('should have a confirm item', () => {
|
||||
@@ -108,13 +114,17 @@ describe('<SelectionToolbar />', () => {
|
||||
selectionToolbar: { items: [{ key: 'mine' }] },
|
||||
},
|
||||
};
|
||||
const STItem = ({ key, isCustom }) => `-${key}:${isCustom}-`;
|
||||
const STItem = ({ isCustom }) => `-${isCustom}-`;
|
||||
const styled = () => ['a'];
|
||||
const [{ default: STB }] = aw.mock([
|
||||
['**/SelectionToolbarItem.jsx', () => STItem],
|
||||
['**/styled.js', () => styled],
|
||||
], ['../../src/components/SelectionToolbar']);
|
||||
const html = render.render(<STB sn={props.sn} />);
|
||||
expect(html).to.equal('<div class="a">-mine:true--clear:false--cancel:false--confirm:false-</div>');
|
||||
const c = renderer.create(<STB sn={props.sn} />);
|
||||
expect(c.toJSON()).to.eql({
|
||||
type: 'div',
|
||||
props: { className: 'a' },
|
||||
children: ['-true-', '-false-', '-false-', '-false-'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,9 +22,10 @@
|
||||
"devDependencies": {
|
||||
"@nebula.js/supernova": "^0.1.0",
|
||||
"@nebula.js/ui": "^0.1.0",
|
||||
"html-looks-like": "^1.0.3",
|
||||
"node-event-emitter": "^0.0.1",
|
||||
"preact": "^8.4.2",
|
||||
"preact-render-to-string": "^4.1.0"
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-leonardo-ui": "^0.15.0",
|
||||
"react-test-renderer": "^16.8.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import SelectionsBack from '@nebula.js/ui/icons/SelectionsBack';
|
||||
import SelectionsForward from '@nebula.js/ui/icons/SelectionsForward';
|
||||
@@ -121,7 +122,7 @@ function MultiState({
|
||||
);
|
||||
}
|
||||
|
||||
export class AppSelections extends preact.Component {
|
||||
export class AppSelections extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
@@ -201,7 +202,7 @@ export default function mount({
|
||||
element,
|
||||
api,
|
||||
}) {
|
||||
const reference = preact.render(
|
||||
ReactDOM.render(
|
||||
<AppSelections
|
||||
api={api}
|
||||
/>,
|
||||
@@ -209,7 +210,7 @@ export default function mount({
|
||||
);
|
||||
|
||||
const unmount = () => {
|
||||
preact.render('', element, reference);
|
||||
ReactDOM.unmountComponentAtNode(element);
|
||||
};
|
||||
|
||||
return () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
import Grid from '@nebula.js/ui/components/Grid';
|
||||
import styled from '@nebula.js/ui/components/styled';
|
||||
@@ -42,7 +42,7 @@ const Content = ({ children }) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
class Cell extends preact.Component {
|
||||
class Cell extends React.Component {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.styledClasses = ['nebulajs', ...styled({
|
||||
@@ -52,6 +52,7 @@ class Cell extends preact.Component {
|
||||
fontFamily: '$fontFamily',
|
||||
color: '$grey25',
|
||||
})].join(' ');
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
componentDidCatch() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
import { prefixer } from '../utils/utils';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
import Text from '@nebula.js/ui/components/Text';
|
||||
import Grid from '@nebula.js/ui/components/Grid';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
import Text from '@nebula.js/ui/components/Text';
|
||||
|
||||
const Header = ({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
const Component = () => (
|
||||
<div> </div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
const Component = () => (
|
||||
<div>More stuff required</div>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
import styled from '@nebula.js/ui/components/styled';
|
||||
|
||||
import Item from './SelectionToolbarItem';
|
||||
|
||||
class Component extends preact.Component {
|
||||
class Component extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const api = props.sn.component.selections;
|
||||
@@ -24,7 +24,7 @@ class Component extends preact.Component {
|
||||
background: '$grey100',
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
});
|
||||
}).join(' ');
|
||||
|
||||
const items = [];
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
import ButtonInline from '@nebula.js/ui/components/ButtonInline';
|
||||
|
||||
@@ -12,7 +12,7 @@ const ICONS = {
|
||||
'clear-selections': ClearSelections,
|
||||
};
|
||||
|
||||
export default class Item extends preact.Component {
|
||||
export default class Item extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
const constrainElement = (el, d) => {
|
||||
/* eslint-disable no-param-reassign */
|
||||
@@ -88,7 +88,7 @@ const scheduleRender = (props, prev, initial, contentElement) => {
|
||||
return prom;
|
||||
};
|
||||
|
||||
class Supernova extends preact.Component {
|
||||
class Supernova extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.initial = {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Cell from './Cell';
|
||||
|
||||
export default function boot({
|
||||
element,
|
||||
model,
|
||||
}, props, config) {
|
||||
const reference = preact.render(
|
||||
ReactDOM.render(
|
||||
<Cell
|
||||
{...props}
|
||||
model={model}
|
||||
@@ -14,14 +15,14 @@ export default function boot({
|
||||
);
|
||||
|
||||
const unmount = () => {
|
||||
preact.render('', element, reference);
|
||||
ReactDOM.unmountComponentAtNode(element);
|
||||
};
|
||||
|
||||
const update = (p) => {
|
||||
preact.render(<Cell
|
||||
ReactDOM.render(<Cell
|
||||
{...p}
|
||||
model={model}
|
||||
/>, element, reference);
|
||||
/>, element);
|
||||
};
|
||||
|
||||
model.once('closed', unmount);
|
||||
@@ -31,6 +32,5 @@ export default function boot({
|
||||
update(p);
|
||||
},
|
||||
unmount,
|
||||
reference,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
import styled from './styled';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
import styled from './styled';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
import styled from './styled';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
import styled from './styled';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import preact from 'preact';
|
||||
import React from 'react';
|
||||
|
||||
function getFontSize(size) {
|
||||
if (size === 'large') {
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
"keywords": [],
|
||||
"scripts": {},
|
||||
"devDependencies": {
|
||||
"preact": "^8.4.2"
|
||||
"react": "^16.8.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,15 +29,23 @@ const browserList = [
|
||||
];
|
||||
|
||||
const GLOBALS = {
|
||||
react: 'React',
|
||||
'react-dom': 'ReactDOM',
|
||||
};
|
||||
|
||||
const EXTERNALS = [
|
||||
'react',
|
||||
'react-dom',
|
||||
'react-leonardo-ui',
|
||||
];
|
||||
|
||||
const config = (isEsm) => {
|
||||
const outputFile = isEsm ? pkg.module : pkg.main;
|
||||
const basename = path.basename(outputFile);
|
||||
const dir = path.dirname(outputFile);
|
||||
const umdName = basename.replace(/-([a-z])/g, (m, p1) => p1.toUpperCase()).split('.js').join('');
|
||||
|
||||
const external = isEsm ? Object.keys(pkg.dependencies || {}) : [];
|
||||
const external = [...EXTERNALS, ...(isEsm ? Object.keys(pkg.dependencies || {}) : [])];
|
||||
const globals = {};
|
||||
external.forEach((e) => {
|
||||
if ([GLOBALS[e]]) {
|
||||
@@ -76,7 +84,7 @@ const config = (isEsm) => {
|
||||
}],
|
||||
],
|
||||
plugins: [
|
||||
['@babel/plugin-transform-react-jsx', { pragma: 'preact.h' }],
|
||||
['@babel/plugin-transform-react-jsx'],
|
||||
],
|
||||
}),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user