TECH;Localization doc page

This commit is contained in:
Roman Jaroš 2020-01-22 20:41:12 +01:00
parent 6940d3911a
commit 31d409c69d
48 changed files with 654 additions and 229 deletions

2
Jenkinsfile vendored
View file

@ -20,7 +20,7 @@ node {
sh "npm run test"
}
stage("build") {
sh "npm run build:doc"
sh "npm run build:app"
}
stage("release") {
if (env.BRANCH_NAME.startsWith("release/") && !isReleaseCommit()) {

View file

@ -1,5 +1,5 @@
import React from 'react';
import { hot } from 'react-hot-loader';
// import { hot } from 'react-hot-loader';
import { Route, Router } from 'react-router';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@ -27,6 +27,7 @@ import SliderPage from 'documentation/pages/SliderPage/components';
import ToasterPage from 'documentation/pages/ToasterPage/components';
import { THEME } from 'documentation/constants';
import { MenuLocalization } from 'documentation/localization/menu';
import LocalizationPage from 'documentation/pages/LocalizationPage';
import { MainStyle } from '../styles/App';
import { StyledUserName, StyledUserContainer } from '../styles/User';
@ -68,7 +69,8 @@ const App = (): React.ReactElement => {
},
{
label: getLabelMessage(MenuLocalization.localization),
href: '/',
href: '/localization',
subMenu: [{ label: 'Advanced', href: '/localization-advanced' }],
},
];
@ -98,6 +100,7 @@ const App = (): React.ReactElement => {
>
<Router history={history}>
<Route path="/" exact component={WelcomePage} />
{/* Components */}
<Route path="/button" component={ButtonPage} />
<Route path="/calendar" component={CalendarPage} />
<Route path="/checkbox" component={CheckboxPage} />
@ -114,6 +117,9 @@ const App = (): React.ReactElement => {
<Route path="/signout" component={SignOutPage} />
<Route path="/slider" component={SliderPage} />
<Route path="/toaster" component={ToasterPage} />
{/* Localization */}
<Route path="/localization" component={LocalizationPage} />
<Route path="/localization-advanced" component={LocalizationPage} />
</Router>
</PageLayout>
</MainStyle>
@ -121,4 +127,4 @@ const App = (): React.ReactElement => {
);
};
export default hot(module)(App);
export default App;

View file

@ -33,19 +33,19 @@ const DocTable = (props: IProps): React.ReactElement => {
},
comment: {
component: (
<React.Fragment>
<>
{prop.comment.split('\n').map((i, key) => (
<div key={key}>{i}</div>
))}
</React.Fragment>
</>
),
},
}))(props.propDefinition);
return (
<React.Fragment>
<>
<Table cols={cols()} rows={rows} />
</React.Fragment>
</>
);
};

View file

@ -0,0 +1,17 @@
import styled from '@romanjaros/treejs-components/styled';
const InlineCode = styled.span.attrs({
className: 'InlineCode',
})`
font-size: 14px;
font-family: monospace;
background-color: ${p => p.theme.gray};
color: ${p => p.theme.black};
padding: 4px 5px;
border-radius: 6px;
`;
export default InlineCode;

View file

@ -122,8 +122,14 @@ exports[`(component) App should match snapshot 1`] = `
],
},
Object {
"href": "/",
"href": "/localization",
"label": "Localization",
"subMenu": Array [
Object {
"href": "/localization-advanced",
"label": "Advanced",
},
],
},
]
}
@ -284,6 +290,14 @@ exports[`(component) App should match snapshot 1`] = `
component={[Function]}
path="/toaster"
/>
<Route
component={[Function]}
path="/localization"
/>
<Route
component={[Function]}
path="/localization-advanced"
/>
</Router>
</PageLayout>
</styled.div>

View file

