Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MARKET-1671 Emoji component #771

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
47 changes: 47 additions & 0 deletions components/bl-emoji/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Emoji

Emoji is a component of Backendless UI-Builder designer. The component is designed to select and use emojis.

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

## Properties

| Property | Type | Default Value | Logic | Data Binding | UI Setting | Description |
|-----------------------------------------------|--------------------------------------------------------------------|-----------------|------------------------------|--------------|------------|------------------------------------------------------------------------|
| Disabled<br/>`disabled` | Checkbox | `false` | Disabled Logic | YES | YES | This handler allows you to disable a component. |
| Button Color<br/>`buttonColor` | Color | `#000000` | Button Color Logic | YES | YES | This handler allows you to specify the button color. |
| Button Size<br/>`buttonSize` | Text | "24px" | Button Size Logic | YES | YES | This handler allows you to specify the button size. |
| Dropdown List Height<br/>`dropdownHeight` | Text | "500px" | Dropdown List Height Logic | YES | YES | This handler allows you to specify the dropdown list height. |
| Dropdown List Width<br/>`dropdownWidth` | Text | "400px" | Dropdown List Width Logic | YES | YES | This handler allows you to specify the dropdown list width. |
| Dropdown List Position<br/>`dropdownPosition` | Select [Left:`left`<br/>Center:`center`<br/>Right:`right`] | Center:`center` | Dropdown List Position Logic | YES | YES | This handler allows you to select the position of the dropdown. |
| Theme<br/>`theme` | Select [Light:`light`<br/>Dark:`dark`<br/>Auto:`auto`] | Light:`light` | Theme Logic | YES | YES | This handler allows you to select a theme for the emoji dropdown list. |
| Emoji Style<br/>`emojiStyle` | Select [Apple:`apple`<br/>Google:`google`<br/>Facebook:`facebook`] | Apple:`apple` | Emoji Style Logic | YES | YES | This handler allows you to select an emoji style. |
| Search Disabled<br/>`searchDisabled` | Checkbox | `true` | Search Disabled Logic | YES | YES | This handler allows you to disable the emoji search field. |

Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it easy and obvious to implement binding emojis with default input? If no - need an instruction how to do it.

## Events

| Name | Triggers | Context Blocks |
|-----------------------|---------------------------|----------------------------------------------------|
| On Emoji Select Event | when an emoji is selected | Emoji: `String`, Emoji Names: [`String`, `String`] |
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you provide example values that returns from context blocks?


## Styles

**Theme**
````
@bl-customComponent-emoji-themeColor: @themePrimary;
@bl-customComponent-emoji-backgroundColor: @appBackgroundColor;
@bl-customComponent-emoji-textColor: @appTextColor;
````

