diff --git a/html/elements/Br.js b/html/elements/Br.js
new file mode 100644
index 00000000..57e79d35
--- /dev/null
+++ b/html/elements/Br.js
@@ -0,0 +1,12 @@
+import React from 'react';
+import { Text } from '@shoutem/ui';
+
+function Br() {
+ return (
+
+ {"\n"}
+
+ );
+}
+
+export default Br;
diff --git a/html/elements/Inline.js b/html/elements/Inline.js
index f13bbf12..323e033c 100644
--- a/html/elements/Inline.js
+++ b/html/elements/Inline.js
@@ -3,6 +3,7 @@ import _ from 'lodash';
import { View } from '../../components/View';
import { Text } from '../../components/Text';
+import { removeWhiteSpace } from './Text';
import { TouchableOpacity } from '../../components/TouchableOpacity';
import { Display } from '../services/ElementRegistry';
import {
@@ -93,7 +94,15 @@ export const Inline = function (props) {
return null;
}
- const children = groupInlineNodes(childElements);
+ // Browsers ignore white space (new lines) around element tags,
+ // we need to remove it here manually so it doesn't get rendered by RN.
+ const trimmedChildren = removeWhiteSpace(childElements);
+
+ // Group inline elements, such as text, so that
+ // it gets shown in the same line. Like concatenation.
+ // Block elements are standalone because they break the line.
+ const children = groupInlineNodes(trimmedChildren);
+
const renderedChildren = renderGroupedChildren(children, renderElement);
if (isInline(children)) {
diff --git a/html/elements/Text.js b/html/elements/Text.js
index 3bb04488..cf469ca5 100644
--- a/html/elements/Text.js
+++ b/html/elements/Text.js
@@ -1,14 +1,29 @@
import React from 'react';
import { Text } from 'react-native';
+import _ from 'lodash';
import { ElementPropTypes, combineMappers, mapElementProps } from '../Html';
-function removeNewLines(childElements) {
- return childElements.filter(child => child !== '\n');
+function isWhiteSpaceWrappedWithText(element) {
+ return _.size(element.childElements) === 1 && isWhiteSpaceString(element.childElements[0]);
+}
+
+function isWhiteSpaceString(element) {
+ return _.isString(element) && element.trim().length === 0;
+}
+
+function isWhiteSpace(element) {
+ return isWhiteSpaceString(element) || isWhiteSpaceWrappedWithText(element);
+}
+
+export function removeWhiteSpace(childElements) {
+ return childElements.filter(child => !isWhiteSpace(child));
}
export function TextElement(props) {
- const textualChildElements = removeNewLines(props.childElements);
+ // Remove empty white space lines used just to move element in new line.
+ // Use "p" or "br" to add new line.
+ const textualChildElements = removeWhiteSpace(props.childElements);
if (textualChildElements.length === 0) {
// Even if there is no children to render, the Text must be rendered
diff --git a/html/elements/list/Li.js b/html/elements/list/Li.js
index b406ba5a..ec066d5f 100644
--- a/html/elements/list/Li.js
+++ b/html/elements/list/Li.js
@@ -12,15 +12,15 @@ import { Inline } from '../Inline';
* @param style {Object}
* @returns {Component}
*/
-function Li({ childElements, renderElement, prefix, style }) {
+function Li({ element, renderElement, style }) {
+ const { childElements, attributes: { key } } = element;
return (
-
- {prefix || null}
-
-
+
);
}
diff --git a/html/elements/list/Ol.js b/html/elements/list/Ol.js
index 108df77b..2f6388e2 100644
--- a/html/elements/list/Ol.js
+++ b/html/elements/list/Ol.js
@@ -7,10 +7,12 @@ import pickLiChildElements from './helpers/pickLiChildElements';
import { ElementPropTypes, combineMappers, mapElementProps } from '../../Html';
import Li from './Li';
-function createPrefixCreator(type, prefixStyle) {
- return function (element, index) {
- // TODO (Braco) - Handle all types
- return {index};
+function createNumberElement(element, index) {
+ return {
+ tag: 'number',
+ attributes: {
+ index,
+ },
};
}
@@ -18,7 +20,7 @@ export function Ol({ style, childElements, type, renderElement }) {
const liItems = pickLiChildElements(childElements);
return (
- {renderItems(Li, liItems, renderElement, createPrefixCreator(type, style.prefix))}
+ {renderItems(liItems, renderElement, createNumberElement)}
);
}
diff --git a/html/elements/list/Ul.js b/html/elements/list/Ul.js
index 079f4335..04fbf0f0 100644
--- a/html/elements/list/Ul.js
+++ b/html/elements/list/Ul.js
@@ -1,4 +1,5 @@
import React from 'react';
+import { Text } from '@shoutem/ui';
import { View } from '../../../components/View';
import { ElementPropTypes, combineMappers, mapElementProps } from '../../Html';
@@ -6,12 +7,18 @@ import renderItems from './helpers/renderItems';
import pickLiChildElements from './helpers/pickLiChildElements';
import Li from './Li';
+function createBulletElement(element, index) {
+ return {
+ tag: 'bullet',
+ };
+}
+
export function Ul({ style, childElements, renderElement }) {
// TODO (Braco) - handle list-style-type from inlineStyle prop
const liItems = pickLiChildElements(childElements);
return (
- {renderItems(Li, liItems, renderElement)}
+ {renderItems(liItems, renderElement, createBulletElement)}
);
}
diff --git a/html/elements/list/helpers/renderItems.js b/html/elements/list/helpers/renderItems.js
index 5016b4a2..7ac5e56e 100644
--- a/html/elements/list/helpers/renderItems.js
+++ b/html/elements/list/helpers/renderItems.js
@@ -1,17 +1,21 @@
import React from 'react';
import _ from 'lodash';
-export default function renderItems(Component, childElements, renderElement, prefix) {
+import { createElementNode } from '../../../services/HtmlParser';
+
+export default function renderItems(childElements, renderElement, createPrefixElement) {
return _.reduce(childElements, (items, element, index) => {
- const resolvedPrefix = _.isFunction(prefix) ? prefix(element, index) : undefined;
- items.push(
-
- );
+ const { childElements: itemChildElements } = element;
+
+ const prefix = createPrefixElement ? createPrefixElement(element, index) : null;
+ const childElements = prefix ? [prefix, ...itemChildElements] : itemChildElements;
+
+ const elem = {
+ ...element,
+ childElements,
+ };
+
+ items.push(renderElement(elem));
return items;
}, []);
}
diff --git a/html/elements/list/index.js b/html/elements/list/index.js
index 0924eb02..b97d2412 100644
--- a/html/elements/list/index.js
+++ b/html/elements/list/index.js
@@ -1,9 +1,13 @@
import Ul from './Ul';
import Li from './Li';
import Ol from './Ol';
+import Bullet from './prefix/Bullet';
+import Number from './prefix/Number';
export {
Ul,
Ol,
Li,
+ Bullet,
+ Number,
};
diff --git a/html/elements/list/prefix/Bullet.js b/html/elements/list/prefix/Bullet.js
new file mode 100644
index 00000000..94967031
--- /dev/null
+++ b/html/elements/list/prefix/Bullet.js
@@ -0,0 +1,6 @@
+import React from 'react';
+import { Text } from '@shoutem/ui';
+
+export default function ({ style }) {
+ return •;
+}
diff --git a/html/elements/list/prefix/Number.js b/html/elements/list/prefix/Number.js
new file mode 100644
index 00000000..84840cef
--- /dev/null
+++ b/html/elements/list/prefix/Number.js
@@ -0,0 +1,8 @@
+import React from 'react';
+import { View, Text } from '@shoutem/ui';
+
+export default function ({ element, style }) {
+ const { index } = element.attributes;
+
+ return {index}.;
+};
diff --git a/html/index.js b/html/index.js
index ff6ef9f9..119adb47 100644
--- a/html/index.js
+++ b/html/index.js
@@ -20,9 +20,10 @@ import Inline, { InlineSettings } from './elements/Inline';
import Virtual from './elements/Virtual';
import Block from './elements/Block';
import Text from './elements/Text';
-import { Ul, Ol, Li } from './elements/list';
+import { Ul, Ol, Li, Bullet, Number } from './elements/list';
import Img from './elements/Img';
import A from './elements/A';
+import Br from './elements/Br';
// Text elements with primary inline display
Html.registerElement('em', Inline, InlineSettings);
@@ -34,6 +35,7 @@ Html.registerElement('span', Inline, InlineSettings);
// Functional
Html.registerElement('a', A, InlineSettings);
Html.registerElement('img', Img);
+Html.registerElement('br', Br, InlineSettings);
// Containers
Html.registerElement('header', Virtual);
@@ -45,6 +47,9 @@ Html.registerElement('section', Virtual);
// List
Html.registerElement('ul', Ul);
Html.registerElement('ol', Ol);
+Html.registerElement('li', Li);
+Html.registerElement('bullet', Bullet, { display: Display.INLINE });
+Html.registerElement('number', Number, { display: Display.INLINE });
// Text base
Html.registerElement('text', Text, { display: Display.INLINE });
diff --git a/package.json b/package.json
index a5d9d052..ebeef5c2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@shoutem/ui",
- "version": "0.16.0",
+ "version": "0.17.0",
"description": "Styleable set of components for React Native applications",
"dependencies": {
"@shoutem/animation": "~0.11.0",
diff --git a/theme.js b/theme.js
index 1317139c..f0217ebb 100644
--- a/theme.js
+++ b/theme.js
@@ -1482,6 +1482,9 @@ export default (variables = defaultThemeVariables) => ({
}),
};
},
+ boxingAnimation() {
+ return {};
+ },
position: 'absolute',
right: 0,
top: 0,
@@ -1983,14 +1986,23 @@ export default (variables = defaultThemeVariables) => ({
// HTML lists
ul: {
container: {},
- prefix: {}, // Not implemented yet
},
ol: {
container: {},
- prefix: {},
},
- li: {
- flexDirection: 'row',
+ number: {
+ // Font should be monospace so that item content has same offset
+ // Can not apply width to the Text for some reason
+ fontFamily: Platform.OS === 'ios' ? 'Menlo-Regular' : 'monospace',
+ fontSize: 12,
+ },
+ bullet: {
+ },
+ li: { // Inline element
+ container: {
+ },
+ text: {
+ },
},
// HTML containers