@ -34,7 +34,7 @@ const store = createStore(
),
);
initLocalization({ lng: window.localStorage.getItem(LANGUAGE) as string | 'cs' });
initLocalization({ lng: window.localStorage.getItem(LANGUAGE) as string || 'cs' });
addLocalization(localization);
render(

View file

@ -4,7 +4,7 @@ export const button: InternalButtonLocalization = {
default: 'výchozí',
send: 'odeslat',
disabled: 'neaktivní',
status: 'status',
status: 'Podle stavu',
};
export default button;

View file

@ -3,6 +3,7 @@ import { localizationWithNamespace } from '@romanjaros/treejs-localization/decor
const withNS = localizationWithNamespace('color');
export class InternalColorLocalization {
@withNS public main: string;
@withNS public purple: string;
@withNS public blue: string;
@withNS public green: string;

View file

@ -1,6 +1,7 @@
import { InternalColorLocalization } from '..';
export const color: InternalColorLocalization = {
main: 'bez témy',
purple: 'fialová',
blue: 'modrá',
green: 'zelená',

View file

@ -1,6 +1,7 @@
import { InternalColorLocalization } from '..';
export const color: InternalColorLocalization = {
main: 'no theme',
purple: 'purple',
blue: 'blue',
green: 'green',

View file

@ -21,6 +21,13 @@ const ButtonPage = (): React.ReactElement => {
<>
<h2>{getLabelMessage(MenuLocalization.button)}</h2>
Pro import komponenty použijte
<Grid>
<GridCol size={6}>
<Code code={`import Button from '@romanjaros/treejs-components/Button';`} language="js" />
</GridCol>
</Grid>
<h3>{getLabelMessage(ButtonLocalization.default)}</h3>
<Grid>
<GridCol size={3}>

View file

@ -14,14 +14,14 @@
},
"typeParameter": [
{
"id": 14,
"id": 16,
"name": "S",
"kind": 131072,
"kindString": "Type parameter",
"flags": {}
},
{
"id": 15,
"id": 17,
"name": "SS",
"kind": 131072,
"kindString": "Type parameter",
@ -50,10 +50,10 @@
"type": "intrinsic",
"name": "string"
},
"defaultValue": "\"TestComponent\""
"defaultValue": "\"Button\""
},
{
"id": 40,
"id": 42,
"name": "UNSAFE_componentWillMount",
"kind": 2048,
"kindString": "Method",
@ -63,7 +63,7 @@
},
"signatures": [
{
"id": 41,
"id": 43,
"name": "UNSAFE_componentWillMount",
"kind": 4096,
"kindString": "Call signature",
@ -109,7 +109,7 @@
}
},
{
"id": 46,
"id": 48,
"name": "UNSAFE_componentWillReceiveProps",
"kind": 2048,
"kindString": "Method",
@ -119,7 +119,7 @@
},
"signatures": [
{
"id": 47,
"id": 49,
"name": "UNSAFE_componentWillReceiveProps",
"kind": 4096,
"kindString": "Call signature",
@ -144,7 +144,7 @@
},
"parameters": [
{
"id": 48,
"id": 50,
"name": "nextProps",
"kind": 32768,
"kindString": "Parameter",
@ -168,7 +168,7 @@
}
},
{
"id": 49,
"id": 51,
"name": "nextContext",
"kind": 32768,
"kindString": "Parameter",
@ -202,7 +202,7 @@
}
},
{
"id": 55,
"id": 57,
"name": "UNSAFE_componentWillUpdate",
"kind": 2048,
"kindString": "Method",
@ -212,7 +212,7 @@
},
"signatures": [
{
"id": 56,
"id": 58,
"name": "UNSAFE_componentWillUpdate",
"kind": 4096,
"kindString": "Call signature",
@ -237,7 +237,7 @@
},
"parameters": [
{
"id": 57,
"id": 59,
"name": "nextProps",
"kind": 32768,
"kindString": "Parameter",
@ -261,7 +261,7 @@
}
},
{
"id": 58,
"id": 60,
"name": "nextState",
"kind": 32768,
"kindString": "Parameter",
@ -278,7 +278,7 @@
}
},
{
"id": 59,
"id": 61,
"name": "nextContext",
"kind": 32768,
"kindString": "Parameter",
@ -312,7 +312,7 @@
}
},
{
"id": 25,
"id": 27,
"name": "componentDidCatch",
"kind": 2048,
"kindString": "Method",
@ -322,7 +322,7 @@
},
"signatures": [
{
"id": 26,
"id": 28,
"name": "componentDidCatch",
"kind": 4096,
"kindString": "Call signature",
@ -332,7 +332,7 @@
},
"parameters": [
{
"id": 27,
"id": 29,
"name": "error",
"kind": 32768,
"kindString": "Parameter",
@ -343,7 +343,7 @@
}
},
{
"id": 28,
"id": 30,
"name": "errorInfo",
"kind": 32768,
"kindString": "Parameter",
@ -377,7 +377,7 @@
}
},
{
"id": 16,
"id": 18,
"name": "componentDidMount",
"kind": 2048,
"kindString": "Method",
@ -387,7 +387,7 @@
},
"signatures": [
{
"id": 17,
"id": 19,
"name": "componentDidMount",
"kind": 4096,
"kindString": "Call signature",
@ -418,7 +418,7 @@
}
},
{
"id": 33,
"id": 35,
"name": "componentDidUpdate",
"kind": 2048,
"kindString": "Method",
@ -428,7 +428,7 @@
},
"signatures": [
{
"id": 34,
"id": 36,
"name": "componentDidUpdate",
"kind": 4096,
"kindString": "Call signature",
@ -439,7 +439,7 @@
},
"parameters": [
{
"id": 35,
"id": 37,
"name": "prevProps",
"kind": 32768,
"kindString": "Parameter",
@ -463,7 +463,7 @@
}
},
{
"id": 36,
"id": 38,
"name": "prevState",
"kind": 32768,
"kindString": "Parameter",
@ -480,7 +480,7 @@
}
},
{
"id": 37,
"id": 39,
"name": "snapshot",
"kind": 32768,
"kindString": "Parameter",
@ -516,7 +516,7 @@
}
},
{
"id": 38,
"id": 40,
"name": "componentWillMount",
"kind": 2048,
"kindString": "Method",
@ -526,7 +526,7 @@
},
"signatures": [
{
"id": 39,
"id": 41,
"name": "componentWillMount",
"kind": 4096,
"kindString": "Call signature",
@ -572,7 +572,7 @@
}
},
{
"id": 42,
"id": 44,
"name": "componentWillReceiveProps",
"kind": 2048,
"kindString": "Method",
@ -582,7 +582,7 @@
},
"signatures": [
{
"id": 43,
"id": 45,
"name": "componentWillReceiveProps",
"kind": 4096,
"kindString": "Call signature",
@ -607,7 +607,7 @@
},
"parameters": [
{
"id": 44,
"id": 46,
"name": "nextProps",
"kind": 32768,
"kindString": "Parameter",
@ -631,7 +631,7 @@
}
},
{
"id": 45,
"id": 47,
"name": "nextContext",
"kind": 32768,
"kindString": "Parameter",
@ -665,7 +665,7 @@
}
},
{
"id": 23,
"id": 25,
"name": "componentWillUnmount",
"kind": 2048,
"kindString": "Method",
@ -675,7 +675,7 @@
},
"signatures": [
{
"id": 24,
"id": 26,
"name": "componentWillUnmount",
"kind": 4096,
"kindString": "Call signature",
@ -706,7 +706,7 @@
}
},
{
"id": 50,
"id": 52,
"name": "componentWillUpdate",
"kind": 2048,
"kindString": "Method",
@ -716,7 +716,7 @@
},
"signatures": [
{
"id": 51,
"id": 53,
"name": "componentWillUpdate",
"kind": 4096,
"kindString": "Call signature",
@ -741,7 +741,7 @@
},
"parameters": [
{
"id": 52,
"id": 54,
"name": "nextProps",
"kind": 32768,
"kindString": "Parameter",
@ -765,7 +765,7 @@
}
},
{
"id": 53,
"id": 55,
"name": "nextState",
"kind": 32768,
"kindString": "Parameter",
@ -782,7 +782,7 @@
}
},
{
"id": 54,
"id": 56,
"name": "nextContext",
"kind": 32768,
"kindString": "Parameter",
@ -816,7 +816,7 @@
}
},
{
"id": 29,
"id": 31,
"name": "getSnapshotBeforeUpdate",
"kind": 2048,
"kindString": "Method",
@ -826,7 +826,7 @@
},
"signatures": [
{
"id": 30,
"id": 32,
"name": "getSnapshotBeforeUpdate",
"kind": 4096,
"kindString": "Call signature",
@ -837,7 +837,7 @@
},
"parameters": [
{
"id": 31,
"id": 33,
"name": "prevProps",
"kind": 32768,
"kindString": "Parameter",
@ -861,7 +861,7 @@
}
},
{
"id": 32,
"id": 34,
"name": "prevState",
"kind": 32768,
"kindString": "Parameter",
@ -910,7 +910,7 @@
}
},
{
"id": 12,
"id": 14,
"name": "render",
"kind": 2048,
"kindString": "Method",
@ -920,7 +920,7 @@
},
"signatures": [
{
"id": 13,
"id": 15,
"name": "render",
"kind": 4096,
"kindString": "Call signature",
@ -934,13 +934,13 @@
"sources": [
{
"fileName": "src/Button/index.tsx",
"line": 39,
"line": 43,
"character": 14
}
]
},
{
"id": 18,
"id": 20,
"name": "shouldComponentUpdate",
"kind": 2048,
"kindString": "Method",
@ -950,7 +950,7 @@
},
"signatures": [
{
"id": 19,
"id": 21,
"name": "shouldComponentUpdate",
"kind": 4096,
"kindString": "Call signature",
@ -961,7 +961,7 @@
},
"parameters": [
{
"id": 20,
"id": 22,
"name": "nextProps",
"kind": 32768,
"kindString": "Parameter",
@ -985,7 +985,7 @@
}
},
{
"id": 21,
"id": 23,
"name": "nextState",
"kind": 32768,
"kindString": "Parameter",
@ -1002,7 +1002,7 @@
}
},
{
"id": 22,
"id": 24,
"name": "nextContext",
"kind": 32768,
"kindString": "Parameter",
@ -1034,6 +1034,60 @@
"type": "reference",
"name": "ComponentLifecycle.shouldComponentUpdate"
}
},
{
"id": 12,
"name": "defaultProps",
"kind": 2097152,
"kindString": "Object literal",
"flags": {
"isPublic": true,
"isStatic": true,
"isExported": true
},
"children": [
{
"id": 13,
"name": "status",
"kind": 32,
"kindString": "Variable",
"flags": {
"isExported": true
},
"sources": [
{
"fileName": "src/Button/index.tsx",
"line": 34,
"character": 8
}
],
"type": {
"type": "reference",
"name": "STATUS"
},
"defaultValue": " STATUS.none"
}
],
"groups": [
{
"title": "Variables",
"kind": 32,
"children": [
13
]
}
],
"sources": [
{
"fileName": "src/Button/index.tsx",
"line": 33,
"character": 27
}
],
"type": {
"type": "intrinsic",
"name": "object"
}
}
],
"groups": [
@ -1048,19 +1102,26 @@
"title": "Methods",
"kind": 2048,
"children": [
40,
46,
55,
25,
16,
33,
38,
42,
23,
50,
29,
12,
18
48,
57,
27,
18,
35,
40,
44,
25,
52,
31,
14,
20
]
},
{
"title": "Object literals",
"kind": 2097152,
"children": [
12
]
}
],

