@ctrl-ui/react 0.8.18 → 0.8.20

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 (106) hide show
  1. package/README.md +7 -0
  2. package/dist/action-bar.js +2 -2
  3. package/dist/audio-device-select.js +5 -2
  4. package/dist/blocks/coding-agent.js +22 -12
  5. package/dist/blocks/design-canvas-inspector.js +6 -3
  6. package/dist/blocks/design-canvas.js +20 -10
  7. package/dist/blocks/discussion-markdown-input.d.ts +14 -0
  8. package/dist/blocks/discussion-markdown-input.js +36 -0
  9. package/dist/blocks/discussion.d.ts +9 -3
  10. package/dist/blocks/discussion.js +82 -16
  11. package/dist/blocks/file-explorer.js +46 -24
  12. package/dist/blocks/settings.js +10 -6
  13. package/dist/chat-composer-editor/extensions/mention.d.ts +1 -1
  14. package/dist/chat-message.d.ts +13 -0
  15. package/dist/chat-message.js +198 -3
  16. package/dist/filter-bar/editor.js +5 -2
  17. package/dist/knob-contracts/flow-knobs.d.ts +4 -0
  18. package/dist/knob-contracts/flow-knobs.js +32 -0
  19. package/dist/knob-contracts/item-knobs.d.ts +1 -1
  20. package/dist/knob-contracts/item-knobs.js +4 -1
  21. package/dist/knob-contracts/label-knobs.d.ts +4 -0
  22. package/dist/knob-contracts/label-knobs.js +4 -0
  23. package/dist/knob-contracts/markdown-editor-knobs.d.ts +4 -0
  24. package/dist/knob-contracts/markdown-editor-knobs.js +17 -0
  25. package/dist/knob-contracts/morphing-panel-knobs.d.ts +1 -1
  26. package/dist/knob-contracts/morphing-panel-knobs.js +2 -1
  27. package/dist/knob-contracts/resize-handle-knobs.d.ts +4 -0
  28. package/dist/knob-contracts/resize-handle-knobs.js +12 -0
  29. package/dist/knob-contracts/sidebar-knobs.d.ts +1 -1
  30. package/dist/knob-contracts/sidebar-knobs.js +10 -0
  31. package/dist/knob-contracts/switch-knobs.d.ts +1 -1
  32. package/dist/knob-contracts/switch-knobs.js +1 -0
  33. package/dist/lib/canvas-grid.d.ts +4 -0
  34. package/dist/lib/canvas-grid.js +5 -0
  35. package/dist/markdown-editor/context.d.ts +22 -0
  36. package/dist/markdown-editor/context.js +10 -0
  37. package/dist/markdown-editor/drag-handle.d.ts +6 -0
  38. package/dist/markdown-editor/drag-handle.js +126 -0
  39. package/dist/markdown-editor/extensions.d.ts +10 -0
  40. package/dist/markdown-editor/extensions.js +139 -0
  41. package/dist/markdown-editor/suggestions.d.ts +12 -0
  42. package/dist/markdown-editor/suggestions.js +235 -0
  43. package/dist/markdown-editor/toolbar.d.ts +9 -0
  44. package/dist/markdown-editor/toolbar.js +339 -0
  45. package/dist/markdown-editor/uploads.d.ts +23 -0
  46. package/dist/markdown-editor/uploads.js +32 -0
  47. package/dist/markdown-editor/use-image-uploads.d.ts +12 -0
  48. package/dist/markdown-editor/use-image-uploads.js +120 -0
  49. package/dist/markdown-editor.d.ts +27 -0
  50. package/dist/markdown-editor.js +202 -0
  51. package/dist/styles/index.css +9 -4
  52. package/dist/styles/recipes/chat-message-edit.css +105 -0
  53. package/dist/styles/recipes/code.css +4 -0
  54. package/dist/styles/recipes/field.css +1 -1
  55. package/dist/styles/recipes/flow.css +304 -0
  56. package/dist/styles/recipes/infinite-canvas.css +1 -1
  57. package/dist/styles/recipes/item.css +39 -2
  58. package/dist/styles/recipes/label.css +19 -0
  59. package/dist/styles/recipes/markdown-editor.css +234 -0
  60. package/dist/styles/recipes/morphing-panel.css +53 -12
  61. package/dist/styles/recipes/page-layout.css +11 -1
  62. package/dist/styles/recipes/resize-handle.css +126 -0
  63. package/dist/styles/recipes/sidebar-mobile.css +171 -0
  64. package/dist/styles/recipes/switch.css +17 -5
  65. package/dist/styles/recipes/toolbar.css +8 -1
  66. package/dist/styles/theme.css +1 -0
  67. package/dist/ui/autocomplete.js +1 -1
  68. package/dist/ui/code.js +1 -0
  69. package/dist/ui/color-picker.js +1 -1
  70. package/dist/ui/combobox.d.ts +1 -1
  71. package/dist/ui/combobox.js +1 -1
  72. package/dist/ui/dockable-panel.js +1 -1
  73. package/dist/ui/flow.d.ts +51 -0
  74. package/dist/ui/flow.js +153 -0
  75. package/dist/ui/infinite-canvas.js +3 -3
  76. package/dist/ui/item.d.ts +5 -3
  77. package/dist/ui/item.js +2 -1
  78. package/dist/ui/label.d.ts +8 -0
  79. package/dist/ui/label.js +14 -0
  80. package/dist/ui/markdown.d.ts +2 -1
  81. package/dist/ui/markdown.js +3 -3
  82. package/dist/ui/morphing-panel.d.ts +21 -4
  83. package/dist/ui/morphing-panel.js +152 -36
  84. package/dist/ui/resize-handle.d.ts +11 -0
  85. package/dist/ui/resize-handle.js +26 -0
  86. package/dist/ui/sidebar-mobile.d.ts +17 -0
  87. package/dist/ui/sidebar-mobile.js +70 -0
  88. package/dist/ui/sidebar-provider.d.ts +1 -0
  89. package/dist/ui/sidebar-provider.js +3 -0
  90. package/dist/ui/sidebar.d.ts +3 -1
  91. package/dist/ui/sidebar.js +101 -49
  92. package/dist/ui/toolbar.d.ts +3 -1
  93. package/dist/ui/toolbar.js +2 -1
  94. package/dist/ui/typography.d.ts +47 -0
  95. package/dist/ui/typography.js +61 -0
  96. package/dist/ui/use-switch-drag.js +1 -1
  97. package/package.json +41 -1
  98. package/dist/environment-variables.d.ts +0 -125
  99. package/dist/environment-variables.js +0 -512
  100. package/dist/hooks/use-environment-variables.d.ts +0 -50
  101. package/dist/hooks/use-environment-variables.js +0 -188
  102. package/dist/knob-contracts/environment-variables-knobs.d.ts +0 -4
  103. package/dist/knob-contracts/environment-variables-knobs.js +0 -12
  104. package/dist/lib/env-file.d.ts +0 -27
  105. package/dist/lib/env-file.js +0 -218
  106. package/dist/styles/recipes/environment-variables.css +0 -170
