@hauktui/registry 0.0.1

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 (139) hide show
  1. package/components/accordion/accordion.tsx +146 -0
  2. package/components/accordion/index.ts +2 -0
  3. package/components/alert/alert.tsx +69 -0
  4. package/components/alert/index.ts +2 -0
  5. package/components/alert-dialog/alert-dialog.tsx +185 -0
  6. package/components/alert-dialog/index.ts +2 -0
  7. package/components/avatar/avatar.tsx +57 -0
  8. package/components/avatar/index.ts +2 -0
  9. package/components/avatar-group/avatar-group.tsx +144 -0
  10. package/components/avatar-group/index.ts +2 -0
  11. package/components/badge/badge.tsx +52 -0
  12. package/components/badge/index.ts +2 -0
  13. package/components/banner/banner.tsx +407 -0
  14. package/components/banner/index.ts +2 -0
  15. package/components/breadcrumb/breadcrumb.tsx +58 -0
  16. package/components/breadcrumb/index.ts +2 -0
  17. package/components/button/button.tsx +114 -0
  18. package/components/button/index.ts +2 -0
  19. package/components/calendar/calendar.tsx +250 -0
  20. package/components/calendar/index.ts +2 -0
  21. package/components/card/card.tsx +88 -0
  22. package/components/card/index.ts +2 -0
  23. package/components/carousel/carousel.tsx +185 -0
  24. package/components/carousel/index.ts +2 -0
  25. package/components/chart/chart.tsx +189 -0
  26. package/components/chart/index.ts +2 -0
  27. package/components/checkbox/checkbox.tsx +98 -0
  28. package/components/checkbox/index.ts +2 -0
  29. package/components/code-block/code-block.tsx +214 -0
  30. package/components/code-block/index.ts +2 -0
  31. package/components/collapsible/collapsible.tsx +123 -0
  32. package/components/collapsible/index.ts +2 -0
  33. package/components/color-picker/color-picker.tsx +211 -0
  34. package/components/color-picker/index.ts +2 -0
  35. package/components/combobox/combobox.tsx +275 -0
  36. package/components/combobox/index.ts +2 -0
  37. package/components/command/command.tsx +304 -0
  38. package/components/command/index.ts +2 -0
  39. package/components/confirm-dialog/confirm-dialog.tsx +140 -0
  40. package/components/confirm-dialog/index.ts +2 -0
  41. package/components/context-menu/context-menu.tsx +188 -0
  42. package/components/context-menu/index.ts +2 -0
  43. package/components/countdown/countdown.tsx +165 -0
  44. package/components/countdown/index.ts +2 -0
  45. package/components/data-table/data-table.tsx +256 -0
  46. package/components/data-table/index.ts +2 -0
  47. package/components/date-picker/date-picker.tsx +280 -0
  48. package/components/date-picker/index.ts +2 -0
  49. package/components/dialog/dialog.tsx +84 -0
  50. package/components/dialog/index.ts +2 -0
  51. package/components/drawer/drawer.tsx +141 -0
  52. package/components/drawer/index.ts +2 -0
  53. package/components/dropdown-menu/dropdown-menu.tsx +188 -0
  54. package/components/dropdown-menu/index.ts +2 -0
  55. package/components/empty/empty.tsx +107 -0
  56. package/components/empty/index.ts +2 -0
  57. package/components/field/field.tsx +83 -0
  58. package/components/field/index.ts +2 -0
  59. package/components/form/form.tsx +202 -0
  60. package/components/form/index.ts +8 -0
  61. package/components/hover-card/hover-card.tsx +72 -0
  62. package/components/hover-card/index.ts +2 -0
  63. package/components/input-otp/index.ts +2 -0
  64. package/components/input-otp/input-otp.tsx +176 -0
  65. package/components/kbd/index.ts +2 -0
  66. package/components/kbd/kbd.tsx +30 -0
  67. package/components/label/index.ts +2 -0
  68. package/components/label/label.tsx +56 -0
  69. package/components/list/index.ts +2 -0
  70. package/components/list/list.tsx +247 -0
  71. package/components/menubar/index.ts +2 -0
  72. package/components/menubar/menubar.tsx +220 -0
  73. package/components/navigation-menu/index.ts +6 -0
  74. package/components/navigation-menu/navigation-menu.tsx +216 -0
  75. package/components/pagination/index.ts +2 -0
  76. package/components/pagination/pagination.tsx +158 -0
  77. package/components/password-input/index.ts +2 -0
  78. package/components/password-input/password-input.tsx +198 -0
  79. package/components/popover/index.ts +2 -0
  80. package/components/popover/popover.tsx +102 -0
  81. package/components/progress/index.ts +2 -0
  82. package/components/progress/progress.tsx +73 -0
  83. package/components/radio-group/index.ts +2 -0
  84. package/components/radio-group/radio-group.tsx +167 -0
  85. package/components/resizable/index.ts +2 -0
  86. package/components/resizable/resizable.tsx +141 -0
  87. package/components/scroll-area/index.ts +2 -0
  88. package/components/scroll-area/scroll-area.tsx +133 -0
  89. package/components/select/index.ts +2 -0
  90. package/components/select/select.tsx +185 -0
  91. package/components/separator/index.ts +2 -0
  92. package/components/separator/separator.tsx +63 -0
  93. package/components/sheet/index.ts +2 -0
  94. package/components/sheet/sheet.tsx +137 -0
  95. package/components/sidebar/index.ts +2 -0
  96. package/components/sidebar/sidebar.tsx +225 -0
  97. package/components/skeleton/index.ts +2 -0
  98. package/components/skeleton/skeleton.tsx +64 -0
  99. package/components/slider/index.ts +2 -0
  100. package/components/slider/slider.tsx +128 -0
  101. package/components/spinner/index.ts +2 -0
  102. package/components/spinner/spinner.tsx +57 -0
  103. package/components/stat/index.ts +2 -0
  104. package/components/stat/stat.tsx +138 -0
  105. package/components/stepper/index.ts +2 -0
  106. package/components/stepper/stepper.tsx +219 -0
  107. package/components/switch/index.ts +2 -0
  108. package/components/switch/switch.tsx +102 -0
  109. package/components/table/index.ts +2 -0
  110. package/components/table/table.tsx +242 -0
  111. package/components/tabs/index.ts +2 -0
  112. package/components/tabs/tabs.tsx +240 -0
  113. package/components/tag-input/index.ts +2 -0
  114. package/components/tag-input/tag-input.tsx +180 -0
  115. package/components/terminal/index.ts +2 -0
  116. package/components/terminal/terminal.tsx +162 -0
  117. package/components/text-input/index.ts +2 -0
  118. package/components/text-input/text-input.tsx +179 -0
  119. package/components/textarea/index.ts +2 -0
  120. package/components/textarea/textarea.tsx +206 -0
  121. package/components/timeline/index.ts +2 -0
  122. package/components/timeline/timeline.tsx +167 -0
  123. package/components/toast/index.ts +2 -0
  124. package/components/toast/toast.tsx +93 -0
  125. package/components/toggle/index.ts +2 -0
  126. package/components/toggle/toggle.tsx +114 -0
  127. package/components/toggle-group/index.ts +2 -0
  128. package/components/toggle-group/toggle-group.tsx +176 -0
  129. package/components/tooltip/index.ts +2 -0
  130. package/components/tooltip/tooltip.tsx +65 -0
  131. package/components/tree-view/index.ts +2 -0
  132. package/components/tree-view/tree-view.tsx +245 -0
  133. package/components/typography/index.ts +12 -0
  134. package/components/typography/typography.tsx +154 -0
  135. package/dist/index.d.ts +102 -0
  136. package/dist/index.js +938 -0
  137. package/dist/index.js.map +1 -0
  138. package/package.json +41 -0
  139. package/registry.json +923 -0
