livemark 0.0.0-dev

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/LICENSE.md +9 -0
  2. package/README.md +3 -0
  3. package/build/actions/config/define.d.ts +6 -0
  4. package/build/actions/config/define.js +8 -0
  5. package/build/actions/config/define.unit.d.ts +1 -0
  6. package/build/actions/config/define.unit.js +34 -0
  7. package/build/actions/config/load.d.ts +5 -0
  8. package/build/actions/config/load.js +22 -0
  9. package/build/actions/config/load.unit.d.ts +1 -0
  10. package/build/actions/config/load.unit.js +23 -0
  11. package/build/commands/build.d.ts +5 -0
  12. package/build/commands/build.js +13 -0
  13. package/build/commands/preview.d.ts +5 -0
  14. package/build/commands/preview.js +18 -0
  15. package/build/commands/start.d.ts +5 -0
  16. package/build/commands/start.js +19 -0
  17. package/build/docs/markdown/includes/example.d.ts +9 -0
  18. package/build/docs/markdown/includes/example.js +5 -0
  19. package/build/entrypoints/main.d.ts +2 -0
  20. package/build/entrypoints/main.js +12 -0
  21. package/build/helpers/program.d.ts +2 -0
  22. package/build/helpers/program.js +5 -0
  23. package/build/index.d.ts +1 -0
  24. package/build/index.js +2 -0
  25. package/build/livemark.config.d.ts +9 -0
  26. package/build/livemark.config.js +5 -0
  27. package/build/models/config.d.ts +33 -0
  28. package/build/models/config.js +14 -0
  29. package/build/program.d.ts +2 -0
  30. package/build/program.js +14 -0
  31. package/build/vite.config.d.ts +2 -0
  32. package/build/vite.config.js +48 -0
  33. package/build/website/client.tsx +10 -0
  34. package/build/website/components/Abbr.tsx +17 -0
  35. package/build/website/components/AnsiCode.tsx +15 -0
  36. package/build/website/components/Banner.tsx +32 -0
  37. package/build/website/components/Breadcrumbs.tsx +19 -0
  38. package/build/website/components/Callout.tsx +72 -0
  39. package/build/website/components/Cards.tsx +66 -0
  40. package/build/website/components/CodeBlock.tsx +118 -0
  41. package/build/website/components/CodeTabs.tsx +83 -0
  42. package/build/website/components/Columns.tsx +17 -0
  43. package/build/website/components/Content.tsx +7 -0
  44. package/build/website/components/ContentTab.tsx +7 -0
  45. package/build/website/components/ContentTabs.tsx +82 -0
  46. package/build/website/components/DefaultCatchBoundary.tsx +54 -0
  47. package/build/website/components/DefinitionList.tsx +21 -0
  48. package/build/website/components/Details.tsx +30 -0
  49. package/build/website/components/FileTree.tsx +52 -0
  50. package/build/website/components/Footer.tsx +9 -0
  51. package/build/website/components/FootnoteRef.tsx +52 -0
  52. package/build/website/components/Heading.tsx +20 -0
  53. package/build/website/components/InlineBadge.tsx +9 -0
  54. package/build/website/components/InlineIcon.tsx +21 -0
  55. package/build/website/components/InlineToc.tsx +31 -0
  56. package/build/website/components/Layout.tsx +220 -0
  57. package/build/website/components/LinkButton.tsx +31 -0
  58. package/build/website/components/Mermaid.tsx +37 -0
  59. package/build/website/components/NotFound.tsx +27 -0
  60. package/build/website/components/PackageTabs.tsx +74 -0
  61. package/build/website/components/PageToolbar.tsx +65 -0
  62. package/build/website/components/PrevNext.tsx +52 -0
  63. package/build/website/components/SearchDialog.tsx +245 -0
  64. package/build/website/components/Section.tsx +24 -0
  65. package/build/website/components/SectionHeader.tsx +35 -0
  66. package/build/website/components/SiteTitle.tsx +16 -0
  67. package/build/website/components/SortableTable.tsx +81 -0
  68. package/build/website/components/SoundCloud.tsx +16 -0
  69. package/build/website/components/Theme.tsx +40 -0
  70. package/build/website/components/Toc.tsx +99 -0
  71. package/build/website/components/YouTube.tsx +16 -0
  72. package/build/website/components/ZoomImage.tsx +30 -0
  73. package/build/website/content-collections.ts +181 -0
  74. package/build/website/elements/accordion.tsx +78 -0
  75. package/build/website/elements/alert-dialog.tsx +185 -0
  76. package/build/website/elements/alert.tsx +74 -0
  77. package/build/website/elements/aspect-ratio.tsx +22 -0
  78. package/build/website/elements/avatar.tsx +107 -0
  79. package/build/website/elements/badge.tsx +51 -0
  80. package/build/website/elements/breadcrumb.tsx +120 -0
  81. package/build/website/elements/button-group.tsx +87 -0
  82. package/build/website/elements/button.tsx +57 -0
  83. package/build/website/elements/calendar.tsx +229 -0
  84. package/build/website/elements/card.tsx +102 -0
  85. package/build/website/elements/carousel.tsx +240 -0
  86. package/build/website/elements/chart.tsx +372 -0
  87. package/build/website/elements/checkbox.tsx +26 -0
  88. package/build/website/elements/collapsible.tsx +19 -0
  89. package/build/website/elements/command.tsx +210 -0
  90. package/build/website/elements/context-menu.tsx +270 -0
  91. package/build/website/elements/dialog.tsx +152 -0
  92. package/build/website/elements/direction.tsx +4 -0
  93. package/build/website/elements/drawer.tsx +127 -0
  94. package/build/website/elements/dropdown-menu.tsx +260 -0
  95. package/build/website/elements/empty.tsx +104 -0
  96. package/build/website/elements/field.tsx +235 -0
  97. package/build/website/elements/hover-card.tsx +49 -0
  98. package/build/website/elements/input-group.tsx +171 -0
  99. package/build/website/elements/input-otp.tsx +84 -0
  100. package/build/website/elements/input.tsx +18 -0
  101. package/build/website/elements/item.tsx +199 -0
  102. package/build/website/elements/kbd.tsx +26 -0
  103. package/build/website/elements/label.tsx +17 -0
  104. package/build/website/elements/menubar.tsx +282 -0
  105. package/build/website/elements/native-select.tsx +56 -0
  106. package/build/website/elements/navigation-menu.tsx +171 -0
  107. package/build/website/elements/pagination.tsx +133 -0
  108. package/build/website/elements/popover.tsx +88 -0
  109. package/build/website/elements/progress.tsx +81 -0
  110. package/build/website/elements/radio-group.tsx +36 -0
  111. package/build/website/elements/resizable.tsx +48 -0
  112. package/build/website/elements/scroll-area.tsx +51 -0
  113. package/build/website/elements/select.tsx +200 -0
  114. package/build/website/elements/separator.tsx +22 -0
  115. package/build/website/elements/sheet.tsx +130 -0
  116. package/build/website/elements/sidebar.tsx +717 -0
  117. package/build/website/elements/skeleton.tsx +13 -0
  118. package/build/website/elements/slider.tsx +57 -0
  119. package/build/website/elements/sonner.tsx +40 -0
  120. package/build/website/elements/spinner.tsx +16 -0
  121. package/build/website/elements/switch.tsx +30 -0
  122. package/build/website/elements/table.tsx +112 -0
  123. package/build/website/elements/tabs.tsx +79 -0
  124. package/build/website/elements/textarea.tsx +16 -0
  125. package/build/website/elements/toggle-group.tsx +87 -0
  126. package/build/website/elements/toggle.tsx +43 -0
  127. package/build/website/elements/tooltip.tsx +67 -0
  128. package/build/website/env.d.ts +10 -0
  129. package/build/website/globals.d.ts +8 -0
  130. package/build/website/helpers/article-icon.ts +59 -0
  131. package/build/website/helpers/articles.ts +24 -0
  132. package/build/website/helpers/resolve-includes.ts +131 -0
  133. package/build/website/helpers/resolve-includes.unit.ts +126 -0
  134. package/build/website/helpers/search-text.ts +15 -0
  135. package/build/website/helpers/style.ts +6 -0
  136. package/build/website/helpers/theme.ts +27 -0
  137. package/build/website/helpers/toc-context.ts +10 -0
  138. package/build/website/helpers/toc.ts +51 -0
  139. package/build/website/helpers/toc.unit.ts +74 -0
  140. package/build/website/hooks/in-view.ts +30 -0
  141. package/build/website/hooks/media.ts +19 -0
  142. package/build/website/models/article.ts +40 -0
  143. package/build/website/plugins/rehype-inline-code.ts +107 -0
  144. package/build/website/plugins/remark-abbr.ts +46 -0
  145. package/build/website/plugins/remark-abbr.unit.ts +99 -0
  146. package/build/website/plugins/remark-ansi.ts +247 -0
  147. package/build/website/plugins/remark-ansi.unit.ts +197 -0
  148. package/build/website/plugins/remark-badge.ts +50 -0
  149. package/build/website/plugins/remark-badge.unit.ts +96 -0
  150. package/build/website/plugins/remark-button.ts +60 -0
  151. package/build/website/plugins/remark-button.unit.ts +147 -0
  152. package/build/website/plugins/remark-callout.ts +57 -0
  153. package/build/website/plugins/remark-card.ts +80 -0
  154. package/build/website/plugins/remark-code-tabs.ts +87 -0
  155. package/build/website/plugins/remark-columns.ts +66 -0
  156. package/build/website/plugins/remark-custom-heading-id.ts +70 -0
  157. package/build/website/plugins/remark-custom-heading-id.unit.ts +131 -0
  158. package/build/website/plugins/remark-deflist.ts +36 -0
  159. package/build/website/plugins/remark-details.ts +49 -0
  160. package/build/website/plugins/remark-filetree.ts +89 -0
  161. package/build/website/plugins/remark-filetree.unit.ts +137 -0
  162. package/build/website/plugins/remark-github-callout.ts +71 -0
  163. package/build/website/plugins/remark-icon.ts +42 -0
  164. package/build/website/plugins/remark-image.ts +25 -0
  165. package/build/website/plugins/remark-media.ts +62 -0
  166. package/build/website/plugins/remark-media.unit.ts +74 -0
  167. package/build/website/plugins/remark-mermaid.ts +23 -0
  168. package/build/website/plugins/remark-npm.ts +52 -0
  169. package/build/website/plugins/remark-steps.ts +36 -0
  170. package/build/website/plugins/remark-steps.unit.ts +97 -0
  171. package/build/website/plugins/remark-tab.ts +100 -0
  172. package/build/website/plugins/remark-tab.unit.ts +181 -0
  173. package/build/website/plugins/remark-toc.ts +39 -0
  174. package/build/website/plugins/remark-toc.unit.ts +82 -0
  175. package/build/website/plugins/shiki-icon.ts +82 -0
  176. package/build/website/plugins/shiki-line-highlight.ts +174 -0
  177. package/build/website/public/logo.svg +72 -0
  178. package/build/website/routeTree.gen.ts +86 -0
  179. package/build/website/router.tsx +34 -0
  180. package/build/website/routes/$.tsx +149 -0
  181. package/build/website/routes/__root.tsx +84 -0
  182. package/build/website/routes/index.tsx +13 -0
  183. package/build/website/server.ts +7 -0
  184. package/build/website/styles/general.css +347 -0
  185. package/build/website/vite.config.ts +36 -0
  186. package/entrypoints/main.ts +12 -0
  187. package/package.json +120 -0