View file

@ -7,6 +7,7 @@ import { generateDocumentationObject } from 'documentation/utils/documentation';
import DocTable from 'documentation/components/DocTable';
import { groups, children } from '../typedoc.json';
import Code from 'documentation/components/Code';
const propDefinition = generateDocumentationObject(groups, children);
@ -14,10 +15,31 @@ const CalendarPage = (): React.ReactElement => (
<>
<h2>Calendar</h2>
<h3>Normal</h3>
Pro import komponenty použijte
<Grid>
<GridCol size={6}>
<Calendar name="calendar" title="Kalendář" />
<Code code={`import Calendar from '@romanjaros/treejs-components/Calendar';`} language="js" />
</GridCol>
</Grid>
<Grid>
<GridCol size={6}>
<Grid>
<GridCol size={12}>
<Calendar name="calendar" title="Kalendář" />
</GridCol>
<GridCol size={12}>
<Code
language="jsx"
code={`
<Calendar
title="Kalendář"
name="calendar"
/>
`}
/>
</GridCol>
</Grid>
</GridCol>
</Grid>

View file

@ -66,7 +66,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 40,
"line": 43,
"character": 3
}
],
@ -754,7 +754,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 58,
"line": 61,
"character": 26
}
],
@ -1250,7 +1250,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 184,
"line": 187,
"character": 14
}
],
@ -1583,7 +1583,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 39,
"line": 42,
"character": 8
}
],
@ -1606,7 +1606,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 38,
"line": 41,
"character": 27
}
],
@ -1667,7 +1667,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 37,
"line": 40,
"character": 14
}
],
@ -1705,10 +1705,13 @@
"flags": {
"isOptional": true
},
"comment": {
"shortText": "For example 'DD.MM.YYYY'"
},
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 24,
"line": 27,
"character": 7
}
],
@ -2077,7 +2080,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 25,
"line": 28,
"character": 6
}
],
@ -2106,7 +2109,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 22,
"line": 23,
"character": 16
}
],
@ -2139,7 +2142,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 29,
"line": 32,
"character": 14
}
],
@ -2157,7 +2160,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 30,
"line": 33,
"character": 12
}
],
@ -2175,7 +2178,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 31,
"line": 34,
"character": 26
}
],
@ -2195,7 +2198,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 32,
"line": 35,
"character": 6
}
],
@ -2220,7 +2223,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 28,
"line": 31,
"character": 16
}
]
@ -2236,7 +2239,7 @@
"sources": [
{
"fileName": "treejs-components/src/Calendar/index.tsx",
"line": 35,
"line": 38,
"character": 17
}
],

