-
Notifications
You must be signed in to change notification settings - Fork 7
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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. | | ||
|
||
## Events | ||
|
||
| Name | Triggers | Context Blocks | | ||
|-----------------------|---------------------------|----------------------------------------------------| | ||
| On Emoji Select Event | when an emoji is selected | Emoji: `String`, Emoji Names: [`String`, `String`] | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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%; | ||
```` |
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": [ | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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" | ||
} | ||
] | ||
} | ||
] | ||
} |
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> |
Large diffs are not rendered by default.
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 = () => { | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. togglePickerVisibility |
||||||||||||||||||||||||||||||||||||||||||||||
setPickerVisibility(prevState => !prevState); | ||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
const handleEmojiClick = event => { | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. onEmojiClick |
||||||||||||||||||||||||||||||||||||||||||||||
const { emoji, names } = event; | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be destructed at arguments |
||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
navigator.clipboard.writeText(emoji); | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||||||||||||||||||||||||||||||||||||||||||||||
onEmojiSelect({ emoji, emojiNames: names }); | ||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
if (!display) { | ||||||||||||||||||||||||||||||||||||||||||||||
return null; | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+31
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? |
||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
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) } /> | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||
</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'; | ||||||||||||||||||||||||||||||||||||||||||||||
} |
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); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
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.