@@ -0,0 +1,235 @@
1
+ import { cva, type VariantProps } from "class-variance-authority"
2
+ import { useMemo } from "react"
3
+ import { cn } from "../helpers/style.ts"
4
+ import { Label } from "./label.tsx"
5
+ import { Separator } from "./separator.tsx"
6
+
7
+ function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
8
+ return (
9
+ <fieldset
10
+ data-slot="field-set"
11
+ className={cn(
12
+ "gap-6 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3 flex flex-col",
13
+ className,
14
+ )}
15
+ {...props}
16
+ />
17
+ )
18
+ }
19
+
20
+ function FieldLegend({
21
+ className,
22
+ variant = "legend",
23
+ ...props
24
+ }: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
25
+ return (
26
+ <legend
27
+ data-slot="field-legend"
28
+ data-variant={variant}
29
+ className={cn(
30
+ "mb-3 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base",
31
+ className,
32
+ )}
33
+ {...props}
34
+ />
35
+ )
36
+ }
37
+
38
+ function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
39
+ return (
40
+ <div
41
+ data-slot="field-group"
42
+ className={cn(
43
+ "gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4 group/field-group @container/field-group flex w-full flex-col",
44
+ className,
45
+ )}
46
+ {...props}
47
+ />
48
+ )
49
+ }
50
+
51
+ const fieldVariants = cva(
52
+ "data-[invalid=true]:text-destructive gap-3 group/field flex w-full",
53
+ {
54
+ variants: {
55
+ orientation: {
56
+ vertical: "flex-col [&>*]:w-full [&>.sr-only]:w-auto",
57
+ horizontal:
58
+ "flex-row items-center [&>[data-slot=field-label]]:flex-auto has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
59
+ responsive:
60
+ "flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto @md/field-group:[&>[data-slot=field-label]]:flex-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
61
+ },
62
+ },
63
+ defaultVariants: {
64
+ orientation: "vertical",
65
+ },
66
+ },
67
+ )
68
+
69
+ function Field({
70
+ className,
71
+ orientation = "vertical",
72
+ ...props
73
+ }: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
74
+ return (
75
+ <div
76
+ role="group"
77
+ data-slot="field"
78
+ data-orientation={orientation}
79
+ className={cn(fieldVariants({ orientation }), className)}
80
+ {...props}
81
+ />
82
+ )
83
+ }
84
+
85
+ function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
86
+ return (
87
+ <div
88
+ data-slot="field-content"
89
+ className={cn(
90
+ "gap-1 group/field-content flex flex-1 flex-col leading-snug",
91
+ className,
92
+ )}
93
+ {...props}
94
+ />
95
+ )
96
+ }
97
+
98
+ function FieldLabel({
99
+ className,
100
+ ...props
101
+ }: React.ComponentProps<typeof Label>) {
102
+ return (
103
+ <Label
104
+ data-slot="field-label"
105
+ className={cn(
106
+ "has-data-checked:bg-primary/5 has-data-checked:border-primary dark:has-data-checked:bg-primary/10 gap-2 group-data-[disabled=true]/field:opacity-50 has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-3 group/field-label peer/field-label flex w-fit leading-snug",
107
+ "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col",
108
+ className,
109
+ )}
110
+ {...props}
111
+ />
112
+ )
113
+ }
114
+
115
+ function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
116
+ return (
117
+ <div
118
+ data-slot="field-label"
119
+ className={cn(
120
+ "gap-2 text-sm font-medium group-data-[disabled=true]/field:opacity-50 flex w-fit items-center leading-snug",
121
+ className,
122
+ )}
123
+ {...props}
124
+ />
125
+ )
126
+ }
127
+
128
+ function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
129
+ return (
130
+ <p
131
+ data-slot="field-description"
132
+ className={cn(
133
+ "text-muted-foreground text-left text-sm [[data-variant=legend]+&]:-mt-1.5 leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
134
+ "last:mt-0 nth-last-2:-mt-1",
135
+ "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
136
+ className,
137
+ )}
138
+ {...props}
139
+ />
140
+ )
141
+ }
142
+
143
+ function FieldSeparator({
144
+ children,
145
+ className,
146
+ ...props
147
+ }: React.ComponentProps<"div"> & {
148
+ children?: React.ReactNode
149
+ }) {
150
+ return (
151
+ <div
152
+ data-slot="field-separator"
153
+ data-content={!!children}
154
+ className={cn(
155
+ "-my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2 relative",
156
+ className,
157
+ )}
158
+ {...props}
159
+ >
160
+ <Separator className="absolute inset-0 top-1/2" />
161
+ {children && (
162
+ <span
163
+ className="text-muted-foreground px-2 bg-background relative mx-auto block w-fit"
164
+ data-slot="field-separator-content"
165
+ >
166
+ {children}
167
+ </span>
168
+ )}
169
+ </div>
170
+ )
171
+ }
172
+
173
+ function FieldError({
174
+ className,
175
+ children,
176
+ errors,
177
+ ...props
178
+ }: React.ComponentProps<"div"> & {
179
+ errors?: Array<{ message?: string } | undefined>
180
+ }) {
181
+ const content = useMemo(() => {
182
+ if (children) {
183
+ return children
184
+ }
185
+
186
+ if (!errors?.length) {
187
+ return null
188
+ }
189
+
190
+ const uniqueErrors = [
191
+ ...new Map(errors.map(error => [error?.message, error])).values(),
192
+ ]
193
+
194
+ if (uniqueErrors?.length === 1) {
195
+ return uniqueErrors[0]?.message
196
+ }
197
+
198
+ return (
199
+ <ul className="ml-4 flex list-disc flex-col gap-1">
200
+ {uniqueErrors.map(
201
+ (error, index) =>
202
+ error?.message && <li key={index}>{error.message}</li>,
203
+ )}
204
+ </ul>
205
+ )
206
+ }, [children, errors])
207
+
208
+ if (!content) {
209
+ return null
210
+ }
211
+
212
+ return (
213
+ <div
214
+ role="alert"
215
+ data-slot="field-error"
216
+ className={cn("text-destructive text-sm font-normal", className)}
217
+ {...props}
218
+ >
219
+ {content}
220
+ </div>
221
+ )
222
+ }
223
+
224
+ export {
225
+ Field,
226
+ FieldLabel,
227
+ FieldDescription,
228
+ FieldError,
229
+ FieldGroup,
230
+ FieldLegend,
231
+ FieldSeparator,
232
+ FieldSet,
233
+ FieldContent,
234
+ FieldTitle,
235
+ }
@@ -0,0 +1,49 @@
1
+ import { PreviewCard as PreviewCardPrimitive } from "@base-ui/react/preview-card"
2
+
3
+ import { cn } from "../helpers/style.ts"
4
+
5
+ function HoverCard({ ...props }: PreviewCardPrimitive.Root.Props) {
6
+ return <PreviewCardPrimitive.Root data-slot="hover-card" {...props} />
7
+ }
8
+
9
+ function HoverCardTrigger({ ...props }: PreviewCardPrimitive.Trigger.Props) {
10
+ return (
11
+ <PreviewCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
12
+ )
13
+ }
14
+
15
+ function HoverCardContent({
16
+ className,
17
+ side = "bottom",
18
+ sideOffset = 4,
19
+ align = "center",
20
+ alignOffset = 4,
21
+ ...props
22
+ }: PreviewCardPrimitive.Popup.Props &
23
+ Pick<
24
+ PreviewCardPrimitive.Positioner.Props,
25
+ "align" | "alignOffset" | "side" | "sideOffset"
26
+ >) {
27
+ return (
28
+ <PreviewCardPrimitive.Portal data-slot="hover-card-portal">
29
+ <PreviewCardPrimitive.Positioner
30
+ align={align}
31
+ alignOffset={alignOffset}
32
+ side={side}
33
+ sideOffset={sideOffset}
34
+ className="isolate z-50"
35
+ >
36
+ <PreviewCardPrimitive.Popup
37
+ data-slot="hover-card-content"
38
+ className={cn(
39
+ "z-50 w-64 origin-(--transform-origin) rounded-lg bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
40
+ className,
41
+ )}
42
+ {...props}
43
+ />
44
+ </PreviewCardPrimitive.Positioner>
45
+ </PreviewCardPrimitive.Portal>
46
+ )
47
+ }
48
+
49
+ export { HoverCard, HoverCardTrigger, HoverCardContent }
@@ -0,0 +1,171 @@
1
+ import { cva, type VariantProps } from "class-variance-authority"
2
+ import { cn } from "../helpers/style.ts"
3
+ import { Button } from "./button.tsx"
4
+ import { Input } from "./input.tsx"
5
+ import { Textarea } from "./textarea.tsx"
6
+
7
+ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
8
+ return (
9
+ <div
10
+ data-slot="input-group"
11
+ role="group"
12
+ className={cn(
13
+ "border-input dark:bg-input/30 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 h-9 rounded-md border shadow-xs transition-[color,box-shadow] has-[[data-slot=input-group-control]:focus-visible]:ring-[3px] has-[[data-slot][aria-invalid=true]]:ring-[3px] has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5 [[data-slot=combobox-content]_&]:focus-within:border-inherit [[data-slot=combobox-content]_&]:focus-within:ring-0 group/input-group relative flex w-full min-w-0 items-center outline-none has-[>textarea]:h-auto",
14
+ className,
15
+ )}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ const inputGroupAddonVariants = cva(
22
+ "text-muted-foreground h-auto gap-2 py-1.5 text-sm font-medium group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4 flex cursor-text items-center justify-center select-none",
23
+ {
24
+ variants: {
25
+ align: {
26
+ "inline-start":
27
+ "pl-2 has-[>button]:ml-[-0.25rem] has-[>kbd]:ml-[-0.15rem] order-first",
28
+ "inline-end":
29
+ "pr-2 has-[>button]:mr-[-0.25rem] has-[>kbd]:mr-[-0.15rem] order-last",
30
+ "block-start":
31
+ "px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2 order-first w-full justify-start",
32
+ "block-end":
33
+ "px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2 order-last w-full justify-start",
34
+ },
35
+ },
36
+ defaultVariants: {
37
+ align: "inline-start",
38
+ },
39
+ },
40
+ )
41
+
42
+ function InputGroupAddon({
43
+ className,
44
+ align = "inline-start",
45
+ ...props
46
+ }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
47
+ return (
48
+ <div
49
+ role="group"
50
+ data-slot="input-group-addon"
51
+ data-align={align}
52
+ className={cn(inputGroupAddonVariants({ align }), className)}
53
+ onClick={e => {
54
+ if ((e.target as HTMLElement).closest("button")) {
55
+ return
56
+ }
57
+ e.currentTarget.parentElement?.querySelector("input")?.focus()
58
+ }}
59
+ {...props}
60
+ />
61
+ )
62
+ }
63
+
64
+ const inputGroupButtonVariants = cva(
65
+ "gap-2 text-sm shadow-none flex items-center",
66
+ {
67
+ variants: {
68
+ size: {
69
+ xs: "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
70
+ sm: "",
71
+ "icon-xs":
72
+ "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
73
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0",
74
+ },
75
+ },
76
+ defaultVariants: {
77
+ size: "xs",
78
+ },
79
+ },
80
+ )
81
+
82
+ function InputGroupButton({
83
+ className,
84
+ type = "button",
85
+ variant = "ghost",
86
+ size = "xs",
87
+ ...props
88
+ }: Omit<React.ComponentProps<typeof Button>, "size" | "type"> &
89
+ VariantProps<typeof inputGroupButtonVariants> & {
90
+ type?: "button" | "submit" | "reset"
91
+ }) {
92
+ return (
93
+ <Button
94
+ type={type}
95
+ data-size={size}
96
+ variant={variant}
97
+ className={cn(inputGroupButtonVariants({ size }), className)}
98
+ {...props}
99
+ />
100
+ )
101
+ }
102
+
103
+ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
104
+ return (
105
+ <span
106
+ className={cn(
107
+ "text-muted-foreground gap-2 text-sm [&_svg:not([class*='size-'])]:size-4 flex items-center [&_svg]:pointer-events-none",
108
+ className,
109
+ )}
110
+ {...props}
111
+ />
112
+ )
113
+ }
114
+
115
+ function InputGroupInput({
116
+ className,
117
+ ...props
118
+ }: React.ComponentProps<"input">) {
119
+ return (
120
+ <Input
121
+ data-slot="input-group-control"
122
+ className={cn(
123
+ "rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent flex-1",
124
+ className,
125
+ )}
126
+ {...props}
127
+ />
128
+ )
129
+ }
130
+
131
+ function InputGroupTextarea({
132
+ className,
133
+ ...props
134
+ }: React.ComponentProps<"textarea">) {
135
+ return (
136
+ <Textarea
137
+ data-slot="input-group-control"
138
+ className={cn(
139
+ "rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent flex-1 resize-none",
140
+ className,
141
+ )}
142
+ {...props}
143
+ />
144
+ )
145
+ }
146
+
147
+ function InputGroupSelect({
148
+ className,
149
+ ...props
150
+ }: React.ComponentProps<"select">) {
151
+ return (
152
+ <select
153
+ data-slot="input-group-control"
154
+ className={cn(
155
+ "rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent px-3 py-2 text-sm outline-none",
156
+ className,
157
+ )}
158
+ {...props}
159
+ />
160
+ )
161
+ }
162
+
163
+ export {
164
+ InputGroup,
165
+ InputGroupAddon,
166
+ InputGroupButton,
167
+ InputGroupText,
168
+ InputGroupInput,
169
+ InputGroupTextarea,
170
+ InputGroupSelect,
171
+ }
@@ -0,0 +1,84 @@
1
+ import * as React from "react"
2
+ import { OTPInput, OTPInputContext } from "input-otp"
3
+ import { MinusIcon } from "lucide-react"
4
+
5
+ import { cn } from "../helpers/style.ts"
6
+
7
+ function InputOTP({
8
+ className,
9
+ containerClassName,
10
+ ...props
11
+ }: React.ComponentProps<typeof OTPInput> & {
12
+ containerClassName?: string
13
+ }) {
14
+ return (
15
+ <OTPInput
16
+ data-slot="input-otp"
17
+ containerClassName={cn(
18
+ "cn-input-otp flex items-center has-disabled:opacity-50",
19
+ containerClassName,
20
+ )}
21
+ spellCheck={false}
22
+ className={cn("disabled:cursor-not-allowed", className)}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
29
+ return (
30
+ <div
31
+ data-slot="input-otp-group"
32
+ className={cn(
33
+ "flex items-center rounded-md has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40",
34
+ className,
35
+ )}
36
+ {...props}
37
+ />
38
+ )
39
+ }
40
+
41
+ function InputOTPSlot({
42
+ index,
43
+ className,
44
+ ...props
45
+ }: React.ComponentProps<"div"> & {
46
+ index: number
47
+ }) {
48
+ const inputOTPContext = React.useContext(OTPInputContext)
49
+ const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}
50
+
51
+ return (
52
+ <div
53
+ data-slot="input-otp-slot"
54
+ data-active={isActive}
55
+ className={cn(
56
+ "relative flex size-9 items-center justify-center border-y border-r border-input text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-3 data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40",
57
+ className,
58
+ )}
59
+ {...props}
60
+ >
61
+ {char}
62
+ {hasFakeCaret && (
63
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
64
+ <div className="h-4 w-px animate-caret-blink bg-foreground duration-1000" />
65
+ </div>
66
+ )}
67
+ </div>
68
+ )
69
+ }
70
+
71
+ function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) {
72
+ return (
73
+ <div
74
+ data-slot="input-otp-separator"
75
+ className="flex items-center [&_svg:not([class*='size-'])]:size-4"
76
+ role="separator"
77
+ {...props}
78
+ >
79
+ <MinusIcon />
80
+ </div>
81
+ )
82
+ }
83
+
84
+ export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
@@ -0,0 +1,18 @@
1
+ import { Input as InputPrimitive } from "@base-ui/react/input"
2
+ import { cn } from "../helpers/style.ts"
3
+
4
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
5
+ return (
6
+ <InputPrimitive
7
+ type={type}
8
+ data-slot="input"
9
+ className={cn(
10
+ "dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 h-9 rounded-md border bg-transparent px-2.5 py-1 text-base shadow-xs transition-[color,box-shadow] file:h-7 file:text-sm file:font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] md:text-sm file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
11
+ className,
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ export { Input }