View file

@ -12,7 +12,7 @@ const propDefinition = generateDocumentationObject(groups, children);
const CheckboxPage = (): React.ReactElement => {
return (
<React.Fragment>
<>
<h2>Checkbox</h2>
<h3>Normal</h3>
@ -31,7 +31,7 @@ const CheckboxPage = (): React.ReactElement => {
<h4>Props</h4>
<DocTable propDefinition={propDefinition} />
</React.Fragment>
</>
);
};

View file

@ -11,7 +11,7 @@ import { groups, children } from '../typedoc.json';
const propDefinition = generateDocumentationObject(groups, children);
const SelectBoxPage = (): React.ReactElement => (
<React.Fragment>
<>
<h2>DatePicker</h2>
<h3>Normal</h3>
@ -23,7 +23,7 @@ const SelectBoxPage = (): React.ReactElement => (
<h4>Props</h4>
<DocTable propDefinition={propDefinition} />
</React.Fragment>
</>
);
export default SelectBoxPage;

View file

@ -20,7 +20,7 @@ interface IProps {
const FetchPage = (props: IProps): React.ReactElement => {
return (
<React.Fragment>
<>
<h2>Fetch endpoint</h2>
<h3>Uživatel</h3>
@ -35,7 +35,7 @@ const FetchPage = (props: IProps): React.ReactElement => {
<ContentLoader isLoading={props.isFetching}>
<pre>{JSON.stringify(props.response, undefined, 2)}</pre>
</ContentLoader>
</React.Fragment>
</>
);
};

View file

@ -42,7 +42,7 @@ export class CustomComponentForm extends React.PureComponent implements IForm<Fo
validationSchema={this.validationSchema}
>
{({ errors }): React.ReactElement => (
<React.Fragment>
<>
<Grid>
<GridCol size={3}>
<Field
@ -61,7 +61,7 @@ export class CustomComponentForm extends React.PureComponent implements IForm<Fo
<Button type="submit" title="Send" />
</GridCol>
</Grid>
</React.Fragment>
</>
)}
</Form>
);

View file

@ -50,7 +50,7 @@ export class ExampleForm extends React.PureComponent implements IForm<FormValues
validationSchema={this.validationSchema}
>
{({ errors }): React.ReactElement => (
<React.Fragment>
<>
<Grid>
<GridCol size={3}>
<Field
@ -101,7 +101,7 @@ export class ExampleForm extends React.PureComponent implements IForm<FormValues
<Button type="submit" title="Send" />
</GridCol>
</Grid>
</React.Fragment>
</>
)}
</Form>
);

View file

@ -4,7 +4,7 @@ import ExampleForm from './ExampleForm';
import CustomComponentForm from './CustomComponentForm';
const FormsPage = (): React.ReactElement => (
<React.Fragment>
<>
<h2>Forms</h2>
<h3>Normal</h3>
@ -12,7 +12,7 @@ const FormsPage = (): React.ReactElement => (
<h3>Custom component</h3>
<CustomComponentForm />
</React.Fragment>
</>
);
export default FormsPage;

View file

@ -13,7 +13,7 @@ const gridPropDefinition = generateDocumentationObject(groups, children, 'IGrid'
const gridColPropDefinition = generateDocumentationObject(groups, children, 'IGridCol');
const GridPage = (): React.ReactElement => (
<React.Fragment>
<>
<h2>Grid</h2>
<h3>Normal</h3>
@ -161,7 +161,7 @@ const GridPage = (): React.ReactElement => (
<DocTable propDefinition={gridPropDefinition} />
<h5>GridCol</h5>
<DocTable propDefinition={gridColPropDefinition} />
</React.Fragment>
</>
);
export default GridPage;

View file

@ -0,0 +1,68 @@
import React from 'react';
import Code from 'documentation/components/Code';
const LocalizationPage = (): React.ReactElement => (
<>
<h2>Define localization simply</h2>
<h3>1. Import</h3>
<Code
code={`
import { initLocalization, addLocalization } from '@romanjaros/treejs-localization/init';
`}
language="js"
/>
<h3>2. Init</h3>
<Code
code={`
// Options is not required and is same as options for i18next.init
// Default country is cs
// Default namespace is common
initLocalization(options)
`}
language="js"
/>
<h3>3. Define</h3>
<Code
code={`
const localization = {
cs: {
namespace: {
key: 'custom localization string',
},
},
};
`}
language="js"
/>
<h3>4. Add</h3>
<Code
code={`
addLocalization(localization);
`}
language="js"
/>
<h3>5. Use</h3>
<Code
code={`
import { getLabelMessage } from '@romanjaros/treejs-localization/message';
// will not work when getLabelMessage is called while webpack build
console.log(getLabelMessage('namespace:key')) => namespace:key
// but for example in component will be work
const App = () => {
return <div>{getLabelMessage('namespace:key')}</div>
};
<App /> => <div>custom localization string</div>
`} language="jsx" />
</>
);
export default LocalizationPage;

View file

@ -0,0 +1,110 @@
import React from 'react';
import Link from '@romanjaros/treejs-components/Link';
import Code from 'documentation/components/Code';
import InlineCode from 'documentation/components/InlineCode';
import Message from '@romanjaros/treejs-components/Message';
import { STATUS } from '@romanjaros/treejs-types/common';
import Section from '@romanjaros/treejs-components/Section';
const LocalizationPage = (): React.ReactElement => (
<>
<h2>Localization</h2>
<h3>1. Import</h3>
<Code
code={`
import { initLocalization, addLocalization } from '@romanjaros/treejs-localization/init';
`}
language="js"
/>
<Section>
<h3>2. Init</h3>
<div>
Please check &nbsp;
<Link href="https://www.i18next.com/overview/api" newTab>
<InlineCode>i18next.init()</InlineCode>
</Link> documentation.
</div>
<div>Default country is cs. Default namespace is common.</div>
<Code
code={`
initLocalization(options)
`}
language="js"
/>
</Section>
<Section>
<h3>3. Define</h3>
Create own object with specific structure. For example:
<Code
code={`
const localization = {
cs: {
namespace: {
key: 'custom localization string',
},
},
};
`}
language="js"
/>
</Section>
<Section>
<h3>4. Add</h3>
Register your localization.
<Code
code={`
addLocalization(localization);
`}
language="js"
/>
</Section>
<Section>
<h3>5. Use</h3>
<div>Add <InlineCode>localization</InlineCode> object to framework.</div>
<div>Import <InlineCode>getLabelMessage</InlineCode> from <InlineCode>treejs-localization</InlineCode></div>
<Code
code={`
import { getLabelMessage } from '@romanjaros/treejs-localization/message';
`}
language="jsx"
/>
<Section>
<Message status={STATUS.warning}>
<>Will not work when <InlineCode>getLabelMessage</InlineCode> is called while webpack build.</>
</Message>
<Code
code={`
console.log(getLabelMessage('namespace:key'))
// namespace:key
`}
language="jsx"
/>
</Section>
But for example in component will be ok.
<Code
code={`
const App = () => {
return <div>{getLabelMessage('namespace:key')}</div>
};
<App />
// <div>custom localization string</div>
`}
language="jsx"
/>
</Section>
</>
);
export default LocalizationPage;

View file

@ -26,7 +26,7 @@ const ComponentB = (): React.ReactElement => {
const ModalPage = (): React.ReactElement => {
return (
<React.Fragment>
<>
<h2>Modal</h2>
<h3>Normal</h3>
@ -83,7 +83,7 @@ const ModalPage = (): React.ReactElement => {
<h4>Props</h4>
<DocTable propDefinition={propDefinition} />
</React.Fragment>
</>
);
};

View file

@ -13,7 +13,7 @@ import { customRender } from './customRender';
const propDefinition = generateDocumentationObject(groups, children);
const RadioButtonPage = (): React.ReactElement => (
<React.Fragment>
<>
<h2>RadioButton</h2>
<h3>Normal</h3>
@ -54,7 +54,7 @@ const RadioButtonPage = (): React.ReactElement => (
<h4>Props</h4>
<DocTable propDefinition={propDefinition} />
</React.Fragment>
</>
);
export default RadioButtonPage;

View file

@ -11,7 +11,7 @@ import { groups, children } from '../typedoc.json';
const propDefinition = generateDocumentationObject(groups, children);
const SelectBoxPage = (): React.ReactElement => (
<React.Fragment>
<>
<h2>SelectBox</h2>
<h3>Normal</h3>
@ -55,7 +55,7 @@ const SelectBoxPage = (): React.ReactElement => (
<h4>Props</h4>
<DocTable propDefinition={propDefinition} />
</React.Fragment>
</>
);
export default SelectBoxPage;

View file

@ -18,7 +18,7 @@ const SliderPage = (): React.ReactElement => {
};
return (
<React.Fragment>
<>
<h2>Slider</h2>
<h3>Normal</h3>
@ -30,7 +30,7 @@ const SliderPage = (): React.ReactElement => {
<h4>Props</h4>
<DocTable propDefinition={propDefinition} />
</React.Fragment>
</>
);
};

View file

@ -36,7 +36,7 @@ const rows: ITableRow[] = [
];
const TablePage = (): React.ReactElement => (
<React.Fragment>
<>
<h2>Table</h2>
<h3>Normal</h3>
@ -44,7 +44,7 @@ const TablePage = (): React.ReactElement => (
<h4>Props</h4>
<DocTable propDefinition={propDefinition} />
</React.Fragment>
</>
);
export default TablePage;

View file

@ -12,7 +12,7 @@ import { groups, children } from '../typedoc.json';
const propDefinition = generateDocumentationObject(groups, children);
const TextFieldPage = (): React.ReactElement => (
<React.Fragment>
<>
<h2>TextField</h2>
<h3>Normal</h3>
@ -53,7 +53,7 @@ const TextFieldPage = (): React.ReactElement => (
<h4>Props</h4>
<DocTable propDefinition={propDefinition} />
</React.Fragment>
</>
);
export default TextFieldPage;

View file

@ -14,7 +14,7 @@ const propDefinition = generateDocumentationObject(groups, children);
const ToasterPage = (): React.ReactElement => {
return (
<React.Fragment>
<>
<h2>Toaster</h2>
<h3>Status</h3>
@ -71,7 +71,7 @@ const ToasterPage = (): React.ReactElement => {
<h4>Props</h4>
<DocTable propDefinition={propDefinition} />
</React.Fragment>
</>
);
};

View file

@ -20,7 +20,7 @@ const handleChangeLanguage = (option: IOption): void => {
};
const WelcomePage = (): React.ReactElement => (
<React.Fragment>
<>
<h2>{getLabelMessage(HomeLocalization.welcome)}</h2>
<Grid>
@ -28,11 +28,12 @@ const WelcomePage = (): React.ReactElement => (
<SelectBox
name="theme"
title={getLabelMessage(HomeLocalization.chooseTheme)}
value={window.localStorage.getItem(THEME)}
value={window.localStorage.getItem(THEME) || 'main'}
options={[
{ code: 'purple', name: getLabelMessage(ColorLocalization.purple) },
{ code: 'blue', name: getLabelMessage(ColorLocalization.blue) },
{ code: 'green', name: getLabelMessage(ColorLocalization.green) },
{ code: 'main', name: getLabelMessage(ColorLocalization.main) },
]}
onChange={changeTheme}
/>
@ -41,7 +42,7 @@ const WelcomePage = (): React.ReactElement => (
<SelectBox
name="language"
title={getLabelMessage(HomeLocalization.chooseLanguage)}
value={window.localStorage.getItem(LANGUAGE)}
value={window.localStorage.getItem(LANGUAGE) || 'cs'}
options={[
{ code: 'cs', name: getLabelMessage(HomeLocalization.cs) },
{ code: 'en', name: getLabelMessage(HomeLocalization.en) },
@ -50,7 +51,7 @@ const WelcomePage = (): React.ReactElement => (
/>
</GridCol>
</Grid>
</React.Fragment>
</>
);
export default WelcomePage;

View file

@ -22,6 +22,15 @@ export const MainStyle = styled.div`
-webkit-tap-highlight-color: transparent;
.pageContent div:not([class]) {
line-height: 2;
}
div.code-toolbar {
position: relative;
margin: 5px 0;
}
pre[class*='language-'] {
margin: 0;
}

View file

@ -8,7 +8,6 @@ import { STATUS } from '@romanjaros/treejs-types/common';
import Section from '../Section';
import Button from '../Button';
import { Grid, GridCol, HORIZONTAL_ALIGN } from '../Grid';
import { MONTHS, WEEK_DAYS_SHORT } from './constants';
import {
@ -18,9 +17,12 @@ import {
StyledCalendarCell,
StyledCalendarNavigationMonth,
} from './style';
import { isNilOrEmpty } from '@romanjaros/treejs-utils';
interface IProps extends IHTMLElement<string> {
// For example 'DD.MM.YYYY'
/**
* For example 'DD.MM.YYYY'
*/
format?: string;
value?: string;
}
@ -124,7 +126,7 @@ class Calendar extends React.Component<IProps, IState> {
};
private getNavigationHeader = () => (
<React.Fragment>
<>
<StyledCalendarNavigation colSpan={1} onClick={this.handleClickPrevYear}>
<FontAwesomeIcon icon="angle-double-left" />
</StyledCalendarNavigation>
@ -143,7 +145,7 @@ class Calendar extends React.Component<IProps, IState> {
<StyledCalendarNavigation colSpan={1} onClick={this.handleClickNextYear}>
<FontAwesomeIcon icon="angle-double-right" />
</StyledCalendarNavigation>
</React.Fragment>
</>
);
private setDate = (date: moment.Moment) => {
@ -176,7 +178,7 @@ class Calendar extends React.Component<IProps, IState> {
private handleChangeDate = (day: number) => (): void => {
const date = this.state.currentMoment.set('date', day).format(this.props.format);
if (this.props.onChange instanceof Function) {
if (!isNilOrEmpty(this.props.onChange)) {
this.props.onChange(date, null);
}
};
@ -185,6 +187,7 @@ class Calendar extends React.Component<IProps, IState> {
return (
<div>
<Section>
{!isNilOrEmpty(this.props.title) && <h2>{this.props.title}</h2>}
<StyledCalendar>
<thead>
<tr>{this.getNavigationHeader()}</tr>
@ -197,11 +200,7 @@ class Calendar extends React.Component<IProps, IState> {
</tbody>
</StyledCalendar>
</Section>
<Grid horizontalAlign={HORIZONTAL_ALIGN.CENTER}>
<GridCol size={12}>
<Button title="Zobrazit dnešní datum" status={STATUS.info} onClick={this.handleClickSetToday} />
</GridCol>
</Grid>
<Button title="Zobrazit dnešní datum" status={STATUS.info} onClick={this.handleClickSetToday} />
</div>
);
}

View file

@ -173,7 +173,7 @@ class PageLayout extends React.PureComponent<IProps, IState> {
const { isLeftMenuOpen, topMenuItems, topMenuMissingItems, isSubMenu, isSubMenuOpen } = this.state;
return (
<React.Fragment>
<>
<StyledLeftMenu open={isLeftMenuOpen} enableLeftMenu={enableLeftMenu}>
<OutsideClickHandler onOutsideClick={this.closeLeftMenu}>
{enableLeftMenu && <StyledLeftMenuLogo>{logo}</StyledLeftMenuLogo>}
@ -228,7 +228,7 @@ class PageLayout extends React.PureComponent<IProps, IState> {
<Modals />
<Toasters />
</React.Fragment>
</>
);
}
}

View file

@ -21,7 +21,7 @@ export const MenuItem = (props: IProps) => {
const [open, setOpen] = React.useState(props.defaultOpen);
return (
<React.Fragment>
<>
<StyledLeftMenuItem isChild={props.isChild || false}>
<StyledLeftMenuLabel onClick={handleOnClick(props)} showPointerCursor={!isNilOrEmpty(props.href)}>
{props.label}
@ -37,7 +37,7 @@ export const MenuItem = (props: IProps) => {
props.subMenu.map((menuItem, i) => (
<MenuItem key={i} isChild={true} onClick={props.onClick} {...menuItem} />
))}
</React.Fragment>
</>
);
};

View file

@ -188,11 +188,14 @@ interface IStyledPageContent {
open: boolean;
}
export const StyledPageContent = styled.div<IStyledPageContent>`
export const StyledPageContent = styled.div.attrs({
className: 'pageContent',
})<IStyledPageContent>`
padding-left: 20px;
padding-right: 20px;
margin-top: 10px;
margin-bottom: 10px;
${p =>
p.open &&

View file

@ -0,0 +1,25 @@
import React from 'react';
import { StyledLink } from './style';
interface IProps {
children: React.ReactElement | string;
href: string;
newTab?: boolean;
}
const Link = (props: IProps): React.ReactElement => {
return (
<StyledLink
{ ...props.newTab ? {
target: "_blank",
rel: "noreferrer noopener",
} : {} }
href={props.href}
>
{props.children}
</StyledLink>
);
};
export default Link;

View file

@ -0,0 +1,12 @@
import styled from '../styled';
export const StyledLink = styled.a.attrs({
className: 'Link',
})`
border-bottom: 1px solid ${p => p.theme.infoColor};
color: ${p => p.theme.black};
text-decoration: none;
padding: 3px;
`;

View file

@ -0,0 +1,33 @@
import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { STATUS } from '@romanjaros/treejs-types/common';
import { StyledMessage, StyledMessageContent, StyledMessageIcon } from './style';
interface IProps {
status: STATUS;
children: React.ReactElement | string;
}
class Message extends React.Component<IProps> {
public render() {
return (
<StyledMessage status={this.props.status}>
<StyledMessageIcon>
{this.props.status === STATUS.info && <FontAwesomeIcon icon="info-circle" />}
{this.props.status === STATUS.success && <FontAwesomeIcon icon="check-circle" />}
{this.props.status === STATUS.warning && <FontAwesomeIcon icon="exclamation-triangle" />}
{this.props.status === STATUS.error && <FontAwesomeIcon icon="exclamation-circle" />}
{this.props.status === STATUS.none && <FontAwesomeIcon icon="hand-peace" />}
</StyledMessageIcon>
<StyledMessageContent>
{this.props.children}
</StyledMessageContent>
</StyledMessage>
);
}
}
export default Message;

View file

@ -0,0 +1,59 @@
import { STATUS } from '@romanjaros/treejs-types/common';
import styled, { css } from '../styled';
interface IStyledMessage {
status: STATUS;
}
export const StyledMessage = styled.div.attrs({
className: 'Message',
})<IStyledMessage>`
padding: 10px 10px 10px 40px;
margin: 14px 0;
background-color: ${p => p.theme.black};
color: ${p => p.theme.white};
${p => p.status === STATUS.info &&
css`
background-color: ${p => p.theme.infoColor};
color: ${p => p.theme.white};
`};
${p => p.status === STATUS.success &&
css`
background-color: ${p => p.theme.successColor};
color: ${p => p.theme.white};
`};
${p => p.status === STATUS.warning &&
css`
background-color: ${p => p.theme.warningColor};
color: ${p => p.theme.white};
`};
${p => p.status === STATUS.error &&
css`
background-color: ${p => p.theme.errorColor};
color: ${p => p.theme.white};
`};
border-radius: 2px;
`;
export const StyledMessageIcon = styled.div`
display: inline-block;
vertical-align: middle;
margin-right: 20px;
font-size: 25px;
`;
export const StyledMessageContent = styled.div`
display: inline-block;
vertical-align: middle;
max-width: 80%;
`;

View file

@ -38,7 +38,7 @@ class Modals extends React.PureComponent<IProps> {
}
return (
<React.Fragment>
<>
{Object.keys(modals).map(key => {
const modal = modals[key];
return (
@ -56,7 +56,7 @@ class Modals extends React.PureComponent<IProps> {
</StyledModalContainer>
);
})}
</React.Fragment>
</>
);
}
}

View file

@ -76,10 +76,10 @@ class RadioButton extends React.PureComponent<IProps, IState> {
{is(Function, customRender) ? (
customRender({ code, name }, this.state.value)
) : (
<React.Fragment>
<>
<FontAwesomeIcon size="lg" icon={this.state.value === code ? 'dot-circle' : 'circle'} />
<span>{name}</span>
</React.Fragment>
</>
)}
</label>
</StyledRadioButtonItem>

View file

@ -5,7 +5,7 @@ interface ISection {
}
export const Section = styled.div<ISection>`
margin-bottom: ${p => p.size || 1}rem;
margin-bottom: ${p => p.size || 2}rem;
`;
export default Section;

View file

@ -41,7 +41,7 @@ export class Slider extends React.Component<IProps, IState> {
public render() {
return (
<React.Fragment>
<>
<StyledInput
type="range"
max={this.props.max}
@ -50,7 +50,7 @@ export class Slider extends React.Component<IProps, IState> {
onChange={this.handleChange}
/>
{this.state.value} / {this.props.max}
</React.Fragment>
</>
);
}
}

View file

@ -3,10 +3,13 @@ import { connect } from 'react-redux';
import { isNilOrEmpty } from '@romanjaros/treejs-utils';
import { StyledToaster, StyledToasterContainer } from '../styles/toaster';
import Message from '../../Message';
import { StyledToasterContainer } from '../styles/toaster';
import { toasters } from '../selectors';
import { IToasterReducer } from '../types';
interface IProps {
toasters: IToasterReducer;
}
@ -24,9 +27,9 @@ class Toasters extends React.Component<IProps> {
{Object.keys(toasters).map(key => {
const toaster = toasters[key];
return (
<StyledToaster key={key} status={toaster.status}>
<Message key={key} status={toaster.status}>
{toaster.message}
</StyledToaster>
</Message>
);
})}
</StyledToasterContainer>

View file

@ -1,6 +1,7 @@
import { STATUS } from '@romanjaros/treejs-types/common';
import styled from '../../styled';
import { StyledMessage } from '../../Message/style';
import styled, { css } from '../../styled';
export const StyledToasterContainer = styled.div`
position: fixed;
@ -27,51 +28,9 @@ export const StyledToasterContainer = styled.div`
@media only screen and (min-width: ${p => p.theme.extraLargeScreenSize}px) {
width: calc((100% / 12 * 2) - 10px);
}
`;
interface IStyledToaster {
status: STATUS;
}
export const StyledToaster = styled.div.attrs({
className: 'Toaster',
})<IStyledToaster>`
padding: 16px;
background-color: ${p => p.theme.black};
color: ${p => p.theme.white};
${p =>
p.status === STATUS.info &&
css`
background-color: ${p => p.theme.infoColor};
color: ${p => p.theme.white};
`};
${p =>
p.status === STATUS.success &&
css`
background-color: ${p => p.theme.successColor};
color: ${p => p.theme.white};
`};
${p =>
p.status === STATUS.warning &&
css`
background-color: ${p => p.theme.warningColor};
color: ${p => p.theme.white};
`};
${p =>
p.status === STATUS.error &&
css`
background-color: ${p => p.theme.errorColor};
color: ${p => p.theme.white};
`};
text-align: center;
border-radius: 2px;
margin-bottom: 5px;
& ${StyledMessage} {
padding: 16px;
text-align: center;
}
`;

View file

@ -19,6 +19,11 @@ import {
faAngleDoubleRight,
faChevronDown,
faChevronUp,
faExclamationTriangle,
faHandPeace,
faInfoCircle,
faExclamationCircle,
faCheckCircle,
} from '@fortawesome/free-solid-svg-icons';
library.add(
@ -40,6 +45,11 @@ library.add(
faAngleDoubleRight,
faChevronDown,
faChevronUp,
faExclamationTriangle,
faHandPeace,
faInfoCircle,
faExclamationCircle,
faCheckCircle,
);
export interface ThemeInterface {

View file

@ -11,30 +11,31 @@
"eslint": "eslint -c .eslintrc modules/**/*.{ts,tsx}",
"stylelint": "stylelint modules/**/*.ts",
"lint": "npm run eslint && npm run stylelint",
"build:doc": "node genDoc.js && lerna run --stream --scope documentation build",
"build:tsdoc": "node genDoc.js",
"build:app": "npm run build:tsdoc && lerna run --stream --scope documentation build",
"build:module": "lerna run --ignore documentation build",
"clean:module": "lerna run --ignore documentation clean",
"serve": "http-server dist/client",
"postinstall": "lerna bootstrap"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.25",
"@fortawesome/free-solid-svg-icons": "^5.11.2",
"@fortawesome/react-fontawesome": "^0.1.7",
"@fortawesome/fontawesome-svg-core": "^1.2.26",
"@fortawesome/free-solid-svg-icons": "^5.12.0",
"@fortawesome/react-fontawesome": "^0.1.8",
"@hot-loader/react-dom": "^16.11.0",
"clipboard": "^2.0.4",
"formik": "^1.5.2",
"i18next": "19.0.0",
"moment": "^2.24.0",
"prismjs": "^1.17.1",
"polished": "3.4.2",
"prismjs": "^1.19.0",
"ramda": "^0.26.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-outside-click-handler": "1.2.4",
"react-redux": "^7.1.3",
"react-router": "^5.1.2",
"redux": "^4.0.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"styled-components": "^4.4.1",
@ -42,51 +43,51 @@
"yup": "^0.27.0"
},
"devDependencies": {
"@types/enzyme": "^3.9.0",
"@types/enzyme": "^3.10.4",
"@types/enzyme-adapter-react-16": "^1.0.5",
"@types/jest": "^24.0.23",
"@types/node": "^12.12.14",
"@types/jest": "^24.9.0",
"@types/node": "^12.12.25",
"@types/prismjs": "^1.16.0",
"@types/ramda": "^0.26.36",
"@types/react": "^16.9.13",
"@types/react-dom": "^16.8.2",
"@types/ramda": "^0.26.40",
"@types/react": "^16.9.19",
"@types/react-dom": "^16.9.5",
"@types/react-outside-click-handler": "^1.3.0",
"@types/react-redux": "^7.1.5",
"@types/react-redux": "^7.1.6",
"@types/react-router": "^4.4.5",
"@types/styled-components": "^4.4.0",
"@types/yup": "^0.26.26",
"@typescript-eslint/eslint-plugin": "^2.9.0",
"@typescript-eslint/parser": "^2.9.0",
"@types/styled-components": "^4.4.2",
"@types/yup": "^0.26.27",
"@typescript-eslint/eslint-plugin": "^2.17.0",
"@typescript-eslint/parser": "^2.17.0",
"awesome-typescript-loader": "^5.2.1",
"copy-webpack-plugin": "^5.0.5",
"copy-webpack-plugin": "^5.1.1",
"cross-env": "^5.2.0",
"css-loader": "^3.2.0",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.15.1",
"css-loader": "^3.4.2",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"enzyme-to-json": "^3.4.3",
"eslint": "^6.7.1",
"eslint-plugin-react": "^7.17.0",
"eslint": "^6.8.0",
"eslint-plugin-react": "^7.18.0",
"eslint-plugin-react-hooks": "^1.5.0",
"eslint-plugin-typescript": "^0.14.0",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"http-server": "^0.12.0",
"http-server": "^0.12.1",
"jest": "^24.3.0",
"lerna": "^3.19.0",
"lerna": "^3.20.2",
"link-module-alias": "1.2.0",
"react-hot-loader": "^4.12.18",
"react-hot-loader": "^4.12.19",
"source-map-loader": "^0.2.4",
"style-loader": "^1.0.1",
"style-loader": "^1.1.3",
"stylelint": "^9.10.1",
"stylelint-config-recommended": "^2.1.0",
"stylelint-config-styled-components": "^0.1.1",
"stylelint-processor-styled-components": "^1.9.0",
"ts-jest": "^24.2.0",
"ts-node": "^8.5.4",
"ts-jest": "^24.3.0",
"ts-node": "^8.6.2",
"tsconfig-paths": "^3.8.0",
"typedoc": "^0.15.3",
"webpack": "^4.41.2",
"typedoc": "^0.15.8",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0"
"webpack-dev-server": "^3.10.1"
}
}