cursedbelt 5.79.1 → 5.79.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"OtpInput.d.ts","sourceRoot":"","sources":["../../../src/react/components/OtpInput.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,aAAa;IAC5B,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;+DAC2D;IAC3D,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,MAAU,EACV,UAAU,EACV,SAAqB,EACrB,QAAQ,EACR,SAAS,EACT,EAAE,EACF,IAAI,EACJ,YAAY,EAAE,SAAS,EACvB,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,SAAS,GACV,EAAE,aAAa,+BAsGf"}
1
+ {"version":3,"file":"OtpInput.d.ts","sourceRoot":"","sources":["../../../src/react/components/OtpInput.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,aAAa;IAC5B,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;+DAC2D;IAC3D,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,MAAU,EACV,UAAU,EACV,SAAqB,EACrB,QAAQ,EACR,SAAS,EACT,EAAE,EACF,IAAI,EACJ,YAAY,EAAE,SAAS,EACvB,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,SAAS,GACV,EAAE,aAAa,+BA+Gf"}
@@ -31,8 +31,11 @@ export function OtpInput({ value, onChange, length = 6, onComplete, inputMode =
31
31
  refs.current[clamped]?.focus();
32
32
  refs.current[clamped]?.select();
33
33
  };
34
- const handleChange = (index, raw) => {
35
- const clean = sanitize(raw);
34
+ const handleChange = (index, raw, typed) => {
35
+ // A key typed into a box that already holds a character arrives APPENDED to it ("47"),
36
+ // since no box is capped at one: the key is the event's own `data`. An autofill or a
37
+ // replacement carries the whole code in the value.
38
+ const clean = sanitize(typed ?? raw);
36
39
  if (!clean) {
37
40
  // A deletion/clear of this box: drop just this position.
38
41
  if (chars[index])
@@ -40,8 +43,9 @@ export function OtpInput({ value, onChange, length = 6, onComplete, inputMode =
40
43
  return;
41
44
  }
42
45
  // Typing (or autofilling) writes from this box forward, so a multi-char autofill
43
- // or a fast typist never loses characters.
44
- const merged = (chars.slice(0, index).join('') + clean).slice(0, length);
46
+ // or a fast typist never loses characters. The boxes after what was written keep
47
+ // theirs: correcting the third digit of a full code is not retyping the last three.
48
+ const merged = (chars.slice(0, index).join('') + clean + chars.slice(index + clean.length).join('')).slice(0, length);
45
49
  commit(merged);
46
50
  focusBox(index + clean.length);
47
51
  };
@@ -79,6 +83,12 @@ export function OtpInput({ value, onChange, length = 6, onComplete, inputMode =
79
83
  refs.current[i] = el;
80
84
  }, id: i === 0 ? baseId : `${baseId}-${i}`, name: i === 0 ? name : undefined, type: 'text', inputMode: inputMode, autoComplete: i === 0 ? 'one-time-code' : 'off',
81
85
  // biome-ignore lint/a11y/noAutofocus: opt-in via prop; first box only
82
- autoFocus: autoFocus && i === 0, maxLength: 1, disabled: disabled, value: char, "aria-label": ariaLabel ? `${ariaLabel} digit ${i + 1}` : `Digit ${i + 1}`, "aria-invalid": ariaInvalid, "aria-describedby": i === 0 ? ariaDescribedBy : undefined, onChange: (e) => handleChange(i, e.target.value), onKeyDown: (e) => handleKeyDown(i, e), onPaste: (e) => handlePaste(i, e), onFocus: (e) => e.currentTarget.select(), className: BOX_CLASS }, i))) }));
86
+ autoFocus: autoFocus && i === 0,
87
+ // 🔴 Never 1: a browser that honours `maxLength` on autofill (iOS Safari's "From
88
+ // Messages" chip) would hand the code box one digit. `commit` is the limit.
89
+ maxLength: length, disabled: disabled, value: char, "aria-label": ariaLabel ? `${ariaLabel} digit ${i + 1}` : `Digit ${i + 1}`, "aria-invalid": ariaInvalid, "aria-describedby": i === 0 ? ariaDescribedBy : undefined, onChange: (e) => {
90
+ const input = e.nativeEvent;
91
+ handleChange(i, e.target.value, input.inputType === 'insertText' && input.data ? input.data : null);
92
+ }, onKeyDown: (e) => handleKeyDown(i, e), onPaste: (e) => handlePaste(i, e), onFocus: (e) => e.currentTarget.select(), className: BOX_CLASS }, i))) }));
83
93
  }
