Explorar el Código

Finished feature #1930

bugfix/1930
Djordje Mitrovic hace 3 años
padre
commit
43e32e8022

+ 4
- 0
src/assets/images/svg/link.svg Ver fichero

@@ -0,0 +1,4 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.25 5.25H13.5C13.9925 5.25 14.4801 5.347 14.9351 5.53545C15.39 5.72391 15.8034 6.00013 16.1517 6.34835C16.4999 6.69657 16.7761 7.10997 16.9645 7.56494C17.153 8.01991 17.25 8.50754 17.25 9C17.25 9.49246 17.153 9.98009 16.9645 10.4351C16.7761 10.89 16.4999 11.3034 16.1517 11.6517C15.8034 11.9999 15.39 12.2761 14.9351 12.4645C14.4801 12.653 13.9925 12.75 13.5 12.75H11.25M6.75 12.75H4.5C4.00754 12.75 3.51991 12.653 3.06494 12.4645C2.60997 12.2761 2.19657 11.9999 1.84835 11.6517C1.14509 10.9484 0.75 9.99456 0.75 9C0.75 8.00544 1.14509 7.05161 1.84835 6.34835C2.55161 5.64509 3.50544 5.25 4.5 5.25H6.75" stroke="#667080" stroke-width="1.24" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6 9H12" stroke="#667080" stroke-width="1.24" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 51
- 0
src/components/Popovers/LinkPopover/LinkPopover.js Ver fichero

@@ -0,0 +1,51 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import {
FieldLabel,
FinishButton,
LinkField,
LinkPopoverContainer,
} from "./LinkPopover.styled";
import { useTranslation } from "react-i18next";
import selectedTheme from "../../../themes";

const LinkPopover = (props) => {
const { t } = useTranslation();
const [linkValue, setLinkValue] = useState("");

const handleClickFinishButton = () => {
let urlLink = linkValue.trim();
if (urlLink.startsWith("http://") || urlLink.startsWith("https://"))
props?.callbackFunction(urlLink); else props?.callbackFunction(`http://${urlLink}`)
};

return (
<LinkPopoverContainer>
<FieldLabel leftText={t("labels.link")} />
<LinkField
placeholder={t("examples.link")}
italicPlaceholder
value={linkValue}
onChange={(event) => setLinkValue(event.target.value)}
autoFocus
fullWidth
/>
<FinishButton
buttoncolor={selectedTheme.colors.primaryPurple}
textcolor={"white"}
variant={"contained"}
style={{ fontWeight: "600" }}
fullWidth
onClick={handleClickFinishButton}
>
{t("common.fillIn")}
</FinishButton>
</LinkPopoverContainer>
);
};

LinkPopover.propTypes = {
callbackFunction: PropTypes.func,
};

export default LinkPopover;

+ 45
- 0
src/components/Popovers/LinkPopover/LinkPopover.styled.js Ver fichero

@@ -0,0 +1,45 @@
import { Box } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../themes";
import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton";
import { Label } from "../../CheckBox/Label";
import { TextField } from "../../TextFields/TextField/TextField";

export const LinkPopoverContainer = styled(Box)`
display: flex;
flex-direction: column;
padding: 9px 18px;
gap: 9px;
width: 311px;
background: white;
box-shadow: 4px 4px 9px rgba(0, 0, 0, 0.12);
border-radius: 4px;
`;
export const FieldLabel = styled(Label)`
position: relative;
bottom: -4px;
& label {
font-size: 12px;
font-weight: 600;
line-height: 20px;
color: ${selectedTheme.colors.primaryGrayText};
cursor: auto;
letter-spacing: 0.2px;
}
@media (max-width: 600px) {
& label {
font-size: 9px;
}
}
`;
export const FinishButton = styled(PrimaryButton)`
height: 42px;
&:hover {
background-color: ${selectedTheme.colors.primaryPurple};
color: white !important;
border-radius: 4px;
}
`;
export const LinkField = styled(TextField)`
margin: 0;
`

+ 55
- 0
src/components/RichTextComponent/LinkButton/LinkButton.js Ver fichero

@@ -0,0 +1,55 @@
import React from "react";
import PropTypes from "prop-types";
import { useSlate } from "slate-react";
import { Editor } from "slate";
import { LinkButtonContainer, LinkIcon } from "./LinkButton.styled";
import { useState } from "react";
import LinkPopover from "../../Popovers/LinkPopover/LinkPopover";
import PopoverComponent from "../../Popovers/PopoverComponent";

const toggleMark = (editor, format, link) => {
Editor.addMark(editor, format, link);
};