@@ -1,512 +0,0 @@
1
- "use client";
2
- import { cn } from "./lib/cn.js";
3
- import { Button } from "./ui/button.js";
4
- import { DUPLICATE_ENVIRONMENT_VARIABLE_MESSAGE, collectEnvironmentVariables, rowsToEnvFileText } from "./lib/env-file.js";
5
- import { useEnvironmentVariables } from "./hooks/use-environment-variables.js";
6
- import { InputGroup, InputGroupAddon } from "./ui/input-group.js";
7
- import { Input } from "./ui/input.js";
8
- import { createContext, use, useId, useRef, useState } from "react";
9
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
- import { AlertTriangleIcon, EyeIcon, EyeOffIcon, FileUpIcon, PlusIcon, RotateCcwIcon, SaveIcon, Trash2Icon } from "lucide-react";
11
- //#region src/environment-variables.tsx
12
- const EnvironmentVariablesContext = createContext(null);
13
- function useEnvironmentVariablesContext(componentName) {
14
- const context = use(EnvironmentVariablesContext);
15
- if (!context) throw new Error(`${componentName} must be used inside <EnvironmentVariables.Root>.`);
16
- return context;
17
- }
18
- function EnvironmentVariablesRoot({ editor, disabled = false, readOnly = false, rowErrors, keyLabel = "Key", valueLabel = "Value", keyPlaceholder = "OPENAI_API_KEY", valuePlaceholder = "sk-…", duplicateKeyMessage = DUPLICATE_ENVIRONMENT_VARIABLE_MESSAGE, revealValueLabel = (key) => `Show value for ${key}`, onSubmit, className, children, ...props }) {
19
- const pendingRef = useRef(false);
20
- const [pending, setPending] = useState(false);
21
- async function handleSubmit(event) {
22
- if (event.defaultPrevented || !onSubmit) return;
23
- event.preventDefault();
24
- if (pendingRef.current || editor.hasDuplicateKeys) return;
25
- const rows = editor.getRowsForSubmit();
26
- const payload = {
27
- rows,
28
- variables: collectEnvironmentVariables(rows),
29
- envFileText: rowsToEnvFileText(rows),
30
- reset: () => editor.resetRows(rows)
31
- };
32
- pendingRef.current = true;
33
- setPending(true);
34
- try {
35
- await onSubmit(payload);
36
- } finally {
37
- pendingRef.current = false;
38
- setPending(false);
39
- }
40
- }
41
- return /* @__PURE__ */ jsx(EnvironmentVariablesContext.Provider, {
42
- value: {
43
- editor,
44
- disabled,
45
- readOnly,
46
- rowErrors,
47
- keyLabel,
48
- valueLabel,
49
- keyPlaceholder,
50
- valuePlaceholder,
51
- duplicateKeyMessage,
52
- revealValueLabel,
53
- pending
54
- },
55
- children: /* @__PURE__ */ jsx("form", {
56
- "data-control-ui": "environment-variables",
57
- "data-control-family": "environment-variables",
58
- "data-slot": "root",
59
- "data-surface": "panel",
60
- "data-disabled": disabled ? "true" : void 0,
61
- "data-readonly": readOnly ? "true" : void 0,
62
- "aria-busy": pending || void 0,
63
- className: cn("flex min-w-0 flex-col", className),
64
- onSubmit: handleSubmit,
65
- ...props,
66
- children
67
- })
68
- });
69
- }
70
- function EnvironmentVariablesComponent({ editor: providedEditor, initialRows, rows, onRowsChange, createDefaultRow, createRow, getEditableRows, getPreservedRows, maxUploadSize, title = "Environment variables", description, error, submitLabel = "Save", resetLabel = "Reset", addLabel = "Add variable", hideDefaultActions = false, children, onSubmit, ...props }) {
71
- const internalEditor = useEnvironmentVariables({
72
- initialRows,
73
- rows,
74
- onRowsChange,
75
- createDefaultRow,
76
- createRow,
77
- getEditableRows,
78
- getPreservedRows,
79
- maxUploadSize
80
- });
81
- return /* @__PURE__ */ jsx(EnvironmentVariablesRoot, {
82
- editor: providedEditor ?? internalEditor,
83
- onSubmit,
84
- ...props,
85
- children: children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [
86
- /* @__PURE__ */ jsx(EnvironmentVariablesHeader, {
87
- title,
88
- description
89
- }),
90
- /* @__PURE__ */ jsx(EnvironmentVariablesToolbar, {}),
91
- /* @__PURE__ */ jsx(EnvironmentVariablesUploadError, {}),
92
- /* @__PURE__ */ jsx(EnvironmentVariablesRows, {}),
93
- /* @__PURE__ */ jsx(EnvironmentVariablesDuplicateKeysError, {}),
94
- /* @__PURE__ */ jsx(EnvironmentVariablesMessage, { error }),
95
- !hideDefaultActions && /* @__PURE__ */ jsxs(EnvironmentVariablesActions, { children: [/* @__PURE__ */ jsx(EnvironmentVariablesAddButton, { children: addLabel }), /* @__PURE__ */ jsxs("div", {
96
- className: "flex min-w-0 items-center",
97
- children: [/* @__PURE__ */ jsx(EnvironmentVariablesResetButton, { children: resetLabel }), onSubmit ? /* @__PURE__ */ jsx(EnvironmentVariablesSubmitButton, { children: submitLabel }) : null]
98
- })] })
99
- ] })
100
- });
101
- }
102
- function EnvironmentVariablesHeader({ title, description, className, children, ...props }) {
103
- if (children) return /* @__PURE__ */ jsx("div", {
104
- "data-control-ui": "environment-variables",
105
- "data-control-family": "environment-variables",
106
- "data-slot": "header",
107
- className: cn("flex flex-col", className),
108
- ...props,
109
- children
110
- });
111
- if (!title && !description) return null;
112
- return /* @__PURE__ */ jsxs("div", {
113
- "data-control-ui": "environment-variables",
114
- "data-control-family": "environment-variables",
115
- "data-slot": "header",
116
- className: cn("flex flex-col", className),
117
- ...props,
118
- children: [title ? /* @__PURE__ */ jsx("div", {
119
- "data-control-ui": "environment-variables",
120
- "data-control-family": "environment-variables",
121
- "data-slot": "title",
122
- children: title
123
- }) : null, description ? /* @__PURE__ */ jsx("div", {
124
- "data-control-ui": "environment-variables",
125
- "data-control-family": "environment-variables",
126
- "data-slot": "description",
127
- className: "max-w-2xl",
128
- children: description
129
- }) : null]
130
- });
131
- }
132
- function EnvironmentVariablesToolbar({ className, children, ...props }) {
133
- const { readOnly } = useEnvironmentVariablesContext("EnvironmentVariables.Toolbar");
134
- if (readOnly) return null;
135
- return /* @__PURE__ */ jsx("div", {
136
- "data-control-ui": "environment-variables",
137
- "data-control-family": "environment-variables",
138
- "data-slot": "toolbar",
139
- className: cn("flex min-w-0 flex-col sm:flex-row sm:items-center", className),
140
- ...props,
141
- children: children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("p", {
142
- "data-control-ui": "environment-variables",
143
- "data-control-family": "environment-variables",
144
- "data-slot": "hint",
145
- className: "min-w-0 flex-1",
146
- children: [
147
- "Paste one or more",
148
- " ",
149
- /* @__PURE__ */ jsx("code", {
150
- "data-control-ui": "environment-variables",
151
- "data-control-family": "environment-variables",
152
- "data-slot": "hint-code",
153
- children: "KEY=value"
154
- }),
155
- " ",
156
- "lines directly into any field."
157
- ]
158
- }), /* @__PURE__ */ jsx(EnvironmentVariablesUploadButton, {})] })
159
- });
160
- }
161
- function EnvironmentVariablesUploadButton({ inputLabel = "Import .env file", children = "Upload .env", variant = "surface", size = "sm", disabled, onClick, ...props }) {
162
- const { editor, disabled: contextDisabled, readOnly } = useEnvironmentVariablesContext("EnvironmentVariables.UploadButton");
163
- const inputId = useId();
164
- const isDisabled = disabled ?? (contextDisabled || readOnly);
165
- function handleChange(event) {
166
- editor.handleFileUpload(event);
167
- }
168
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("input", {
169
- id: inputId,
170
- type: "file",
171
- accept: ".env,text/plain",
172
- className: "sr-only",
173
- tabIndex: -1,
174
- disabled: isDisabled,
175
- "aria-label": inputLabel,
176
- onChange: handleChange
177
- }), /* @__PURE__ */ jsxs(Button, {
178
- type: "button",
179
- variant,
180
- size,
181
- disabled: isDisabled,
182
- onClick: (event) => {
183
- onClick?.(event);
184
- if (!event.defaultPrevented) event.currentTarget.ownerDocument.getElementById(inputId)?.click();
185
- },
186
- ...props,
187
- children: [/* @__PURE__ */ jsx(FileUpIcon, {
188
- "aria-hidden": "true",
189
- className: "size-3.5"
190
- }), children]
191
- })] });
192
- }
193
- function EnvironmentVariablesRows({ rowErrors, className, children, ...props }) {
194
- const { editor, keyLabel, valueLabel, readOnly } = useEnvironmentVariablesContext("EnvironmentVariables.Rows");
195
- return /* @__PURE__ */ jsx("div", {
196
- "data-control-ui": "environment-variables",
197
- "data-control-family": "environment-variables",
198
- "data-slot": "rows",
199
- className: cn("min-w-0", className),
200
- ...props,
201
- children: children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
202
- "aria-hidden": "true",
203
- "data-control-ui": "environment-variables",
204
- "data-control-family": "environment-variables",
205
- "data-slot": "column-labels",
206
- className: cn("hidden min-w-0 grid-cols-[minmax(0,1fr)_minmax(0,1.2fr)_auto] sm:grid", readOnly && "grid-cols-[minmax(0,1fr)_minmax(0,1.2fr)]"),
207
- children: [
208
- /* @__PURE__ */ jsx("span", { children: keyLabel }),
209
- /* @__PURE__ */ jsx("span", { children: valueLabel }),
210
- !readOnly ? /* @__PURE__ */ jsx("span", { className: "size-[var(--control-h-sm)]" }) : null
211
- ]
212
- }), editor.rows.map((row, index) => /* @__PURE__ */ jsx(EnvironmentVariablesRow, {
213
- row,
214
- index,
215
- rowErrors
216
- }, editor.getRowId(index)))] })
217
- });
218
- }
219
- function EnvironmentVariablesRow({ row, index, rowErrors, className, ...props }) {
220
- const { editor, disabled, readOnly, rowErrors: contextRowErrors, keyLabel, valueLabel, keyPlaceholder, valuePlaceholder, duplicateKeyMessage, revealValueLabel } = useEnvironmentVariablesContext("EnvironmentVariables.Row");
221
- const resolvedRowErrors = rowErrors ?? contextRowErrors;
222
- const keyError = resolvedRowErrors?.[index]?.key ?? (editor.rowHasDuplicateKey(index) ? duplicateKeyMessage : null);
223
- const valueError = resolvedRowErrors?.[index]?.value;
224
- const isDisabled = disabled || readOnly;
225
- const rowId = editor.getRowId(index);
226
- const keyInputId = `${rowId}-key`;
227
- const valueInputId = `${rowId}-value`;
228
- const keyErrorId = `${keyInputId}-error`;
229
- const valueErrorId = `${valueInputId}-error`;
230
- const rowName = row.key.trim() || `row ${index + 1}`;
231
- const valueRevealed = editor.isValueRevealed(index);
232
- const removeRowLabel = `Remove environment variable ${rowName}`;
233
- function handlePaste(event) {
234
- if (editor.handlePaste(index, event.clipboardData.getData("text"))) event.preventDefault();
235
- }
236
- return /* @__PURE__ */ jsxs("div", {
237
- "data-control-ui": "environment-variables",
238
- "data-control-family": "environment-variables",
239
- "data-slot": "row",
240
- className: cn("relative grid min-w-0 sm:grid-cols-[minmax(0,1fr)_minmax(0,1.2fr)_auto]", className),
241
- ...props,
242
- children: [
243
- /* @__PURE__ */ jsxs("div", {
244
- className: "flex min-w-0 flex-col",
245
- children: [
246
- /* @__PURE__ */ jsx("label", {
247
- "data-control-ui": "environment-variables",
248
- "data-control-family": "environment-variables",
249
- "data-slot": "field-label",
250
- htmlFor: keyInputId,
251
- className: "sm:sr-only",
252
- children: keyLabel
253
- }),
254
- /* @__PURE__ */ jsx(Input, {
255
- id: keyInputId,
256
- size: "sm",
257
- value: row.key,
258
- placeholder: keyPlaceholder,
259
- disabled: isDisabled,
260
- "aria-invalid": Boolean(keyError),
261
- "aria-describedby": keyError ? keyErrorId : void 0,
262
- onChange: (event) => editor.updateRow(index, { key: event.target.value }),
263
- onPaste: handlePaste
264
- }),
265
- keyError ? /* @__PURE__ */ jsx("p", {
266
- id: keyErrorId,
267
- "data-control-ui": "environment-variables",
268
- "data-control-family": "environment-variables",
269
- "data-slot": "field-error",
270
- children: keyError
271
- }) : null
272
- ]
273
- }),
274
- /* @__PURE__ */ jsxs("div", {
275
- className: "flex min-w-0 flex-col",
276
- children: [
277
- /* @__PURE__ */ jsx("label", {
278
- "data-control-ui": "environment-variables",
279
- "data-control-family": "environment-variables",
280
- "data-slot": "field-label",
281
- htmlFor: valueInputId,
282
- className: "sm:sr-only",
283
- children: valueLabel
284
- }),
285
- /* @__PURE__ */ jsxs(InputGroup, {
286
- size: "sm",
287
- children: [/* @__PURE__ */ jsx(Input, {
288
- id: valueInputId,
289
- value: row.value,
290
- placeholder: valuePlaceholder,
291
- disabled: isDisabled,
292
- "aria-invalid": Boolean(valueError),
293
- "aria-describedby": valueError ? valueErrorId : void 0,
294
- type: valueRevealed ? "text" : "password",
295
- onChange: (event) => editor.updateRow(index, { value: event.target.value }),
296
- onPaste: handlePaste
297
- }), /* @__PURE__ */ jsx(InputGroupAddon, {
298
- className: "pe-1",
299
- children: /* @__PURE__ */ jsx(Button, {
300
- type: "button",
301
- variant: "quiet",
302
- size: "sm",
303
- iconOnly: true,
304
- disabled: isDisabled,
305
- "aria-label": revealValueLabel(rowName),
306
- "aria-pressed": valueRevealed,
307
- title: revealValueLabel(rowName),
308
- onClick: () => editor.toggleValueVisibility(index),
309
- children: valueRevealed ? /* @__PURE__ */ jsx(EyeOffIcon, {
310
- "aria-hidden": "true",
311
- className: "size-3.5"
312
- }) : /* @__PURE__ */ jsx(EyeIcon, {
313
- "aria-hidden": "true",
314
- className: "size-3.5"
315
- })
316
- })
317
- })]
318
- }),
319
- valueError ? /* @__PURE__ */ jsx("p", {
320
- id: valueErrorId,
321
- "data-control-ui": "environment-variables",
322
- "data-control-family": "environment-variables",
323
- "data-slot": "field-error",
324
- children: valueError
325
- }) : null
326
- ]
327
- }),
328
- !readOnly ? /* @__PURE__ */ jsx(Button, {
329
- type: "button",
330
- variant: "quiet",
331
- tone: "danger",
332
- size: "sm",
333
- iconOnly: true,
334
- disabled,
335
- "aria-label": removeRowLabel,
336
- title: "Remove variable",
337
- className: "absolute top-2 end-1 sm:static sm:justify-self-end sm:self-start",
338
- onClick: () => editor.removeRow(index),
339
- children: /* @__PURE__ */ jsx(Trash2Icon, {
340
- "aria-hidden": "true",
341
- className: "size-3.5"
342
- })
343
- }) : null
344
- ]
345
- });
346
- }
347
- function EnvironmentVariablesAddButton({ children = "Add variable", variant = "surface", size = "sm", disabled, onClick, ...props }) {
348
- const { editor, disabled: contextDisabled, readOnly } = useEnvironmentVariablesContext("EnvironmentVariables.AddButton");
349
- if (readOnly) return null;
350
- return /* @__PURE__ */ jsxs(Button, {
351
- type: "button",
352
- variant,
353
- size,
354
- disabled: disabled ?? contextDisabled,
355
- onClick: (event) => {
356
- onClick?.(event);
357
- if (!event.defaultPrevented) editor.appendRow();
358
- },
359
- ...props,
360
- children: [/* @__PURE__ */ jsx(PlusIcon, {
361
- "aria-hidden": "true",
362
- className: "size-3.5"
363
- }), children]
364
- });
365
- }
366
- function EnvironmentVariablesResetButton({ children = "Reset", variant = "quiet", size = "sm", disabled, onClick, ...props }) {
367
- const { editor, disabled: contextDisabled, readOnly } = useEnvironmentVariablesContext("EnvironmentVariables.ResetButton");
368
- if (readOnly) return null;
369
- return /* @__PURE__ */ jsxs(Button, {
370
- type: "button",
371
- variant,
372
- size,
373
- disabled: disabled ?? (contextDisabled || !editor.isDirty),
374
- onClick: (event) => {
375
- onClick?.(event);
376
- if (!event.defaultPrevented) editor.resetRows();
377
- },
378
- ...props,
379
- children: [/* @__PURE__ */ jsx(RotateCcwIcon, {
380
- "aria-hidden": "true",
381
- className: "size-3.5"
382
- }), children]
383
- });
384
- }
385
- function EnvironmentVariablesSubmitButton({ children = "Save", variant = "solid", tone = "primary", size = "sm", disabled, ...props }) {
386
- const { editor, disabled: contextDisabled, readOnly, pending } = useEnvironmentVariablesContext("EnvironmentVariables.SubmitButton");
387
- if (readOnly) return null;
388
- return /* @__PURE__ */ jsxs(Button, {
389
- type: "submit",
390
- variant,
391
- tone,
392
- size,
393
- disabled: disabled ?? (contextDisabled || pending || editor.hasDuplicateKeys),
394
- ...props,
395
- children: [/* @__PURE__ */ jsx(SaveIcon, {
396
- "aria-hidden": "true",
397
- className: "size-3.5"
398
- }), children]
399
- });
400
- }
401
- function EnvironmentVariablesActions({ className, ...props }) {
402
- return /* @__PURE__ */ jsx("div", {
403
- "data-control-ui": "environment-variables",
404
- "data-control-family": "environment-variables",
405
- "data-slot": "actions",
406
- className: cn("flex min-w-0 items-center justify-between", className),
407
- ...props
408
- });
409
- }
410
- function EnvironmentVariablesMessage({ error, className, children, ...props }) {
411
- const content = children ?? error;
412
- if (!content) return null;
413
- return /* @__PURE__ */ jsxs("div", {
414
- role: "alert",
415
- "data-control-ui": "environment-variables",
416
- "data-control-family": "environment-variables",
417
- "data-slot": "message",
418
- className: cn("flex items-start", className),
419
- ...props,
420
- children: [/* @__PURE__ */ jsx(AlertTriangleIcon, {
421
- "aria-hidden": "true",
422
- className: "mt-0.5 size-3.5 shrink-0"
423
- }), /* @__PURE__ */ jsx("span", {
424
- className: "min-w-0",
425
- children: content
426
- })]
427
- });
428
- }
429
- function EnvironmentVariablesDuplicateKeysError({ message, ...props }) {
430
- const { editor, duplicateKeyMessage } = useEnvironmentVariablesContext("EnvironmentVariables.DuplicateKeysError");
431
- if (!editor.hasDuplicateKeys) return null;
432
- return /* @__PURE__ */ jsx(EnvironmentVariablesMessage, {
433
- error: message ?? duplicateKeyMessage,
434
- ...props
435
- });
436
- }
437
- function EnvironmentVariablesUploadError(props) {
438
- const { editor } = useEnvironmentVariablesContext("EnvironmentVariables.UploadError");
439
- return /* @__PURE__ */ jsx(EnvironmentVariablesMessage, {
440
- error: editor.uploadError,
441
- ...props
442
- });
443
- }
444
- function EnvironmentVariablesReadOnlyList({ rows, emptyMessage = "No environment variables", className, children, ...props }) {
445
- const context = use(EnvironmentVariablesContext);
446
- const filledRows = (rows ?? context?.editor.rows ?? []).filter((row) => row.key.trim());
447
- return /* @__PURE__ */ jsx("div", {
448
- "data-control-ui": "environment-variables",
449
- "data-control-family": "environment-variables",
450
- "data-slot": "readonly-list",
451
- className: cn("flex flex-col", className),
452
- ...props,
453
- children: children ?? (filledRows.length > 0 ? filledRows.map((row) => /* @__PURE__ */ jsx(EnvironmentVariablesReadOnlyItem, {
454
- name: row.key,
455
- value: row.value
456
- }, row.key)) : /* @__PURE__ */ jsx("div", {
457
- "data-control-ui": "environment-variables",
458
- "data-control-family": "environment-variables",
459
- "data-slot": "empty",
460
- children: emptyMessage
461
- }))
462
- });
463
- }
464
- function EnvironmentVariablesReadOnlyItem({ name, value, revealed = false, hiddenValueLabel = "Hidden value", className, ...props }) {
465
- return /* @__PURE__ */ jsxs("div", {
466
- "data-control-ui": "environment-variables",
467
- "data-control-family": "environment-variables",
468
- "data-slot": "readonly-item",
469
- className: cn("grid min-w-0 grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)]", className),
470
- ...props,
471
- children: [/* @__PURE__ */ jsx("span", {
472
- "data-control-ui": "environment-variables",
473
- "data-control-family": "environment-variables",
474
- "data-slot": "readonly-key",
475
- className: "min-w-0 truncate",
476
- title: typeof name === "string" ? name : void 0,
477
- children: name
478
- }), /* @__PURE__ */ jsx("span", {
479
- "data-control-ui": "environment-variables",
480
- "data-control-family": "environment-variables",
481
- "data-slot": "readonly-value",
482
- className: "min-w-0 truncate",
483
- title: revealed && typeof value === "string" ? value : void 0,
484
- children: revealed ? value : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
485
- "aria-hidden": "true",
486
- children: "••••••••"
487
- }), /* @__PURE__ */ jsx("span", {
488
- className: "sr-only",
489
- children: hiddenValueLabel
490
- })] })
491
- })]
492
- });
493
- }
494
- const EnvironmentVariables = Object.assign(EnvironmentVariablesComponent, {
495
- Root: EnvironmentVariablesRoot,
496
- Header: EnvironmentVariablesHeader,
497
- Toolbar: EnvironmentVariablesToolbar,
498
- UploadButton: EnvironmentVariablesUploadButton,
499
- UploadError: EnvironmentVariablesUploadError,
500
- Rows: EnvironmentVariablesRows,
501
- Row: EnvironmentVariablesRow,
502
- AddButton: EnvironmentVariablesAddButton,
503
- ResetButton: EnvironmentVariablesResetButton,
504
- SubmitButton: EnvironmentVariablesSubmitButton,
505
- Actions: EnvironmentVariablesActions,
506
- Message: EnvironmentVariablesMessage,
507
- DuplicateKeysError: EnvironmentVariablesDuplicateKeysError,
508
- ReadOnlyList: EnvironmentVariablesReadOnlyList,
509
- ReadOnlyItem: EnvironmentVariablesReadOnlyItem
510
- });
511
- //#endregion
512
- export { EnvironmentVariables, EnvironmentVariablesActions, EnvironmentVariablesAddButton, EnvironmentVariablesDuplicateKeysError, EnvironmentVariablesHeader, EnvironmentVariablesMessage, EnvironmentVariablesReadOnlyItem, EnvironmentVariablesReadOnlyList, EnvironmentVariablesResetButton, EnvironmentVariablesRoot, EnvironmentVariablesRow, EnvironmentVariablesRows, EnvironmentVariablesSubmitButton, EnvironmentVariablesToolbar, EnvironmentVariablesUploadButton, EnvironmentVariablesUploadError };
@@ -1,50 +0,0 @@
1
- import { EnvironmentVariableEntry } from "../lib/env-file.js";
2
- //#region src/hooks/use-environment-variables.d.ts
3
- export type EnvironmentVariableRow = EnvironmentVariableEntry;
4
- export type EnvironmentVariablesImportMode = "auto" | "bulk";
5
- export interface UseEnvironmentVariablesOptions<TRow extends EnvironmentVariableRow = EnvironmentVariableRow> {
6
- initialRows?: readonly TRow[];
7
- rows?: readonly TRow[];
8
- onRowsChange?: (rows: TRow[]) => void;
9
- createDefaultRow?: () => TRow;
10
- createRow?: (entry: EnvironmentVariableEntry) => TRow;
11
- getEditableRows?: (rows: readonly TRow[]) => readonly TRow[];
12
- getPreservedRows?: (rows: readonly TRow[]) => readonly TRow[];
13
- maxUploadSize?: number;
14
- }
15
- export interface EnvironmentVariablesFileUploadEvent {
16
- target: {
17
- files?: FileList | readonly File[] | null;
18
- value: string;
19
- };
20
- }
21
- export interface EnvironmentVariablesImportOptions {
22
- targetIndex?: number;
23
- mode?: EnvironmentVariablesImportMode;
24
- }
25
- export interface EnvironmentVariablesController<TRow extends EnvironmentVariableRow = EnvironmentVariableRow> {
26
- rows: readonly TRow[];
27
- uploadError: string | null;
28
- duplicateKeys: Set<string>;
29
- hasDuplicateKeys: boolean;
30
- isDirty: boolean;
31
- setRows: (rows: readonly TRow[]) => TRow[];
32
- resetRows: (rows?: readonly TRow[]) => TRow[];
33
- appendRow: (row?: TRow) => TRow[];
34
- updateRow: (index: number, patch: Partial<EnvironmentVariableEntry>) => TRow[];
35
- removeRow: (index: number) => TRow[];
36
- getRowsForSubmit: () => TRow[];
37
- getEnvironmentVariablesForSubmit: () => Record<string, string>;
38
- getEnvFileTextForSubmit: () => string;
39
- importText: (text: string, options?: EnvironmentVariablesImportOptions) => boolean;
40
- handleFileUpload: (event: EnvironmentVariablesFileUploadEvent) => Promise<void>;
41
- handlePaste: (index: number, text: string) => boolean;
42
- clearUploadError: () => void;
43
- getRowId: (index: number) => string;
44
- isValueRevealed: (index: number) => boolean;
45
- toggleValueVisibility: (index: number) => void;
46
- rowHasDuplicateKey: (index: number) => boolean;
47
- }
48
- export declare function useEnvironmentVariables<TRow extends EnvironmentVariableRow = EnvironmentVariableRow>(options?: UseEnvironmentVariablesOptions<TRow>): EnvironmentVariablesController<TRow>;
49
- export declare function parseEnvironmentVariablesImportText(text: string, mode?: EnvironmentVariablesImportMode): EnvironmentVariableEntry[];
50
- //#endregion