blodemd 0.0.5 → 0.0.7

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.
Files changed (187) hide show
  1. package/README.md +2 -2
  2. package/dev-server/app/[[...slug]]/page.tsx +139 -0
  3. package/dev-server/app/blodemd-dev/invalidate/route.ts +12 -0
  4. package/dev-server/app/blodemd-dev/static/[...path]/route.ts +32 -0
  5. package/dev-server/app/blodemd-dev/version/route.ts +14 -0
  6. package/dev-server/app/blodemd-internal/proxy/route.ts +86 -0
  7. package/dev-server/app/error.tsx +24 -0
  8. package/dev-server/app/favicon.ico +0 -0
  9. package/dev-server/app/globals.css +4 -0
  10. package/dev-server/app/layout.tsx +38 -0
  11. package/dev-server/app/not-found.tsx +18 -0
  12. package/dev-server/app/search/route.ts +17 -0
  13. package/dev-server/components/dev-reload-script.tsx +86 -0
  14. package/dev-server/components/providers.tsx +15 -0
  15. package/dev-server/lib/dev-state.ts +8 -0
  16. package/dev-server/lib/local-content-source.ts +103 -0
  17. package/dev-server/lib/local-runtime.tsx +558 -0
  18. package/dev-server/next-env.d.ts +5 -0
  19. package/dev-server/next.config.js +46 -0
  20. package/dev-server/package.json +57 -0
  21. package/dev-server/postcss.config.mjs +7 -0
  22. package/dev-server/public/glide-variable.woff2 +0 -0
  23. package/dev-server/tsconfig.json +50 -0
  24. package/dist/cli.mjs +311 -86
  25. package/dist/cli.mjs.map +1 -1
  26. package/docs/app/globals.css +457 -0
  27. package/docs/components/api/api-playground.tsx +295 -0
  28. package/docs/components/api/api-reference.tsx +121 -0
  29. package/docs/components/content/collection-index.tsx +114 -0
  30. package/docs/components/docs/contextual-menu.tsx +406 -0
  31. package/docs/components/docs/copy-page-menu.tsx +255 -0
  32. package/docs/components/docs/doc-header.tsx +210 -0
  33. package/docs/components/docs/doc-shell.tsx +313 -0
  34. package/docs/components/docs/doc-sidebar.tsx +211 -0
  35. package/docs/components/docs/doc-toc.tsx +45 -0
  36. package/docs/components/docs/mobile-nav.tsx +205 -0
  37. package/docs/components/icons/doc-icon.tsx +96 -0
  38. package/docs/components/mdx/accordion.tsx +83 -0
  39. package/docs/components/mdx/badge.tsx +79 -0
  40. package/docs/components/mdx/callout.tsx +88 -0
  41. package/docs/components/mdx/card.tsx +110 -0
  42. package/docs/components/mdx/code-block.tsx +75 -0
  43. package/docs/components/mdx/code-group.tsx +94 -0
  44. package/docs/components/mdx/color.tsx +87 -0
  45. package/docs/components/mdx/columns.tsx +25 -0
  46. package/docs/components/mdx/expandable.tsx +45 -0
  47. package/docs/components/mdx/field-layout.tsx +77 -0
  48. package/docs/components/mdx/frame.tsx +23 -0
  49. package/docs/components/mdx/get-text-content.ts +18 -0
  50. package/docs/components/mdx/icon.tsx +12 -0
  51. package/docs/components/mdx/index.tsx +107 -0
  52. package/docs/components/mdx/installer.tsx +20 -0
  53. package/docs/components/mdx/panel.tsx +11 -0
  54. package/docs/components/mdx/param-field.tsx +56 -0
  55. package/docs/components/mdx/preview.tsx +36 -0
  56. package/docs/components/mdx/prompt.tsx +63 -0
  57. package/docs/components/mdx/request-example.tsx +27 -0
  58. package/docs/components/mdx/response-field.tsx +42 -0
  59. package/docs/components/mdx/steps.tsx +92 -0
  60. package/docs/components/mdx/tabs.tsx +88 -0
  61. package/docs/components/mdx/tile.tsx +43 -0
  62. package/docs/components/mdx/tooltip.tsx +71 -0
  63. package/docs/components/mdx/tree.tsx +120 -0
  64. package/docs/components/mdx/type-table.tsx +71 -0
  65. package/docs/components/mdx/update.tsx +44 -0
  66. package/docs/components/mdx/video.tsx +12 -0
  67. package/docs/components/mdx/view.tsx +66 -0
  68. package/docs/components/providers.tsx +15 -0
  69. package/docs/components/ui/breadcrumb.tsx +92 -0
  70. package/docs/components/ui/button.tsx +90 -0
  71. package/docs/components/ui/card.tsx +92 -0
  72. package/docs/components/ui/command.tsx +139 -0
  73. package/docs/components/ui/dialog.tsx +97 -0
  74. package/docs/components/ui/field.tsx +237 -0
  75. package/docs/components/ui/input.tsx +105 -0
  76. package/docs/components/ui/label.tsx +22 -0
  77. package/docs/components/ui/popover.tsx +72 -0
  78. package/docs/components/ui/search.tsx +384 -0
  79. package/docs/components/ui/separator.tsx +26 -0
  80. package/docs/components/ui/sheet.tsx +104 -0
  81. package/docs/components/ui/sidebar.tsx +433 -0
  82. package/docs/components/ui/theme-toggle.tsx +62 -0
  83. package/docs/components/ui/tooltip.tsx +53 -0
  84. package/docs/lib/contextual-options.ts +193 -0
  85. package/docs/lib/docs-collection.ts +22 -0
  86. package/docs/lib/mdx.ts +87 -0
  87. package/docs/lib/navigation.ts +288 -0
  88. package/docs/lib/openapi.ts +158 -0
  89. package/docs/lib/routes.ts +44 -0
  90. package/docs/lib/server-cache.ts +83 -0
  91. package/docs/lib/shiki.ts +40 -0
  92. package/docs/lib/theme.ts +29 -0
  93. package/docs/lib/toc.ts +2 -0
  94. package/docs/lib/utils.ts +5 -0
  95. package/package.json +43 -6
  96. package/packages/@repo/common/dist/index.d.ts +9 -0
  97. package/packages/@repo/common/dist/index.d.ts.map +1 -0
  98. package/packages/@repo/common/dist/index.js +42 -0
  99. package/packages/@repo/common/package.json +34 -0
  100. package/packages/@repo/common/src/index.ts +51 -0
  101. package/packages/@repo/contracts/dist/api-key.d.ts +30 -0
  102. package/packages/@repo/contracts/dist/api-key.d.ts.map +1 -0
  103. package/packages/@repo/contracts/dist/api-key.js +20 -0
  104. package/packages/@repo/contracts/dist/dates.d.ts +4 -0
  105. package/packages/@repo/contracts/dist/dates.d.ts.map +1 -0
  106. package/packages/@repo/contracts/dist/dates.js +2 -0
  107. package/packages/@repo/contracts/dist/deployment.d.ts +71 -0
  108. package/packages/@repo/contracts/dist/deployment.d.ts.map +1 -0
  109. package/packages/@repo/contracts/dist/deployment.js +46 -0
  110. package/packages/@repo/contracts/dist/domain.d.ts +94 -0
  111. package/packages/@repo/contracts/dist/domain.d.ts.map +1 -0
  112. package/packages/@repo/contracts/dist/domain.js +36 -0
  113. package/packages/@repo/contracts/dist/ids.d.ts +14 -0
  114. package/packages/@repo/contracts/dist/ids.d.ts.map +1 -0
  115. package/packages/@repo/contracts/dist/ids.js +10 -0
  116. package/packages/@repo/contracts/dist/index.d.ts +10 -0
  117. package/packages/@repo/contracts/dist/index.d.ts.map +1 -0
  118. package/packages/@repo/contracts/dist/index.js +11 -0
  119. package/packages/@repo/contracts/dist/pagination.d.ts +23 -0
  120. package/packages/@repo/contracts/dist/pagination.d.ts.map +1 -0
  121. package/packages/@repo/contracts/dist/pagination.js +15 -0
  122. package/packages/@repo/contracts/dist/project.d.ts +25 -0
  123. package/packages/@repo/contracts/dist/project.d.ts.map +1 -0
  124. package/packages/@repo/contracts/dist/project.js +23 -0
  125. package/packages/@repo/contracts/dist/tenant.d.ts +111 -0
  126. package/packages/@repo/contracts/dist/tenant.d.ts.map +1 -0
  127. package/packages/@repo/contracts/dist/tenant.js +56 -0
  128. package/packages/@repo/contracts/dist/user.d.ts +9 -0
  129. package/packages/@repo/contracts/dist/user.d.ts.map +1 -0
  130. package/packages/@repo/contracts/dist/user.js +9 -0
  131. package/packages/@repo/contracts/package.json +37 -0
  132. package/packages/@repo/contracts/src/api-key.ts +27 -0
  133. package/packages/@repo/contracts/src/dates.ts +4 -0
  134. package/packages/@repo/contracts/src/deployment.ts +73 -0
  135. package/packages/@repo/contracts/src/domain.ts +51 -0
  136. package/packages/@repo/contracts/src/ids.ts +22 -0
  137. package/packages/@repo/contracts/src/index.ts +11 -0
  138. package/packages/@repo/contracts/src/pagination.ts +21 -0
  139. package/packages/@repo/contracts/src/project.ts +30 -0
  140. package/packages/@repo/contracts/src/tenant.ts +92 -0
  141. package/packages/@repo/contracts/src/user.ts +12 -0
  142. package/packages/@repo/models/dist/docs-config.d.ts +985 -0
  143. package/packages/@repo/models/dist/docs-config.d.ts.map +1 -0
  144. package/packages/@repo/models/dist/docs-config.js +548 -0
  145. package/packages/@repo/models/dist/index.d.ts +3 -0
  146. package/packages/@repo/models/dist/index.d.ts.map +1 -0
  147. package/packages/@repo/models/dist/index.js +3 -0
  148. package/packages/@repo/models/dist/tenant.d.ts +25 -0
  149. package/packages/@repo/models/dist/tenant.d.ts.map +1 -0
  150. package/packages/@repo/models/dist/tenant.js +1 -0
  151. package/packages/@repo/models/package.json +37 -0
  152. package/packages/@repo/models/src/docs-config.ts +648 -0
  153. package/packages/@repo/models/src/index.ts +3 -0
  154. package/packages/@repo/models/src/tenant.ts +29 -0
  155. package/packages/@repo/prebuild/dist/index.d.ts +2 -0
  156. package/packages/@repo/prebuild/dist/index.d.ts.map +1 -0
  157. package/packages/@repo/prebuild/dist/index.js +2 -0
  158. package/packages/@repo/prebuild/dist/openapi.d.ts +43 -0
  159. package/packages/@repo/prebuild/dist/openapi.d.ts.map +1 -0
  160. package/packages/@repo/prebuild/dist/openapi.js +58 -0
  161. package/packages/@repo/prebuild/package.json +39 -0
  162. package/packages/@repo/prebuild/src/index.ts +2 -0
  163. package/packages/@repo/prebuild/src/openapi.ts +116 -0
  164. package/packages/@repo/previewing/dist/blob-source.d.ts +16 -0
  165. package/packages/@repo/previewing/dist/blob-source.d.ts.map +1 -0
  166. package/packages/@repo/previewing/dist/blob-source.js +110 -0
  167. package/packages/@repo/previewing/dist/content-source.d.ts +12 -0
  168. package/packages/@repo/previewing/dist/content-source.d.ts.map +1 -0
  169. package/packages/@repo/previewing/dist/content-source.js +1 -0
  170. package/packages/@repo/previewing/dist/fs-source.d.ts +11 -0
  171. package/packages/@repo/previewing/dist/fs-source.d.ts.map +1 -0
  172. package/packages/@repo/previewing/dist/fs-source.js +72 -0
  173. package/packages/@repo/previewing/dist/index.d.ts +120 -0
  174. package/packages/@repo/previewing/dist/index.d.ts.map +1 -0
  175. package/packages/@repo/previewing/dist/index.js +984 -0
  176. package/packages/@repo/previewing/package.json +41 -0
  177. package/packages/@repo/previewing/src/blob-source.ts +167 -0
  178. package/packages/@repo/previewing/src/content-source.ts +12 -0
  179. package/packages/@repo/previewing/src/fs-source.ts +104 -0
  180. package/packages/@repo/previewing/src/index.ts +1490 -0
  181. package/packages/@repo/validation/dist/index.d.ts +12 -0
  182. package/packages/@repo/validation/dist/index.d.ts.map +1 -0
  183. package/packages/@repo/validation/dist/index.js +30 -0
  184. package/packages/@repo/validation/package.json +37 -0
  185. package/packages/@repo/validation/src/index.ts +59 -0
  186. package/packages/@repo/validation/src/mintlify-docs-schema.json +5016 -0
  187. package/scripts/prepare-package.mjs +39 -0