**Dimensions**
````
@bl-customComponent-emoji-disabled-opacity: 0.38;
@bl-customComponent-emoji-button-transform-onHover: scale(1.2);
@bl-customComponent-emoji-button-transition-onHover: transform .3s;
@bl-customComponent-emoji-emojiPicker-zIndex: 100;
@bl-customComponent-emoji-dropdownPosition-left: -93%;
@bl-customComponent-emoji-dropdownPosition-center: -46%;
@bl-customComponent-emoji-dropdownPosition-right: 0%;
````
187 changes: 187 additions & 0 deletions components/bl-emoji/component.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
{
"id": "c_9a93b7887145faf22c0fe8941612bac3",
"name": "Emoji",
"description": "The component is for emoji selection.",
"showInToolbox": true,
"faIcon": "icons",
"mainJS": "dist/index.js",
"type": "custom",
"category": "Custom Components",
"properties": [
{
Copy link
Collaborator

Choose a reason for hiding this comment

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

Need actions and property that could control picker visibility

"type": "checkbox",
"name": "disabled",
"label": "Disabled",
"settingTooltip": "This setting allows you to disable the component.",
"showInSettings": true,
"hasLogicHandler": true,
"handlerId": "disabledLogic",
"handlerLabel": "Disabled Logic",
"handlerDescription": "This handler allows you to disable the component.",
"dataBinding": true
},
{
"type": "color",
"name": "buttonColor",
"label": "Button Color",
"settingTooltip": "This setting allows you to specify the color of the button.",
"showInSettings": true,
"defaultValue": "#000000",
"hasLogicHandler": true,
"handlerId": "buttonColorLogic",
"handlerLabel": "Button Color Logic",
"handlerDescription": "This handler allows you to specify the color of the button.",
"dataBinding": true
},
{
"type": "text",
"name": "buttonSize",
"label": "Button Size",
"settingTooltip": "This setting allows you to specify the button size.",
"showInSettings": true,
"defaultValue": "24px",
"hasLogicHandler": true,
"handlerId": "buttonSizeLogic",
"handlerLabel": "Button Size Logic",
"handlerDescription": "This handler allows you to specify the button size.",
"dataBinding": true
},
{
"type": "text",
"name": "dropdownHeight",
"label": "Dropdown List Height",
"settingTooltip": "This setting allows you to specify the dropdown list height.",
"showInSettings": true,
"defaultValue": "500px",
"hasLogicHandler": true,
"handlerId": "dropdownHeightLogic",
"handlerLabel": "Dropdown List Height Logic",
"handlerDescription": "This handler allows you to specify the dropdown list height.",
"dataBinding": true
},
{
"type": "text",
"name": "dropdownWidth",
"label": "Dropdown List Width",
"settingTooltip": "This setting allows you to specify the dropdown list width.",
"showInSettings": true,
"defaultValue": "400px",
"hasLogicHandler": true,
"handlerId": "dropdownWidthLogic",
"handlerLabel": "Dropdown List Width Logic",
"handlerDescription": "This handler allows you to specify the dropdown list width.",
"dataBinding": true
},
{
"type": "select",
"name": "dropdownPosition",
"label": "Dropdown List Position",
"settingTooltip": "This setting allows you to select the position of the dropdown.",
"showInSettings": true,
"defaultValue": "center",
"hasLogicHandler": true,
"handlerId": "dropdownPositionLogic",
"handlerLabel": "Dropdown List Position Logic",
"handlerDescription": "This handler allows you to select the position of the dropdown.",
"dataBinding": true,
"options": [
{
"value": "left",
"label": "Left"
},
{
"value": "center",
"label": "Center"
},
{
"value": "right",
"label": "Right"
}
]
},
{
"type": "select",
"name": "theme",
"label": "Theme",
"settingTooltip": "This setting allows you to select a theme for the emoji dropdown list.",
"showInSettings": true,
"defaultValue": "light",
"hasLogicHandler": true,
"handlerId": "themeLogic",
"handlerLabel": "Theme Logic",
"handlerDescription": "This handler allows you to select a theme for the emoji dropdown list.",
"dataBinding": true,
"options": [
{
"value": "light",
"label": "Light"
},
{
"value": "dark",
"label": "Dark"
},
{
"value": "auto",
"label": "Auto"
}
]
},
{
"type": "select",
"name": "emojiStyle",
"label": "Emoji Style",
"settingTooltip": "This setting allows you to select an emoji style.",
"showInSettings": true,
"defaultValue": "apple",
"hasLogicHandler": true,
"handlerId": "emojiStyleLogic",
"handlerLabel": "Emoji Style Logic",
"handlerDescription": "This handler allows you to select an emoji style.",
"dataBinding": true,
"options": [
{
"value": "apple",
"label": "Apple"
},
{
"value": "google",
"label": "Google"
},
{
"value": "facebook",
"label": "Facebook"
}
]
},
{
"type": "checkbox",
"name": "searchDisabled",
"label": "Search Disabled",
"settingTooltip": "This setting allows you to disable the emoji search field.",
"showInSettings": true,
"hasLogicHandler": true,
"handlerId": "searchDisabledLogic",
"handlerLabel": "Search Disabled Logic",
"handlerDescription": "This handler allows you to disable the emoji search field.",
"dataBinding": true
}
],
"eventHandlers": [
{
"name": "onEmojiSelect",
"label": "On Emoji Select Event",
"output": false,
"handlerDescription": "This event is triggered when an emoji is selected.",
"contextBlocks": [
{
"id": "emoji",
"label": "Emoji"
},
{
"id": "emojiNames",
"label": "Emoji Names"
}
]
}
]
}
1 change: 1 addition & 0 deletions components/bl-emoji/preview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div data-module-type="system" data-module-id="block" data-display data-uid="ca952a7c95b20e7ac219d2d2ec9e29d7" style="display:flex;flex-shrink:0;padding:0 0 0 0;min-height:auto;min-width:auto;flex-direction:row;align-items:center;justify-content:flex-start;"><i data-icon="emoji_emotions" data-size="default" data-module-type="system" data-module-id="icon" data-display data-uid="2b9a2ee421affd9e5fef2ca5f8d5a36d" style="color:rgb(40, 245, 190);"></i></div>
1 change: 1 addition & 0 deletions components/bl-emoji/src/emoji-picker-react.min.js

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions components/bl-emoji/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useState, useMemo } from 'react';

