pull/3206/head
Mime Čuvalo 2024-03-19 10:28:40 +00:00
rodzic 5edf7dd00d
commit a668447d22
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: BA84499022AC984D
10 zmienionych plików z 190 dodań i 43 usunięć

Wyświetl plik

@ -1592,3 +1592,83 @@ it from receiving any pointer events or affecting the cursor. */
font-size: 12px;
font-family: monospace;
}
/* --------------------- Tooltips --------------------- */
.TooltipContent {
border-radius: 4px;
padding: 10px 15px;
font-size: 15px;
line-height: 1;
color: var(--violet-11);
background-color: white;
box-shadow: hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px;
user-select: none;
animation-duration: 400ms;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
will-change: transform, opacity;
}
.TooltipContent[data-state='delayed-open'][data-side='top'] {
animation-name: slideDownAndFade;
}
.TooltipContent[data-state='delayed-open'][data-side='right'] {
animation-name: slideLeftAndFade;
}
.TooltipContent[data-state='delayed-open'][data-side='bottom'] {
animation-name: slideUpAndFade;
}
.TooltipContent[data-state='delayed-open'][data-side='left'] {
animation-name: slideRightAndFade;
}
.TooltipArrow {
fill: white;
}
div[data-radix-popper-content-wrapper] {
z-index: 200 !important; /* var(--layer-canvas); */
}
@keyframes slideUpAndFade {
from {
opacity: 0;
transform: translateY(2px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideRightAndFade {
from {
opacity: 0;
transform: translateX(-2px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideDownAndFade {
from {
opacity: 0;
transform: translateY(-2px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideLeftAndFade {
from {
opacity: 0;
transform: translateX(2px);
}
to {
opacity: 1;
transform: translateX(0);
}
}

Wyświetl plik

@ -216,9 +216,9 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
isPrecise: boolean;
}>;
point: ObjectValidator< {
type: "point";
x: number;
y: number;
type: "point";
}>;
}, never>;
end: UnionValidator<"type", {
@ -230,9 +230,9 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
isPrecise: boolean;
}>;
point: ObjectValidator< {
type: "point";
x: number;
y: number;
type: "point";
}>;
}, never>;
bend: Validator<number>;
@ -1048,9 +1048,9 @@ export class LineShapeUtil extends ShapeUtil<TLLineShape> {
size: EnumStyleProp<"l" | "m" | "s" | "xl">;
spline: EnumStyleProp<"cubic" | "line">;
points: DictValidator<string, {
id: string;
x: number;
y: number;
id: string;
index: IndexKey;
}>;
};
@ -1112,7 +1112,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
verticalAlign: "end" | "middle" | "start";
url: string;
text: string;
reacji: Record<string, number> | undefined;
reacji: Record<string, string[]> | undefined;
};
type: "note";
x: number;
@ -1137,7 +1137,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
verticalAlign: "end" | "middle" | "start";
url: string;
text: string;
reacji: Record<string, number> | undefined;
reacji: Record<string, string[]> | undefined;
};
type: "note";
x: number;
@ -1154,7 +1154,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
// (undocumented)
onEditEnd: TLOnEditEndHandler<TLNoteShape>;
// (undocumented)
onReacjiSelect: (shape: TLNoteShape, reacji: string, step: number) => void;
onReacjiSelect: (shape: TLNoteShape, emoji: string, name: string) => void;
// (undocumented)
static props: {
color: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
@ -1165,7 +1165,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
growY: Validator<number>;
url: Validator<string>;
text: Validator<string>;
reacji: Validator<Record<string, number> | undefined>;
reacji: Validator<Record<string, string[]> | undefined>;
};
// (undocumented)
toSvg(shape: TLNoteShape, ctx: SvgExportContext): SVGGElement;

Wyświetl plik

@ -1619,7 +1619,7 @@
},
{
"kind": "Content",
"text": "<{\n x: number;\n y: number;\n type: \"point\";\n }>;\n }, never>;\n end: import(\"@tldraw/editor\")."
"text": "<{\n type: \"point\";\n x: number;\n y: number;\n }>;\n }, never>;\n end: import(\"@tldraw/editor\")."
},
{
"kind": "Reference",
@ -1664,7 +1664,7 @@
},
{
"kind": "Content",
"text": "<{\n x: number;\n y: number;\n type: \"point\";\n }>;\n }, never>;\n bend: import(\"@tldraw/editor\")."
"text": "<{\n type: \"point\";\n x: number;\n y: number;\n }>;\n }, never>;\n bend: import(\"@tldraw/editor\")."
},
{
"kind": "Reference",
@ -12361,7 +12361,7 @@
},
{
"kind": "Content",
"text": "<string, {\n id: string;\n x: number;\n y: number;\n index: import(\"@tldraw/editor\")."
"text": "<string, {\n x: number;\n y: number;\n id: string;\n index: import(\"@tldraw/editor\")."
},
{
"kind": "Reference",
@ -13201,7 +13201,7 @@
},
{
"kind": "Content",
"text": "<string, number> | undefined;\n };\n type: \"note\";\n x: number;\n y: number;\n rotation: number;\n index: import(\"@tldraw/editor\")."
"text": "<string, string[]> | undefined;\n };\n type: \"note\";\n x: number;\n y: number;\n rotation: number;\n index: import(\"@tldraw/editor\")."
},
{
"kind": "Reference",
@ -13294,7 +13294,7 @@
},
{
"kind": "Content",
"text": "<string, number> | undefined;\n };\n type: \"note\";\n x: number;\n y: number;\n rotation: number;\n index: import(\"@tldraw/editor\")."
"text": "<string, string[]> | undefined;\n };\n type: \"note\";\n x: number;\n y: number;\n rotation: number;\n index: import(\"@tldraw/editor\")."
},
{
"kind": "Reference",
@ -13413,7 +13413,7 @@
},
{
"kind": "Content",
"text": ", reacji: string, step: number) => void"
"text": ", emoji: string, name: string) => void"
},
{
"kind": "Content",
@ -13533,7 +13533,7 @@
},
{
"kind": "Content",
"text": "<string, number> | undefined>;\n }"
"text": "<string, string[]> | undefined>;\n }"
},
{
"kind": "Content",

Wyświetl plik

@ -54,6 +54,7 @@
"@radix-ui/react-select": "^1.2.0",
"@radix-ui/react-slider": "^1.1.0",
"@radix-ui/react-toast": "^1.1.1",
"@radix-ui/react-tooltip": "^1.0.7",
"@tldraw/editor": "workspace:*",
"canvas-size": "^1.2.6",
"classnames": "^2.3.2",

Wyświetl plik

@ -1,3 +1,4 @@
import * as Tooltip from '@radix-ui/react-tooltip'
import {
DefaultFontFamilies,
Editor,
@ -10,8 +11,9 @@ import {
noteShapeMigrations,
noteShapeProps,
toDomPrecision,
uniq,
} from '@tldraw/editor'
import { useEffect, useRef, useState } from 'react'
import { FC, PropsWithChildren, ReactNode, useEffect, useRef, useState } from 'react'
import { Root, createRoot } from 'react-dom/client'
import { HyperlinkButton } from '../shared/HyperlinkButton'
import { useDefaultColorTheme } from '../shared/ShapeFill'
@ -99,7 +101,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
<Reacji
editor={this.editor}
reacji={reacji}
onSelect={(reacji, step) => this.onReacjiSelect(shape, reacji, step)}
onSelect={(emoji, name) => this.onReacjiSelect(shape, emoji, name)}
/>
</div>
{'url' in shape.props && shape.props.url && (
@ -109,16 +111,22 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
)
}
onReacjiSelect = (shape: TLNoteShape, reacji: string, step: number) => {
const newReacji = Object.assign({}, shape.props.reacji)
newReacji[reacji] = (newReacji[reacji] || 0) + step
onReacjiSelect = (shape: TLNoteShape, emoji: string, name: string) => {
const reacji = Object.assign({}, shape.props.reacji)
const includesPersonAlready = reacji[emoji]?.includes(name)
reacji[emoji] = includesPersonAlready
? reacji[emoji].filter((n) => n !== name)
: uniq([...(reacji[emoji] || []), name])
if (!reacji[emoji].length) {
delete reacji[emoji]
}
this.editor.updateShapes([
{
...shape,
props: {
...shape.props,
reacji: Object.fromEntries(Object.entries(newReacji).filter(([_, count]) => count > 0)),
reacji,
},
},
])
@ -211,7 +219,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
}
}
type ReacjiBagType = { [key: string]: number }
type ReacjiBagType = { [key: string]: string[] }
function Reacji({
editor,
@ -220,10 +228,11 @@ function Reacji({
}: {
editor: Editor
reacji: ReacjiBagType | undefined
onSelect: (reacji: string, step: number) => void
onSelect: (emoji: string, name: string) => void
}) {
const [renderRoot, setRenderRoot] = useState<Root>()
const addButtonRef = useRef<HTMLButtonElement>(null)
const name = editor.user?.getName() || 'Me'
useEffect(() => {
const div = document.createElement('div')
@ -239,12 +248,12 @@ function Reacji({
}, [])
const onEmojiSelect = async (emoji: any) => {
onSelect(emoji.native, 1)
onSelect(emoji.native, name)
closeMenu()
}
const onEmojiRetract = (reacji: string) => {
onSelect(reacji, -1)
const onEmojiRetract = (emoji: string) => {
onSelect(emoji, name)
}
const closeMenu = () => {
@ -268,18 +277,41 @@ function Reacji({
return (
<div className="tl-note__reacji">
{reacji &&
Object.entries(reacji).map(([reacji, count]) => (
<button key={reacji} onMouseDown={() => onEmojiRetract(reacji)}>
{reacji} <span className="tl-note__reacji-count">{count}</span>
</button>
Object.entries(reacji).map(([reacji, people]) => (
<TooltipWrapper tooltip={people.join(', ')}>
<button key={reacji} onMouseDown={() => onEmojiRetract(reacji)}>
{reacji} <span className="tl-note__reacji-count">{people.length}</span>
</button>
</TooltipWrapper>
))}
<button className="tl-note__reacji-add" ref={addButtonRef} onMouseDown={handleOpen}>
+
</button>
<TooltipWrapper tooltip="Add emoji">
<button className="tl-note__reacji-add" ref={addButtonRef} onMouseDown={handleOpen}>
+
</button>
</TooltipWrapper>
</div>
)
}
const TooltipWrapper: FC<PropsWithChildren<{ tooltip: string | ReactNode }>> = ({
children,
tooltip,
}) => {
return (
<Tooltip.Provider delayDuration={200}>
<Tooltip.Root>
<Tooltip.Trigger asChild>{children}</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Content className="TooltipContent" sideOffset={5}>
{tooltip}
<Tooltip.Arrow className="TooltipArrow" />
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
</Tooltip.Provider>
)
}
function getGrowY(editor: Editor, shape: TLNoteShape, prevGrowY = 0) {
const PADDING = 17

Wyświetl plik

@ -10,6 +10,7 @@ export type EmojiDialogProps = {
left: number
onEmojiSelect: (emoji: any) => void
onClickOutside: () => void
disableFrequentRows?: boolean
}
export default track(function EmojiDialog({
@ -18,6 +19,7 @@ export default track(function EmojiDialog({
left,
onEmojiSelect,
onClickOutside,
disableFrequentRows,
}: EmojiDialogProps) {
const isDarkMode = useValue('isDarkMode', () => editor.user.getIsDarkMode(), [editor])
const ref = useRef(null)
@ -33,7 +35,7 @@ export default track(function EmojiDialog({
editor.on('event', eventListener)
instance.current = new Picker({
maxFrequentRows: 0,
maxFrequentRows: disableFrequentRows ? 0 : undefined,
onEmojiSelect,
onClickOutside,
theme,
@ -48,7 +50,7 @@ export default track(function EmojiDialog({
EmojiDialogSingleton = null
editor.off('event', eventListener)
}
}, [editor, theme, onEmojiSelect, onClickOutside])
}, [editor, theme, onEmojiSelect, onClickOutside, disableFrequentRows])
return (
<div

Wyświetl plik

@ -47,9 +47,9 @@ export const arrowShapeProps: {
isPrecise: boolean;
} & {}>;
point: T.ObjectValidator<{
type: "point";
x: number;
y: number;
type: "point";
} & {}>;
}, never>;
end: T.UnionValidator<"type", {
@ -61,9 +61,9 @@ export const arrowShapeProps: {
isPrecise: boolean;
} & {}>;
point: T.ObjectValidator<{
type: "point";
x: number;
y: number;
type: "point";
} & {}>;
}, never>;
bend: T.Validator<number>;
@ -684,9 +684,9 @@ export const lineShapeProps: {
size: EnumStyleProp<"l" | "m" | "s" | "xl">;
spline: EnumStyleProp<"cubic" | "line">;
points: T.DictValidator<string, {
id: string;
x: number;
y: number;
id: string;
index: IndexKey;
} & {}>;
};
@ -707,7 +707,7 @@ export const noteShapeProps: {
growY: T.Validator<number>;
url: T.Validator<string>;
text: T.Validator<string>;
reacji: T.Validator<Record<string, number> | undefined>;
reacji: T.Validator<Record<string, string[]> | undefined>;
};
// @internal (undocumented)

Wyświetl plik

@ -364,7 +364,7 @@
},
{
"kind": "Content",
"text": "<{\n x: number;\n y: number;\n type: \"point\";\n } & {}>;\n }, never>;\n end: "
"text": "<{\n type: \"point\";\n x: number;\n y: number;\n } & {}>;\n }, never>;\n end: "
},
{
"kind": "Reference",
@ -409,7 +409,7 @@
},
{
"kind": "Content",
"text": "<{\n x: number;\n y: number;\n type: \"point\";\n } & {}>;\n }, never>;\n bend: "
"text": "<{\n type: \"point\";\n x: number;\n y: number;\n } & {}>;\n }, never>;\n bend: "
},
{
"kind": "Reference",
@ -2818,7 +2818,7 @@
},
{
"kind": "Content",
"text": "<string, {\n id: string;\n x: number;\n y: number;\n index: "
"text": "<string, {\n x: number;\n y: number;\n id: string;\n index: "
},
{
"kind": "Reference",
@ -2972,7 +2972,7 @@
},
{
"kind": "Content",
"text": "<string, number> | undefined>;\n}"
"text": "<string, string[]> | undefined>;\n}"
}
],
"fileUrlPath": "packages/tlschema/src/shapes/TLNoteShape.ts",

Wyświetl plik

@ -20,7 +20,7 @@ export const noteShapeProps = {
growY: T.positiveNumber,
url: T.linkUrl,
text: T.string,
reacji: T.dict(T.string, T.positiveInteger).optional(),
reacji: T.dict(T.string, T.arrayOf(T.string)).optional(),
}
/** @public */

Wyświetl plik

@ -5557,6 +5557,37 @@ __metadata:
languageName: node
linkType: hard
"@radix-ui/react-tooltip@npm:^1.0.7":
version: 1.0.7
resolution: "@radix-ui/react-tooltip@npm:1.0.7"
dependencies:
"@babel/runtime": "npm:^7.13.10"
"@radix-ui/primitive": "npm:1.0.1"
"@radix-ui/react-compose-refs": "npm:1.0.1"
"@radix-ui/react-context": "npm:1.0.1"
"@radix-ui/react-dismissable-layer": "npm:1.0.5"
"@radix-ui/react-id": "npm:1.0.1"
"@radix-ui/react-popper": "npm:1.1.3"
"@radix-ui/react-portal": "npm:1.0.4"
"@radix-ui/react-presence": "npm:1.0.1"
"@radix-ui/react-primitive": "npm:1.0.3"
"@radix-ui/react-slot": "npm:1.0.2"
"@radix-ui/react-use-controllable-state": "npm:1.0.1"
"@radix-ui/react-visually-hidden": "npm:1.0.3"
peerDependencies:
"@types/react": "*"
"@types/react-dom": "*"
react: ^16.8 || ^17.0 || ^18.0
react-dom: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 8f075a78db9bfe3dac251266feeb771923176d388c3232f9bad8d85417b5d80d2470697e1c7cae6765d3af16e48552ab9810137c2db193bc37e61b97388e92e8
languageName: node
linkType: hard
"@radix-ui/react-use-callback-ref@npm:1.0.1":
version: 1.0.1
resolution: "@radix-ui/react-use-callback-ref@npm:1.0.1"
@ -23010,6 +23041,7 @@ __metadata:
"@radix-ui/react-select": "npm:^1.2.0"
"@radix-ui/react-slider": "npm:^1.1.0"
"@radix-ui/react-toast": "npm:^1.1.1"
"@radix-ui/react-tooltip": "npm:^1.0.7"
"@testing-library/jest-dom": "npm:^5.16.5"
"@testing-library/react": "npm:^14.0.0"
"@tldraw/editor": "workspace:*"