const LinkButton = (props) => {
const editor = useSlate();
const [isLinkPopoverShowing, setIsLinkPopoverShowing] = useState(false);
const [linkPopoverAnchor, setLinkPopoverAnchor] = useState(null);

const callbackFunction = (link) => {
setIsLinkPopoverShowing(false);
toggleMark(editor, "a", link);
};
const handleClickLinkButton = (event) => {
setIsLinkPopoverShowing(true);
setLinkPopoverAnchor(event.currentTarget);
};
const handleCloseLinkPopover = () => {
setIsLinkPopoverShowing(false);
};
console.log();
return (
<>
<LinkButtonContainer
format={props?.format}
onMouseDown={handleClickLinkButton}
>
<LinkIcon />
</LinkButtonContainer>
<PopoverComponent
anchorEl={linkPopoverAnchor}
open={isLinkPopoverShowing}
onClose={handleCloseLinkPopover}
content={<LinkPopover callbackFunction={callbackFunction} />}
/>
</>
);
};
LinkButton.propTypes = {
format: PropTypes.any,
icon: PropTypes.any,
selectedColor: PropTypes.any,
setSelectedColor: PropTypes.func,
};
export default LinkButton;

+ 11
- 0
src/components/RichTextComponent/LinkButton/LinkButton.styled.js Ver fichero

@@ -0,0 +1,11 @@
import { Box } from "@mui/material";
import styled from "styled-components";
import { ReactComponent as Link } from "../../../assets/images/svg/link.svg";

export const LinkButtonContainer = styled(Box)`
display: inline;
cursor: pointer;
position: relative;
top: 2px;
`;
export const LinkIcon = styled(Link)``

+ 24
- 1
src/components/RichTextComponent/RichTextComponent.js Ver fichero

@@ -1,6 +1,6 @@
import React, { useCallback, useMemo } from "react";
import { Editable, withReact, Slate } from "slate-react";
import { createEditor } from "slate";
import { createEditor, Editor } from "slate";
import PropTypes from "prop-types";

import RichTextElement from "./RichTextElement/RichTextElement";
@@ -21,6 +21,7 @@ import useIsMobile from "../../hooks/useIsMobile";
import { useTranslation } from "react-i18next";
import { isJsonString } from "../../util/helpers/jsonHelper";
import { useEffect } from "react";
import LinkButton from "./LinkButton/LinkButton";

const RichTextComponent = (props) => {
const { isMobile } = useIsMobile();
@@ -60,6 +61,26 @@ const RichTextComponent = (props) => {
editor={editor}
value={isJsonString(props?.value) ? JSON.parse(props?.value) : value}
onChange={(newValue) => {
console.log(
editor.selection
? Editor.string(editor, editor.selection)
: "<no selection>"
);
const marks = Editor.marks(editor);
console.log("marks", marks);
if (marks) {
console.log("ovde je true");
console.log("marks a", marks?.a);
if (
((editor?.selection &&
Editor.string(editor, editor.selection).length === 0) ||
!editor?.selection) &&
marks?.a
) {
console.log("marks", marks);
Editor.removeMark(editor, "a");
}
}
if (props?.onChange) props?.onChange(JSON.stringify(newValue));
else setValue(newValue);
}}
@@ -69,6 +90,7 @@ const RichTextComponent = (props) => {
<MarkButton format="bold" icon="B" />
<MarkButton format="italic" icon="I" />
<MarkButton format="underline" icon="U" />
<LinkButton />
<BlockButton format="bulleted-list" icon={<BulletedList />} />
<ColorButton
selectedColor={selectedColor}
@@ -87,6 +109,7 @@ const RichTextComponent = (props) => {
renderLeaf={renderLeaf}
spellCheck
autoFocus
on
readOnly={props?.readOnly}
/>
</EditableInnerContainer>

+ 7
- 0
src/components/RichTextComponent/RichTextLeaf/RichTextLeaf.js Ver fichero

@@ -19,6 +19,13 @@ const RichTextLeaf = ({ attributes, children, leaf }) => {
if (leaf.color) {
children = <span style={{ color: leaf.color }}>{children}</span>;
}
if (leaf.a) {
children = (
<a href={leaf.a} target="_blank">{/*eslint-disable-line*/}
{children}
</a>
);
}
return <span {...attributes}>{children}</span>;
};


+ 5
- 0
src/i18n/resources/rs.js Ver fichero

@@ -47,6 +47,7 @@ export default {
date: {
range: "{{start}} do {{end}}",
},
fillIn: "Unesi"
},
login: {
welcome: "React template",
@@ -603,6 +604,7 @@ export default {
messageUser: "Message user",
prevPage: "Previous page",
nextPage: "Next page",
link: "Link"
},
colorPicker: {
label: "Boja: ",
@@ -612,4 +614,7 @@ export default {
purple: "Ljubičasta",
pink: "Roze",
},
examples: {
link: "ex. https://google.com/"
}
};

Cargando…
Cancelar
Guardar