mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
Merge pull request #57 from bknd-io/feat/elements-docs-and-custom
restructured elements for better customization
This commit is contained in:
@@ -14,3 +14,6 @@ export { registries } from "modules/registries";
|
||||
|
||||
export type * from "./adapter";
|
||||
export { Api, type ApiOptions } from "./Api";
|
||||
|
||||
export type { MediaFieldSchema } from "media/AppMedia";
|
||||
export type { UserFieldSchema } from "auth/AppAuth";
|
||||
|
||||
@@ -7,10 +7,23 @@ export type AuthScreenProps = {
|
||||
action?: "login" | "register";
|
||||
logo?: ReactNode;
|
||||
intro?: ReactNode;
|
||||
formOnly?: boolean;
|
||||
};
|
||||
|
||||
export function AuthScreen({ method = "POST", action = "login", logo, intro }: AuthScreenProps) {
|
||||
export function AuthScreen({
|
||||
method = "POST",
|
||||
action = "login",
|
||||
logo,
|
||||
intro,
|
||||
formOnly
|
||||
}: AuthScreenProps) {
|
||||
const { strategies, basepath, loading } = useAuthStrategies();
|
||||
const Form = <AuthForm auth={{ basepath, strategies }} method={method} action={action} />;
|
||||
|
||||
if (formOnly) {
|
||||
if (loading) return null;
|
||||
return Form;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-1 flex-col select-none h-dvh w-dvw justify-center items-center bknd-admin">
|
||||
@@ -25,7 +38,7 @@ export function AuthScreen({ method = "POST", action = "login", logo, intro }: A
|
||||
<p className="text-primary/50">Enter your credentials below to get access.</p>
|
||||
</div>
|
||||
)}
|
||||
<AuthForm auth={{ basepath, strategies }} method={method} action={action} />
|
||||
{Form}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useAuthStrategies } from "../hooks/use-auth";
|
||||
import { AuthForm } from "./AuthForm";
|
||||
import { AuthScreen } from "./AuthScreen";
|
||||
import { SocialLink } from "./SocialLink";
|
||||
@@ -7,3 +8,5 @@ export const Auth = {
|
||||
Form: AuthForm,
|
||||
SocialLink: SocialLink
|
||||
};
|
||||
|
||||
export { useAuthStrategies };
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export { Auth } from "./auth";
|
||||
export * from "./auth";
|
||||
export * from "./media";
|
||||
|
||||
@@ -1,31 +1,32 @@
|
||||
import type { RepoQuery, RepoQueryIn } from "data";
|
||||
import type { RepoQueryIn } from "data";
|
||||
import type { MediaFieldSchema } from "media/AppMedia";
|
||||
import type { TAppMediaConfig } from "media/media-schema";
|
||||
import { useId } from "react";
|
||||
import { useApi, useBaseUrl, useEntityQuery, useInvalidate } from "ui/client";
|
||||
import { type ReactNode, createContext, useContext, useId } from "react";
|
||||
import { useApi, useEntityQuery, useInvalidate } from "ui/client";
|
||||
import { useEvent } from "ui/hooks/use-event";
|
||||
import { Dropzone, type DropzoneProps, type DropzoneRenderProps, type FileState } from "./Dropzone";
|
||||
import { mediaItemsToFileStates } from "./helper";
|
||||
|
||||
export type DropzoneContainerProps = {
|
||||
children?: (props: DropzoneRenderProps) => JSX.Element;
|
||||
children?: ReactNode;
|
||||
initialItems?: MediaFieldSchema[];
|
||||
entity?: {
|
||||
name: string;
|
||||
id: number;
|
||||
field: string;
|
||||
};
|
||||
media?: Pick<TAppMediaConfig, "entity_name" | "storage">;
|
||||
query?: RepoQueryIn;
|
||||
} & Partial<Pick<TAppMediaConfig, "basepath" | "entity_name" | "storage">> &
|
||||
Partial<DropzoneProps>;
|
||||
} & Omit<Partial<DropzoneProps>, "children" | "initialItems">;
|
||||
|
||||
const DropzoneContainerContext = createContext<DropzoneRenderProps>(undefined!);
|
||||
|
||||
export function DropzoneContainer({
|
||||
initialItems,
|
||||
basepath = "/api/media",
|
||||
storage = {},
|
||||
entity_name = "media",
|
||||
media,
|
||||
entity,
|
||||
query,
|
||||
children,
|
||||
...props
|
||||
}: DropzoneContainerProps) {
|
||||
const id = useId();
|
||||
@@ -33,10 +34,11 @@ export function DropzoneContainer({
|
||||
const baseUrl = api.baseUrl;
|
||||
const invalidate = useInvalidate();
|
||||
const limit = query?.limit ? query?.limit : props.maxItems ? props.maxItems : 50;
|
||||
console.log("dropzone:baseUrl", baseUrl);
|
||||
const entity_name = (media?.entity_name ?? "media") as "media";
|
||||
//console.log("dropzone:baseUrl", baseUrl);
|
||||
|
||||
const $q = useEntityQuery(
|
||||
entity_name as "media",
|
||||
entity_name,
|
||||
undefined,
|
||||
{
|
||||
...query,
|
||||
@@ -89,6 +91,18 @@ export function DropzoneContainer({
|
||||
autoUpload
|
||||
initialItems={_initialItems}
|
||||
{...props}
|
||||
/>
|
||||
>
|
||||
{children
|
||||
? (props) => (
|
||||
<DropzoneContainerContext.Provider value={props}>
|
||||
{children}
|
||||
</DropzoneContainerContext.Provider>
|
||||
)
|
||||
: undefined}
|
||||
</Dropzone>
|
||||
);
|
||||
}
|
||||
|
||||
export function useDropzone() {
|
||||
return useContext(DropzoneContainerContext);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import { PreviewWrapperMemoized } from "./Dropzone";
|
||||
import { DropzoneContainer } from "./DropzoneContainer";
|
||||
import { DropzoneContainer, useDropzone } from "./DropzoneContainer";
|
||||
|
||||
export const Media = {
|
||||
Dropzone: DropzoneContainer,
|
||||
Preview: PreviewWrapperMemoized
|
||||
Preview: PreviewWrapperMemoized,
|
||||
useDropzone: useDropzone
|
||||
};
|
||||
|
||||
export { useDropzone as useMediaDropzone };
|
||||
|
||||
export type {
|
||||
PreviewComponentProps,
|
||||
FileState,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type DropzoneRenderProps, Media } from "ui/elements";
|
||||
import { Media } from "ui/elements";
|
||||
import { Scrollable } from "ui/layouts/AppShell/AppShell";
|
||||
|
||||
export default function DropzoneElementTest() {
|
||||
@@ -12,7 +12,7 @@ export default function DropzoneElementTest() {
|
||||
maxItems={1}
|
||||
overwrite
|
||||
>
|
||||
{(props) => <CustomUserAvatarDropzone {...props} />}
|
||||
<CustomUserAvatarDropzone />
|
||||
</Media.Dropzone>
|
||||
</div>
|
||||
|
||||
@@ -49,12 +49,13 @@ export default function DropzoneElementTest() {
|
||||
);
|
||||
}
|
||||
|
||||
function CustomUserAvatarDropzone({
|
||||
wrapperRef,
|
||||
inputProps,
|
||||
state: { files, isOver, isOverAccepted, showPlaceholder },
|
||||
actions: { openFileInput }
|
||||
}: DropzoneRenderProps) {
|
||||
function CustomUserAvatarDropzone() {
|
||||
const {
|
||||
wrapperRef,
|
||||
inputProps,
|
||||
state: { files, isOver, isOverAccepted, showPlaceholder },
|
||||
actions: { openFileInput }
|
||||
} = Media.useDropzone();
|
||||
const file = files[0];
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user