import EmojiPicker from './emoji-picker-react.min.js';

const { cn, normalizeDimensionValue } = BackendlessUI.CSSUtils;

export default function EmojiComponent({ component, eventHandlers, elRef }) {
const {
classList, style, display, disabled, buttonColor, buttonSize,
dropdownHeight, dropdownWidth, dropdownPosition, theme, emojiStyle, searchDisabled
} = component;
const { onEmojiSelect } = eventHandlers;

const [pickerVisibility, setPickerVisibility] = useState(false);

const validButtonSize = useMemo(() => normalizeDimensionValue(buttonSize), [buttonSize]);
const validDropdownWidth = useMemo(() => normalizeDimensionValue(dropdownWidth), [dropdownWidth]);
const validDropdownHeight = useMemo(() => normalizeDimensionValue(dropdownHeight), [dropdownHeight]);

const handleEmojiButtonClick = () => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

togglePickerVisibility

setPickerVisibility(prevState => !prevState);
};

const handleEmojiClick = event => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

onEmojiClick

const { emoji, names } = event;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could be destructed at arguments


navigator.clipboard.writeText(emoji);
Copy link
Collaborator

Choose a reason for hiding this comment

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

But how it will be inserted into text fields? Pasting? It may not be convenient.
We should try to find a way to link it with input and write an emoji directly into it, without a clipboard.

onEmojiSelect({ emoji, emojiNames: names });
};

if (!display) {
return null;
}
Comment on lines +31 to +33
Copy link
Collaborator

Choose a reason for hiding this comment

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

For now it's impossible to always show it? It could be shown only after some trigger?
If yes need to add this possibility


return (
<div
ref={ elRef }
style={ style }
className={
cn("bl-customComponent-emoji", classList, { "bl-customComponent-emoji--disabled": disabled })
}>
<div className="emoji-picker">
<div onClick={ handleEmojiButtonClick } className="emoji-picker__button">
<svg width={ validButtonSize } height={ validButtonSize } viewBox="0 0 512 512" fill={ buttonColor }>
<path d={ getIconPath(pickerVisibility) } />
Copy link
Collaborator

Choose a reason for hiding this comment

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

Two icon components and something like that

{ pickerVisibility ? : }

</svg>
</div>
Comment on lines +43 to +47
Copy link
Collaborator

Choose a reason for hiding this comment

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

Component?

{ pickerVisibility &&
<div className={ cn("emoji-picker__dropdown", `emoji-picker__dropdown-position--${ dropdownPosition }`) }>
<EmojiPicker
theme={ theme }
emojiStyle={ emojiStyle }
width={ validDropdownWidth }
height={ validDropdownHeight }
searchDisabled={ searchDisabled }
onEmojiClick={ handleEmojiClick }
/>
</div>
}
Comment on lines +48 to +59
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
{ pickerVisibility &&
<div className={ cn("emoji-picker__dropdown", `emoji-picker__dropdown-position--${ dropdownPosition }`) }>
<EmojiPicker
theme={ theme }
emojiStyle={ emojiStyle }
width={ validDropdownWidth }
height={ validDropdownHeight }
searchDisabled={ searchDisabled }
onEmojiClick={ handleEmojiClick }
/>
</div>
}
<PickerLayoutManager dropdownPosition={dropdownPosition} pickerVisibility={pickerVisibility}>
<EmojiPicker
theme={ theme }
emojiStyle={ emojiStyle }
width={ validDropdownWidth }
height={ validDropdownHeight }
searchDisabled={ searchDisabled }
onEmojiClick={ handleEmojiClick }
/>
</PickerLayoutManager>

</div>
</div>
);
}

