Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions components/bl-list-component/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# List

List is the component that can be used in Backendless [UI-Builder](https://backendless.com/developers/#ui-builder). It allows you to add a standard list to your application.

<p align="center">
<img src="./thumbnail.png" alt="main thumbnail" width="643"/>
</p>

Additional properties allow customizing the font size, background color, text color, padding and behavior of the component. Refer to the Properties section below.

## Configuration

The configuration can be done in the UI Builder or using the Codeless Logic. You need to select the type of list (ordered/unordered) and specify the data that will be displayed inside the list.

## Properties

| Property | Type | Default value | Logic | Data Binding | UI Setting | Description |
|--------------------------|------------|---------------|--------------------|--------------|------------|-------------------------------------------------------------------|
| Type | *Select* | `"Unordered"` | Type Logic | NO | YES | Controls the type of list(ul/ol). |
| List Items | *JSON* | | ListItems Logic | YES | NO | Specifies a JSON array containing data for the list items. Watch [Codeless Examples] #codeless-examples). |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Describe signature

| Background | *Color* | | | NO | YES | Controls the background color of the main block. |
| Width | *Text* | | | NO | YES | Controls the width of the main block. |
| Color | *Color* | | | NO | YES | Controls the color of the list items. |
| Font Size | *Text* | | | NO | YES | Controls the font size of the list items. |

## Events

| Name | Triggers | Context Blocks |
|---------------------------|--------------------------------------------------------|----------------|
| On Click List Item | when the user click any item of the list | `List Item` |

## Styles

**Theme**
````
@bl-customComponent-list-theme: @themePrimary;
@bl-customComponent-list-themeTextColor: @appTextColor;
````

**Dimensions**
```
@bl-customComponent-list-item-size: 20px;
```

**Colors**
````
@bl-customComponent-list-item-hover-background-color: if(@isLightTheme, rgba(0, 0, 0, 0.04), rgba(255, 255, 255, 0.04));
````

## Codeless Examples

Below is a Codeless Example highlighting how to use the List component:

![list data example](example-images/list-data-example.png)
![list data example view](example-images/list-data-example-view.png)
88 changes: 88 additions & 0 deletions components/bl-list-component/component.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{
"id": "c_f95c74e56529269bdafe747715db7bbe",
"name": "List",
"description": "The List component allows the user to add a standard list to an application.",
"showInToolbox": true,
"faIcon": "pencil-ruler",
"mainJS": "dist/index.js",
"type": "custom",
"category": "Custom Components",
"properties": [
{
"type": "select",
"name": "type",
"label": "Type",
"showInSettings": true,
"defaultValue": "ul",
"hasLogicHandler": false,
"handlerId": "typeLogic",
"options": [
{
"value": "ul",
"label": "Unordered"
},
{
"value": "ol",
"label": "Ordered"
}
],
"handlerLabel": "Type Logic"
},
{
"type": "json",
"name": "listItems",
"showInSettings": false,
"hasLogicHandler": true,
"handlerId": "listItemsLogic",
"handlerLabel": "List Items Logic",
"dataBinding": true
},
{
"type": "color",
"name": "backgroundColor",
"label": "Background",
"showInSettings": true,
"hasLogicHandler": false,
"handlerId": "backgroundColorLogic"
},
{
"type": "text",
"name": "width",
"label": "Width",
"showInSettings": true,
"hasLogicHandler": false,
"handlerId": "widthLogic"
},
{
"type": "color",
"name": "color",
"label": "Color",
"showInSettings": true,
"hasLogicHandler": false,
"handlerId": "colorLogic"
},
{
"type": "text",
"name": "fontSize",
"label": "Font Size",
"showInSettings": true,
"hasLogicHandler": false,
"handlerId": "fontSizeLogic"
}
],
"eventHandlers": [
{
"name": "onClickListItem",
"label": "On Click List Item Event",
"contextBlocks": [
{
"id": "item",
"label": "List Item"
}
]
}
],
"actions": [],
"settings": [],
"pods": {}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions components/bl-list-component/preview.html

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions components/bl-list-component/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { List } from './list';

export default function ListComponent ({
component, eventHandlers
}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In one line

Suggested change
export default function ListComponent ({
component, eventHandlers
}) {
export default function ListComponent ({ component, eventHandlers }) {

Also, did you setup eslint and editorconfig in your IDE?
https://github.com/Backendless/eslint-config
https://github.com/v-excelsior/editor-config/blob/main/.editorconfig


const { cn } = BackendlessUI.CSSUtils;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be moved out from the component. You don't need to create cn every render

const { style, classList, width, backgroundColor } = component;

style.width = width;
style.backgroundColor = backgroundColor;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
style.width = width;
style.backgroundColor = backgroundColor;
const styles = useMemo(()=> ({...style, width, backgroundColor}), [style, width, backgroundColor])

return (
<div className={ cn('bl-customComponent-list', classList) } style={ style }>
<List component={component}
eventHandlers={eventHandlers}/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<List component={component}
eventHandlers={eventHandlers}/>
<List component={component} eventHandlers={eventHandlers}/>

</div>
)
}
53 changes: 53 additions & 0 deletions components/bl-list-component/src/list-content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { List } from './list';

export function ListContent({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in one line

component, eventHandlers, child}) {

const { color, fontSize, listItems, type} = component;

const itemStyles = {
color : color,
fontSize: fontSize
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant variable

Also

{color, fontSile} works good too


const onItemClick = (key) => {
eventHandlers.onClickListItem({item: key});
}

const getItems = (items) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was named a Render Function. In general, we wan't create them - because we write on react and there are preferable component approach.

You made it almost right - but there is a mistake in entities.

We must have an two components:

ListItem - that render an ordinary item (li) and creates a sibling List if it has children.
List - that render a collection of items

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, pseudo code for that looks like:

function List({ children }) {
  return (
    <ul>
      { children.map(child => {
        return (
          <Item { ...child }/>
        )
      }) }
    </ul>
  )
}

function Item(itemProps) {
  return (
    <>
      <li>{ itemProps.text } </li>
      { itemProps.children && <List children={ itemProps.children }/> }
    </>
  )
}

return (items || []).map((item, i) => {
if (item.child && item.child.length !== 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

child should be plural - children

return (
<li key={i.toString()}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be without toString

className="list__item"
style = {itemStyles}
onClick={(e) => {
e.stopPropagation();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we realy need stop propagation here?

onItemClick(item.item);
}}
>
{item.item}
<List component={component}
child={item.child}
eventHandlers={eventHandlers}/>
</li>
)
} else {
return (
<li key={i.toString()}
className="list__item"
style = {itemStyles}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setup eslint and editorconfig

onClick={(e) => {
e.stopPropagation();
onItemClick(item.item);
}}
>
{item.item}
</li>
)
}
});
}

return (getItems(child || listItems))
}
30 changes: 30 additions & 0 deletions components/bl-list-component/src/list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ListContent } from './list-content';

export function List ({
component, eventHandlers, child
}) {

const listType = (type) => {
if(type && type === 'ol') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create map for enums

const ListTypes = {
ORDERED: 'ol',
UNORDERED: 'ul'
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also read this article https://www.robinwieruch.de/react-as-prop/

briefly:

<List as="ul" ...>

and in list component:

const Component = as

return (<Component ... />)

return (
<ol className="list">
<ListContent
component={component}
child={child}
eventHandlers={eventHandlers} />
</ol>
)
} else {
return (
<ul className="list">
<ListContent
component={component}
child={child}
eventHandlers={eventHandlers} />
</ul>
)
}
};

return (listType(component.type))
}
25 changes: 25 additions & 0 deletions components/bl-list-component/styles/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@bl-customComponent-list-theme: @themePrimary;
@bl-customComponent-list-themeTextColor: @appTextColor;

@bl-customComponent-list-item-hover-background-color: if(@isLightTheme, rgba(0, 0, 0, 0.04), rgba(255, 255, 255, 0.04));

@bl-customComponent-list-item-size: 20px;

.bl-customComponent-list {
color: @bl-customComponent-list-themeTextColor;
user-select: none;

.list {
margin: @bl-customComponent-list-item-size;
}

.list__item {
padding: @bl-customComponent-list-item-size / 2;
line-height: 1.3;
cursor: pointer;

&:hover {
background-color: @bl-customComponent-list-item-hover-background-color;
}
}
}
Binary file added components/bl-list-component/thumbnail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.