@@ -0,0 +1,139 @@
1
+ "use client";
2
+
3
+ import { SearchIcon } from "blode-icons-react";
4
+ import { Command as CommandPrimitive } from "cmdk";
5
+ import type * as React from "react";
6
+
7
+ import {
8
+ Dialog,
9
+ DialogContent,
10
+ DialogDescription,
11
+ DialogHeader,
12
+ DialogTitle,
13
+ } from "@/components/ui/dialog";
14
+ import { cn } from "@/lib/utils";
15
+
16
+ const Command = ({
17
+ className,
18
+ ...props
19
+ }: React.ComponentProps<typeof CommandPrimitive>) => (
20
+ <CommandPrimitive
21
+ className={cn(
22
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
23
+ className
24
+ )}
25
+ data-slot="command"
26
+ {...props}
27
+ />
28
+ );
29
+
30
+ const CommandDialog = ({
31
+ title = "Command Palette",
32
+ description = "Search for a command to run...",
33
+ children,
34
+ className,
35
+ showCloseButton = true,
36
+ ...props
37
+ }: React.ComponentProps<typeof Dialog> & {
38
+ title?: string;
39
+ description?: string;
40
+ children?: React.ReactNode;
41
+ className?: string;
42
+ showCloseButton?: boolean;
43
+ } & Omit<React.ComponentProps<typeof Dialog>, "children">) => (
44
+ <Dialog {...props}>
45
+ <DialogContent
46
+ className={cn("overflow-hidden p-0", className)}
47
+ showCloseButton={showCloseButton}
48
+ >
49
+ <DialogHeader className="sr-only">
50
+ <DialogTitle>{title}</DialogTitle>
51
+ <DialogDescription>{description}</DialogDescription>
52
+ </DialogHeader>
53
+ <Command className="**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
54
+ {children}
55
+ </Command>
56
+ </DialogContent>
57
+ </Dialog>
58
+ );
59
+
60
+ const CommandInput = ({
61
+ className,
62
+ ...props
63
+ }: React.ComponentProps<typeof CommandPrimitive.Input>) => (
64
+ <div
65
+ className="flex h-9 items-center gap-2 border-b px-3"
66
+ data-slot="command-input-wrapper"
67
+ >
68
+ <SearchIcon className="size-4 shrink-0 opacity-50" />
69
+ <CommandPrimitive.Input
70
+ className={cn(
71
+ "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
72
+ className
73
+ )}
74
+ data-slot="command-input"
75
+ {...props}
76
+ />
77
+ </div>
78
+ );
79
+
80
+ const CommandList = ({
81
+ className,
82
+ ...props
83
+ }: React.ComponentProps<typeof CommandPrimitive.List>) => (
84
+ <CommandPrimitive.List
85
+ className={cn(
86
+ "max-h-[300px] scroll-py-1 overflow-y-auto overflow-x-hidden",
87
+ className
88
+ )}
89
+ data-slot="command-list"
90
+ {...props}
91
+ />
92
+ );
93
+
94
+ const CommandEmpty = ({
95
+ ...props
96
+ }: React.ComponentProps<typeof CommandPrimitive.Empty>) => (
97
+ <CommandPrimitive.Empty
98
+ className="py-6 text-center text-sm"
99
+ data-slot="command-empty"
100
+ {...props}
101
+ />
102
+ );
103
+
104
+ const CommandGroup = ({
105
+ className,
106
+ ...props
107
+ }: React.ComponentProps<typeof CommandPrimitive.Group>) => (
108
+ <CommandPrimitive.Group
109
+ className={cn(
110
+ "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:text-xs",
111
+ className
112
+ )}
113
+ data-slot="command-group"
114
+ {...props}
115
+ />
116
+ );
117
+
118
+ const CommandItem = ({
119
+ className,
120
+ ...props
121
+ }: React.ComponentProps<typeof CommandPrimitive.Item>) => (
122
+ <CommandPrimitive.Item
123
+ className={cn(
124
+ "relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0",
125
+ className
126
+ )}
127
+ data-slot="command-item"
128
+ {...props}
129
+ />
130
+ );
131
+
132
+ export {
133
+ CommandDialog,
134
+ CommandInput,
135
+ CommandList,
136
+ CommandEmpty,
137
+ CommandGroup,
138
+ CommandItem,
139
+ };
@@ -0,0 +1,97 @@
1
+ "use client";
2
+
3
+ import { XIcon } from "blode-icons-react";
4
+ import { Dialog as DialogPrimitive } from "radix-ui";
5
+ import * as React from "react";
6
+
7
+ import { cn } from "@/lib/utils";
8
+
9
+ const Dialog = ({
10
+ ...props
11
+ }: React.ComponentProps<typeof DialogPrimitive.Root>) => (
12
+ <DialogPrimitive.Root data-slot="dialog" {...props} />
13
+ );
14
+
15
+ const DialogPortal = ({
16
+ ...props
17
+ }: React.ComponentProps<typeof DialogPrimitive.Portal>) => (
18
+ <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
19
+ );
20
+
21
+ const DialogOverlay = ({
22
+ className,
23
+ ...props
24
+ }: React.ComponentProps<typeof DialogPrimitive.Overlay>) => (
25
+ <DialogPrimitive.Overlay
26
+ data-slot="dialog-overlay"
27
+ className={cn(
28
+ "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
29
+ className
30
+ )}
31
+ {...props}
32
+ />
33
+ );
34
+
35
+ const DialogContent = ({
36
+ className,
37
+ children,
38
+ showCloseButton = true,
39
+ ...props
40
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
41
+ showCloseButton?: boolean;
42
+ }) => (
43
+ <DialogPortal data-slot="dialog-portal">
44
+ <DialogOverlay />
45
+ <DialogPrimitive.Content
46
+ data-slot="dialog-content"
47
+ className={cn(
48
+ "fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg",
49
+ className
50
+ )}
51
+ {...props}
52
+ >
53
+ {children}
54
+ {showCloseButton && (
55
+ <DialogPrimitive.Close
56
+ data-slot="dialog-close"
57
+ className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
58
+ >
59
+ <XIcon />
60
+ <span className="sr-only">Close</span>
61
+ </DialogPrimitive.Close>
62
+ )}
63
+ </DialogPrimitive.Content>
64
+ </DialogPortal>
65
+ );
66
+
67
+ const DialogHeader = ({ className, ...props }: React.ComponentProps<"div">) => (
68
+ <div
69
+ data-slot="dialog-header"
70
+ className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
71
+ {...props}
72
+ />
73
+ );
74
+
75
+ const DialogTitle = ({
76
+ className,
77
+ ...props
78
+ }: React.ComponentProps<typeof DialogPrimitive.Title>) => (
79
+ <DialogPrimitive.Title
80
+ data-slot="dialog-title"
81
+ className={cn("text-lg leading-none font-semibold", className)}
82
+ {...props}
83
+ />
84
+ );
85
+
86
+ const DialogDescription = ({
87
+ className,
88
+ ...props
89
+ }: React.ComponentProps<typeof DialogPrimitive.Description>) => (
90
+ <DialogPrimitive.Description
91
+ data-slot="dialog-description"
92
+ className={cn("text-sm text-muted-foreground", className)}
93
+ {...props}
94
+ />
95
+ );
96
+
97
+ export { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle };
@@ -0,0 +1,237 @@
1
+ "use client";
2
+
3
+ import { cva } from "class-variance-authority";
4
+ import type { VariantProps } from "class-variance-authority";
5
+ import { useMemo } from "react";
6
+
7
+ import { Label } from "@/components/ui/label";
8
+ import { Separator } from "@/components/ui/separator";
9
+ import { cn } from "@/lib/utils";
10
+
11
+ const FieldSet = ({
12
+ className,
13
+ ...props
14
+ }: React.ComponentProps<"fieldset">) => (
15
+ <fieldset
16
+ className={cn(
17
+ "flex flex-col gap-6",
18
+ "has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
19
+ className
20
+ )}
21
+ data-slot="field-set"
22
+ {...props}
23
+ />
24
+ );
25
+
26
+ const FieldLegend = ({
27
+ className,
28
+ variant = "legend",
29
+ ...props
30
+ }: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) => (
31
+ <legend
32
+ className={cn(
33
+ "mb-3 font-medium",
34
+ "data-[variant=legend]:text-base",
35
+ "data-[variant=label]:text-sm",
36
+ className
37
+ )}
38
+ data-slot="field-legend"
39
+ data-variant={variant}
40
+ {...props}
41
+ />
42
+ );
43
+
44
+ const FieldGroup = ({ className, ...props }: React.ComponentProps<"div">) => (
45
+ <div
46
+ className={cn(
47
+ "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
48
+ className
49
+ )}
50
+ data-slot="field-group"
51
+ {...props}
52
+ />
53
+ );
54
+
55
+ const fieldVariants = cva(
56
+ "group/field flex w-full gap-3 data-[invalid=true]:text-destructive",
57
+ {
58
+ defaultVariants: {
59
+ orientation: "vertical",
60
+ },
61
+ variants: {
62
+ orientation: {
63
+ horizontal: [
64
+ "flex-row items-center",
65
+ "[&>[data-slot=field-label]]:flex-auto",
66
+ "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
67
+ ],
68
+ responsive: [
69
+ "@md/field-group:flex-row flex-col @md/field-group:items-center @md/field-group:[&>*]:w-auto [&>*]:w-full [&>.sr-only]:w-auto",
70
+ "@md/field-group:[&>[data-slot=field-label]]:flex-auto",
71
+ "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
72
+ ],
73
+ vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
74
+ },
75
+ },
76
+ }
77
+ );
78
+
79
+ const Field = ({
80
+ className,
81
+ orientation = "vertical",
82
+ ...props
83
+ }: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) => (
84
+ <div
85
+ className={cn(fieldVariants({ orientation }), className)}
86
+ data-orientation={orientation}
87
+ data-slot="field"
88
+ role="group"
89
+ {...props}
90
+ />
91
+ );
92
+
93
+ const FieldContent = ({ className, ...props }: React.ComponentProps<"div">) => (
94
+ <div
95
+ className={cn(
96
+ "group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
97
+ className
98
+ )}
99
+ data-slot="field-content"
100
+ {...props}
101
+ />
102
+ );
103
+
104
+ const FieldLabel = ({
105
+ className,
106
+ ...props
107
+ }: React.ComponentProps<typeof Label>) => (
108
+ <Label
109
+ className={cn(
110
+ "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
111
+ "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
112
+ "has-data-[state=checked]:border-primary has-data-[state=checked]:bg-primary/5 dark:has-data-[state=checked]:bg-primary/10",
113
+ className
114
+ )}
115
+ data-slot="field-label"
116
+ {...props}
117
+ />
118
+ );
119
+
120
+ const FieldTitle = ({ className, ...props }: React.ComponentProps<"div">) => (
121
+ <div
122
+ className={cn(
123
+ "flex w-fit items-center gap-2 font-medium text-sm leading-snug group-data-[disabled=true]/field:opacity-50",
124
+ className
125
+ )}
126
+ data-slot="field-label"
127
+ {...props}
128
+ />
129
+ );
130
+
131
+ const FieldDescription = ({
132
+ className,
133
+ ...props
134
+ }: React.ComponentProps<"p">) => (
135
+ <p
136
+ className={cn(
137
+ "font-normal text-muted-foreground text-sm leading-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
138
+ "nth-last-2:-mt-1 last:mt-0 [[data-variant=legend]+&]:-mt-1.5",
139
+ "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
140
+ className
141
+ )}
142
+ data-slot="field-description"
143
+ {...props}
144
+ />
145
+ );
146
+
147
+ const FieldSeparator = ({
148
+ children,
149
+ className,
150
+ ...props
151
+ }: React.ComponentProps<"div"> & {
152
+ children?: React.ReactNode;
153
+ }) => (
154
+ <div
155
+ className={cn(
156
+ "relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
157
+ className
158
+ )}
159
+ data-content={!!children}
160
+ data-slot="field-separator"
161
+ {...props}
162
+ >
163
+ <Separator className="absolute inset-0 top-1/2" />
164
+ {children && (
165
+ <span
166
+ className="relative mx-auto block w-fit bg-background px-2 text-muted-foreground"
167
+ data-slot="field-separator-content"
168
+ >
169
+ {children}
170
+ </span>
171
+ )}
172
+ </div>
173
+ );
174
+
175
+ const FieldError = ({
176
+ className,
177
+ children,
178
+ errors,
179
+ ...props
180
+ }: React.ComponentProps<"div"> & {
181
+ errors?: ({ message?: string } | undefined)[];
182
+ }) => {
183
+ const content = useMemo(() => {
184
+ if (children) {
185
+ return children;
186
+ }
187
+
188
+ if (!errors?.length) {
189
+ return null;
190
+ }
191
+
192
+ const uniqueErrors = [
193
+ ...new Map(errors.map((error) => [error?.message, error])).values(),
194
+ ];
195
+
196
+ if (uniqueErrors?.length === 1) {
197
+ return uniqueErrors[0]?.message;
198
+ }
199
+
200
+ return (
201
+ <ul className="ml-4 flex list-disc flex-col gap-1">
202
+ {uniqueErrors.map(
203
+ (error) =>
204
+ error?.message && <li key={error.message}>{error.message}</li>
205
+ )}
206
+ </ul>
207
+ );
208
+ }, [children, errors]);
209
+
210
+ if (!content) {
211
+ return null;
212
+ }
213
+
214
+ return (
215
+ <div
216
+ className={cn("font-normal text-destructive text-sm", className)}
217
+ data-slot="field-error"
218
+ role="alert"
219
+ {...props}
220
+ >
221
+ {content}
222
+ </div>
223
+ );
224
+ };
225
+
226
+ export {
227
+ Field,
228
+ FieldLabel,
229
+ FieldDescription,
230
+ FieldError,
231
+ FieldGroup,
232
+ FieldLegend,
233
+ FieldSeparator,
234
+ FieldSet,
235
+ FieldContent,
236
+ FieldTitle,
237
+ };
@@ -0,0 +1,105 @@
1
+ "use client";
2
+
3
+ import { CircleXFilledIcon } from "blode-icons-react";
4
+ import * as React from "react";
5
+
6
+ import { cn } from "@/lib/utils";
7
+
8
+ export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
9
+ clearable?: boolean;
10
+ clearClassName?: string;
11
+ hasError?: boolean;
12
+ leftAddon?: React.ReactNode | null;
13
+ leftControl?: React.ReactNode | null;
14
+ onClear?: () => void;
15
+ rightAddon?: React.ReactNode | null;
16
+ rightControl?: React.ReactNode | null;
17
+ }
18
+
19
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
20
+ (
21
+ {
22
+ className,
23
+ clearClassName,
24
+ hasError,
25
+ clearable,
26
+ onClear,
27
+ leftAddon,
28
+ rightAddon,
29
+ leftControl,
30
+ rightControl,
31
+ ...props
32
+ },
33
+ ref
34
+ ) => (
35
+ <label
36
+ className={cn("relative w-full", {
37
+ "input-group": !!leftAddon || !!rightAddon,
38
+ })}
39
+ >
40
+ {leftAddon && (
41
+ <span className="shrink-0 cursor-pointer">{leftAddon}</span>
42
+ )}
43
+
44
+ {leftControl && (
45
+ <div className="absolute top-0 left-0 flex h-full flex-row place-items-center items-center justify-center">
46
+ {leftControl}
47
+ </div>
48
+ )}
49
+
50
+ <div className="w-full">
51
+ <input
52
+ className={cn(
53
+ "input flex h-[var(--field-height)] w-full rounded-[var(--field-radius)] border border-input bg-card px-[var(--field-padding-x)] py-[var(--field-padding-y)] font-normal font-sans text-base text-foreground leading-snug shadow-input transition-colors placeholder:text-placeholder-foreground hover:border-input-hover focus:border-ring focus:outline-hidden focus:ring-2 focus:ring-ring/15 focus:ring-offset-1 focus:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
54
+ {
55
+ "border-destructive-foreground": hasError,
56
+ "hover:border-input! focus:border-input!": props.readOnly,
57
+ "pr-12": clearable && !!props.value && rightControl,
58
+ "pr-9": clearable && !!props.value,
59
+ },
60
+ className
61
+ )}
62
+ ref={ref}
63
+ {...props}
64
+ />
65
+
66
+ {clearable && !!props.value && (
67
+ <div className="absolute top-0 right-0 flex flex-row gap-1 pr-3">
68
+ <button
69
+ aria-label="clear input"
70
+ className={cn(
71
+ "flex h-[var(--field-height)] cursor-pointer items-center justify-center p-0! text-muted-foreground",
72
+ clearClassName
73
+ )}
74
+ onClick={onClear}
75
+ tabIndex={-1}
76
+ type="button"
77
+ >
78
+ <CircleXFilledIcon className="size-5 text-muted-foreground/50" />
79
+ </button>
80
+ </div>
81
+ )}
82
+ </div>
83
+
84
+ {rightControl && (
85
+ <div
86
+ className={cn(
87
+ "absolute top-0 right-0 flex h-full flex-row place-items-center items-center justify-center",
88
+ {
89
+ "right-9": clearable && !!props.value,
90
+ }
91
+ )}
92
+ >
93
+ {rightControl}
94
+ </div>
95
+ )}
96
+
97
+ {rightAddon && (
98
+ <span className="shrink-0 cursor-pointer">{rightAddon}</span>
99
+ )}
100
+ </label>
101
+ )
102
+ );
103
+ Input.displayName = "Input";
104
+
105
+ export { Input };
@@ -0,0 +1,22 @@
1
+ "use client";
2
+
3
+ import { Label as LabelPrimitive } from "radix-ui";
4
+ import * as React from "react";
5
+
6
+ import { cn } from "@/lib/utils";
7
+
8
+ const Label = ({
9
+ className,
10
+ ...props
11
+ }: React.ComponentProps<typeof LabelPrimitive.Root>) => (
12
+ <LabelPrimitive.Root
13
+ data-slot="label"
14
+ className={cn(
15
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
16
+ className
17
+ )}
18
+ {...props}
19
+ />
20
+ );
21
+
22
+ export { Label };
@@ -0,0 +1,72 @@
1
+ "use client";
2
+
3
+ import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
4
+ import type * as React from "react";
5
+
6
+ import { cn } from "@/lib/utils";
7
+
8
+ const Popover = ({
9
+ ...props
10
+ }: React.ComponentProps<typeof PopoverPrimitive.Root>) => (
11
+ <PopoverPrimitive.Root data-slot="popover" {...props} />
12
+ );
13
+
14
+ const PopoverTrigger = ({
15
+ asChild = false,
16
+ children,
17
+ ...props
18
+ }: React.ComponentProps<typeof PopoverPrimitive.Trigger> & {
19
+ asChild?: boolean;
20
+ }) => {
21
+ const render =
22
+ asChild && children && typeof children === "object"
23
+ ? (children as React.ReactElement)
24
+ : undefined;
25
+
26
+ return (
27
+ <PopoverPrimitive.Trigger
28
+ data-slot="popover-trigger"
29
+ render={render}
30
+ {...props}
31
+ >
32
+ {asChild ? null : children}
33
+ </PopoverPrimitive.Trigger>
34
+ );
35
+ };
36
+
37
+ const PopoverContent = ({
38
+ children,
39
+ className,
40
+ align = "center",
41
+ alignOffset = 0,
42
+ side = "bottom",
43
+ sideOffset = 4,
44
+ ...props
45
+ }: React.ComponentProps<typeof PopoverPrimitive.Popup> &
46
+ Pick<
47
+ React.ComponentProps<typeof PopoverPrimitive.Positioner>,
48
+ "align" | "alignOffset" | "side" | "sideOffset"
49
+ >) => (
50
+ <PopoverPrimitive.Portal>
51
+ <PopoverPrimitive.Positioner
52
+ align={align}
53
+ alignOffset={alignOffset}
54
+ className="isolate z-50"
55
+ side={side}
56
+ sideOffset={sideOffset}
57
+ >
58
+ <PopoverPrimitive.Popup
59
+ className={cn(
60
+ "z-50 w-72 origin-(--transform-origin) rounded-md border bg-popover p-4 text-popover-foreground shadow-soft outline-hidden data-closed:animate-out data-open:animate-in data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
61
+ className
62
+ )}
63
+ data-slot="popover-content"
64
+ {...props}
65
+ >
66
+ {children}
67
+ </PopoverPrimitive.Popup>
68
+ </PopoverPrimitive.Positioner>
69
+ </PopoverPrimitive.Portal>
70
+ );
71
+
72
+ export { Popover, PopoverTrigger, PopoverContent };