feat: added floating toolbar on text selection (#378)

style: re-designed create-issue modal
This commit is contained in:
Dakshesh Jain 2023-03-06 22:49:06 +05:30 committed by GitHub
parent d28fe930a6
commit 82f8b6d387
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 86 additions and 39 deletions

View File

@ -21,6 +21,7 @@ import { CreateUpdateCycleModal } from "components/cycles";
import { CreateLabelModal } from "components/labels";
// ui
import { Button, CustomMenu, Input, Loader } from "components/ui";
import { PrimaryButton } from "components/ui/button/primary-button";
// icons
import { XMarkIcon } from "@heroicons/react/24/outline";
// helpers
@ -156,7 +157,7 @@ export const IssueForm: FC<IssueFormProps> = ({
/>
)}
/>
<h3 className="text-lg font-medium leading-6 text-gray-900">
<h3 className="text-xl font-semibold leading-6 text-gray-900">
{status ? "Update" : "Create"} Issue
</h3>
</div>
@ -189,11 +190,11 @@ export const IssueForm: FC<IssueFormProps> = ({
<div>
<Input
id="name"
label="Title"
name="name"
onChange={handleTitleChange}
className="resize-none"
placeholder="Enter title"
className="resize-none text-xl"
placeholder="Title"
mode="transparent"
autoComplete="off"
error={errors.name}
register={register}
@ -219,7 +220,7 @@ export const IssueForm: FC<IssueFormProps> = ({
</span>
?
</a>
</Link>{" "}
</Link>
</p>
<button
type="button"
@ -234,9 +235,6 @@ export const IssueForm: FC<IssueFormProps> = ({
)}
</div>
<div>
<label htmlFor={"description"} className="mb-2 text-gray-500">
Description
</label>
<Controller
name="description"
control={control}
@ -245,7 +243,7 @@ export const IssueForm: FC<IssueFormProps> = ({
value={value}
onJSONChange={(jsonValue) => setValue("description", jsonValue)}
onHTMLChange={(htmlValue) => setValue("description_html", htmlValue)}
placeholder="Enter Your Text..."
placeholder="Description"
/>
)}
/>
@ -333,7 +331,7 @@ export const IssueForm: FC<IssueFormProps> = ({
</div>
</div>
</div>
<div className="mt-5 flex items-center justify-between gap-2">
<div className="-mx-5 mt-5 flex items-center justify-between gap-2 border-t px-5 pt-5">
<div
className="flex cursor-pointer items-center gap-1"
onClick={() => setCreateMore((prevData) => !prevData)}
@ -360,15 +358,15 @@ export const IssueForm: FC<IssueFormProps> = ({
<Button type="button" theme="secondary" onClick={handleClose}>
Discard
</Button>
<Button type="submit" disabled={isSubmitting}>
<PrimaryButton type="submit" size="sm" loading={isSubmitting}>
{status
? isSubmitting
? "Updating Issue..."
: "Update Issue"
: isSubmitting
? "Creating Issue..."
: "Create Issue"}
</Button>
? "Adding Issue..."
: "Add Issue"}
</PrimaryButton>
</div>
</div>
</form>

View File

@ -231,7 +231,7 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = ({
</Transition.Child>
<div className="fixed inset-0 z-10 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
<div className="mt-10 flex min-h-full items-start justify-center p-4 text-center sm:p-0 md:mt-20">
<Transition.Child
as={React.Fragment}
enter="ease-out duration-300"

View File

@ -185,7 +185,9 @@ export const SingleProjectCard: React.FC<ProjectCardProps> = ({
</span>
)}
</div>
<p className="mt-3.5 mb-7">{truncateText(project.description ?? "", 100)}</p>
<p className="mt-3.5 mb-7 break-all">
{truncateText(project.description ?? "", 100)}
</p>
</a>
</Link>
<div className="flex h-full items-end justify-between">

View File

@ -34,9 +34,8 @@ import fileService from "services/file.service";
// ui
import { Spinner } from "components/ui";
// components
import { RichTextToolbar } from "./toolbar";
import { CustomFloatingToolbar } from "./toolbar/float-tool-tip";
import { MentionAutoComplete } from "./mention-autocomplete";
import { FloatingLinkToolbar } from "./toolbar/link";
export interface IRemirrorRichTextEditor {
placeholder?: string;
@ -51,6 +50,9 @@ export interface IRemirrorRichTextEditor {
customClassName?: string;
}
// eslint-disable-next-line no-duplicate-imports
import { FloatingWrapper, FloatingToolbar } from "@remirror/react";
const RemirrorRichTextEditor: FC<IRemirrorRichTextEditor> = (props) => {
const {
placeholder,
@ -182,30 +184,42 @@ const RemirrorRichTextEditor: FC<IRemirrorRichTextEditor> = (props) => {
<Remirror
manager={manager}
initialContent={state}
classNames={[`p-4 focus:outline-none ${customClassName}`]}
classNames={[
`p-4 relative focus:outline-none rounded-md border border-transparent focus:border-theme ${customClassName}`,
]}
editable={editable}
onBlur={() => {
onBlur(jsonValue, htmlValue);
}}
>
<div className="rounded-md border">
{showToolbar && editable && (
<div className="box-border w-full border-b py-2">
<RichTextToolbar />
</div>
{(!value || value === "" || value?.content?.[0]?.content === undefined) && (
<p className="pointer-events-none absolute top-[8.8rem] left-9 text-gray-300">
{placeholder || "Enter text..."}
</p>
)}
<EditorComponent />
{imageLoader && (
<div className="p-4">
<Spinner />
</div>
)}
{/* <TableComponents /> */}
<FloatingLinkToolbar />
{editable && (
<FloatingWrapper
positioner="always"
floatingLabel="Custom Floating Toolbar"
renderOutsideEditor
>
<FloatingToolbar className="z-[9999] overflow-hidden rounded">
<CustomFloatingToolbar />
</FloatingToolbar>
</FloatingWrapper>
)}
<MentionAutoComplete mentions={mentions} tags={tags} />
{<OnChangeJSON onChange={handleJSONChange} />}
{<OnChangeHTML onChange={handleHTMLChange} />}
</div>
</Remirror>
</div>
);

View File

@ -0,0 +1,33 @@
// buttons
import {
ToggleBoldButton,
ToggleItalicButton,
ToggleUnderlineButton,
ToggleStrikeButton,
ToggleOrderedListButton,
ToggleBulletListButton,
ToggleCodeButton,
} from "@remirror/react";
import HeadingControls from "./heading-controls";
export const CustomFloatingToolbar: React.FC = () => (
<div className="z-[99999] flex items-center gap-y-2 divide-x rounded border bg-white p-1 px-0.5 shadow-md">
<div className="flex items-center gap-x-1 px-2">
<HeadingControls />
</div>
<div className="flex items-center gap-x-1 px-2">
<ToggleBoldButton />
<ToggleItalicButton />
<ToggleUnderlineButton />
<ToggleStrikeButton />
</div>
<div className="flex items-center gap-x-1 px-2">
<ToggleOrderedListButton />
<ToggleBulletListButton />
</div>
<div className="flex items-center gap-x-1 px-2">
<ToggleCodeButton />
</div>
</div>
);

View File

@ -173,12 +173,12 @@ export const FloatingLinkToolbar = () => {
return (
<>
{!isEditing && (
<FloatingToolbar className="shadow-lg rounded bg-white p-1">
<FloatingToolbar className="rounded bg-white p-1 shadow-lg">
{linkEditButtons}
</FloatingToolbar>
)}
{!isEditing && empty && (
<FloatingToolbar positioner={linkPositioner} className="shadow-lg rounded bg-white p-1">
<FloatingToolbar positioner={linkPositioner} className="rounded bg-white p-1 shadow-lg">
{linkEditButtons}
</FloatingToolbar>
)}