Sfoglia il codice sorgente

Added library

feature/1737
djordjemitrovic00 3 anni fa
parent
commit
cb135ef048

+ 24974
- 42
package-lock.json
File diff soppresso perché troppo grande
Vedi File


+ 2
- 0
package.json Vedi File

@@ -45,6 +45,8 @@
"redux-saga": "^1.1.3",
"rive-react": "^3.0.23",
"sass": "^1.34.1",
"slate": "^0.86.0",
"slate-react": "^0.86.0",
"socket.io": "^4.5.1",
"socket.io-client": "^4.5.1",
"styled-components": "^5.3.5",

+ 2
- 14
src/components/Cards/CreateOfferCard/FirstPart/OfferDescriptionField/OfferDescriptionField.js Vedi File

@@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
import useIsMobile from "../../../../../hooks/useIsMobile";
import { FieldLabel } from "../FirstPartCreateOffer.styled";
import { DescriptionField } from "./OfferDescriptionField.styled";
import RichTextComponent from "../../../../RichTextComponent/RichTextComponent";

const OfferDescriptionField = (props) => {
const formik = props.formik;
@@ -13,20 +14,7 @@ const OfferDescriptionField = (props) => {
<>
<FieldLabel leftText={t("offer.productDescription")} />
{!isMobile ? (
<DescriptionField
name="description"
placeholder={t("offer.description")}
margin="normal"
italicPlaceholder
value={formik.values.description}
onChange={formik.handleChange}
error={formik.touched.description && formik.errors.description}
helperText={formik.touched.description && formik.errors.description}
fullWidth
multiline
minRows={4}
height={"100px"}
/>
<RichTextComponent />
) : (
<DescriptionField
name="description"

+ 15
- 0
src/components/Cards/CreateOfferCard/FirstPart/OfferDescriptionField/OfferDescriptionField.styled.js Vedi File

@@ -1,4 +1,5 @@
import styled from "styled-components";
import selectedTheme from "../../../../../themes";
import { TextField } from "../../../../TextFields/TextField/TextField";

export const DescriptionField = styled(TextField)`
@@ -13,3 +14,17 @@ export const DescriptionField = styled(TextField)`
}
}
`;
export const Element = styled.p`
background-color: ${selectedTheme.colors.primaryBackgroundColor};
padding: 0;
box-sizing: border-box;
overflow-y: auto;
width: 100%;
margin: 16px 0;
padding-left: 0;
height: 100px;
font-size: 16px;
padding: 8px 14px;
border: 1px solid rgba(0, 0, 0, 0.23);
border-radius: 4px;
`;

+ 79
- 0
src/components/RichTextComponent/BlockButton/BlockButton.js Vedi File

@@ -0,0 +1,79 @@
import React from "react";
import PropTypes from "prop-types";
import { Button, Icon } from "@mui/material";
import { useSlate } from "slate-react";
import { Editor, Transforms, Element as SlateElement } from "slate";
const LIST_TYPES = ["numbered-list", "bulleted-list"];
const TEXT_ALIGN_TYPES = ["left", "center", "right", "justify"];
const BlockButton = ({ format, icon }) => {
const editor = useSlate();
return (
<Button
active={isBlockActive(
editor,
format,
TEXT_ALIGN_TYPES.includes(format) ? "align" : "type"
)}
onMouseDown={(event) => {
event.preventDefault();
toggleBlock(editor, format);
}}
>
<Icon>{icon}</Icon>
</Button>
);
};
const isBlockActive = (editor, format, blockType = "type") => {
const { selection } = editor;
if (!selection) return false;

const [match] = Array.from(
Editor.nodes(editor, {
at: Editor.unhangRange(editor, selection),
match: (n) =>
!Editor.isEditor(n) &&
SlateElement.isElement(n) &&
n[blockType] === format,
})
);

return !!match;
};
const toggleBlock = (editor, format) => {
const isActive = isBlockActive(
editor,
format,
TEXT_ALIGN_TYPES.includes(format) ? "align" : "type"
);
const isList = LIST_TYPES.includes(format);

Transforms.unwrapNodes(editor, {
match: (n) =>
!Editor.isEditor(n) &&
SlateElement.isElement(n) &&
LIST_TYPES.includes(n.type) &&
!TEXT_ALIGN_TYPES.includes(format),
split: true,
});
let newProperties;
if (TEXT_ALIGN_TYPES.includes(format)) {
newProperties = {
align: isActive ? undefined : format,
};
} else {
newProperties = {
type: isActive ? "paragraph" : isList ? "list-item" : format,
};
}
Transforms.setNodes < SlateElement > (editor, newProperties);

if (!isActive && isList) {
const block = { type: format, children: [] };
Transforms.wrapNodes(editor, block);
}
};
BlockButton.propTypes = {
format: PropTypes.any,
icon: PropTypes.any,
};
export default BlockButton;

+ 0
- 0
src/components/RichTextComponent/BlockButton/BlockButton.styled.js Vedi File


+ 40
- 0
src/components/RichTextComponent/MarkButton/MarkButton.js Vedi File

@@ -0,0 +1,40 @@
import React from "react";
import PropTypes from "prop-types";
import { Button, Icon } from "@mui/material";
import { useSlate } from "slate-react";
import { Editor } from "slate";

const toggleMark = (editor, format) => {
const isActive = isMarkActive(editor, format);

if (isActive) {
Editor.removeMark(editor, format);
} else {
Editor.addMark(editor, format, true);
}
};

const isMarkActive = (editor, format) => {
const marks = Editor.marks(editor);
return marks ? marks[format] === true : false;
};

const MarkButton = ({ format, icon }) => {
const editor = useSlate();
return (
<Button
active={isMarkActive(editor, format)}
onMouseDown={(event) => {
event.preventDefault();
toggleMark(editor, format);
}}
>
<Icon>{`${icon} ${isMarkActive(editor, format)}`}</Icon>
</Button>
);
};
MarkButton.propTypes = {
format: PropTypes.any,
icon: PropTypes.any,
};
export default MarkButton;

+ 82
- 0
src/components/RichTextComponent/RichTextComponent.js Vedi File

@@ -0,0 +1,82 @@
import React, { useCallback, useMemo } from "react";
import { Editable, withReact, Slate } from "slate-react";
import { createEditor } from "slate";

import RichTextElement from "./RichTextElement/RichTextElement";
import BlockButton from "./BlockButton/BlockButton";
import MarkButton from "./MarkButton/MarkButton";
import RichTextLeaf from "./RichTextLeaf/RichTextLeaf";

const RichTextComponent = () => {
const renderElement = useCallback(
(props) => <RichTextElement {...props} />,
[]
);
const renderLeaf = useCallback((props) => <RichTextLeaf {...props} />, []);
const editor = useMemo(() => withReact(createEditor()), []);

return (
<Slate editor={editor} value={initialValue}>
<div>
<MarkButton format="bold" icon="format_bold" />
<MarkButton format="italic" icon="format_italic" />
<MarkButton format="underline" icon="format_underlined" />
<MarkButton format="code" icon="code" />
<BlockButton format="heading-one" icon="looks_one" />
<BlockButton format="heading-two" icon="looks_two" />
<BlockButton format="block-quote" icon="format_quote" />
<BlockButton format="numbered-list" icon="format_list_numbered" />
<BlockButton format="bulleted-list" icon="format_list_bulleted" />
<BlockButton format="left" icon="format_align_left" />
<BlockButton format="center" icon="format_align_center" />
<BlockButton format="right" icon="format_align_right" />
<BlockButton format="justify" icon="format_align_justify" />
</div>
<Editable
renderElement={renderElement}
renderLeaf={renderLeaf}
placeholder="Enter some rich text…"
spellCheck
autoFocus
/>
</Slate>
);
};

const initialValue = [
{
type: "paragraph",
children: [
{ text: "This is editable " },
{ text: "rich", bold: true },
{ text: " text, " },
{ text: "much", italic: true },
{ text: " better than a " },
{ text: "<textarea>", code: true },
{ text: "!" },
],
},
{
type: "paragraph",
children: [
{
text: "Since it's rich text, you can do things like turn a selection of text ",
},
{ text: "bold", bold: true },
{
text: ", or add a semantically rendered block quote in the middle of the page, like this:",
},
],
},
{
type: "block-quote",
children: [{ text: "A wise quote." }],
},
{
type: "paragraph",
align: "center",
children: [{ text: "Try it out for yourself!" }],
},
];

export default RichTextComponent;

+ 58
- 0
src/components/RichTextComponent/RichTextElement/RichTextElement.js Vedi File

@@ -0,0 +1,58 @@
import React from "react";
import PropTypes from "prop-types";

const RichTextElement = ({ attributes, children, element }) => {
const style = { textAlign: element.align };
switch (element.type) {
case "block-quote":
return (
<blockquote style={style} {...attributes}>
{children}
</blockquote>
);
case "bulleted-list":
return (
<ul style={style} {...attributes}>
{children}
</ul>
);
case "heading-one":
return (
<h1 style={style} {...attributes}>
{children}
</h1>
);
case "heading-two":
return (
<h2 style={style} {...attributes}>
{children}
</h2>
);
case "list-item":
return (
<li style={style} {...attributes}>
{children}
</li>
);
case "numbered-list":
return (
<ol style={style} {...attributes}>
{children}
</ol>
);
default:
return (
<p style={style} {...attributes}>
{children}
</p>
);
}
};

RichTextElement.propTypes = {
attributes: PropTypes.any,
children: PropTypes.any,
element: PropTypes.any,
};

export default RichTextElement;

+ 28
- 0
src/components/RichTextComponent/RichTextLeaf/RichTextLeaf.js Vedi File

@@ -0,0 +1,28 @@
import React from "react";
import PropTypes from "prop-types";
const RichTextLeaf = ({ attributes, children, leaf }) => {
if (leaf.bold) {
children = <strong>{children}</strong>;
}

if (leaf.code) {
children = <code>{children}</code>;
}

if (leaf.italic) {
children = <em>{children}</em>;
}

if (leaf.underline) {
children = <u>{children}</u>;
}

return <span {...attributes}>{children}</span>;
};

RichTextLeaf.propTypes = {
attributes: PropTypes.any,
children: PropTypes.any,
leaf: PropTypes.any,
};
export default RichTextLeaf;

+ 4
- 1
src/components/TextFields/TextField/TextField.js Vedi File

@@ -14,6 +14,7 @@ export const TextField = React.forwardRef((props, ref) => {
setIsFieldEmpty(false);
}
}, [props.value]);
console.log(props);
return (
<TextFieldContainer
style={props.containerStyle}
@@ -21,6 +22,7 @@ export const TextField = React.forwardRef((props, ref) => {
height={props.height}
>
<TextFieldStyled
{...props.attributes}
inputRef={ref}
inputProps={props.inputProps}
placeholder={props.placeholder}
@@ -98,11 +100,12 @@ TextField.propTypes = {
endAdornment: PropTypes.node,
style: PropTypes.any,
}),
attributes: PropTypes.any,
};

TextField.defaultProps = {
italicPlaceholder: false,
showAnimation: false,
height: "48px",
font: selectedTheme.fonts.textFont
font: selectedTheme.fonts.textFont,
};

+ 68
- 3
yarn.lock Vedi File

@@ -2178,6 +2178,11 @@
"resolved" "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz"
"version" "5.1.1"

"@types/is-hotkey@^0.1.1":
"integrity" "sha512-yB5C7zcOM7idwYZZ1wKQ3pTfjA9BbvFqRWvKB46GFddxnJtHwi/b9y84ykQtxQPg5qhdpg4Q/kWU3EGoCTmLzQ=="
"resolved" "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.7.tgz"
"version" "0.1.7"

"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
"integrity" "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw=="
"resolved" "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz"
@@ -2215,7 +2220,7 @@
"resolved" "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
"version" "0.0.29"

"@types/lodash@^4.14.175":
"@types/lodash@^4.14.149", "@types/lodash@^4.14.175":
"integrity" "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q=="
"resolved" "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz"
"version" "4.14.182"
@@ -4023,6 +4028,11 @@
"safe-buffer" "5.1.2"
"vary" "~1.1.2"

"compute-scroll-into-view@^1.0.17":
"integrity" "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg=="
"resolved" "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz"
"version" "1.0.17"

"concat-map@0.0.1":
"integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
"resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
@@ -4811,6 +4821,11 @@
dependencies:
"path-type" "^4.0.0"

"direction@^1.0.3":
"integrity" "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ=="
"resolved" "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz"
"version" "1.0.4"

"dns-equal@^1.0.0":
"integrity" "sha1-s55/HabrCnW6nBcySzR1PEfgZU0="
"resolved" "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz"
@@ -6599,6 +6614,11 @@
"resolved" "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz"
"version" "5.1.8"

"immer@^9.0.6":
"integrity" "sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ=="
"resolved" "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz"
"version" "9.0.16"

"immer@^9.0.7":
"integrity" "sha512-ubBeqQutOSLIFCUBN03jGeOS6a3DoYlSYwYJTa+gSKEZKU5redJIqkIdZ3JVv/4RZpfcXdAWH5zCNLWPRv2WDw=="
"resolved" "https://registry.npmjs.org/immer/-/immer-9.0.14.tgz"
@@ -6958,6 +6978,11 @@
dependencies:
"is-extglob" "^2.1.1"

"is-hotkey@^0.1.6":
"integrity" "sha512-qs3NZ1INIS+H+yeo7cD9pDfwYV/jqRh1JG9S9zYrNudkoUQg7OL7ziXqRKu+InFjUIDoP2o6HIkLYMh1pcWgyQ=="
"resolved" "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.1.8.tgz"
"version" "0.1.8"

"is-installed-globally@^0.4.0":
"integrity" "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ=="
"resolved" "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz"
@@ -7044,6 +7069,11 @@
dependencies:
"isobject" "^3.0.1"

"is-plain-object@^5.0.0":
"integrity" "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
"resolved" "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz"
"version" "5.0.0"

"is-potential-custom-element-name@^1.0.1":
"integrity" "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
"resolved" "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz"
@@ -8143,7 +8173,7 @@
"resolved" "https://registry.npmjs.org/lodash.unset/-/lodash.unset-4.5.2.tgz"
"version" "4.5.2"

"lodash@^4.17.11", "lodash@^4.17.14", "lodash@^4.17.15", "lodash@^4.17.19", "lodash@^4.17.20", "lodash@^4.17.21", "lodash@^4.17.5", "lodash@^4.7.0", "lodash@>=3.5 <5", "lodash@4":
"lodash@^4.17.11", "lodash@^4.17.14", "lodash@^4.17.15", "lodash@^4.17.19", "lodash@^4.17.20", "lodash@^4.17.21", "lodash@^4.17.4", "lodash@^4.17.5", "lodash@^4.7.0", "lodash@>=3.5 <5", "lodash@4":
"integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
"resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
"version" "4.17.21"
@@ -10369,7 +10399,7 @@
"strip-ansi" "6.0.0"
"text-table" "0.2.0"

"react-dom@*", "react-dom@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0", "react-dom@^17.0.0 || ^18.0.0", "react-dom@^17.0.2", "react-dom@>= 16.8.0", "react-dom@>=16", "react-dom@>=16.6.0":
"react-dom@*", "react-dom@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0", "react-dom@^17.0.0 || ^18.0.0", "react-dom@^17.0.2", "react-dom@>= 16.8.0", "react-dom@>=16", "react-dom@>=16.6.0", "react-dom@>=16.8.0":
"integrity" "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA=="
"resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz"
"version" "17.0.2"
@@ -11337,6 +11367,13 @@
"ajv" "^6.12.5"
"ajv-keywords" "^3.5.2"

"scroll-into-view-if-needed@^2.2.20":
"integrity" "sha512-hxpAR6AN+Gh53AdAimHM6C8oTN1ppwVZITihix+WqalywBeFcQ6LdQP5ABNl26nX8GTEL7VT+b8lKpdqq65wXg=="
"resolved" "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.29.tgz"
"version" "2.2.29"
dependencies:
"compute-scroll-into-view" "^1.0.17"

"section-iterator@^2.0.0":
"integrity" "sha512-xvTNwcbeDayXotnV32zLb3duQsP+4XosHpb/F+tu6VzEZFmIjzPdNk6/O+QOOx5XTh08KL2ufdXeCO33p380pQ=="
"resolved" "https://registry.npmjs.org/section-iterator/-/section-iterator-2.0.0.tgz"
@@ -11609,6 +11646,29 @@
"resolved" "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
"version" "3.0.0"

"slate-react@^0.86.0":
"integrity" "sha512-FlzG0CL1MtpZk7DRH6a101FdqdhTi+vZ23SbY5hQudIdgLo7QnUBv97BRe30VctqsL9L+Z2OsFHSCmWpIIxJAw=="
"resolved" "https://registry.npmjs.org/slate-react/-/slate-react-0.86.0.tgz"
"version" "0.86.0"
dependencies:
"@types/is-hotkey" "^0.1.1"
"@types/lodash" "^4.14.149"
"direction" "^1.0.3"
"is-hotkey" "^0.1.6"
"is-plain-object" "^5.0.0"
"lodash" "^4.17.4"
"scroll-into-view-if-needed" "^2.2.20"
"tiny-invariant" "1.0.6"

"slate@^0.86.0", "slate@>=0.65.3":
"integrity" "sha512-aexL720Tpqx6St5oz0jo0/wZWCT7z8lChKkVJo2eiFkSNmoSnCGR62d2itAvmse7dEXkl4DbfAxRQPj8JDuGTg=="
"resolved" "https://registry.npmjs.org/slate/-/slate-0.86.0.tgz"
"version" "0.86.0"
dependencies:
"immer" "^9.0.6"
"is-plain-object" "^5.0.0"
"tiny-warning" "^1.0.3"

"slice-ansi@^4.0.0":
"integrity" "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ=="
"resolved" "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz"
@@ -12398,6 +12458,11 @@
"resolved" "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz"
"version" "1.2.0"

"tiny-invariant@1.0.6":
"integrity" "sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA=="
"resolved" "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.6.tgz"
"version" "1.0.6"

"tiny-warning@^1.0.0", "tiny-warning@^1.0.2", "tiny-warning@^1.0.3":
"integrity" "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
"resolved" "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz"

Loading…
Annulla
Salva