@tastic/profile 0.3.3 → 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 +8 -1
- package/dist/index.mjs +8 -1
- package/package.json +12 -12
- package/src/ProfilesManager.tsx +26 -5
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.
|
|
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",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"!src/__mocks__"
|
|
46
46
|
],
|
|
47
47
|
"scripts": {
|
|
48
|
-
"build": "tsup
|
|
49
|
-
"build:watch": "tsup
|
|
48
|
+
"build": "tsup",
|
|
49
|
+
"build:watch": "tsup --watch",
|
|
50
50
|
"fix": "eslint --fix",
|
|
51
51
|
"lint": "eslint",
|
|
52
52
|
"prepublishOnly": "npm run build",
|
|
@@ -62,14 +62,15 @@
|
|
|
62
62
|
},
|
|
63
63
|
"prettier": "@infinitetoken/eslint-config/prettier",
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@infinitetoken/eslint-config": "^0.1.
|
|
66
|
-
"@infinitetoken/
|
|
67
|
-
"@
|
|
68
|
-
"@rific/
|
|
69
|
-
"@rific/
|
|
70
|
-
"@rific/
|
|
71
|
-
"@
|
|
72
|
-
"@tastic/
|
|
65
|
+
"@infinitetoken/eslint-config": "^0.1.8",
|
|
66
|
+
"@infinitetoken/jest-config": "^0.2.1",
|
|
67
|
+
"@infinitetoken/tsconfig": "^0.3.0",
|
|
68
|
+
"@rific/auto-paper": "^0.10.3",
|
|
69
|
+
"@rific/feedback-press": "^0.10.8",
|
|
70
|
+
"@rific/focus-chain": "^0.4.7",
|
|
71
|
+
"@rific/toaster": "^0.6.3",
|
|
72
|
+
"@tastic/core": "^0.1.5",
|
|
73
|
+
"@tastic/hud": "^0.1.6",
|
|
73
74
|
"@testing-library/dom": "^10.4.1",
|
|
74
75
|
"@testing-library/react": "^16.3.2",
|
|
75
76
|
"@types/jest": "^30.0.0",
|
|
@@ -86,7 +87,6 @@
|
|
|
86
87
|
"react-native": "^0.85.3",
|
|
87
88
|
"react-native-paper": "^5.15.2",
|
|
88
89
|
"react-native-safe-area-context": "^5.0.0",
|
|
89
|
-
"ts-jest": "^29.4.9",
|
|
90
90
|
"tsup": "^8.0.0",
|
|
91
91
|
"typescript": "^6.0.3"
|
|
92
92
|
},
|
package/src/ProfilesManager.tsx
CHANGED
|
@@ -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.
|
|
276
|
-
// color trigger here
|
|
277
|
-
// the tag
|
|
278
|
-
//
|
|
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
|