From 665adb3f4041d747d2e43d21ab9e525b88b15510 Mon Sep 17 00:00:00 2001 From: rimar1337 <132627503+rimar1337@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:47:48 +0700 Subject: [PATCH] button --- src/components/Composer.tsx | 289 +++++++++++++---------- src/components/Login.tsx | 8 +- src/components/UniversalPostRenderer.tsx | 2 + src/components/radix-m3-rd/Button.tsx | 59 +++++ src/routes/profile.$did/index.tsx | 19 +- 5 files changed, 242 insertions(+), 135 deletions(-) create mode 100644 src/components/radix-m3-rd/Button.tsx diff --git a/src/components/Composer.tsx b/src/components/Composer.tsx index ce4cbb8..ae2cf9a 100644 --- a/src/components/Composer.tsx +++ b/src/components/Composer.tsx @@ -8,12 +8,14 @@ import { composerAtom } from "~/utils/atoms"; import { useQueryPost } from "~/utils/useQuery"; import { ProfileThing } from "./Login"; +import { Button } from "./radix-m3-rd/Button"; import { UniversalPostRendererATURILoader } from "./UniversalPostRenderer"; const MAX_POST_LENGTH = 300; export function Composer() { const [composerState, setComposerState] = useAtom(composerAtom); + const [closeConfirmState, setCloseConfirmState] = useState(false); const { agent } = useAuth(); const [postText, setPostText] = useState(""); @@ -112,9 +114,6 @@ export function Composer() { setPosting(false); } } - // if (composerState.kind === "closed") { - // return null; - // } const getPlaceholder = () => { switch (composerState.kind) { @@ -132,133 +131,181 @@ export function Composer() { const isPostButtonDisabled = posting || !postText.trim() || isParentLoading || charsLeft < 0; + function handleAttemptClose() { + if (postText.trim() && !posting) { + setCloseConfirmState(true); + } else { + setComposerState({ kind: "closed" }); + } + } + + function handleConfirmClose() { + setComposerState({ kind: "closed" }); + setCloseConfirmState(false); + setPostText(""); + } + return ( - { - if (!open) setComposerState({ kind: "closed" }); - }} - > - - - - -
-
- - - - -
-
- - {charsLeft} - - + + + + + + + +
+
+ + {charsLeft} + + +
-
- {postSuccess ? ( -
- ✓ - - Posted! - -
- ) : ( -
- {composerState.kind === "reply" && ( -
- {isParentLoading ? ( -
- Loading parent post... -
- ) : parentUri ? ( - - ) : ( -
- Could not load parent post. -
- )} -
- )} - -
- -
- setPostText(e.target.value)} - disabled={posting} - autoFocus - /> -
+ {postSuccess ? ( +
+ ✓ + + Posted! +
- - {composerState.kind === "quote" && ( -
- {isParentLoading ? ( -
- Loading parent post... -
- ) : parentUri ? ( - + {composerState.kind === "reply" && ( +
+ {isParentLoading ? ( +
+ Loading parent post... +
+ ) : parentUri ? ( + + ) : ( +
+ Could not load parent post. +
+ )} +
+ )} + +
+ +
+ setPostText(e.target.value)} + disabled={posting} + autoFocus /> - ) : ( -
- Could not load parent post. -
- )} +
- )} - {postError && ( -
- {postError} -
- )} + {composerState.kind === "quote" && ( +
+ {isParentLoading ? ( +
+ Loading parent post... +
+ ) : parentUri ? ( + + ) : ( +
+ Could not load parent post. +
+ )} +
+ )} + + {postError && ( +
+ {postError} +
+ )} +
+ )} +
+ + + + + {/* Close confirmation dialog */} + + + + + + +
+
+ Discard your post? +
+
+ You will lose your draft +
+
+ +
- )} -
-
-
-
+
+ + + + ); } diff --git a/src/components/Login.tsx b/src/components/Login.tsx index 365f54d..e1336d5 100644 --- a/src/components/Login.tsx +++ b/src/components/Login.tsx @@ -7,6 +7,8 @@ import { useAuth } from "~/providers/UnifiedAuthProvider"; import { imgCDNAtom } from "~/utils/atoms"; import { useQueryIdentity, useQueryProfile } from "~/utils/useQuery"; +import { Button } from "./radix-m3-rd/Button"; + // --- 1. The Main Component (Orchestrator with `compact` prop) --- export default function Login({ compact = false, @@ -49,12 +51,12 @@ export default function Login({ You are logged in!

- +
); diff --git a/src/components/UniversalPostRenderer.tsx b/src/components/UniversalPostRenderer.tsx index adc70d9..07f103c 100644 --- a/src/components/UniversalPostRenderer.tsx +++ b/src/components/UniversalPostRenderer.tsx @@ -1557,8 +1557,10 @@ function UniversalPostRenderer({ className="rounded-full w-[58px] h-[58px] object-cover border border-gray-300 dark:border-gray-800 bg-gray-300 dark:bg-gray-600" />
+
+
diff --git a/src/components/radix-m3-rd/Button.tsx b/src/components/radix-m3-rd/Button.tsx new file mode 100644 index 0000000..f6efa27 --- /dev/null +++ b/src/components/radix-m3-rd/Button.tsx @@ -0,0 +1,59 @@ +import { Slot } from "@radix-ui/react-slot"; +import clsx from "clsx"; +import * as React from "react"; + +export type ButtonVariant = "filled" | "outlined" | "text" | "secondary"; +export type ButtonSize = "sm" | "md" | "lg"; + +const variantClasses: Record = { + filled: + "bg-gray-300 text-gray-900 hover:bg-gray-400 dark:bg-gray-600 dark:text-white dark:hover:bg-gray-500", + secondary: + "bg-gray-300 text-gray-900 hover:bg-gray-400 dark:bg-gray-600 dark:text-white dark:hover:bg-gray-500", + outlined: + "border border-gray-800 text-gray-800 hover:bg-gray-100 dark:border-gray-200 dark:text-gray-200 dark:hover:bg-gray-800/10", + text: "bg-transparent text-gray-800 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-800/10", +}; + +const sizeClasses: Record = { + sm: "px-3 py-1.5 text-sm", + md: "px-4 py-2 text-base", + lg: "px-6 py-3 text-lg", +}; + +export function Button({ + variant = "filled", + size = "md", + asChild = false, + ref, + className, + children, + ...props +}: { + variant?: ButtonVariant; + size?: ButtonSize; + asChild?: boolean; + className?: string; + children?: React.ReactNode; + ref?: React.Ref; +} & React.ComponentPropsWithoutRef<"button">) { + const Comp = asChild ? Slot : "button"; + + return ( + + {children} + + ); +} + +Button.displayName = "Button"; diff --git a/src/routes/profile.$did/index.tsx b/src/routes/profile.$did/index.tsx index c8757aa..3f60c4a 100644 --- a/src/routes/profile.$did/index.tsx +++ b/src/routes/profile.$did/index.tsx @@ -5,6 +5,7 @@ import { useAtom } from "jotai"; import React, { type ReactNode, useEffect, useState } from "react"; import { Header } from "~/components/Header"; +import { Button } from "~/components/radix-m3-rd/Button"; import { renderTextWithFacets, UniversalPostRendererATURILoader, @@ -170,9 +171,9 @@ function ProfileComponent() { also save it persistently */} - +
{/* Info Card */} @@ -248,7 +249,7 @@ export function FollowButton({ {identity?.did !== agent?.did ? ( <> {!(followRecords?.length && followRecords?.length > 0) ? ( - + ) : ( - + )} ) : ( - + )} ); -- 2.51.2