@tastic/profile 0.14.1 → 0.16.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 +46 -11
- package/dist/index.d.mts +67 -30
- package/dist/index.d.ts +67 -30
- package/dist/index.js +429 -237
- package/dist/index.mjs +393 -206
- package/package.json +9 -9
- package/src/IdentityChip.tsx +8 -2
- package/src/OptionPicker.tsx +64 -0
- package/src/PickerMenu.tsx +512 -0
- package/src/ProfileColorContext.tsx +30 -8
- package/src/ProfilePicker.tsx +61 -426
- package/src/ProfilesManager.tsx +9 -6
- package/src/SwatchLayer.tsx +28 -0
- package/src/index.ts +4 -3
- package/src/redux/resolveInitialProfiles.ts +3 -2
- package/src/redux/seatColorsSlice.ts +79 -29
- package/src/redux/useSharedProfilesSync.ts +12 -6
- package/src/sharedProfileStore.ts +87 -11
package/README.md
CHANGED
|
@@ -49,7 +49,9 @@ see its own doc comment for why that component is generic over your own `Profile
|
|
|
49
49
|
- **`ProfilePicker`**: a name trigger + selection popover: pick an existing profile, fall back to a
|
|
50
50
|
null/"guest" selection, or (if `onManage` is passed) navigate to a management screen. Selection
|
|
51
51
|
only - creating, renaming, and deleting all live in `ProfilesManager`. Generic over your own
|
|
52
|
-
`Profile` type (see above).
|
|
52
|
+
`Profile` type (see above). `takenId` disables one other seat's profile in the list; `takenIds`
|
|
53
|
+
(an array) disables several, for a lobby with more than two seats, and never disables the
|
|
54
|
+
picker's own selection, so you can pass every seated id. Placement props (all optional, see "Fake-rotated frames" below):
|
|
53
55
|
`align` (force a horizontal side), `alignOverride` (substitute the whole placement result), and
|
|
54
56
|
`rotation` (forwarded to the automatic measurement). `colorSection`
|
|
55
57
|
(`{ value, onChange, previewValue?, swatches?, label?, caption? }`) puts a Color row at the top of
|
|
@@ -72,7 +74,7 @@ see its own doc comment for why that component is generic over your own `Profile
|
|
|
72
74
|
`profiles`/`defaultColor`/`onCreate`/`onSave`/`onDelete` as `ProfilesManager` itself, plus
|
|
73
75
|
`onBack`. Owns its own `ProfilesManagerHandle` ref internally - there's no `ref` prop here, since
|
|
74
76
|
nothing outside it needs one anymore.
|
|
75
|
-
- **`readSharedProfiles` / `loadSharedProfiles` / `saveSharedProfiles` / `isSharedProfileStoreAvailable`**: an *optional*
|
|
77
|
+
- **`readSharedProfiles` / `loadSharedProfiles` / `saveSharedProfiles` / `subscribeSharedProfiles` / `isSharedProfileStoreAvailable`**: an *optional*
|
|
76
78
|
cross-app roster, shared between multiple apps of yours via a native iOS App Group (same Apple
|
|
77
79
|
Developer Team, same `"com.apple.security.application-groups"` entitlement value on every
|
|
78
80
|
participating app). This only ever carries the base `Profile` shape above - a host app's own
|
|
@@ -103,9 +105,17 @@ see its own doc comment for why that component is generic over your own `Profile
|
|
|
103
105
|
result can't replace a roster or lead to a write.
|
|
104
106
|
|
|
105
107
|
Backed by a small native Expo Module (`ios/TasticProfileModule.swift`) wrapping
|
|
106
|
-
`UserDefaults(suiteName:)`
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
`UserDefaults(suiteName:)` on iOS (see `expo-module.config.json`'s `"apple"`-only platform list),
|
|
109
|
+
and on the web by `localStorage`, under the key `<groupId>:sharedProfiles`: games served from one
|
|
110
|
+
origin (for example `games.example.com/<game>/`) share it the way apps share an App Group, while
|
|
111
|
+
games on different origins can't see each other's. The web store writes and removes a probe key
|
|
112
|
+
once at load and stays unavailable if that fails (storage blocked), and after a write that fails
|
|
113
|
+
anyway, reads fail until a write succeeds, so an older roster can't undo a local change.
|
|
114
|
+
`subscribeSharedProfiles(groupId, listener)` hands `listener` the roster another tab or game on
|
|
115
|
+
the same origin has just saved (the browser's `storage` event); it does nothing on native.
|
|
116
|
+
`useSharedProfilesSync` subscribes for you. `isSharedProfileStoreAvailable` is `false` on
|
|
117
|
+
Android, on a web page that can't write `localStorage`, and on any iOS build that hasn't run
|
|
118
|
+
`expo prebuild` since adding this App Group's entitlement, so a host app always needs its own
|
|
109
119
|
local-storage fallback path regardless of platform. Requires the App Group itself to be declared
|
|
110
120
|
in each consuming app's own Expo config, e.g.:
|
|
111
121
|
|
|
@@ -278,7 +288,7 @@ so a host app plugs the reducer(s) into whatever store it already has:
|
|
|
278
288
|
Always local, like the guest/CPU/override colors below, and never part of the shared
|
|
279
289
|
App Group roster, since who's selected on *this* device is naturally per-app, per-device state.
|
|
280
290
|
|
|
281
|
-
## Muted profile colors (`ProfileColorProvider`)
|
|
291
|
+
## Muted profile colors and drawn swatches (`ProfileColorProvider`)
|
|
282
292
|
|
|
283
293
|
An app that draws profile colors through a transform (Solitaire blends them toward its muted
|
|
284
294
|
card-back palette) wraps its tree once:
|
|
@@ -298,6 +308,26 @@ for free. Only what's drawn changes: saved colors, `onCreate`/`onSave` values an
|
|
|
298
308
|
untouched. `useProfileColorPreview()` returns the provider's function (or `undefined`), and
|
|
299
309
|
`useProfileDisplayColor(hex)` resolves one color. Without a provider nothing changes.
|
|
300
310
|
|
|
311
|
+
`renderSwatch` (also optional, with or without `preview`) draws the fill of every round swatch this
|
|
312
|
+
package draws, in place of the flat color: `ProfileChip`, the pickers' chip trigger, the Color row's
|
|
313
|
+
swatch and the color page's swatches. It's called as `renderSwatch(color, size)` with the drawn
|
|
314
|
+
color (after `preview`) and the circle's diameter, and its drawing is clipped to the circle, behind
|
|
315
|
+
the tag, icon or check. The tag and check still take their contrast from `color`, so treat it as
|
|
316
|
+
the primary color of whatever you draw. Hangman draws a pie of each color's triad:
|
|
317
|
+
|
|
318
|
+
```tsx
|
|
319
|
+
import { getTriadicPalette } from '@rific/auto-paper'
|
|
320
|
+
import { ProfileColorProvider, type ProfileSwatchRenderer } from '@tastic/profile'
|
|
321
|
+
|
|
322
|
+
const renderSwatch: ProfileSwatchRenderer = (color, size) => <TriadPie colors={getTriadicPalette(color)} size={size} />
|
|
323
|
+
<ProfileColorProvider renderSwatch={renderSwatch}>{children}</ProfileColorProvider>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
(`TriadPie` is your own component, e.g. three `react-native-svg` arcs.) Give it a stable identity
|
|
327
|
+
(module level, or `useCallback`). Rows that fill with a color (a selected picker row) stay flat, and
|
|
328
|
+
so do `@tastic/hud`'s `InlineColorPicker` swatches in `ProfilesManager`'s edit row, which don't read
|
|
329
|
+
this provider. `useProfileSwatchRenderer()` returns it (or `undefined`).
|
|
330
|
+
|
|
301
331
|
## Per-seat color persistence
|
|
302
332
|
|
|
303
333
|
A loadout/lobby screen's color for a given seat is never just "the selected profile's saved
|
|
@@ -362,11 +392,16 @@ Published to the public npm registry via tag-based CI (OIDC trusted publishing -
|
|
|
362
392
|
## Peer dependencies
|
|
363
393
|
|
|
364
394
|
`react`, `react-native`, `react-native-paper`, `react-native-safe-area-context`, `@rific/auto-paper`
|
|
365
|
-
(`getContrastColor`, `useAutoPaperTheme`), `@rific/feedback-press`
|
|
366
|
-
`@rific/focus-chain` (`useFocusChain`), `@rific/toaster` (`useToast`),
|
|
367
|
-
(`
|
|
368
|
-
(a peer of `@tastic/hud` itself) - none of these are bundled, so
|
|
369
|
-
already has.
|
|
395
|
+
(`defaultColors`, `FadingScrollView`, `getContrastColor`, `useAutoPaperTheme`), `@rific/feedback-press`
|
|
396
|
+
(`TouchableRipple`), `@rific/focus-chain` (`useFocusChain`), `@rific/toaster` (`useToast`),
|
|
397
|
+
`@tastic/hud` >= 0.23.0 (`ConfirmDialog`, `InlineColorPicker`, `PopoverBody`, `useAutoAlign`,
|
|
398
|
+
`usePopoverHost`), `@tastic/core` (a peer of `@tastic/hud` itself) - none of these are bundled, so
|
|
399
|
+
use whatever versions your app already has.
|
|
400
|
+
|
|
401
|
+
This package imports `@tastic/hud` only through its light `@tastic/hud/chrome` entry, never the main
|
|
402
|
+
one (which also loads Skia and `@tastic/split-screen`), so an app with neither, like Hangman, can use
|
|
403
|
+
every component here. That's why it needs hud 0.23.0, the first whose `./chrome` has the popover
|
|
404
|
+
pieces and the color picker.
|
|
370
405
|
|
|
371
406
|
`expo-modules-core` is an *optional* peer - only resolved by `loadSharedProfiles`/`saveSharedProfiles`
|
|
372
407
|
for the native App Group bridge described above; safe to omit entirely on an Android/web-only
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,54 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { PopoverHost, PopoverRotation } from '@tastic/hud';
|
|
2
|
+
import { RefObject, ReactNode, Ref } from 'react';
|
|
3
|
+
import { PopoverHost, PopoverRotation } from '@tastic/hud/chrome';
|
|
5
4
|
import { View, StyleProp, ViewStyle } from 'react-native';
|
|
5
|
+
import { SeedColor } from '@rific/auto-paper';
|
|
6
|
+
|
|
7
|
+
interface ProfilePickerColorSection {
|
|
8
|
+
value: string;
|
|
9
|
+
onChange: (hex: string) => void;
|
|
10
|
+
previewValue?: (hex: string) => string;
|
|
11
|
+
swatches?: SeedColor[];
|
|
12
|
+
label?: string;
|
|
13
|
+
caption?: string;
|
|
14
|
+
takenValue?: string;
|
|
15
|
+
allowSwapTaken?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface ProfilePickerAlignResult {
|
|
18
|
+
align: 'left' | 'right' | 'center';
|
|
19
|
+
verticalAlign: 'below' | 'above';
|
|
20
|
+
maxHeight: number;
|
|
21
|
+
measured: boolean;
|
|
22
|
+
triggerRef: RefObject<View | null>;
|
|
23
|
+
}
|
|
24
|
+
interface ProfilePickerContentSize {
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface OptionPickerOption<T extends string> {
|
|
30
|
+
value: T;
|
|
31
|
+
label: string;
|
|
32
|
+
icon?: string;
|
|
33
|
+
}
|
|
34
|
+
declare function getOptionPickerContentSize(optionCount: number, colorSection?: Pick<ProfilePickerColorSection, 'swatches' | 'caption'>): ProfilePickerContentSize;
|
|
35
|
+
interface OptionPickerProps<T extends string> {
|
|
36
|
+
id: string;
|
|
37
|
+
host: PopoverHost;
|
|
38
|
+
options: OptionPickerOption<T>[];
|
|
39
|
+
value: T;
|
|
40
|
+
onChange: (value: T) => void;
|
|
41
|
+
color: string;
|
|
42
|
+
dark: boolean;
|
|
43
|
+
icon: string;
|
|
44
|
+
rowIcon?: string;
|
|
45
|
+
colorSection?: ProfilePickerColorSection;
|
|
46
|
+
align?: 'left' | 'right' | 'center';
|
|
47
|
+
alignOverride?: ProfilePickerAlignResult;
|
|
48
|
+
rotation?: PopoverRotation;
|
|
49
|
+
triggerStyle?: StyleProp<ViewStyle>;
|
|
50
|
+
}
|
|
51
|
+
declare function OptionPicker<T extends string>({ id, host, options, value, onChange, color, dark, icon, rowIcon, colorSection, align, alignOverride, rotation, triggerStyle }: OptionPickerProps<T>): react.JSX.Element;
|
|
6
52
|
|
|
7
53
|
interface Profile {
|
|
8
54
|
id: string;
|
|
@@ -20,33 +66,17 @@ interface Props {
|
|
|
20
66
|
}
|
|
21
67
|
declare function ProfileChip({ profile, size, filled }: Props): react.JSX.Element;
|
|
22
68
|
|
|
69
|
+
type ProfileSwatchRenderer = (color: string, size: number) => ReactNode;
|
|
23
70
|
interface ProfileColorProviderProps {
|
|
24
|
-
preview
|
|
71
|
+
preview?: (hex: string) => string;
|
|
72
|
+
renderSwatch?: ProfileSwatchRenderer;
|
|
25
73
|
children: ReactNode;
|
|
26
74
|
}
|
|
27
|
-
declare function ProfileColorProvider({ preview, children }: ProfileColorProviderProps): react.JSX.Element;
|
|
75
|
+
declare function ProfileColorProvider({ preview, renderSwatch, children }: ProfileColorProviderProps): react.JSX.Element;
|
|
28
76
|
declare function useProfileColorPreview(): ((hex: string) => string) | undefined;
|
|
77
|
+
declare function useProfileSwatchRenderer(): ProfileSwatchRenderer | undefined;
|
|
29
78
|
declare function useProfileDisplayColor(hex: string): string;
|
|
30
79
|
|
|
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
|
-
}
|
|
39
|
-
interface ProfilePickerAlignResult {
|
|
40
|
-
align: 'left' | 'right' | 'center';
|
|
41
|
-
verticalAlign: 'below' | 'above';
|
|
42
|
-
maxHeight: number;
|
|
43
|
-
measured: boolean;
|
|
44
|
-
triggerRef: RefObject<View | null>;
|
|
45
|
-
}
|
|
46
|
-
interface ProfilePickerContentSize {
|
|
47
|
-
width: number;
|
|
48
|
-
height: number;
|
|
49
|
-
}
|
|
50
80
|
declare function getProfilePickerContentSize(profileCount: number, hasManageRow?: boolean, colorSection?: Pick<ProfilePickerColorSection, 'swatches' | 'caption'>): ProfilePickerContentSize;
|
|
51
81
|
interface ProfilePickerProps<P extends Profile> {
|
|
52
82
|
idPrefix: string;
|
|
@@ -54,6 +84,7 @@ interface ProfilePickerProps<P extends Profile> {
|
|
|
54
84
|
profiles: P[];
|
|
55
85
|
selectedId: string | null;
|
|
56
86
|
takenId?: string | null;
|
|
87
|
+
takenIds?: readonly string[];
|
|
57
88
|
color: string;
|
|
58
89
|
dark: boolean;
|
|
59
90
|
align?: 'left' | 'right' | 'center';
|
|
@@ -67,7 +98,7 @@ interface ProfilePickerProps<P extends Profile> {
|
|
|
67
98
|
colorSection?: ProfilePickerColorSection;
|
|
68
99
|
triggerStyle?: StyleProp<ViewStyle>;
|
|
69
100
|
}
|
|
70
|
-
declare function ProfilePicker<P extends Profile>({ idPrefix, host, profiles, selectedId, takenId, color, dark, align
|
|
101
|
+
declare function ProfilePicker<P extends Profile>({ idPrefix, host, profiles, selectedId, takenId, takenIds, color, dark, align, alignOverride, rotation, guestLabel, nullLabel, nullIcon, onSelect, onManage, colorSection, triggerStyle }: ProfilePickerProps<P>): react.JSX.Element;
|
|
71
102
|
|
|
72
103
|
type MD3TextVariant$1 = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall';
|
|
73
104
|
interface ProfileEditPatch {
|
|
@@ -189,19 +220,23 @@ interface SetLastGuestColorPayload<TSeat> {
|
|
|
189
220
|
color: string;
|
|
190
221
|
seat: TSeat;
|
|
191
222
|
}
|
|
192
|
-
interface
|
|
223
|
+
interface ProfileColorPick {
|
|
224
|
+
color: string;
|
|
225
|
+
profileColor: string;
|
|
226
|
+
}
|
|
227
|
+
interface SetProfileColorPayload {
|
|
228
|
+
profile: Pick<Profile, 'id' | 'color'>;
|
|
193
229
|
color: string | null;
|
|
194
|
-
seat: TSeat;
|
|
195
230
|
}
|
|
196
231
|
interface SeatColorsActions<TSeat> {
|
|
197
232
|
setLastCpuColor: ActionCreator<string>;
|
|
198
233
|
setLastGuestColor: ActionCreator<SetLastGuestColorPayload<TSeat>>;
|
|
199
|
-
|
|
234
|
+
setProfileColor: ActionCreator<SetProfileColorPayload>;
|
|
200
235
|
}
|
|
201
236
|
type SeatColorsState<TSeat extends string | number> = {
|
|
202
237
|
lastCpuColor: string;
|
|
203
238
|
lastGuestColor: Record<TSeat, string>;
|
|
204
|
-
|
|
239
|
+
profileColors: Record<string, ProfileColorPick>;
|
|
205
240
|
};
|
|
206
241
|
interface SeatColorsSlice<TSeat extends string | number> {
|
|
207
242
|
actions: SeatColorsActions<TSeat>;
|
|
@@ -210,6 +245,7 @@ interface SeatColorsSlice<TSeat extends string | number> {
|
|
|
210
245
|
payload?: unknown;
|
|
211
246
|
}) => SeatColorsState<TSeat>;
|
|
212
247
|
}
|
|
248
|
+
declare function profileSeatColor(profile: Pick<Profile, 'id' | 'color'>, profileColors: Record<string, ProfileColorPick>): string;
|
|
213
249
|
declare function createSeatColorsSlice<TSeat extends string | number>(namespace: string, defaultState: SeatColorsState<TSeat>, mountKey?: string): SeatColorsSlice<TSeat>;
|
|
214
250
|
|
|
215
251
|
interface UseSharedProfilesSyncOptions {
|
|
@@ -227,5 +263,6 @@ declare const isSharedProfileStoreAvailable: boolean;
|
|
|
227
263
|
declare function readSharedProfiles(groupId: string): Promise<Profile[] | null>;
|
|
228
264
|
declare function loadSharedProfiles(groupId: string): Promise<Profile[]>;
|
|
229
265
|
declare function saveSharedProfiles(groupId: string, profiles: Profile[]): Promise<void>;
|
|
266
|
+
declare function subscribeSharedProfiles(groupId: string, listener: (profiles: Profile[]) => void): () => void;
|
|
230
267
|
|
|
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
|
|
268
|
+
export { type CreateProfileInput, MAX_PROFILE_NAME_LENGTH, MAX_TAG_LENGTH, OptionPicker, type OptionPickerOption, type Profile, ProfileChip, type ProfileColorPick, ProfileColorProvider, type ProfileEditPatch, type ProfileExtensionActions, type ProfileExtensionSlice, type ProfileExtensionState, ProfilePicker, type ProfilePickerAlignResult, type ProfilePickerColorSection, type ProfilePickerContentSize, type ProfileSelectionActions, type ProfileSelectionSlice, type ProfileSelectionState, type ProfileSwatchRenderer, ProfilesManager, type ProfilesManagerHandle, type ProfilesManagerProps, ProfilesScreen, type ProfilesScreenProps, type SeatColorsActions, type SeatColorsSlice, type SeatColorsState, type SelectProfilePayload, type SetLastGuestColorPayload, type SetProfileColorPayload, type SetProfileExtensionPayload, type UpdateProfilePayload, type UseSharedProfilesSyncOptions, type UseSharedProfilesSyncResult, avoidSeatColorClash, createProfileExtensionSlice, createProfileRecord, createProfileSelectionSlice, createSeatColorsSlice, getOptionPickerContentSize, getProfilePickerContentSize, isSharedProfileStoreAvailable, isValidProfile, isValidTag, loadSharedProfiles, profileSeatColor, profilesActions, profilesReducer, readSharedProfiles, resolveInitialProfiles, saveSharedProfiles, subscribeSharedProfiles, useProfileColorPreview, useProfileDisplayColor, useProfileSwatchRenderer, useSharedProfilesSync };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,54 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { PopoverHost, PopoverRotation } from '@tastic/hud';
|
|
2
|
+
import { RefObject, ReactNode, Ref } from 'react';
|
|
3
|
+
import { PopoverHost, PopoverRotation } from '@tastic/hud/chrome';
|
|
5
4
|
import { View, StyleProp, ViewStyle } from 'react-native';
|
|
5
|
+
import { SeedColor } from '@rific/auto-paper';
|
|
6
|
+
|
|
7
|
+
interface ProfilePickerColorSection {
|
|
8
|
+
value: string;
|
|
9
|
+
onChange: (hex: string) => void;
|
|
10
|
+
previewValue?: (hex: string) => string;
|
|
11
|
+
swatches?: SeedColor[];
|
|
12
|
+
label?: string;
|
|
13
|
+
caption?: string;
|
|
14
|
+
takenValue?: string;
|
|
15
|
+
allowSwapTaken?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface ProfilePickerAlignResult {
|
|
18
|
+
align: 'left' | 'right' | 'center';
|
|
19
|
+
verticalAlign: 'below' | 'above';
|
|
20
|
+
maxHeight: number;
|
|
21
|
+
measured: boolean;
|
|
22
|
+
triggerRef: RefObject<View | null>;
|
|
23
|
+
}
|
|
24
|
+
interface ProfilePickerContentSize {
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface OptionPickerOption<T extends string> {
|
|
30
|
+
value: T;
|
|
31
|
+
label: string;
|
|
32
|
+
icon?: string;
|
|
33
|
+
}
|
|
34
|
+
declare function getOptionPickerContentSize(optionCount: number, colorSection?: Pick<ProfilePickerColorSection, 'swatches' | 'caption'>): ProfilePickerContentSize;
|
|
35
|
+
interface OptionPickerProps<T extends string> {
|
|
36
|
+
id: string;
|
|
37
|
+
host: PopoverHost;
|
|
38
|
+
options: OptionPickerOption<T>[];
|
|
39
|
+
value: T;
|
|
40
|
+
onChange: (value: T) => void;
|
|
41
|
+
color: string;
|
|
42
|
+
dark: boolean;
|
|
43
|
+
icon: string;
|
|
44
|
+
rowIcon?: string;
|
|
45
|
+
colorSection?: ProfilePickerColorSection;
|
|
46
|
+
align?: 'left' | 'right' | 'center';
|
|
47
|
+
alignOverride?: ProfilePickerAlignResult;
|
|
48
|
+
rotation?: PopoverRotation;
|
|
49
|
+
triggerStyle?: StyleProp<ViewStyle>;
|
|
50
|
+
}
|
|
51
|
+
declare function OptionPicker<T extends string>({ id, host, options, value, onChange, color, dark, icon, rowIcon, colorSection, align, alignOverride, rotation, triggerStyle }: OptionPickerProps<T>): react.JSX.Element;
|
|
6
52
|
|
|
7
53
|
interface Profile {
|
|
8
54
|
id: string;
|
|
@@ -20,33 +66,17 @@ interface Props {
|
|
|
20
66
|
}
|
|
21
67
|
declare function ProfileChip({ profile, size, filled }: Props): react.JSX.Element;
|
|
22
68
|
|
|
69
|
+
type ProfileSwatchRenderer = (color: string, size: number) => ReactNode;
|
|
23
70
|
interface ProfileColorProviderProps {
|
|
24
|
-
preview
|
|
71
|
+
preview?: (hex: string) => string;
|
|
72
|
+
renderSwatch?: ProfileSwatchRenderer;
|
|
25
73
|
children: ReactNode;
|
|
26
74
|
}
|
|
27
|
-
declare function ProfileColorProvider({ preview, children }: ProfileColorProviderProps): react.JSX.Element;
|
|
75
|
+
declare function ProfileColorProvider({ preview, renderSwatch, children }: ProfileColorProviderProps): react.JSX.Element;
|
|
28
76
|
declare function useProfileColorPreview(): ((hex: string) => string) | undefined;
|
|
77
|
+
declare function useProfileSwatchRenderer(): ProfileSwatchRenderer | undefined;
|
|
29
78
|
declare function useProfileDisplayColor(hex: string): string;
|
|
30
79
|
|
|
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
|
-
}
|
|
39
|
-
interface ProfilePickerAlignResult {
|
|
40
|
-
align: 'left' | 'right' | 'center';
|
|
41
|
-
verticalAlign: 'below' | 'above';
|
|
42
|
-
maxHeight: number;
|
|
43
|
-
measured: boolean;
|
|
44
|
-
triggerRef: RefObject<View | null>;
|
|
45
|
-
}
|
|
46
|
-
interface ProfilePickerContentSize {
|
|
47
|
-
width: number;
|
|
48
|
-
height: number;
|
|
49
|
-
}
|
|
50
80
|
declare function getProfilePickerContentSize(profileCount: number, hasManageRow?: boolean, colorSection?: Pick<ProfilePickerColorSection, 'swatches' | 'caption'>): ProfilePickerContentSize;
|
|
51
81
|
interface ProfilePickerProps<P extends Profile> {
|
|
52
82
|
idPrefix: string;
|
|
@@ -54,6 +84,7 @@ interface ProfilePickerProps<P extends Profile> {
|
|
|
54
84
|
profiles: P[];
|
|
55
85
|
selectedId: string | null;
|
|
56
86
|
takenId?: string | null;
|
|
87
|
+
takenIds?: readonly string[];
|
|
57
88
|
color: string;
|
|
58
89
|
dark: boolean;
|
|
59
90
|
align?: 'left' | 'right' | 'center';
|
|
@@ -67,7 +98,7 @@ interface ProfilePickerProps<P extends Profile> {
|
|
|
67
98
|
colorSection?: ProfilePickerColorSection;
|
|
68
99
|
triggerStyle?: StyleProp<ViewStyle>;
|
|
69
100
|
}
|
|
70
|
-
declare function ProfilePicker<P extends Profile>({ idPrefix, host, profiles, selectedId, takenId, color, dark, align
|
|
101
|
+
declare function ProfilePicker<P extends Profile>({ idPrefix, host, profiles, selectedId, takenId, takenIds, color, dark, align, alignOverride, rotation, guestLabel, nullLabel, nullIcon, onSelect, onManage, colorSection, triggerStyle }: ProfilePickerProps<P>): react.JSX.Element;
|
|
71
102
|
|
|
72
103
|
type MD3TextVariant$1 = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall';
|
|
73
104
|
interface ProfileEditPatch {
|
|
@@ -189,19 +220,23 @@ interface SetLastGuestColorPayload<TSeat> {
|
|
|
189
220
|
color: string;
|
|
190
221
|
seat: TSeat;
|
|
191
222
|
}
|
|
192
|
-
interface
|
|
223
|
+
interface ProfileColorPick {
|
|
224
|
+
color: string;
|
|
225
|
+
profileColor: string;
|
|
226
|
+
}
|
|
227
|
+
interface SetProfileColorPayload {
|
|
228
|
+
profile: Pick<Profile, 'id' | 'color'>;
|
|
193
229
|
color: string | null;
|
|
194
|
-
seat: TSeat;
|
|
195
230
|
}
|
|
196
231
|
interface SeatColorsActions<TSeat> {
|
|
197
232
|
setLastCpuColor: ActionCreator<string>;
|
|
198
233
|
setLastGuestColor: ActionCreator<SetLastGuestColorPayload<TSeat>>;
|
|
199
|
-
|
|
234
|
+
setProfileColor: ActionCreator<SetProfileColorPayload>;
|
|
200
235
|
}
|
|
201
236
|
type SeatColorsState<TSeat extends string | number> = {
|
|
202
237
|
lastCpuColor: string;
|
|
203
238
|
lastGuestColor: Record<TSeat, string>;
|
|
204
|
-
|
|
239
|
+
profileColors: Record<string, ProfileColorPick>;
|
|
205
240
|
};
|
|
206
241
|
interface SeatColorsSlice<TSeat extends string | number> {
|
|
207
242
|
actions: SeatColorsActions<TSeat>;
|
|
@@ -210,6 +245,7 @@ interface SeatColorsSlice<TSeat extends string | number> {
|
|
|
210
245
|
payload?: unknown;
|
|
211
246
|
}) => SeatColorsState<TSeat>;
|
|
212
247
|
}
|
|
248
|
+
declare function profileSeatColor(profile: Pick<Profile, 'id' | 'color'>, profileColors: Record<string, ProfileColorPick>): string;
|
|
213
249
|
declare function createSeatColorsSlice<TSeat extends string | number>(namespace: string, defaultState: SeatColorsState<TSeat>, mountKey?: string): SeatColorsSlice<TSeat>;
|
|
214
250
|
|
|
215
251
|
interface UseSharedProfilesSyncOptions {
|
|
@@ -227,5 +263,6 @@ declare const isSharedProfileStoreAvailable: boolean;
|
|
|
227
263
|
declare function readSharedProfiles(groupId: string): Promise<Profile[] | null>;
|
|
228
264
|
declare function loadSharedProfiles(groupId: string): Promise<Profile[]>;
|
|
229
265
|
declare function saveSharedProfiles(groupId: string, profiles: Profile[]): Promise<void>;
|
|
266
|
+
declare function subscribeSharedProfiles(groupId: string, listener: (profiles: Profile[]) => void): () => void;
|
|
230
267
|
|
|
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
|
|
268
|
+
export { type CreateProfileInput, MAX_PROFILE_NAME_LENGTH, MAX_TAG_LENGTH, OptionPicker, type OptionPickerOption, type Profile, ProfileChip, type ProfileColorPick, ProfileColorProvider, type ProfileEditPatch, type ProfileExtensionActions, type ProfileExtensionSlice, type ProfileExtensionState, ProfilePicker, type ProfilePickerAlignResult, type ProfilePickerColorSection, type ProfilePickerContentSize, type ProfileSelectionActions, type ProfileSelectionSlice, type ProfileSelectionState, type ProfileSwatchRenderer, ProfilesManager, type ProfilesManagerHandle, type ProfilesManagerProps, ProfilesScreen, type ProfilesScreenProps, type SeatColorsActions, type SeatColorsSlice, type SeatColorsState, type SelectProfilePayload, type SetLastGuestColorPayload, type SetProfileColorPayload, type SetProfileExtensionPayload, type UpdateProfilePayload, type UseSharedProfilesSyncOptions, type UseSharedProfilesSyncResult, avoidSeatColorClash, createProfileExtensionSlice, createProfileRecord, createProfileSelectionSlice, createSeatColorsSlice, getOptionPickerContentSize, getProfilePickerContentSize, isSharedProfileStoreAvailable, isValidProfile, isValidTag, loadSharedProfiles, profileSeatColor, profilesActions, profilesReducer, readSharedProfiles, resolveInitialProfiles, saveSharedProfiles, subscribeSharedProfiles, useProfileColorPreview, useProfileDisplayColor, useProfileSwatchRenderer, useSharedProfilesSync };
|