@@ -0,0 +1,202 @@
1
+ import React, { createContext, useContext, useState, useCallback } from "react";
2
+ import { Box, Text } from "ink";
3
+ import type { Tokens } from "@hauktui/tokens";
4
+ import { useTokens } from "@hauktui/primitives-ink";
5
+
6
+ export interface FormState {
7
+ values: Record<string, unknown>;
8
+ errors: Record<string, string>;
9
+ touched: Record<string, boolean>;
10
+ }
11
+
12
+ export interface FormContextValue {
13
+ values: Record<string, unknown>;
14
+ errors: Record<string, string>;
15
+ touched: Record<string, boolean>;
16
+ setValue: (name: string, value: unknown) => void;
17
+ setError: (name: string, error: string) => void;
18
+ setTouched: (name: string) => void;
19
+ handleSubmit: () => void;
20
+ }
21
+
22
+ const FormContext = createContext<FormContextValue | null>(null);
23
+
24
+ export function useFormContext(): FormContextValue {
25
+ const context = useContext(FormContext);
26
+ if (!context) {
27
+ throw new Error("useFormContext must be used within a Form");
28
+ }
29
+ return context;
30
+ }
31
+
32
+ export interface FormProps {
33
+ /** Initial form values */
34
+ defaultValues?: Record<string, unknown>;
35
+ /** Callback when form is submitted */
36
+ onSubmit?: (values: Record<string, unknown>) => void;
37
+ /** Validation function */
38
+ validate?: (values: Record<string, unknown>) => Record<string, string>;
39
+ /** Form children */
40
+ children: React.ReactNode;
41
+ /** Custom tokens override */
42
+ tokens?: Tokens;
43
+ }
44
+
45
+ export function Form({
46
+ defaultValues = {},
47
+ onSubmit,
48
+ validate,
49
+ children,
50
+ tokens: propTokens,
51
+ }: FormProps): React.ReactElement {
52
+ const contextTokens = useTokens();
53
+ const tokens = propTokens ?? contextTokens;
54
+
55
+ const [values, setValues] = useState<Record<string, unknown>>(defaultValues);
56
+ const [errors, setErrors] = useState<Record<string, string>>({});
57
+ const [touched, setTouchedState] = useState<Record<string, boolean>>({});
58
+
59
+ const setValue = useCallback((name: string, value: unknown) => {
60
+ setValues((prev) => ({ ...prev, [name]: value }));
61
+ // Clear error when value changes
62
+ setErrors((prev) => {
63
+ const next = { ...prev };
64
+ delete next[name];
65
+ return next;
66
+ });
67
+ }, []);
68
+
69
+ const setError = useCallback((name: string, error: string) => {
70
+ setErrors((prev) => ({ ...prev, [name]: error }));
71
+ }, []);
72
+
73
+ const setTouched = useCallback((name: string) => {
74
+ setTouchedState((prev) => ({ ...prev, [name]: true }));
75
+ }, []);
76
+
77
+ const handleSubmit = useCallback(() => {
78
+ // Validate if validator provided
79
+ if (validate) {
80
+ const validationErrors = validate(values);
81
+ if (Object.keys(validationErrors).length > 0) {
82
+ setErrors(validationErrors);
83
+ return;
84
+ }
85
+ }
86
+ onSubmit?.(values);
87
+ }, [values, validate, onSubmit]);
88
+
89
+ const contextValue: FormContextValue = {
90
+ values,
91
+ errors,
92
+ touched,
93
+ setValue,
94
+ setError,
95
+ setTouched,
96
+ handleSubmit,
97
+ };
98
+
99
+ return React.createElement(
100
+ FormContext.Provider,
101
+ { value: contextValue },
102
+ React.createElement(Box, { flexDirection: "column", gap: 1 }, children)
103
+ );
104
+ }
105
+
106
+ export interface FormFieldProps {
107
+ /** Field name */
108
+ name: string;
109
+ /** Field label */
110
+ label?: string;
111
+ /** Whether field is required */
112
+ required?: boolean;
113
+ /** Help text */
114
+ description?: string;
115
+ /** Field children (input component) */
116
+ children: React.ReactElement;
117
+ /** Custom tokens override */
118
+ tokens?: Tokens;
119
+ }
120
+
121
+ export function FormField({
122
+ name,
123
+ label,
124
+ required,
125
+ description,
126
+ children,
127
+ tokens: propTokens,
128
+ }: FormFieldProps): React.ReactElement {
129
+ const contextTokens = useTokens();
130
+ const tokens = propTokens ?? contextTokens;
131
+ const form = useFormContext();
132
+
133
+ const error = form.errors[name];
134
+ const isTouched = form.touched[name];
135
+
136
+ return React.createElement(
137
+ Box,
138
+ { flexDirection: "column" },
139
+ label
140
+ ? React.createElement(
141
+ Box,
142
+ { gap: 1 },
143
+ React.createElement(
144
+ Text,
145
+ { color: tokens.colors.fg, bold: true },
146
+ label
147
+ ),
148
+ required
149
+ ? React.createElement(Text, { color: tokens.colors.danger }, "*")
150
+ : null
151
+ )
152
+ : null,
153
+ description
154
+ ? React.createElement(
155
+ Text,
156
+ { color: tokens.colors.muted, dimColor: true },
157
+ description
158
+ )
159
+ : null,
160
+ children,
161
+ error && isTouched
162
+ ? React.createElement(Text, { color: tokens.colors.danger }, `✗ ${error}`)
163
+ : null
164
+ );
165
+ }
166
+
167
+ export interface FormMessageProps {
168
+ /** Message type */
169
+ type?: "error" | "success" | "info";
170
+ /** Message content */
171
+ children: React.ReactNode;
172
+ /** Custom tokens override */
173
+ tokens?: Tokens;
174
+ }
175
+
176
+ export function FormMessage({
177
+ type = "error",
178
+ children,
179
+ tokens: propTokens,
180
+ }: FormMessageProps): React.ReactElement {
181
+ const contextTokens = useTokens();
182
+ const tokens = propTokens ?? contextTokens;
183
+
184
+ const colors = {
185
+ error: tokens.colors.danger,
186
+ success: tokens.colors.success,
187
+ info: tokens.colors.accent,
188
+ };
189
+
190
+ const icons = {
191
+ error: "✗",
192
+ success: "✓",
193
+ info: "ℹ",
194
+ };
195
+
196
+ return React.createElement(
197
+ Box,
198
+ { gap: 1 },
199
+ React.createElement(Text, { color: colors[type] }, icons[type]),
200
+ React.createElement(Text, { color: colors[type] }, children)
201
+ );
202
+ }
@@ -0,0 +1,8 @@
1
+ export { Form, FormField, FormMessage, useFormContext } from "./form.js";
2
+ export type {
3
+ FormProps,
4
+ FormFieldProps,
5
+ FormMessageProps,
6
+ FormState,
7
+ FormContextValue,
8
+ } from "./form.js";
@@ -0,0 +1,72 @@
1
+ import React from "react";
2
+ import { Box, Text } from "ink";
3
+ import type { Tokens } from "@hauktui/tokens";
4
+ import { useTokens } from "@hauktui/primitives-ink";
5
+
6
+ export interface HoverCardProps {
7
+ /** The trigger element */
8
+ children: React.ReactNode;
9
+ /** Content to show in the hover card */
10
+ content: React.ReactNode;
11
+ /** Whether the hover card is visible */
12
+ open: boolean;
13
+ /** Position of the card */
14
+ position?: "top" | "bottom" | "left" | "right";
15
+ /** Width of the card */
16
+ width?: number;
17
+ /** Custom tokens override */
18
+ tokens?: Tokens;
19
+ }
20
+
21
+ export function HoverCard({
22
+ children,
23
+ content,
24
+ open,
25
+ position = "bottom",
26
+ width = 30,
27
+ tokens: propTokens,
28
+ }: HoverCardProps): React.ReactElement {
29
+ const contextTokens = useTokens();
30
+ const tokens = propTokens ?? contextTokens;
31
+
32
+ const cardElement = React.createElement(
33
+ Box,
34
+ {
35
+ flexDirection: "column",
36
+ borderStyle: "round",
37
+ borderColor: tokens.colors.border,
38
+ width,
39
+ paddingX: 1,
40
+ paddingY: 0,
41
+ marginTop: position === "bottom" ? 0 : undefined,
42
+ marginBottom: position === "top" ? 0 : undefined,
43
+ },
44
+ content
45
+ );
46
+
47
+ if (!open) {
48
+ return React.createElement(Box, null, children);
49
+ }
50
+
51
+ const isVertical = position === "top" || position === "bottom";
52
+
53
+ const containerProps: Record<string, unknown> = {
54
+ flexDirection: isVertical ? "column" : "row",
55
+ alignItems: isVertical ? "flex-start" : "center",
56
+ gap: 0,
57
+ };
58
+
59
+ if (position === "top") {
60
+ return React.createElement(Box, containerProps, cardElement, children);
61
+ }
62
+
63
+ if (position === "bottom") {
64
+ return React.createElement(Box, containerProps, children, cardElement);
65
+ }
66
+
67
+ if (position === "left") {
68
+ return React.createElement(Box, containerProps, cardElement, children);
69
+ }
70
+
71
+ return React.createElement(Box, containerProps, children, cardElement);
72
+ }
@@ -0,0 +1,2 @@
1
+ export { HoverCard } from "./hover-card.js";
2
+ export type { HoverCardProps } from "./hover-card.js";
@@ -0,0 +1,2 @@
1
+ export { InputOTP } from "./input-otp.js";
2
+ export type { InputOTPProps } from "./input-otp.js";
@@ -0,0 +1,176 @@
1
+ import React, { useState, useCallback } from "react";
2
+ import { Box, Text, useInput } from "ink";
3
+ import type { Tokens } from "@hauktui/tokens";
4
+ import { useTokens, useFocusable } from "@hauktui/primitives-ink";
5
+ import { stableId } from "@hauktui/core";
6
+
7
+ export interface InputOTPProps {
8
+ /** Number of OTP digits */
9
+ length?: number;
10
+ /** Controlled value */
11
+ value?: string;
12
+ /** Callback when value changes */
13
+ onChange?: (value: string) => void;
14
+ /** Callback when all digits are filled */
15
+ onComplete?: (value: string) => void;
16
+ /** Whether to mask the input */
17
+ mask?: boolean;
18
+ /** Mask character */
19
+ maskChar?: string;
20
+ /** Whether the input is disabled */
21
+ disabled?: boolean;
22
+ /** Custom tokens override */
23
+ tokens?: Tokens;
24
+ /** Focus ID for focus management */
25
+ focusId?: string;
26
+ /** Label text */
27
+ label?: string;
28
+ /** Separator between groups */
29
+ separator?: string;
30
+ /** Group size (for visual grouping) */
31
+ groupSize?: number;
32
+ }
33
+
34
+ export function InputOTP({
35
+ length = 6,
36
+ value: controlledValue,
37
+ onChange,
38
+ onComplete,
39
+ mask = false,
40
+ maskChar = "●",
41
+ disabled = false,
42
+ tokens: propTokens,
43
+ focusId,
44
+ label,
45
+ separator = "-",
46
+ groupSize = 3,
47
+ }: InputOTPProps): React.ReactElement {
48
+ const contextTokens = useTokens();
49
+ const tokens = propTokens ?? contextTokens;
50
+ const id = focusId ?? stableId("input-otp");
51
+ const { isFocused } = useFocusable(id);
52
+
53
+ const [internalValue, setInternalValue] = useState("");
54
+ const isControlled = controlledValue !== undefined;
55
+ const currentValue = isControlled ? controlledValue : internalValue;
56
+
57
+ const updateValue = useCallback(
58
+ (newValue: string) => {
59
+ // Only allow digits
60
+ const digits = newValue.replace(/\D/g, "").slice(0, length);
61
+
62
+ if (!isControlled) {
63
+ setInternalValue(digits);
64
+ }
65
+ onChange?.(digits);
66
+
67
+ if (digits.length === length) {
68
+ onComplete?.(digits);
69
+ }
70
+ },
71
+ [isControlled, length, onChange, onComplete]
72
+ );
73
+
74
+ useInput(
75
+ (input, key) => {
76
+ if (!isFocused || disabled) return;
77
+
78
+ if (key.backspace || key.delete) {
79
+ updateValue(currentValue.slice(0, -1));
80
+ } else if (/^\d$/.test(input)) {
81
+ updateValue(currentValue + input);
82
+ }
83
+ },
84
+ { isActive: isFocused }
85
+ );
86
+
87
+ // Render OTP boxes
88
+ const renderBoxes = () => {
89
+ const boxes: React.ReactElement[] = [];
90
+
91
+ for (let i = 0; i < length; i++) {
92
+ const char = currentValue[i];
93
+ const isCursor = i === currentValue.length && isFocused;
94
+ const isFilled = char !== undefined;
95
+
96
+ // Add separator between groups
97
+ if (i > 0 && groupSize > 0 && i % groupSize === 0) {
98
+ boxes.push(
99
+ React.createElement(
100
+ Text,
101
+ { key: `sep-${i}`, color: tokens.colors.muted },
102
+ ` ${separator} `
103
+ )
104
+ );
105
+ }
106
+
107
+ const displayChar = isFilled
108
+ ? mask
109
+ ? maskChar
110
+ : char
111
+ : isCursor
112
+ ? "▎"
113
+ : " ";
114
+
115
+ boxes.push(
116
+ React.createElement(
117
+ Box,
118
+ {
119
+ key: i,
120
+ borderStyle: "single",
121
+ borderColor: isCursor
122
+ ? tokens.colors.focus
123
+ : isFilled
124
+ ? tokens.colors.accent
125
+ : tokens.colors.border,
126
+ paddingX: 1,
127
+ },
128
+ React.createElement(
129
+ Text,
130
+ {
131
+ color: isCursor
132
+ ? tokens.colors.focus
133
+ : isFilled
134
+ ? tokens.colors.fg
135
+ : tokens.colors.muted,
136
+ bold: isFilled,
137
+ },
138
+ displayChar
139
+ )
140
+ )
141
+ );
142
+ }
143
+
144
+ return boxes;
145
+ };
146
+
147
+ return React.createElement(
148
+ Box,
149
+ { flexDirection: "column" },
150
+ // Label
151
+ label
152
+ ? React.createElement(
153
+ Text,
154
+ { color: tokens.colors.fg, bold: true },
155
+ label
156
+ )
157
+ : null,
158
+ // OTP boxes
159
+ React.createElement(
160
+ Box,
161
+ {
162
+ gap: 0,
163
+ borderStyle: isFocused ? "round" : undefined,
164
+ borderColor: isFocused ? tokens.colors.focus : undefined,
165
+ paddingX: isFocused ? 1 : 0,
166
+ },
167
+ ...renderBoxes()
168
+ ),
169
+ // Status
170
+ React.createElement(
171
+ Text,
172
+ { color: tokens.colors.muted, dimColor: true },
173
+ `${currentValue.length}/${length} digits`
174
+ )
175
+ );
176
+ }
@@ -0,0 +1,2 @@
1
+ export { Kbd } from "./kbd.js";
2
+ export type { KbdProps } from "./kbd.js";
@@ -0,0 +1,30 @@
1
+ import React from "react";
2
+ import { Text } from "ink";
3
+ import type { Tokens } from "@hauktui/tokens";
4
+ import { useTokens } from "@hauktui/primitives-ink";
5
+
6
+ export interface KbdProps {
7
+ /** Key or key combination to display */
8
+ children: React.ReactNode;
9
+ /** Custom tokens override */
10
+ tokens?: Tokens;
11
+ }
12
+
13
+ export function Kbd({
14
+ children,
15
+ tokens: propTokens,
16
+ }: KbdProps): React.ReactElement {
17
+ const contextTokens = useTokens();
18
+ const tokens = propTokens ?? contextTokens;
19
+
20
+ return React.createElement(
21
+ Text,
22
+ {
23
+ backgroundColor: tokens.colors.border,
24
+ color: tokens.colors.fg,
25
+ },
26
+ " ",
27
+ children,
28
+ " "
29
+ );
30
+ }
@@ -0,0 +1,2 @@
1
+ export { Label } from "./label.js";
2
+ export type { LabelProps } from "./label.js";
@@ -0,0 +1,56 @@
1
+ import React from "react";
2
+ import { Box, Text } from "ink";
3
+ import type { Tokens } from "@hauktui/tokens";
4
+ import { useTokens } from "@hauktui/primitives-ink";
5
+
6
+ export interface LabelProps {
7
+ /** Label text */
8
+ children: React.ReactNode;
9
+ /** Whether the associated field is required */
10
+ required?: boolean;
11
+ /** Custom tokens override */
12
+ tokens?: Tokens;
13
+ /** Label position relative to its content */
14
+ position?: "top" | "left";
15
+ /** Description text below the label */
16
+ description?: string;
17
+ }
18
+
19
+ export function Label({
20
+ children,
21
+ required = false,
22
+ tokens: propTokens,
23
+ position = "top",
24
+ description,
25
+ }: LabelProps): React.ReactElement {
26
+ const contextTokens = useTokens();
27
+ const tokens = propTokens ?? contextTokens;
28
+
29
+ const labelContent = React.createElement(
30
+ Box,
31
+ { gap: 0 },
32
+ React.createElement(
33
+ Text,
34
+ { color: tokens.colors.fg, bold: true },
35
+ children
36
+ ),
37
+ required
38
+ ? React.createElement(Text, { color: tokens.colors.danger }, " *")
39
+ : null
40
+ );
41
+
42
+ if (description) {
43
+ return React.createElement(
44
+ Box,
45
+ { flexDirection: "column" },
46
+ labelContent,
47
+ React.createElement(
48
+ Text,
49
+ { color: tokens.colors.muted, dimColor: true },
50
+ description
51
+ )
52
+ );
53
+ }
54
+
55
+ return labelContent;
56
+ }
@@ -0,0 +1,2 @@
1
+ export { List } from "./list.js";
2
+ export type { ListProps, ListItem } from "./list.js";