Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 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
6 changes: 0 additions & 6 deletions src/components/Label/Label.css

This file was deleted.

30 changes: 17 additions & 13 deletions src/components/Label/Label.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { type ReactNode, useMemo } from "react";
import { twMerge } from "tailwind-merge";
import { contrast, hslColorToCss, hslToHex } from "./color-utils";
import "./Label.css";
import { useMemo } from "react";

export function Label({
label,
icon = "",
endSlot,
className = "",
variant = "filled",
showTooltip = false,
}: {
label: string;
icon?: string;
endSlot?: ReactNode;
className?: string;
variant?: "filled" | "outlined";
showTooltip?: boolean;
Expand All @@ -22,29 +21,34 @@ export function Label({

const style = useMemo(
() => ({
backgroundColor: variant === "filled" ? mainColor.hex : hslColorToCss(dimmedMainColor.hsl),
color: variant === "filled" ? contrastMainColor : mainColor.hex,
"--dark-bg-color": hslColorToCss(variant === "filled" ? mainColor.hsl : dimmedMainColor.dark),
"--light-bg-color": hslColorToCss(variant === "filled" ? mainColor.hsl : dimmedMainColor.light),
"--dark-text-color": variant === "filled" ? contrastMainColor : mainColor.hex,
"--light-text-color": variant === "filled" ? contrastMainColor : "#000000",
border: variant === "filled" ? "1px solid transparent" : `1px solid ${mainColor.hex}`,
}),
[dimmedMainColor, contrastMainColor, variant, mainColor],
[contrastMainColor, variant, mainColor, dimmedMainColor],
);

return (
<span
style={style}
className={twMerge("label truncate rounded-xl px-2.5 py-0.5", className)}
className={twMerge(
"label inline-flex items-center min-w-0 max-w-full rounded-xl px-2.5 py-0.5 bg-[var(--light-bg-color)] dark:bg-[var(--dark-bg-color)] text-[var(--light-text-color)] dark:text-[var(--dark-text-color)]",
className,
)}
title={showTooltip ? label : undefined}
>
{icon} {label}
<span className="truncate">{label}</span>
{endSlot}
</span>
);
}

function dimColor(mainColor: { hsl: [number, number, number] }) {
const newDimmedSaturation = mainColor.hsl[1] * 0.75;
const newDimmedLightness = mainColor.hsl[2] / 5;
const newHsl = [mainColor.hsl[0], newDimmedSaturation, newDimmedLightness] as [number, number, number];
return { hsl: newHsl };
const darkColor = [mainColor.hsl[0], mainColor.hsl[1] * 0.75, mainColor.hsl[2] / 5] as [number, number, number];
const lightColor = [mainColor.hsl[0], 80, 90] as [number, number, number];
return { dark: darkColor, light: lightColor };
}

function bestTextColor(bgHex: string) {
Expand Down
13 changes: 0 additions & 13 deletions src/components/NoteManager/NoteManager.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,6 @@
}


.note-manager .new-note button {
width: 100%;
}

.note-manager textarea,
.note-manager input {
padding: 1rem;
resize: vertical;
width: 100%;
box-sizing: border-box;
border-radius: 6px;
}

.note-manager .validation-message {
padding-bottom: 10px;
color: #f22;
Expand Down
9 changes: 5 additions & 4 deletions src/components/NoteManager/NoteManager.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { memo, useCallback, useContext, useEffect, useState } from "react";
import "./NoteManager.css";
import { Button, Textarea } from "@fluffylabs/shared-ui";
import { twMerge } from "tailwind-merge";
import { validateMath } from "../../utils/validateMath";
import { type ILocationContext, LocationContext } from "../LocationProvider/LocationProvider";
Expand Down Expand Up @@ -75,8 +76,8 @@ function Notes() {

return (
<div className="note-manager flex flex-col gap-2.5" style={{ opacity: notesReady ? 1.0 : 0.3 }}>
<div className="new-note">
<textarea
<div className="flex flex-col p-2 gap-2">
<Textarea
disabled={selectedBlocks.length === 0}
className={noteContentError ? "error" : ""}
autoFocus
Expand All @@ -86,9 +87,9 @@ function Notes() {
/>

{noteContentError ? <div className="validation-message">{noteContentError}</div> : null}
<button disabled={noteContent.length < 1} onClick={handleAddNoteClick} className="default-button">
<Button disabled={noteContent.length < 1} onClick={handleAddNoteClick} variant="secondary">
Add
</button>
</Button>
</div>

<MemoizedNotesList
Expand Down
Empty file.
39 changes: 16 additions & 23 deletions src/components/NoteManager/components/Note.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Button, cn } from "@fluffylabs/shared-ui";
import { type ChangeEvent, useCallback, useEffect, useMemo, useState } from "react";
import { validateMath } from "../../../utils/validateMath";
import { useLocationContext } from "../../LocationProvider/LocationProvider";
import type { INotesContext } from "../../NotesProvider/NotesProvider";
import { type IDecoratedNote, NoteSource } from "../../NotesProvider/types/DecoratedNote";
import type { IStorageNote } from "../../NotesProvider/types/StorageNote";
import { NoteLabels } from "./NoteLabels";
import { NoteLink } from "./NoteLink";
import "./Note.css";
import { Button, cn } from "@fluffylabs/shared-ui";
import { useLocationContext } from "../../LocationProvider/LocationProvider";
import { NoteLayout } from "./NoteLayout";
import { NoteLink } from "./NoteLink";
import { TinyIconButton } from "./SiimpleComponents";

export type NotesItem = {
location: string; // serialized InDocSelection
Expand Down Expand Up @@ -55,12 +54,13 @@ export function Note({ note, active = false, onEditNote, onDeleteNote }: NotePro
setNoteContentError("");
}, [note, isEditable]);

const handleNoteContentChange = useCallback(
(ev: ChangeEvent<HTMLTextAreaElement>) => {
setNoteDirty({ ...noteDirty, content: ev.currentTarget.value });
},
[noteDirty],
);
const handleNoteLabelsChange = useCallback((labels: string[]) => {
setNoteDirty((prevNoteDirty) => ({ ...prevNoteDirty, labels }));
}, []);

const handleNoteContentChange = useCallback((ev: ChangeEvent<HTMLTextAreaElement>) => {
setNoteDirty((prev) => ({ ...prev, content: ev.currentTarget.value }));
}, []);

const handleDeleteClick = useCallback(() => {
onDeleteNote(note);
Expand Down Expand Up @@ -128,6 +128,7 @@ export function Note({ note, active = false, onEditNote, onDeleteNote }: NotePro
isEditing,
noteDirty,
handleNoteContentChange,
handleNoteLabelsChange,
}),
[
note,
Expand All @@ -139,6 +140,7 @@ export function Note({ note, active = false, onEditNote, onDeleteNote }: NotePro
isEditing,
noteDirty,
handleNoteContentChange,
handleNoteLabelsChange,
],
);

Expand Down Expand Up @@ -166,20 +168,11 @@ export function Note({ note, active = false, onEditNote, onDeleteNote }: NotePro
{active && !isEditing && (
<>
<NoteLayout.SelectedText />
<NoteLabels note={note} />
<NoteLayout.Text />
<NoteLayout.Labels />
{isEditable && (
<div className="flex flex-1 justify-end">
<Button
variant="ghost"
intent="neutralStrong"
className="p-2 h-6 -top-0.5 relative"
data-testid={"edit-button"}
onClick={handleEditClick}
aria-label="Edit note"
>
✏️
</Button>
<TinyIconButton data-testid={"edit-button"} onClick={handleEditClick} aria-label="Edit note" icon="✏️" />
</div>
)}
</>
Expand All @@ -188,9 +181,9 @@ export function Note({ note, active = false, onEditNote, onDeleteNote }: NotePro
<>
<>
<NoteLayout.SelectedText />
<NoteLabels note={note} />
<NoteLayout.TextArea className={noteContentError ? "error" : ""} />
{noteContentError ? <div className="validation-message">{noteContentError}</div> : null}
<NoteLayout.Labels />
<div className="actions gap-2">
<Button variant="ghost" intent="destructive" size="sm" onClick={handleDeleteClick}>
Delete
Expand Down
4 changes: 3 additions & 1 deletion src/components/NoteManager/components/NoteContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type ChangeEvent, createContext, useContext } from "react";
import type { INotesContext } from "../../NotesProvider/NotesProvider";
import type { IDecoratedNote } from "../../NotesProvider/types/DecoratedNote";
import type { IStorageNote } from "../../NotesProvider/types/StorageNote";

export const noteContext = createContext<{
note: IDecoratedNote;
Expand All @@ -9,7 +10,8 @@ export const noteContext = createContext<{
handleSaveClick: () => void;
handleCancelClick: () => void;
handleNoteContentChange: (ev: ChangeEvent<HTMLTextAreaElement>) => void;
noteDirty: { content: string };
handleNoteLabelsChange: (labels: string[]) => void;
noteDirty: IStorageNote;
onEditNote: INotesContext["handleUpdateNote"];
isEditing: boolean;
} | null>(null);
Expand Down
Loading
Loading