function getIconPath(pickerVisibility) {
if (pickerVisibility) {
return 'M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm349.5 52.4c18.7-4.4 35.9 12 25.5 28.1C350.4 374.6 306.3 400 255.9 400s-94.5-25.4-119.1-63.5c-10.4-16.1 6.8-32.5 25.5-28.1c28.9 6.8 60.5 10.5 93.6 10.5s64.7-3.7 93.6-10.5zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm165.8 21.7c-7.6 8.1-20.2 8.5-28.3 .9s-8.5-20.2-.9-28.3c14.5-15.5 35.2-22.3 54.6-22.3s40.1 6.8 54.6 22.3c7.6 8.1 7.1 20.7-.9 28.3s-20.7 7.1-28.3-.9c-5.5-5.8-14.8-9.7-25.4-9.7s-19.9 3.8-25.4 9.7z';
}

return 'M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm177.6 62.1C192.8 334.5 218.8 352 256 352s63.2-17.5 78.4-33.9c9-9.7 24.2-10.4 33.9-1.4s10.4 24.2 1.4 33.9c-22 23.8-60 49.4-113.6 49.4s-91.7-25.5-113.6-49.4c-9-9.7-8.4-24.9 1.4-33.9s24.9-8.4 33.9 1.4zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z';
}
55 changes: 55 additions & 0 deletions components/bl-emoji/styles/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
@bl-customComponent-emoji-themeColor: @themePrimary;
@bl-customComponent-emoji-backgroundColor: @appBackgroundColor;
@bl-customComponent-emoji-textColor: @appTextColor;

@bl-customComponent-emoji-disabled-opacity: 0.38;

@bl-customComponent-emoji-button-transform-onHover: scale(1.2);
@bl-customComponent-emoji-button-transition-onHover: transform .3s;
@bl-customComponent-emoji-emojiPicker-zIndex: 100;

@bl-customComponent-emoji-dropdownPosition-left: -93%;
@bl-customComponent-emoji-dropdownPosition-center: -46%;
@bl-customComponent-emoji-dropdownPosition-right: 0%;

.bl-customComponent-emoji {
display: flex;
height: auto;
width: auto;

&--disabled {
opacity: @bl-customComponent-emoji-disabled-opacity;
pointer-events: none;
cursor: default;
}

.emoji-picker {
position: relative;

&__button {
cursor: pointer;

&:hover {
transform: @bl-customComponent-emoji-button-transform-onHover;
transition: @bl-customComponent-emoji-button-transition-onHover;
}
}

&__dropdown {
position: absolute;
z-index: @bl-customComponent-emoji-emojiPicker-zIndex;

&-position--left {
transform: translateX(@bl-customComponent-emoji-dropdownPosition-left);
}

&-position--center {
transform: translateX(@bl-customComponent-emoji-dropdownPosition-center);
}

&-position--right {
transform: translateX(@bl-customComponent-emoji-dropdownPosition-right);
}
}
}
}
Binary file added components/bl-emoji/thumbnail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.