84
94
  //# sourceMappingURL=OtpInput.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OtpInput.js","sourceRoot":"","sources":["../../../src/react/components/OtpInput.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"OtpInput.js","sourceRoot":"","sources":["../../../src/react/components/OtpInput.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectFieldImpl.d.ts","sourceRoot":"","sources":["../../../src/react/components/SelectFieldImpl.tsx"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,oBAAoB,EAG1B,MAAM,uBAAuB,CAAC;AAE/B;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,KAAK,EACL,aAAa,EACb,OAAY,EACZ,MAAW,EACX,WAAuB,EACvB,QAAQ,EACR,UAAiB,EACjB,IAAW,EACX,EAAE,EACF,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,UAAU,EACV,SAAS,EACT,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,WAAmB,EACnB,YAAoB,GACrB,EAAE,oBAAoB,+BAgGtB"}
1
+ {"version":3,"file":"SelectFieldImpl.d.ts","sourceRoot":"","sources":["../../../src/react/components/SelectFieldImpl.tsx"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,oBAAoB,EAG1B,MAAM,uBAAuB,CAAC;AAE/B;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,KAAK,EACL,aAAa,EACb,OAAY,EACZ,MAAW,EACX,WAAuB,EACvB,QAAQ,EACR,UAAiB,EACjB,IAAW,EACX,EAAE,EACF,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,UAAU,EACV,SAAS,EACT,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,WAAmB,EACnB,YAAoB,GACrB,EAAE,oBAAoB,+BAqGtB"}
@@ -21,6 +21,13 @@ export default function SelectFieldImpl({ value, onValueChange, options = [], gr
21
21
  if (initialFocus && !initialOpen)
22
22
  triggerRef.current?.focus();
23
23
  }, [initialFocus, initialOpen]);
24
- return (_jsxs(RSelect.Root, { value: value, onValueChange: onValueChange, disabled: disabled, name: name, required: required, defaultOpen: initialOpen, children: [_jsxs(RSelect.Trigger, { ref: triggerRef, id: id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, className: cn(RAW_BUTTON, selectTriggerClass({ fieldStyle, size, className })), children: [_jsx("span", { className: SELECT_VALUE_CLASS, children: _jsx(RSelect.Value, { placeholder: placeholder }) }), _jsx(RSelect.Icon, { asChild: true, children: _jsx(ChevronDown, { className: 'size-4 shrink-0 opacity-50' }) })] }), _jsx(RSelect.Portal, { container: container, children: _jsxs(RSelect.Content, { position: 'popper', sideOffset: 4, collisionPadding: FLOATING_COLLISION_PADDING, className: cn(FLOATING_CONTENT_BASE, FLOATING_ANIMATION, 'max-h-[var(--radix-select-content-available-height)] min-w-[var(--radix-select-trigger-width)] p-1'), children: [_jsx(RSelect.ScrollUpButton, { className: 'flex cursor-default items-center justify-center py-1', children: _jsx(ChevronUp, { className: 'size-4' }) }), _jsxs(RSelect.Viewport, { children: [empty && (_jsxs("div", { className: 'flex flex-col gap-0.5 px-2 py-2.5 text-left', children: [_jsx("span", { className: 'text-sm font-medium', children: emptyLabel ?? 'Nothing to choose from yet' }), emptyHint && _jsx("span", { className: 'text-xs text-muted-foreground', children: emptyHint })] })), allGroups.map((group, gi) => (_jsxs(RSelect.Group, { children: [group.label && (_jsx(RSelect.Label, { className: 'px-2 py-1.5 text-xs font-semibold text-muted-foreground', children: group.label })), group.options.map((opt) => (_jsxs(RSelect.Item, { value: opt.value, disabled: opt.disabled, className: cn(FLOATING_ITEM_BASE, 'pr-8'), children: [_jsx(RSelect.ItemIndicator, { className: 'absolute right-2 flex size-4 items-center justify-center', children: _jsx(Check, { className: 'size-3' }) }), _jsx(RSelect.ItemText, { children: opt.label }), opt.description && (_jsx("span", { className: 'text-xs text-muted-foreground', children: opt.description }))] }, opt.value))), gi < allGroups.length - 1 && _jsx(RSelect.Separator, { className: 'my-1 h-px bg-border' })] }, group.label ?? gi)))] }), _jsx(RSelect.ScrollDownButton, { className: 'flex cursor-default items-center justify-center py-1', children: _jsx(ChevronDown, { className: 'size-4' }) })] }) })] }));
24
+ return (_jsxs(RSelect.Root, { value: value,
25
+ // 🔴 "" is never a choice — Radix refuses an item whose value is "". Inside a <form> its
26
+ // hidden native <select> reads "" back for a value code set before that option exists,
27
+ // and reported it here as a pick: collections' Folder picker reset (forge task 3166).
28
+ onValueChange: (next) => {
29
+ if (next !== '')
30
+ onValueChange?.(next);
31
+ }, disabled: disabled, name: name, required: required, defaultOpen: initialOpen, children: [_jsxs(RSelect.Trigger, { ref: triggerRef, id: id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, className: cn(RAW_BUTTON, selectTriggerClass({ fieldStyle, size, className })), children: [_jsx("span", { className: SELECT_VALUE_CLASS, children: _jsx(RSelect.Value, { placeholder: placeholder }) }), _jsx(RSelect.Icon, { asChild: true, children: _jsx(ChevronDown, { className: 'size-4 shrink-0 opacity-50' }) })] }), _jsx(RSelect.Portal, { container: container, children: _jsxs(RSelect.Content, { position: 'popper', sideOffset: 4, collisionPadding: FLOATING_COLLISION_PADDING, className: cn(FLOATING_CONTENT_BASE, FLOATING_ANIMATION, 'max-h-[var(--radix-select-content-available-height)] min-w-[var(--radix-select-trigger-width)] p-1'), children: [_jsx(RSelect.ScrollUpButton, { className: 'flex cursor-default items-center justify-center py-1', children: _jsx(ChevronUp, { className: 'size-4' }) }), _jsxs(RSelect.Viewport, { children: [empty && (_jsxs("div", { className: 'flex flex-col gap-0.5 px-2 py-2.5 text-left', children: [_jsx("span", { className: 'text-sm font-medium', children: emptyLabel ?? 'Nothing to choose from yet' }), emptyHint && _jsx("span", { className: 'text-xs text-muted-foreground', children: emptyHint })] })), allGroups.map((group, gi) => (_jsxs(RSelect.Group, { children: [group.label && (_jsx(RSelect.Label, { className: 'px-2 py-1.5 text-xs font-semibold text-muted-foreground', children: group.label })), group.options.map((opt) => (_jsxs(RSelect.Item, { value: opt.value, disabled: opt.disabled, className: cn(FLOATING_ITEM_BASE, 'pr-8'), children: [_jsx(RSelect.ItemIndicator, { className: 'absolute right-2 flex size-4 items-center justify-center', children: _jsx(Check, { className: 'size-3' }) }), _jsx(RSelect.ItemText, { children: opt.label }), opt.description && (_jsx("span", { className: 'text-xs text-muted-foreground', children: opt.description }))] }, opt.value))), gi < allGroups.length - 1 && _jsx(RSelect.Separator, { className: 'my-1 h-px bg-border' })] }, group.label ?? gi)))] }), _jsx(RSelect.ScrollDownButton, { className: 'flex cursor-default items-center justify-center py-1', children: _jsx(ChevronDown, { className: 'size-4' }) })] }) })] }));
25
32
  }
26
33
  //# sourceMappingURL=SelectFieldImpl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SelectFieldImpl.js","sourceRoot":"","sources":["../../../src/react/components/SelectFieldImpl.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SelectFieldImpl.js","sourceRoot":"","sources":["../../../src/react/components/SelectFieldImpl.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursedbelt",
3
- "version": "5.79.1",
3
+ "version": "5.79.3",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "description": "The React design system of the cursedbelt split — components, styles, theme. cursedbelt-core below it; server tier in cursedbelt-server.",
@@ -1,5 +1,5 @@
1
1
  import { afterEach, describe, expect, mock, test } from 'bun:test';
2
- import { cleanup, fireEvent, render } from '@testing-library/react';
2
+ import { act, cleanup, fireEvent, render } from '@testing-library/react';
3
3
  import { useState } from 'react';
4
4
  import { OtpInput } from './OtpInput.js';
5
5
 
@@ -65,6 +65,48 @@ describe('OtpInput', () => {
65
65
  expect(onComplete).toHaveBeenCalledWith('654321');
66
66
  });
67
67
 
68
+ test('🔴 an autofilled code in the first box fills all six — no box caps it at one digit', () => {
69
+ const onComplete = mock(() => {});
70
+ const { container } = render(<Controlled onComplete={onComplete} />);
71
+ const b = boxes(container);
72
+ // happy-dom does not enforce maxLength on a value set; a phone's autofill does.
73
+ for (const box of b) expect(box.maxLength).toBeGreaterThanOrEqual(6);
74
+ fireEvent.change(b[0], { target: { value: '123456' } });
75
+ expect(val(container)).toBe('123456');
76
+ expect(b.map((x) => x.value)).toEqual(['1', '2', '3', '4', '5', '6']);
77
+ expect(onComplete).toHaveBeenCalledWith('123456');
78
+ });
79
+
80
+ test('a key typed into a box that holds a digit replaces it, not appends to it', () => {
81
+ const { container } = render(<Controlled />);
82
+ const b = boxes(container);
83
+ fireEvent.change(b[0], { target: { value: '1' } });
84
+ fireEvent.change(b[1], { target: { value: '2' } });
85
+ const typed = new InputEvent('input', { bubbles: true, inputType: 'insertText', data: '7' });
86
+ // The browser's own write, under React's value tracker — as a keystroke lands.
87
+ Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set?.call(b[1], '27');
88
+ act(() => {
89
+ b[1].dispatchEvent(typed);
90
+ });
91
+ expect(val(container)).toBe('17');
92
+ });
93
+
94
+ test('🔴 correcting one digit of a full code keeps the digits after it', () => {
95
+ const onComplete = mock(() => {});
96
+ const { container } = render(<Controlled onComplete={onComplete} />);
97
+ const b = boxes(container);
98
+ fireEvent.change(b[0], { target: { value: '123456' } });
99
+ onComplete.mockClear();
100
+ // The box's digit is selected on focus, so the key replaces it: the value is the key alone.
101
+ const typed = new InputEvent('input', { bubbles: true, inputType: 'insertText', data: '9' });
102
+ Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set?.call(b[2], '9');
103
+ act(() => {
104
+ b[2].dispatchEvent(typed);
105
+ });
106
+ expect(val(container)).toBe('129456');
107
+ expect(onComplete).toHaveBeenCalledWith('129456');
108
+ });
109
+
68
110
  test('backspace on an empty box clears the previous digit', () => {
69
111
  const { container } = render(<Controlled />);
70
112
  const b = boxes(container);
@@ -84,16 +84,20 @@ export function OtpInput({
84
84
  refs.current[clamped]?.select();
85
85
  };
86
86
 
87
- const handleChange = (index: number, raw: string) => {
88
- const clean = sanitize(raw);
87
+ const handleChange = (index: number, raw: string, typed: string | null) => {
88
+ // A key typed into a box that already holds a character arrives APPENDED to it ("47"),
89
+ // since no box is capped at one: the key is the event's own `data`. An autofill or a
90
+ // replacement carries the whole code in the value.
91
+ const clean = sanitize(typed ?? raw);
89
92
  if (!clean) {
90
93
  // A deletion/clear of this box: drop just this position.
91
94
  if (chars[index]) commit(chars.slice(0, index).join('') + chars.slice(index + 1).join(''));
92
95
  return;
93
96
  }
94
97
  // Typing (or autofilling) writes from this box forward, so a multi-char autofill
95
- // or a fast typist never loses characters.
96
- const merged = (chars.slice(0, index).join('') + clean).slice(0, length);
98
+ // or a fast typist never loses characters. The boxes after what was written keep
99
+ // theirs: correcting the third digit of a full code is not retyping the last three.
100
+ const merged = (chars.slice(0, index).join('') + clean + chars.slice(index + clean.length).join('')).slice(0, length);
97
101
  commit(merged);
98
102
  focusBox(index + clean.length);
99
103
  };
@@ -145,13 +149,18 @@ export function OtpInput({
145
149
  autoComplete={i === 0 ? 'one-time-code' : 'off'}
146
150
  // biome-ignore lint/a11y/noAutofocus: opt-in via prop; first box only
147
151
  autoFocus={autoFocus && i === 0}
148
- maxLength={1}
152
+ // 🔴 Never 1: a browser that honours `maxLength` on autofill (iOS Safari's "From
153
+ // Messages" chip) would hand the code box one digit. `commit` is the limit.
154
+ maxLength={length}
149
155
  disabled={disabled}
150
156
  value={char}
151
157
  aria-label={ariaLabel ? `${ariaLabel} digit ${i + 1}` : `Digit ${i + 1}`}
152
158
  aria-invalid={ariaInvalid}
153
159
  aria-describedby={i === 0 ? ariaDescribedBy : undefined}
154
- onChange={(e) => handleChange(i, e.target.value)}
160
+ onChange={(e) => {
161
+ const input = e.nativeEvent as InputEvent;
162
+ handleChange(i, e.target.value, input.inputType === 'insertText' && input.data ? input.data : null);
163
+ }}
155
164
  onKeyDown={(e) => handleKeyDown(i, e)}
156
165
  onPaste={(e) => handlePaste(i, e)}
157
166
  onFocus={(e) => e.currentTarget.select()}
@@ -1,8 +1,9 @@
1
1
  import { afterEach, describe, expect, test } from 'bun:test';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
- import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
4
+ import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
5
5
  import { useState } from 'react';
6
+ import { Button } from './Button.js';
6
7
  import { SelectField } from './SelectField.js';
7
8
 
8
9
  afterEach(cleanup);
@@ -115,3 +116,51 @@ describe('SelectField (lazy)', () => {
115
116
  expect(screen.getByRole('option', { name: 'Title' })).toBeTruthy();
116
117
  });
117
118
  });
119
+
120
+ /**
121
+ * 🔴 Inside a <form>, Radix renders a hidden native <select> and copies each value into it; a value
122
+ * that is not one of its options yet reads back as "" and Radix reports `onValueChange("")` — which
123
+ * reset collections' Folder picker after an upload into a NEW folder (forge task 3166).
124
+ */
125
+ describe('SelectField inside a form', () => {
126
+ function Folder({ calls }: { calls: string[] }) {
127
+ const [value, setValue] = useState('title');
128
+ const [options, setOptions] = useState(OPTIONS);
129
+ return (
130
+ <form>
131
+ <SelectField
132
+ aria-label='Folder'
133
+ name='folder'
134
+ value={value}
135
+ onValueChange={(v) => {
136
+ calls.push(v);
137
+ setValue(v);
138
+ }}
139
+ options={options}
140
+ />
141
+ <Button
142
+ tooltip='Land the upload in a new folder'
143
+ onClick={() => {
144
+ setValue('landed');
145
+ setOptions([...OPTIONS, { value: 'landed', label: 'Landed' }]);
146
+ }}
147
+ >
148
+ land
149
+ </Button>
150
+ <output data-v>{value}</output>
151
+ </form>
152
+ );
153
+ }
154
+
155
+ test('a value set by code before its option exists is kept — no onValueChange("")', async () => {
156
+ const calls: string[] = [];
157
+ const { container } = render(<Folder calls={calls} />);
158
+ await act(async () => {
159
+ fireEvent.click(screen.getByRole('button', { name: 'land' }));
160
+ await new Promise((r) => setTimeout(r, 20));
161
+ });
162
+ expect(calls).toEqual([]);
163
+ expect(container.querySelector('[data-v]')?.textContent).toBe('landed');
164
+ expect(screen.getByRole('combobox', { name: 'Folder' }).textContent).toContain('Landed');
165
+ });
166
+ });
@@ -56,7 +56,12 @@ export default function SelectFieldImpl({
56
56
  return (
57
57
  <RSelect.Root
58
58
  value={value}
59
- onValueChange={onValueChange}
59
+ // 🔴 "" is never a choice — Radix refuses an item whose value is "". Inside a <form> its
60
+ // hidden native <select> reads "" back for a value code set before that option exists,
61
+ // and reported it here as a pick: collections' Folder picker reset (forge task 3166).
62
+ onValueChange={(next) => {
63
+ if (next !== '') onValueChange?.(next);
64
+ }}
60
65
  disabled={disabled}
61
66
  name={name}
62
67
  required={required}