@tastic/profile 0.1.0 → 0.1.2

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
@@ -237,7 +237,6 @@ var styles2 = import_react_native2.StyleSheet.create({
237
237
  // src/ProfilesManager.tsx
238
238
  var import_auto_paper3 = require("@rific/auto-paper");
239
239
  var import_feedback_press2 = require("@rific/feedback-press");
240
- var import_focus_chain = require("@rific/focus-chain");
241
240
  var import_toaster = require("@rific/toaster");
242
241
  var import_hud2 = require("@tastic/hud");
243
242
  var import_react2 = require("react");
@@ -384,13 +383,12 @@ function ProfilesManager({ profiles, defaultColor, onCreate, onSave, onDelete, h
384
383
  ] });
385
384
  }
386
385
  function EditRow({ draftName, onNameChange, draftColor, onColorChange, draftTag, onTagChange, tagInvalid, onSubmit, onDelete, autoFocus, fgMuted, host, dark }) {
387
- const register = (0, import_focus_chain.useFocusChain)();
388
- const tag = register();
389
- const name = register();
386
+ const tagInputRef = (0, import_react2.useRef)(null);
387
+ const nameInputRef = (0, import_react2.useRef)(null);
390
388
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: styles3.editRow, children: [
391
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_hud2.InlineColorPicker, { id: "color", host, value: draftColor, onChange: onColorChange, dark, size: CHIP_SIZE }),
392
- /* @__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 }),
393
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.TextInput, { ref: name.ref, ...name.props, mode: "outlined", dense: true, value: draftName, onChangeText: onNameChange, maxLength: MAX_PROFILE_NAME_LENGTH, placeholder: "Name", autoFocus, returnKeyType: "done", style: styles3.nameInput, onSubmitEditing: onSubmit }),
389
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_hud2.InlineColorPicker, { id: "color", host, value: draftColor, onChange: onColorChange, dark }),
390
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.TextInput, { ref: tagInputRef, mode: "outlined", dense: true, value: draftTag, onChangeText: onTagChange, placeholder: "Tag", autoCapitalize: "characters", selectTextOnFocus: true, error: tagInvalid, returnKeyType: "next", style: styles3.tagInput, contentStyle: styles3.tagInputContent, onSubmitEditing: () => nameInputRef.current?.focus() }),
391
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.TextInput, { ref: nameInputRef, mode: "outlined", dense: true, value: draftName, onChangeText: onNameChange, maxLength: MAX_PROFILE_NAME_LENGTH, placeholder: "Name", autoFocus, returnKeyType: "done", style: styles3.nameInput, onSubmitEditing: onSubmit }),
394
392
  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 }) })
395
393
  ] });
396
394
  }
package/dist/index.mjs CHANGED
@@ -205,7 +205,6 @@ var styles2 = StyleSheet2.create({
205
205
  // src/ProfilesManager.tsx
206
206
  import { useAutoPaperTheme } from "@rific/auto-paper";
207
207
  import { TouchableRipple as TouchableRipple2 } from "@rific/feedback-press";
208
- import { useFocusChain } from "@rific/focus-chain";
209
208
  import { useToast } from "@rific/toaster";
210
209
  import { InlineColorPicker, usePopoverHost } from "@tastic/hud";
211
210
  import { useCallback, useEffect, useMemo as useMemo2, useRef, useState } from "react";
@@ -352,13 +351,12 @@ function ProfilesManager({ profiles, defaultColor, onCreate, onSave, onDelete, h
352
351
  ] });
353
352
  }
354
353
  function EditRow({ draftName, onNameChange, draftColor, onColorChange, draftTag, onTagChange, tagInvalid, onSubmit, onDelete, autoFocus, fgMuted, host, dark }) {
355
- const register = useFocusChain();
356
- const tag = register();
357
- const name = register();
354
+ const tagInputRef = useRef(null);
355
+ const nameInputRef = useRef(null);
358
356
  return /* @__PURE__ */ jsxs2(View3, { style: styles3.editRow, children: [
359
- /* @__PURE__ */ jsx3(InlineColorPicker, { id: "color", host, value: draftColor, onChange: onColorChange, dark, size: CHIP_SIZE }),
360
- /* @__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 }),
361
- /* @__PURE__ */ jsx3(TextInput, { ref: name.ref, ...name.props, mode: "outlined", dense: true, value: draftName, onChangeText: onNameChange, maxLength: MAX_PROFILE_NAME_LENGTH, placeholder: "Name", autoFocus, returnKeyType: "done", style: styles3.nameInput, onSubmitEditing: onSubmit }),
357
+ /* @__PURE__ */ jsx3(InlineColorPicker, { id: "color", host, value: draftColor, onChange: onColorChange, dark }),
358
+ /* @__PURE__ */ jsx3(TextInput, { ref: tagInputRef, mode: "outlined", dense: true, value: draftTag, onChangeText: onTagChange, placeholder: "Tag", autoCapitalize: "characters", selectTextOnFocus: true, error: tagInvalid, returnKeyType: "next", style: styles3.tagInput, contentStyle: styles3.tagInputContent, onSubmitEditing: () => nameInputRef.current?.focus() }),
359
+ /* @__PURE__ */ jsx3(TextInput, { ref: nameInputRef, mode: "outlined", dense: true, value: draftName, onChangeText: onNameChange, maxLength: MAX_PROFILE_NAME_LENGTH, placeholder: "Name", autoFocus, returnKeyType: "done", style: styles3.nameInput, onSubmitEditing: onSubmit }),
362
360
  onDelete && /* @__PURE__ */ jsx3(TouchableRipple2, { onPress: onDelete, style: styles3.iconButton, children: /* @__PURE__ */ jsx3(Icon3, { source: "trash-can-outline", size: 18, color: fgMuted }) })
363
361
  ] });
364
362
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tastic/profile",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
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,37 +45,36 @@
45
45
  "scripts": {
46
46
  "build": "tsup src/index.ts --format cjs,esm --dts --clean",
47
47
  "build:watch": "tsup src/index.ts --format cjs,esm --dts --watch",
48
+ "ci": "npm run lint && npm test && npm run typecheck && npm run build",
48
49
  "fix": "eslint --fix",
49
50
  "lint": "eslint",
50
51
  "prepublishOnly": "npm run build",
51
52
  "release": "git push --follow-tags",
52
- "release:major": "npm version major && git push --follow-tags",
53
- "release:minor": "npm version minor && git push --follow-tags",
54
- "release:patch": "npm version patch && git push --follow-tags",
53
+ "release:major": "npm version major && npm run release",
54
+ "release:minor": "npm version minor && npm run release",
55
+ "release:patch": "npm version patch && npm run release",
55
56
  "test": "jest",
56
57
  "test:watch": "jest --watchAll",
57
58
  "typecheck": "tsc --noEmit",
58
- "preversion": "npm run lint && npm test && npm run build"
59
+ "preversion": "npm run ci"
59
60
  },
61
+ "prettier": "@infinitetoken/eslint-config/prettier",
60
62
  "devDependencies": {
61
- "@rific/auto-paper": "file:.yalc/@rific/auto-paper",
62
- "@rific/feedback-press": "^0.10.4",
63
- "@rific/focus-chain": "^0.4.3",
64
- "@rific/toaster": "^0.4.1",
65
- "@tastic/core": "^0.1.2",
66
- "@tastic/hud": "file:.yalc/@tastic/hud",
63
+ "@infinitetoken/eslint-config": "^0.1.4",
64
+ "@infinitetoken/tsconfig": "^0.1.1",
65
+ "@rific/auto-paper": "^0.10.1",
66
+ "@rific/feedback-press": "^0.10.7",
67
+ "@rific/focus-chain": "^0.4.4",
68
+ "@rific/toaster": "^0.6.0",
69
+ "@tastic/core": "^0.1.3",
70
+ "@tastic/hud": "^0.1.5",
67
71
  "@testing-library/dom": "^10.4.1",
68
72
  "@testing-library/react": "^16.3.2",
69
73
  "@types/jest": "^30.0.0",
70
74
  "@types/react": "^19.0.0",
71
- "@typescript-eslint/parser": "^8.59.3",
72
75
  "eslint": "^9.39.4",
73
- "eslint-config-prettier": "^10.1.8",
74
- "eslint-plugin-package-json": "^1.0.0",
75
- "eslint-plugin-prettier": "^5.5.5",
76
76
  "eslint-plugin-react-hooks": "^7.1.1",
77
77
  "eslint-plugin-react-native": "^5.0.0",
78
- "eslint-plugin-simple-import-sort": "^13.0.0",
79
78
  "jest": "^30.4.2",
80
79
  "jest-environment-jsdom": "^30.4.1",
81
80
  "prettier": "^3.8.3",
@@ -86,8 +85,7 @@
86
85
  "react-native-safe-area-context": "^5.0.0",
87
86
  "ts-jest": "^29.4.9",
88
87
  "tsup": "^8.0.0",
89
- "typescript": "^6.0.3",
90
- "typescript-eslint": "^8.59.3"
88
+ "typescript": "^6.0.3"
91
89
  },
92
90
  "peerDependencies": {
93
91
  "@rific/auto-paper": ">=0.9.0",
@@ -1,10 +1,9 @@
1
1
  import { useAutoPaperTheme } from '@rific/auto-paper'
2
2
  import { TouchableRipple } from '@rific/feedback-press'
3
- import { useFocusChain } from '@rific/focus-chain'
4
3
  import { useToast } from '@rific/toaster'
5
4
  import { InlineColorPicker, PopoverHost, usePopoverHost } from '@tastic/hud'
6
- import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
7
- import { KeyboardAvoidingView, Platform, ScrollView, StyleSheet, View } from 'react-native'
5
+ import { ComponentRef, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
6
+ import { KeyboardAvoidingView, Platform, ScrollView, StyleSheet, TextInput as RNTextInput, View } from 'react-native'
8
7
  import { Button, Icon, Portal, Text, TextInput } from 'react-native-paper'
9
8
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
10
9
 
@@ -270,33 +269,27 @@ interface EditRowProps {
270
269
  dark: boolean
271
270
  }
272
271
 
273
- // One row, expanded: the color trigger (@tastic/hud's InlineColorPicker, which takes a size prop
274
- // rather than a fixed one, so it can be clamped to CHIP_SIZE along with every other circle on this
275
- // screen), a tag field clamped to that same CHIP_SIZE footprint, the name taking up whatever's
272
+ // One row, expanded: the color trigger (@tastic/hud's InlineColorPicker), a tag field clamped to
273
+ // CHIP_SIZE, the name taking up whatever's
276
274
  // left, and — only for an existing profile — a delete icon at the very end. No `tag` passed to the
277
275
  // color trigger here — it keeps its plain palette icon regardless of the row's own tag field, since
278
276
  // the tag is already right next to it in its own field, so repeating it on the color trigger too
279
277
  // would be redundant rather than informative.
280
- // Return-key chains tag -> name (see @rific/focus-chain) rather than each field submitting on its
278
+ // Return-key chains tag -> name via explicit refs rather than each field submitting on its
281
279
  // own — submitting the *name* field is what actually commits the row (see the last field's own
282
280
  // onSubmitEditing override below), matching how a normal multi-field form reads: fill fields in
283
281
  // order, the last one finishes it.
284
282
  function EditRow({ draftName, onNameChange, draftColor, onColorChange, draftTag, onTagChange, tagInvalid, onSubmit, onDelete, autoFocus, fgMuted, host, dark }: EditRowProps) {
285
- const register = useFocusChain()
286
- const tag = register()
287
- const name = register()
283
+ const tagInputRef = useRef<ComponentRef<typeof RNTextInput>>(null)
284
+ const nameInputRef = useRef<ComponentRef<typeof RNTextInput>>(null)
288
285
 
289
286
  return (
290
287
  <View style={styles.editRow}>
291
- <InlineColorPicker id='color' host={host} value={draftColor} onChange={onColorChange} dark={dark} size={CHIP_SIZE} />
288
+ <InlineColorPicker id='color' host={host} value={draftColor} onChange={onColorChange} dark={dark} />
292
289
  {/* selectTextOnFocus so tapping into an already-set tag selects it for wholesale replacement
293
290
  — the far more common edit than inserting into the middle of a 1-3 character value. */}
294
- <TextInput ref={tag.ref} {...tag.props} mode='outlined' dense value={draftTag} onChangeText={onTagChange} placeholder='Tag' autoCapitalize='characters' selectTextOnFocus error={tagInvalid} returnKeyType='next' style={styles.tagInput} contentStyle={styles.tagInputContent} />
295
- {/* tag.props' own onSubmitEditing (focus the next field) applies to every field but this
296
- one — as the chain's last field, submitting it should finish the row instead of trying to
297
- focus a field that doesn't exist, so this overrides it with the real commit action. Spread
298
- order matters: name.props first, the explicit prop after, so this wins. */}
299
- <TextInput ref={name.ref} {...name.props} mode='outlined' dense value={draftName} onChangeText={onNameChange} maxLength={MAX_PROFILE_NAME_LENGTH} placeholder='Name' autoFocus={autoFocus} returnKeyType='done' style={styles.nameInput} onSubmitEditing={onSubmit} />
291
+ <TextInput ref={tagInputRef} mode='outlined' dense value={draftTag} onChangeText={onTagChange} placeholder='Tag' autoCapitalize='characters' selectTextOnFocus error={tagInvalid} returnKeyType='next' style={styles.tagInput} contentStyle={styles.tagInputContent} onSubmitEditing={() => nameInputRef.current?.focus()} />
292
+ <TextInput ref={nameInputRef} mode='outlined' dense value={draftName} onChangeText={onNameChange} maxLength={MAX_PROFILE_NAME_LENGTH} placeholder='Name' autoFocus={autoFocus} returnKeyType='done' style={styles.nameInput} onSubmitEditing={onSubmit} />
300
293
  {onDelete && (
301
294
  <TouchableRipple onPress={onDelete} style={styles.iconButton}>
302
295
  <Icon source='trash-can-outline' size={18} color={fgMuted} />