@tastic/profile 0.12.0 → 0.14.0

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/README.md CHANGED
@@ -51,8 +51,12 @@ see its own doc comment for why that component is generic over your own `Profile
51
51
  only - creating, renaming, and deleting all live in `ProfilesManager`. Generic over your own
52
52
  `Profile` type (see above). Placement props (all optional, see "Fake-rotated frames" below):
53
53
  `align` (force a horizontal side), `alignOverride` (substitute the whole placement result), and
54
- `rotation` (forwarded to the automatic measurement). Also exports
55
- `getProfilePickerContentSize(profileCount, hasManageRow?)` - the popover's
54
+ `rotation` (forwarded to the automatic measurement). `colorSection`
55
+ (`{ value, onChange, previewValue?, swatches?, label?, caption? }`) puts a Color row at the top of
56
+ the popover that opens a page of swatches (with a back row), and turns the trigger into one
57
+ button that leads with a chip in `color` with the selected profile's tag; `triggerStyle` styles
58
+ that button. Also exports
59
+ `getProfilePickerContentSize(profileCount, hasManageRow?, colorSection?)` - the popover's
56
60
  `{ width, height }`, for sizing your own placement hook.
57
61
  - **`ProfilesManager`**: the roster screen itself: create/rename/recolor/retag/delete, editing
58
62
  inline in the row you tap, with a destructive-delete confirmation. No navigation of its own (no
@@ -142,7 +146,10 @@ const placement = useMyRotatedAlign(open, width, height) // returns a ProfilePic
142
146
 
143
147
  `getProfilePickerContentSize(profileCount, hasManageRow = false)` returns `{ width, height }`: 220
144
148
  wide, and `8 * 2 + (profileCount + 1 + (hasManageRow ? 1 : 0)) * 36` tall (the null/"guest" row, one
145
- row per profile, and the Manage row when `onManage` is passed).
149
+ row per profile, and the Manage row when `onManage` is passed), or with a color section (pass the same
150
+ object the picker gets) the taller of its two pages: that list plus the Color row (48 with a
151
+ caption, 36 without) and its 9pt divider, or the color page (a 36pt back row and the swatches, 187
152
+ for 20 colors), plus the padding.
146
153
 
147
154
 
148
155
  #### The Profiles screen's color swatch: `useColorPickerAlign`
@@ -180,7 +187,7 @@ Same `profiles`/`defaultColor`/`onCreate`/`onSave`/`onDelete` props as `Profiles
180
187
  `ProfileEditPatch`-shaped, still deliberately not widened to your own richer `CreateProfileInput`;
