@docubook/flame 1.0.0-beta.70 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,164 +0,0 @@
1
- "use client";
2
-
3
- import { cn } from "../../node/utils";
4
- import { X } from "lucide-react";
5
- import { useState, type ReactNode } from "react";
6
-
7
- type DrawerSide = "left" | "right";
8
-
9
- interface DrawerProps {
10
- id: string;
11
- children: ReactNode;
12
- defaultOpen?: boolean;
13
- side?: DrawerSide;
14
- breakpoint?: string;
15
- withOverlay?: boolean;
16
- overlayClassName?: string;
17
- sideClassName?: string;
18
- contentClassName?: string;
19
- className?: string;
20
- }
21
-
22
- export default function Drawer({
23
- id,
24
- children,
25
- defaultOpen = false,
26
- side = "left",
27
- breakpoint = "lg",
28
- withOverlay = true,
29
- overlayClassName,
30
- sideClassName,
31
- contentClassName,
32
- className,
33
- }: DrawerProps) {
34
- const [isOpen, setIsOpen] = useState(defaultOpen);
35
-
36
- const toggleDrawer = () => setIsOpen(!isOpen);
37
- const closeDrawer = () => setIsOpen(false);
38
-
39
- const sidePositionClass = side === "right" ? "drawer-end" : "";
40
-
41
- return (
42
- <div
43
- className={cn(
44
- "drawer",
45
- breakpoint ? `${breakpoint}:drawer-open` : "",
46
- sidePositionClass,
47
- className
48
- )}
49
- >
50
- <input
51
- id={id}
52
- type="checkbox"
53
- className="drawer-toggle"
54
- checked={isOpen}
55
- onChange={toggleDrawer}
56
- aria-label="Toggle drawer"
57
- />
58
-
59
- <div className={cn("drawer-content flex flex-col", contentClassName)}>
60
- {typeof children === "function"
61
- ? (
62
- children as (props: {
63
- open: boolean;
64
- toggle: () => void;
65
- close: () => void;
66
- }) => ReactNode
67
- )({ open: isOpen, toggle: toggleDrawer, close: closeDrawer })
68
- : children}
69
- </div>
70
-
71
- <div className={cn("drawer-side", sideClassName)}>
72
- {withOverlay && (
73
- <label
74
- htmlFor={id}
75
- aria-label="Close sidebar"
76
- className={cn("drawer-overlay", overlayClassName)}
77
- onClick={closeDrawer}
78
- />
79
- )}
80
-
81
- <div className="bg-base-200 min-h-full w-80 p-4">
82
- <div className="mb-4 flex items-center justify-between">
83
- <span className="text-lg font-semibold">Menu</span>
84
- <button
85
- onClick={closeDrawer}
86
- className="btn btn-ghost btn-sm btn-circle"
87
- aria-label="Close drawer"
88
- >
89
- <X className="h-5 w-5" />
90
- </button>
91
- </div>
92
- </div>
93
- </div>
94
- </div>
95
- );
96
- }
97
-
98
- export function useDrawerState(initialState = false) {
99
- const [isOpen, setIsOpen] = useState(initialState);
100
-
101
- return {
102
- isOpen,
103
- open: () => setIsOpen(true),
104
- close: () => setIsOpen(false),
105
- toggle: () => setIsOpen((prev) => !prev),
106
- };
107
- }
108
-
109
- interface DrawerTriggerProps {
110
- drawerId: string;
111
- children: ReactNode;
112
- className?: string;
113
- }
114
-
115
- export function DrawerTrigger({ drawerId, children, className }: DrawerTriggerProps) {
116
- return (
117
- <label htmlFor={drawerId} className={cn("label cursor-pointer", className)}>
118
- {children}
119
- </label>
120
- );
121
- }
122
-
123
- interface DrawerContentProps {
124
- children: ReactNode;
125
- className?: string;
126
- }
127
-
128
- export function DrawerContent({ children, className }: DrawerContentProps) {
129
- return <div className={cn("drawer-content", className)}>{children}</div>;
130
- }
131
-
132
- interface DrawerSidePanelProps {
133
- id: string;
134
- children: ReactNode;
135
- side?: DrawerSide;
136
- withOverlay?: boolean;
137
- overlayClassName?: string;
138
- className?: string;
139
- }
140
-
141
- export function DrawerSidePanel({
142
- id,
143
- children,
144
- side = "left",
145
- withOverlay = true,
146
- overlayClassName,
147
- className,
148
- }: DrawerSidePanelProps) {
149
- return (
150
- <div className={cn("drawer-side", side === "right" ? "drawer-end" : "", className)}>
151
- {withOverlay && (
152
- <label
153
- htmlFor={id}
154
- aria-label="Close sidebar"
155
- className={cn("drawer-overlay", overlayClassName)}
156
- />
157
- )}
158
- {children}
159
- </div>
160
- );
161
- }
162
-
163
- export { Drawer };
164
- export type { DrawerProps, DrawerSide };
@@ -1,94 +0,0 @@
1
- "use client";
2
-
3
- import { type HTMLAttributes, type ReactNode, forwardRef, useRef, useEffect } from "react";
4
- import { cn } from "../../node/utils";
5
-
6
- export interface DropdownProps extends HTMLAttributes<HTMLDetailsElement> {
7
- align?: "start" | "end";
8
- disabled?: boolean;
9
- trigger?: ReactNode;
10
- children?: ReactNode;
11
- }
12
-
13
- export const Dropdown = forwardRef<HTMLDetailsElement, DropdownProps>(
14
- ({ className, align = "start", disabled = false, trigger, children, ...props }, ref) => {
15
- const detailsRef = useRef<HTMLDetailsElement>(null);
16
-
17
- // Close on click outside
18
- useEffect(() => {
19
- const handler = (e: MouseEvent) => {
20
- if (detailsRef.current && !detailsRef.current.contains(e.target as Node)) {
21
- detailsRef.current.open = false;
22
- }
23
- };
24
- document.addEventListener("click", handler);
25
- return () => document.removeEventListener("click", handler);
26
- }, []);
27
-
28
- return (
29
- <details
30
- ref={(el) => {
31
- (detailsRef as React.MutableRefObject<HTMLDetailsElement | null>).current = el;
32
- if (typeof ref === "function") ref(el);
33
- else if (ref) ref.current = el;
34
- }}
35
- className={cn("relative", disabled && "pointer-events-none opacity-50", className)}
36
- {...props}
37
- >
38
- <summary className="cursor-pointer list-none [&::-webkit-details-marker]:hidden">
39
- {trigger}
40
- </summary>
41
- <ul
42
- className={cn(
43
- "bg-base-100 rounded-box border-base-300 absolute z-50 mt-1 w-full min-w-[200px] space-y-1 border p-2 shadow-lg",
44
- align === "end" ? "right-0" : "left-0"
45
- )}
46
- >
47
- {children}
48
- </ul>
49
- </details>
50
- );
51
- }
52
- );
53
- Dropdown.displayName = "Dropdown";
54
-
55
- export interface DropdownItemProps extends HTMLAttributes<HTMLLIElement> {
56
- children?: ReactNode;
57
- }
58
-
59
- export const DropdownItem = forwardRef<HTMLLIElement, DropdownItemProps>(
60
- ({ className, children, ...props }, ref) => (
61
- <li ref={ref} className={cn(className)} role="menuitem" {...props}>
62
- {children}
63
- </li>
64
- )
65
- );
66
- DropdownItem.displayName = "DropdownItem";
67
-
68
- export const DropdownLink = forwardRef<
69
- HTMLAnchorElement,
70
- HTMLAttributes<HTMLAnchorElement> & { href?: string }
71
- >(({ className, children, href, ...props }, ref) => (
72
- <li role="menuitem">
73
- <a ref={ref} href={href} className={cn(className)} {...props}>
74
- {children}
75
- </a>
76
- </li>
77
- ));
78
- DropdownLink.displayName = "DropdownLink";
79
-
80
- export const DropdownLabel = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(
81
- ({ className, children, ...props }, ref) => (
82
- <li ref={ref} className={cn("menu-title", className)} {...props}>
83
- {children}
84
- </li>
85
- )
86
- );
87
- DropdownLabel.displayName = "DropdownLabel";
88
-
89
- export const DropdownDivider = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(
90
- ({ className, ...props }, ref) => (
91
- <li ref={ref} className={cn("border-base-200 my-1 border-t", className)} {...props} />
92
- )
93
- );
94
- DropdownDivider.displayName = "DropdownDivider";
@@ -1,53 +0,0 @@
1
- import { forwardRef } from "react";
2
- import { cn } from "../../node/utils";
3
-
4
- type InputColor =
5
- | "neutral"
6
- | "primary"
7
- | "secondary"
8
- | "accent"
9
- | "info"
10
- | "success"
11
- | "warning"
12
- | "error";
13
- type InputSize = "xs" | "sm" | "md" | "lg" | "xl";
14
-
15
- interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
16
- color?: InputColor;
17
- inputSize?: InputSize;
18
- ghost?: boolean;
19
- }
20
-
21
- export const Input = forwardRef<HTMLInputElement, InputProps>(
22
- ({ className, color, inputSize, ghost, ...props }, ref) => {
23
- return (
24
- <input
25
- ref={ref}
26
- className={cn(
27
- "input",
28
- ghost && "input-ghost",
29
- color && `input-${color}`,
30
- inputSize && `input-${inputSize}`,
31
- className
32
- )}
33
- {...props}
34
- />
35
- );
36
- }
37
- );
38
- Input.displayName = "Input";
39
-
40
- interface InputGroupProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
41
- children: React.ReactNode;
42
- }
43
-
44
- export const InputGroup = forwardRef<HTMLLabelElement, InputGroupProps>(
45
- ({ children, className, ...props }, ref) => {
46
- return (
47
- <label ref={ref} className={cn("input", className)} {...props}>
48
- {children}
49
- </label>
50
- );
51
- }
52
- );
53
- InputGroup.displayName = "InputGroup";
@@ -1,51 +0,0 @@
1
- import { forwardRef } from "react";
2
- import {
3
- ArrowUp,
4
- ArrowDown,
5
- ArrowLeft,
6
- ArrowRight,
7
- Command,
8
- Option,
9
- ChevronUp,
10
- ArrowBigUp,
11
- CircleArrowOutUpLeft,
12
- Space,
13
- Delete,
14
- ArrowRightToLine,
15
- } from "lucide-react";
16
- import { cn } from "../../node/utils";
17
-
18
- type KbdSize = "xs" | "sm" | "md" | "lg" | "xl";
19
-
20
- interface KbdProps extends React.HTMLAttributes<HTMLElement> {
21
- children: React.ReactNode;
22
- size?: KbdSize;
23
- }
24
-
25
- export const Kbd = forwardRef<HTMLElement, KbdProps>(
26
- ({ children, className, size, ...props }, ref) => {
27
- return (
28
- <kbd ref={ref} className={cn("kbd", size && `kbd-${size}`, className)} {...props}>
29
- {children}
30
- </kbd>
31
- );
32
- }
33
- );
34
- Kbd.displayName = "Kbd";
35
-
36
- const iconSize = 12;
37
-
38
- export const FnKey = {
39
- Cmd: () => <Command size={iconSize} />,
40
- Option: () => <Option size={iconSize} />,
41
- Ctrl: () => <ChevronUp size={iconSize} />,
42
- Shift: () => <ArrowBigUp size={iconSize} />,
43
- Esc: () => <CircleArrowOutUpLeft size={iconSize} />,
44
- Space: () => <Space size={iconSize} />,
45
- Delete: () => <Delete size={iconSize} />,
46
- Tab: () => <ArrowRightToLine size={iconSize} />,
47
- Up: () => <ArrowUp size={iconSize} />,
48
- Down: () => <ArrowDown size={iconSize} />,
49
- Left: () => <ArrowLeft size={iconSize} />,
50
- Right: () => <ArrowRight size={iconSize} />,
51
- };
@@ -1,56 +0,0 @@
1
- "use client";
2
-
3
- import { forwardRef, useRef, useCallback } from "react";
4
- import { cn } from "../../node/utils";
5
-
6
- interface ModalProps extends React.DialogHTMLAttributes<HTMLDialogElement> {
7
- children: React.ReactNode;
8
- closeOnBackdrop?: boolean;
9
- placement?: "top" | "middle" | "bottom";
10
- boxClassName?: string;
11
- }
12
-
13
- export const Modal = forwardRef<HTMLDialogElement, ModalProps>(
14
- ({ children, className, closeOnBackdrop = true, placement, boxClassName, ...props }, ref) => {
15
- const placementClass = placement ? `modal-${placement}` : "";
16
-
17
- return (
18
- <dialog ref={ref} className={cn("modal", placementClass, className)} {...props}>
19
- <div className={cn("modal-box", boxClassName)}>{children}</div>
20
- {closeOnBackdrop && (
21
- <form method="dialog" className="modal-backdrop">
22
- <button>esc</button>
23
- </form>
24
- )}
25
- </dialog>
26
- );
27
- }
28
- );
29
- Modal.displayName = "Modal";
30
-
31
- export function ModalAction({
32
- children,
33
- className,
34
- }: {
35
- children: React.ReactNode;
36
- className?: string;
37
- }) {
38
- return (
39
- <div className={cn("modal-action", className)}>
40
- <form method="dialog">{children}</form>
41
- </div>
42
- );
43
- }
44
-
45
- export function useModal() {
46
- const ref = useRef<HTMLDialogElement>(null);
47
- const open = useCallback(() => {
48
- ref.current?.showModal();
49
- setTimeout(() => {
50
- const input = ref.current?.querySelector<HTMLElement>("input, [autofocus]");
51
- input?.focus();
52
- }, 0);
53
- }, []);
54
- const close = useCallback(() => ref.current?.close(), []);
55
- return { ref, open, close };
56
- }
@@ -1,132 +0,0 @@
1
- import type { ReactNode, CSSProperties } from "react";
2
-
3
- export interface NavbarProps {
4
- id?: string;
5
- children?: ReactNode;
6
- className?: string;
7
- style?: CSSProperties;
8
- }
9
-
10
- export interface LogoProps {
11
- src?: string;
12
- alt?: string;
13
- text?: string;
14
- href?: string;
15
- }
16
-
17
- export interface NavMenuItem {
18
- title: string;
19
- href: string;
20
- isExternal?: boolean;
21
- }
22
-
23
- export interface NavMenuProps {
24
- items: NavMenuItem[];
25
- onItemClick?: () => void;
26
- activePath?: string;
27
- }
28
-
29
- export function Navbar({ id, children, className, style }: NavbarProps) {
30
- return (
31
- <nav id={id} className={className} style={style}>
32
- {children}
33
- </nav>
34
- );
35
- }
36
-
37
- export function NavbarContainer({
38
- start,
39
- center,
40
- end,
41
- className,
42
- }: {
43
- start?: ReactNode;
44
- center?: ReactNode;
45
- end?: ReactNode;
46
- className?: string;
47
- }) {
48
- return (
49
- <div className={className}>
50
- {start && <div className="flex-start">{start}</div>}
51
- {center && <div className="flex-center">{center}</div>}
52
- {end && <div className="flex-none">{end}</div>}
53
- </div>
54
- );
55
- }
56
-
57
- export function Logo({ src, alt, text, href = "/" }: LogoProps) {
58
- return (
59
- <a href={href} className="logo-link">
60
- {src ? (
61
- <img src={src} alt={alt || text || "Logo"} className="logo-image" />
62
- ) : (
63
- <span className="logo-text">{text}</span>
64
- )}
65
- </a>
66
- );
67
- }
68
-
69
- export function NavMenu({ items, activePath }: NavMenuProps) {
70
- return (
71
- <ul className="nav-menu">
72
- {items.map((item) => {
73
- const isActive = activePath
74
- ? item.href === "/"
75
- ? activePath === "/"
76
- : activePath === item.href || activePath.startsWith(item.href + "/")
77
- : false;
78
- return (
79
- <li key={item.title + item.href}>
80
- <a
81
- href={item.href}
82
- className={`nav-menu-item ${isActive ? "active" : ""}`}
83
- target={item.isExternal ? "_blank" : undefined}
84
- rel={item.isExternal ? "noopener noreferrer" : undefined}
85
- >
86
- {item.title}
87
- </a>
88
- </li>
89
- );
90
- })}
91
- </ul>
92
- );
93
- }
94
-
95
- export function NavMenuLink({ item, isActive }: { item: NavMenuItem; isActive?: boolean }) {
96
- return (
97
- <a
98
- href={item.href}
99
- className={`nav-menu-item ${isActive ? "active" : ""}`}
100
- target={item.isExternal ? "_blank" : undefined}
101
- rel={item.isExternal ? "noopener noreferrer" : undefined}
102
- >
103
- {item.title}
104
- </a>
105
- );
106
- }
107
-
108
- export function NavToggle({
109
- isOpen,
110
- onClick,
111
- label = "Toggle navigation",
112
- }: {
113
- isOpen: boolean;
114
- onClick: () => void;
115
- label?: string;
116
- }) {
117
- return (
118
- <button
119
- type="button"
120
- onClick={onClick}
121
- aria-label={label}
122
- aria-expanded={isOpen}
123
- className="nav-toggle"
124
- >
125
- <span className={`toggle-icon ${isOpen ? "open" : ""}`}>{isOpen ? "✕" : "☰"}</span>
126
- </button>
127
- );
128
- }
129
-
130
- export function NavbarVersion({ version }: { version: string }) {
131
- return <span className="navbar-version">v{version}</span>;
132
- }