@tastic/profile 0.3.4 → 0.3.5

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.
package/dist/index.js CHANGED
@@ -390,8 +390,15 @@ function EditRow({ draftName, onNameChange, draftColor, onColorChange, draftTag,
390
390
  const register = (0, import_focus_chain.useFocusChain)();
391
391
  const tag = register();
392
392
  const name = register();
393
+ const tagFocusRef = (0, import_react2.useRef)(tag.props.focus);
394
+ (0, import_react2.useEffect)(() => {
395
+ tagFocusRef.current = tag.props.focus;
396
+ });
397
+ (0, import_react2.useEffect)(() => {
398
+ if (host.openId === "color") tagFocusRef.current();
399
+ }, [host.openId]);
393
400
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: styles3.editRow, children: [
394
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_hud2.InlineColorPicker, { id: "color", host, value: draftColor, onChange: onColorChange, dark }),
401
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_hud2.InlineColorPicker, { id: "color", host, value: draftColor, onChange: onColorChange, tag: draftTag, dark }),
395
402
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.TextInput, { ref: tag.ref, ...tag.props, mode: "outlined", dense: true, value: draftTag, onChangeText: onTagChange, placeholder: "Tag", autoCapitalize: "characters", selectTextOnFocus: true, error: tagInvalid, returnKeyType: "next", style: styles3.tagInput, contentStyle: styles3.tagInputContent }),
396
403
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.TextInput, { ref: name.ref, ...name.props, onSubmitEditing: onSubmit, mode: "outlined", dense: true, value: draftName, onChangeText: onNameChange, maxLength: MAX_PROFILE_NAME_LENGTH, placeholder: "Name", autoFocus, returnKeyType: "done", style: styles3.nameInput }),
397
404
  onDelete && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.TouchableRipple, { onPress: onDelete, style: styles3.iconButton, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Icon, { source: "trash-can-outline", size: 18, color: fgMuted }) })
package/dist/index.mjs CHANGED
@@ -362,8 +362,15 @@ function EditRow({ draftName, onNameChange, draftColor, onColorChange, draftTag,
362
362
  const register = useFocusChain();
363
363
  const tag = register();
364
364
  const name = register();
365
+ const tagFocusRef = useRef(tag.props.focus);
366
+ useEffect(() => {
367
+ tagFocusRef.current = tag.props.focus;
368
+ });
369
+ useEffect(() => {
370
+ if (host.openId === "color") tagFocusRef.current();
371
+ }, [host.openId]);
365
372
  return /* @__PURE__ */ jsxs2(View3, { style: styles3.editRow, children: [
366
- /* @__PURE__ */ jsx3(InlineColorPicker, { id: "color", host, value: draftColor, onChange: onColorChange, dark }),
373
+ /* @__PURE__ */ jsx3(InlineColorPicker, { id: "color", host, value: draftColor, onChange: onColorChange, tag: draftTag, dark }),
367
374
  /* @__PURE__ */ jsx3(TextInput, { ref: tag.ref, ...tag.props, mode: "outlined", dense: true, value: draftTag, onChangeText: onTagChange, placeholder: "Tag", autoCapitalize: "characters", selectTextOnFocus: true, error: tagInvalid, returnKeyType: "next", style: styles3.tagInput, contentStyle: styles3.tagInputContent }),
368
375
  /* @__PURE__ */ jsx3(TextInput, { ref: name.ref, ...name.props, onSubmitEditing: onSubmit, mode: "outlined", dense: true, value: draftName, onChangeText: onNameChange, maxLength: MAX_PROFILE_NAME_LENGTH, placeholder: "Name", autoFocus, returnKeyType: "done", style: styles3.nameInput }),
369
376
  onDelete && /* @__PURE__ */ jsx3(TouchableRipple2, { onPress: onDelete, style: styles3.iconButton, children: /* @__PURE__ */ jsx3(Icon3, { source: "trash-can-outline", size: 18, color: fgMuted }) })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tastic/profile",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Player profile identity for local-multiplayer React Native games — a saved name/color/tag a player selects per seat, with a picker, an inline-editable roster screen, and a reusable identity badge, deliberately blind to any app-specific fields (control scheme, stats) an app layers on top",
5
5
  "keywords": [
6
6
  "react-native",
@@ -272,10 +272,11 @@ interface EditRowProps {
272
272
 
273
273
  // One row, expanded: the color trigger (@tastic/hud's InlineColorPicker), a tag field clamped to
274
274
  // CHIP_SIZE, the name taking up whatever's
275
- // left, and — only for an existing profile — a delete icon at the very end. No `tag` passed to the
276
- // color trigger here — it keeps its plain palette icon regardless of the row's own tag field, since
277
- // the tag is already right next to it in its own field, so repeating it on the color trigger too
278
- // would be redundant rather than informative.
275
+ // left, and — only for an existing profile — a delete icon at the very end. `tag={draftTag}` IS
276
+ // passed to the color trigger here (unlike a plain identity badge elsewhere) so it shows the same
277
+ // live draft value the tag field itself does — the two effects below are what wires tapping the
278
+ // swatch to popping the keyboard on the tag field too, so typing a tag and picking a color read as
279
+ // one combined action instead of two separate taps.
279
280
  // Return-key chains tag -> name via @rific/focus-chain rather than each field submitting on its
280
281
  // own — submitting the *name* field is what actually commits the row, so its registration's own
281
282
  // onSubmitEditing (a no-op — it's last in the chain) is overridden with onSubmit below, matching
@@ -285,9 +286,29 @@ function EditRow({ draftName, onNameChange, draftColor, onColorChange, draftTag,
285
286
  const tag = register()
286
287
  const name = register()
287
288
 
289
+ // tag.props.focus (from @rific/focus-chain's own register(), not tag.ref — that's a callback
290
+ // ref, not a ref object, so it has no .current to read) is the hook's own imperative "focus this
291
+ // exact registered field" call. Mirrored into a ref every render, same as commitEditRef above,
292
+ // rather than read directly in the effect below: register() returns a brand-new props object on
293
+ // every render (it isn't memoized), so depending on tag.props.focus directly would rerun that
294
+ // effect — and refocus an already-focused field — on every keystroke into the tag field itself,
295
+ // re-triggering its own selectTextOnFocus mid-type and wiping out what's being typed.
296
+ const tagFocusRef = useRef(tag.props.focus)
297
+ useEffect(() => {
298
+ tagFocusRef.current = tag.props.focus
299
+ })
300
+
301
+ // Lets tapping the swatch itself hand focus straight to the tag field, so one tap both opens the
302
+ // color popover (host.toggle, inside InlineColorPicker's own onPress) and pops the keyboard on
303
+ // the tag field right next to it. Scoped to host.openId so this only fires on an actual open
304
+ // transition, not on every re-render while it's already open.
305
+ useEffect(() => {
306
+ if (host.openId === 'color') tagFocusRef.current()
307
+ }, [host.openId])
308
+
288
309
  return (
289
310
  <View style={styles.editRow}>
290
- <InlineColorPicker id='color' host={host} value={draftColor} onChange={onColorChange} dark={dark} />
311
+ <InlineColorPicker id='color' host={host} value={draftColor} onChange={onColorChange} tag={draftTag} dark={dark} />
291
312
  {/* selectTextOnFocus so tapping into an already-set tag selects it for wholesale replacement
292
313
  — the far more common edit than inserting into the middle of a 1-3 character value. */}
293
314
  {/* eslint-disable-next-line react-hooks/refs -- tag.ref/tag.props come from useFocusChain's