181
188
  compose any extra required fields (a key/control scheme, whatever's specific to your game) in your
182
189
  own closure at the call site, exactly as you already would calling `ProfilesManager` directly -
183
- plus `onBack`. `fg`/`fgMuted`/`bg`/`cardBg`/`titleVariant`/`colorPreview` are all independently
190
+ plus `onBack`. `fg`/`fgMuted`/`bg`/`titleVariant`/`colorPreview` are all independently
184
191
  optional and forward straight through to the internal `ProfilesManager` (`bg` is new here -
185
192
  `ProfilesManager` itself has no `bg`, since it doesn't own a container `View` of its own).
186
193
 
@@ -312,13 +319,10 @@ it.
312
319
  saved color live." Cleared only when that seat's own profile selection genuinely changes, never by
313
320
  merely leaving and returning to the screen.
314
321
 
315
- None of these three are exports of this package today. `lastGuestColor`/`lastCpuColor` predate it
316
- entirely, and `profileOverride` is still hand-rolled per app - typically alongside
317
- `createProfileSelectionSlice`'s own selection state, in the same seat-scoped slice (see e.g.
318
- BoxHockey's `src/redux/seatColorsSlice.ts`) or folded into the app's own `gameSlice.ts` when there's
319
- no dedicated slice to put it in (see Snake's `src/redux/gameSlice.ts`). This section exists so a new
320
- app's author reads the convention here first, rather than hand-rolling something that quietly can't
321
- interop with the rest of the fleet.
322
+ All three live in one slice from this package's `createSeatColorsSlice` (since 0.5.0), which every
323
+ flagship game uses (see e.g. BoxHockey's or Snake's `src/redux/seatColorsSlice.ts`). This section
324
+ exists so a new app's author reads the convention here first, rather than hand-rolling something
325
+ that quietly can't interop with the rest of the fleet.
322
326
 
323
327
  The resolution order at a loadout/lobby screen, for one seat:
324
328
 
package/dist/index.d.mts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, RefObject, Ref } from 'react';
3
+ import { SeedColor } from '@rific/auto-paper';
3
4
  import { PopoverHost, PopoverRotation } from '@tastic/hud';
4
- import { View } from 'react-native';
5
+ import { View, StyleProp, ViewStyle } from 'react-native';
5
6
 
6
7
  interface Profile {
7
8
  id: string;
@@ -27,6 +28,14 @@ declare function ProfileColorProvider({ preview, children }: ProfileColorProvide
27
28
  declare function useProfileColorPreview(): ((hex: string) => string) | undefined;
28
29
  declare function useProfileDisplayColor(hex: string): string;
29
30
 
31
+ interface ProfilePickerColorSection {
32
+ value: string;
33
+ onChange: (hex: string) => void;
34
+ previewValue?: (hex: string) => string;
35
+ swatches?: SeedColor[];
36
+ label?: string;
37
+ caption?: string;
38
+ }
30
39
  interface ProfilePickerAlignResult {
31
40
  align: 'left' | 'right' | 'center';
32
41
  verticalAlign: 'below' | 'above';
@@ -38,7 +47,7 @@ interface ProfilePickerContentSize {
38
47
  width: number;
39
48
  height: number;
40
49
  }
41
- declare function getProfilePickerContentSize(profileCount: number, hasManageRow?: boolean): ProfilePickerContentSize;
50
+ declare function getProfilePickerContentSize(profileCount: number, hasManageRow?: boolean, colorSection?: Pick<ProfilePickerColorSection, 'swatches' | 'caption'>): ProfilePickerContentSize;
42
51
  interface ProfilePickerProps<P extends Profile> {
43
52
  idPrefix: string;
44
53
  host: PopoverHost;
@@ -55,8 +64,10 @@ interface ProfilePickerProps<P extends Profile> {
55
64
  nullIcon?: string;
56
65
  onSelect: (profile: P | null) => void;
57
66
  onManage?: () => void;
67
+ colorSection?: ProfilePickerColorSection;
68
+ triggerStyle?: StyleProp<ViewStyle>;
58
69
  }
59
- declare function ProfilePicker<P extends Profile>({ idPrefix, host, profiles, selectedId, takenId, color, dark, align: forcedAlign, alignOverride, rotation, guestLabel, nullLabel, nullIcon, onSelect, onManage }: ProfilePickerProps<P>): react.JSX.Element;
70
+ declare function ProfilePicker<P extends Profile>({ idPrefix, host, profiles, selectedId, takenId, color, dark, align: forcedAlign, alignOverride, rotation, guestLabel, nullLabel, nullIcon, onSelect, onManage, colorSection, triggerStyle }: ProfilePickerProps<P>): react.JSX.Element;
60
71
 
61
72
  type MD3TextVariant$1 = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall';
62
73
  interface ProfileEditPatch {
@@ -77,12 +88,11 @@ interface ProfilesManagerProps {
77
88
  ref?: Ref<ProfilesManagerHandle>;
78
89
  fg?: string;
79
90
  fgMuted?: string;
80
- cardBg?: string;
81
91
  titleVariant?: MD3TextVariant$1;
82
92
  colorPreview?: (hex: string) => string;
83
93
  useColorPickerAlign?: (open: boolean, contentWidth: number, contentHeight: number) => ProfilePickerAlignResult;
84
94
  }
85
- declare function ProfilesManager({ profiles, defaultColor, onCreate, onSave, onDelete, headerLeft, ref, fg: fgOverride, fgMuted: fgMutedOverride, cardBg: cardBgOverride, titleVariant, colorPreview: colorPreviewProp, useColorPickerAlign }: ProfilesManagerProps): react.JSX.Element;
95
+ declare function ProfilesManager({ profiles, defaultColor, onCreate, onSave, onDelete, headerLeft, ref, fg: fgOverride, fgMuted: fgMutedOverride, titleVariant, colorPreview: colorPreviewProp, useColorPickerAlign }: ProfilesManagerProps): react.JSX.Element;
86
96
 
87
97
  type MD3TextVariant = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall';
88
98
  interface ProfilesScreenProps {
@@ -95,12 +105,11 @@ interface ProfilesScreenProps {
95
105
  fg?: string;
96
106
  fgMuted?: string;
97
107
  bg?: string;
98
- cardBg?: string;
99
108
  titleVariant?: MD3TextVariant;
100
109
  colorPreview?: (hex: string) => string;
101
110
  useColorPickerAlign?: ProfilesManagerProps['useColorPickerAlign'];
102
111
  }
103
- declare function ProfilesScreen({ profiles, defaultColor, onCreate, onSave, onDelete, onBack, fg: fgOverride, fgMuted, bg: bgOverride, cardBg, titleVariant, colorPreview, useColorPickerAlign }: ProfilesScreenProps): react.JSX.Element;
112
+ declare function ProfilesScreen({ profiles, defaultColor, onCreate, onSave, onDelete, onBack, fg: fgOverride, fgMuted, bg: bgOverride, titleVariant, colorPreview, useColorPickerAlign }: ProfilesScreenProps): react.JSX.Element;
104
113
 
105
114
  declare const MAX_PROFILE_NAME_LENGTH = 20;
106
115
  declare const MAX_TAG_LENGTH = 3;
@@ -219,4 +228,4 @@ declare function readSharedProfiles(groupId: string): Promise<Profile[] | null>;
219
228
  declare function loadSharedProfiles(groupId: string): Promise<Profile[]>;
220
229
  declare function saveSharedProfiles(groupId: string, profiles: Profile[]): Promise<void>;
221
230
 
222
- export { type CreateProfileInput, MAX_PROFILE_NAME_LENGTH, MAX_TAG_LENGTH, type Profile, ProfileChip, ProfileColorProvider, type ProfileEditPatch, type ProfileExtensionActions, type ProfileExtensionSlice, type ProfileExtensionState, ProfilePicker, type ProfilePickerAlignResult, type ProfilePickerContentSize, type ProfileSelectionActions, type ProfileSelectionSlice, type ProfileSelectionState, ProfilesManager, type ProfilesManagerHandle, type ProfilesManagerProps, ProfilesScreen, type ProfilesScreenProps, type SeatColorsActions, type SeatColorsSlice, type SeatColorsState, type SelectProfilePayload, type SetLastGuestColorPayload, type SetProfileExtensionPayload, type SetProfileOverridePayload, type UpdateProfilePayload, type UseSharedProfilesSyncOptions, type UseSharedProfilesSyncResult, avoidSeatColorClash, createProfileExtensionSlice, createProfileRecord, createProfileSelectionSlice, createSeatColorsSlice, getProfilePickerContentSize, isSharedProfileStoreAvailable, isValidProfile, isValidTag, loadSharedProfiles, profilesActions, profilesReducer, readSharedProfiles, resolveInitialProfiles, saveSharedProfiles, useProfileColorPreview, useProfileDisplayColor, useSharedProfilesSync };
231
+ export { type CreateProfileInput, MAX_PROFILE_NAME_LENGTH, MAX_TAG_LENGTH, type Profile, ProfileChip, ProfileColorProvider, type ProfileEditPatch, type ProfileExtensionActions, type ProfileExtensionSlice, type ProfileExtensionState, ProfilePicker, type ProfilePickerAlignResult, type ProfilePickerColorSection, type ProfilePickerContentSize, type ProfileSelectionActions, type ProfileSelectionSlice, type ProfileSelectionState, ProfilesManager, type ProfilesManagerHandle, type ProfilesManagerProps, ProfilesScreen, type ProfilesScreenProps, type SeatColorsActions, type SeatColorsSlice, type SeatColorsState, type SelectProfilePayload, type SetLastGuestColorPayload, type SetProfileExtensionPayload, type SetProfileOverridePayload, type UpdateProfilePayload, type UseSharedProfilesSyncOptions, type UseSharedProfilesSyncResult, avoidSeatColorClash, createProfileExtensionSlice, createProfileRecord, createProfileSelectionSlice, createSeatColorsSlice, getProfilePickerContentSize, isSharedProfileStoreAvailable, isValidProfile, isValidTag, loadSharedProfiles, profilesActions, profilesReducer, readSharedProfiles, resolveInitialProfiles, saveSharedProfiles, useProfileColorPreview, useProfileDisplayColor, useSharedProfilesSync };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, RefObject, Ref } from 'react';
3
+ import { SeedColor } from '@rific/auto-paper';
3
4
  import { PopoverHost, PopoverRotation } from '@tastic/hud';
4
- import { View } from 'react-native';
5
+ import { View, StyleProp, ViewStyle } from 'react-native';
5
6
 
6
7
  interface Profile {
7
8
  id: string;
@@ -27,6 +28,14 @@ declare function ProfileColorProvider({ preview, children }: ProfileColorProvide
27
28
  declare function useProfileColorPreview(): ((hex: string) => string) | undefined;
28
29
  declare function useProfileDisplayColor(hex: string): string;
29
30
 
31
+ interface ProfilePickerColorSection {
32
+ value: string;
33
+ onChange: (hex: string) => void;
34
+ previewValue?: (hex: string) => string;
35
+ swatches?: SeedColor[];
36
+ label?: string;
37
+ caption?: string;
38
+ }
30
39
  interface ProfilePickerAlignResult {
31
40
  align: 'left' | 'right' | 'center';
32
41
  verticalAlign: 'below' | 'above';
@@ -38,7 +47,7 @@ interface ProfilePickerContentSize {
38
47
  width: number;
39
48
  height: number;
40
49
  }
41
- declare function getProfilePickerContentSize(profileCount: number, hasManageRow?: boolean): ProfilePickerContentSize;
50
+ declare function getProfilePickerContentSize(profileCount: number, hasManageRow?: boolean, colorSection?: Pick<ProfilePickerColorSection, 'swatches' | 'caption'>): ProfilePickerContentSize;
42
51
  interface ProfilePickerProps<P extends Profile> {
43
52
  idPrefix: string;
44
53
  host: PopoverHost;
@@ -55,8 +64,10 @@ interface ProfilePickerProps<P extends Profile> {
55
64
  nullIcon?: string;
56
65
  onSelect: (profile: P | null) => void;
57
66
  onManage?: () => void;
67
+ colorSection?: ProfilePickerColorSection;
68
+ triggerStyle?: StyleProp<ViewStyle>;
58
69
  }
59
- declare function ProfilePicker<P extends Profile>({ idPrefix, host, profiles, selectedId, takenId, color, dark, align: forcedAlign, alignOverride, rotation, guestLabel, nullLabel, nullIcon, onSelect, onManage }: ProfilePickerProps<P>): react.JSX.Element;
70
+ declare function ProfilePicker<P extends Profile>({ idPrefix, host, profiles, selectedId, takenId, color, dark, align: forcedAlign, alignOverride, rotation, guestLabel, nullLabel, nullIcon, onSelect, onManage, colorSection, triggerStyle }: ProfilePickerProps<P>): react.JSX.Element;
60
71
 
61
72
  type MD3TextVariant$1 = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall';
62
73
  interface ProfileEditPatch {
@@ -77,12 +88,11 @@ interface ProfilesManagerProps {
77
88
  ref?: Ref<ProfilesManagerHandle>;
78
89
  fg?: string;
79
90
  fgMuted?: string;
80
- cardBg?: string;
81
91
  titleVariant?: MD3TextVariant$1;
82
92
  colorPreview?: (hex: string) => string;
83
93
  useColorPickerAlign?: (open: boolean, contentWidth: number, contentHeight: number) => ProfilePickerAlignResult;
84
94
  }
85
- declare function ProfilesManager({ profiles, defaultColor, onCreate, onSave, onDelete, headerLeft, ref, fg: fgOverride, fgMuted: fgMutedOverride, cardBg: cardBgOverride, titleVariant, colorPreview: colorPreviewProp, useColorPickerAlign }: ProfilesManagerProps): react.JSX.Element;
95
+ declare function ProfilesManager({ profiles, defaultColor, onCreate, onSave, onDelete, headerLeft, ref, fg: fgOverride, fgMuted: fgMutedOverride, titleVariant, colorPreview: colorPreviewProp, useColorPickerAlign }: ProfilesManagerProps): react.JSX.Element;
86
96
 
87
97
  type MD3TextVariant = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall';
88
98
  interface ProfilesScreenProps {
@@ -95,12 +105,11 @@ interface ProfilesScreenProps {
95
105
  fg?: string;
96
106
  fgMuted?: string;
97
107
  bg?: string;
98
- cardBg?: string;
99
108
  titleVariant?: MD3TextVariant;
100
109
  colorPreview?: (hex: string) => string;
101
110
  useColorPickerAlign?: ProfilesManagerProps['useColorPickerAlign'];
102
111
  }
103
- declare function ProfilesScreen({ profiles, defaultColor, onCreate, onSave, onDelete, onBack, fg: fgOverride, fgMuted, bg: bgOverride, cardBg, titleVariant, colorPreview, useColorPickerAlign }: ProfilesScreenProps): react.JSX.Element;
112
+ declare function ProfilesScreen({ profiles, defaultColor, onCreate, onSave, onDelete, onBack, fg: fgOverride, fgMuted, bg: bgOverride, titleVariant, colorPreview, useColorPickerAlign }: ProfilesScreenProps): react.JSX.Element;
104
113
 
105
114
  declare const MAX_PROFILE_NAME_LENGTH = 20;
106
115
  declare const MAX_TAG_LENGTH = 3;
@@ -219,4 +228,4 @@ declare function readSharedProfiles(groupId: string): Promise<Profile[] | null>;
219
228
  declare function loadSharedProfiles(groupId: string): Promise<Profile[]>;
220
229
  declare function saveSharedProfiles(groupId: string, profiles: Profile[]): Promise<void>;
221
230
 
222
- export { type CreateProfileInput, MAX_PROFILE_NAME_LENGTH, MAX_TAG_LENGTH, type Profile, ProfileChip, ProfileColorProvider, type ProfileEditPatch, type ProfileExtensionActions, type ProfileExtensionSlice, type ProfileExtensionState, ProfilePicker, type ProfilePickerAlignResult, type ProfilePickerContentSize, type ProfileSelectionActions, type ProfileSelectionSlice, type ProfileSelectionState, ProfilesManager, type ProfilesManagerHandle, type ProfilesManagerProps, ProfilesScreen, type ProfilesScreenProps, type SeatColorsActions, type SeatColorsSlice, type SeatColorsState, type SelectProfilePayload, type SetLastGuestColorPayload, type SetProfileExtensionPayload, type SetProfileOverridePayload, type UpdateProfilePayload, type UseSharedProfilesSyncOptions, type UseSharedProfilesSyncResult, avoidSeatColorClash, createProfileExtensionSlice, createProfileRecord, createProfileSelectionSlice, createSeatColorsSlice, getProfilePickerContentSize, isSharedProfileStoreAvailable, isValidProfile, isValidTag, loadSharedProfiles, profilesActions, profilesReducer, readSharedProfiles, resolveInitialProfiles, saveSharedProfiles, useProfileColorPreview, useProfileDisplayColor, useSharedProfilesSync };
231
+ export { type CreateProfileInput, MAX_PROFILE_NAME_LENGTH, MAX_TAG_LENGTH, type Profile, ProfileChip, ProfileColorProvider, type ProfileEditPatch, type ProfileExtensionActions, type ProfileExtensionSlice, type ProfileExtensionState, ProfilePicker, type ProfilePickerAlignResult, type ProfilePickerColorSection, type ProfilePickerContentSize, type ProfileSelectionActions, type ProfileSelectionSlice, type ProfileSelectionState, ProfilesManager, type ProfilesManagerHandle, type ProfilesManagerProps, ProfilesScreen, type ProfilesScreenProps, type SeatColorsActions, type SeatColorsSlice, type SeatColorsState, type SelectProfilePayload, type SetLastGuestColorPayload, type SetProfileExtensionPayload, type SetProfileOverridePayload, type UpdateProfilePayload, type UseSharedProfilesSyncOptions, type UseSharedProfilesSyncResult, avoidSeatColorClash, createProfileExtensionSlice, createProfileRecord, createProfileSelectionSlice, createSeatColorsSlice, getProfilePickerContentSize, isSharedProfileStoreAvailable, isValidProfile, isValidTag, loadSharedProfiles, profilesActions, profilesReducer, readSharedProfiles, resolveInitialProfiles, saveSharedProfiles, useProfileColorPreview, useProfileDisplayColor, useSharedProfilesSync };