@dloizides/ui-card-roster 0.1.0 → 0.2.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/CHANGELOG.md +8 -0
- package/dist/index.d.mts +17 -4
- package/dist/index.d.ts +17 -4
- package/dist/index.js +32 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +32 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
- `disabled` prop on `CardRoster`: while a save is in flight every mutation (add/rename/remove
|
|
6
|
+
group, reorder, add/edit/delete card) is a no-op and its button reports
|
|
7
|
+
`accessibilityState.disabled`. `RosterEditorContext.disabled` lets the host disable its
|
|
8
|
+
own Save/Delete; save/remove keep the editor and draft open while disabled.
|
|
9
|
+
`useRosterActions` / `useRosterEditor` take an optional trailing `disabled` argument.
|
|
10
|
+
|
|
3
11
|
## 0.1.0
|
|
4
12
|
|
|
5
13
|
- Initial release: `CardRoster` (groups, live card band, Reorder mode, ModalShell edit
|
package/dist/index.d.mts
CHANGED
|
@@ -25,6 +25,8 @@ interface RosterEditorContext<T extends RosterItem> {
|
|
|
25
25
|
groupKey: string;
|
|
26
26
|
/** `true` when the item came from `createItem` and is not in the value yet. */
|
|
27
27
|
isNew: boolean;
|
|
28
|
+
/** `true` while the roster is disabled (a save in flight); save/remove are no-ops. */
|
|
29
|
+
disabled: boolean;
|
|
28
30
|
/** Writes the item into the value (add or update) and closes the editor. */
|
|
29
31
|
save: (item: T) => void;
|
|
30
32
|
cancel: () => void;
|
|
@@ -98,6 +100,11 @@ interface CardRosterProps<T extends RosterItem> {
|
|
|
98
100
|
/** Width at/above which the editor becomes a split pane. Default: ui-layout's breakpoint. */
|
|
99
101
|
wideBreakpoint?: number;
|
|
100
102
|
cardWidth?: number;
|
|
103
|
+
/**
|
|
104
|
+
* Disables every mutation (add/rename/remove group, reorder, add/edit/delete card) —
|
|
105
|
+
* pass `true` while a save is in flight. Buttons expose `accessibilityState.disabled`.
|
|
106
|
+
*/
|
|
107
|
+
disabled?: boolean;
|
|
101
108
|
testID?: string;
|
|
102
109
|
}
|
|
103
110
|
|
|
@@ -172,8 +179,11 @@ interface UseRosterEditorResult<T extends RosterItem> {
|
|
|
172
179
|
openNew: (groupKey: string) => void;
|
|
173
180
|
close: () => void;
|
|
174
181
|
}
|
|
175
|
-
/**
|
|
176
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Owns the edit target + the unsaved draft of a new item; writes through `onChange`.
|
|
184
|
+
* While `disabled` nothing opens, and save/remove are no-ops that keep the editor open.
|
|
185
|
+
*/
|
|
186
|
+
declare function useRosterEditor<T extends RosterItem>(value: RosterValue<T>, onChange: (next: RosterValue<T>) => void, createItem?: (groupKey: string) => T, disabled?: boolean): UseRosterEditorResult<T>;
|
|
177
187
|
|
|
178
188
|
interface RosterActions<T extends RosterItem> {
|
|
179
189
|
addGroup: (group: RosterGroup<T>) => void;
|
|
@@ -182,8 +192,11 @@ interface RosterActions<T extends RosterItem> {
|
|
|
182
192
|
moveGroup: (key: string, delta: number) => void;
|
|
183
193
|
moveItem: (groupKey: string, itemId: string, delta: number) => void;
|
|
184
194
|
}
|
|
185
|
-
/**
|
|
186
|
-
|
|
195
|
+
/**
|
|
196
|
+
* Binds the pure helpers to the controlled value; a no-op never calls `onChange`.
|
|
197
|
+
* While `disabled` (a save in flight) every action is a no-op.
|
|
198
|
+
*/
|
|
199
|
+
declare function useRosterActions<T extends RosterItem>(value: RosterValue<T>, onChange: (next: RosterValue<T>) => void, disabled?: boolean): RosterActions<T>;
|
|
187
200
|
|
|
188
201
|
/** Minimum hit box (CSS px) for every interactive element — mobile-first standard. */
|
|
189
202
|
declare const MIN_TOUCH_TARGET = 44;
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ interface RosterEditorContext<T extends RosterItem> {
|
|
|
25
25
|
groupKey: string;
|
|
26
26
|
/** `true` when the item came from `createItem` and is not in the value yet. */
|
|
27
27
|
isNew: boolean;
|
|
28
|
+
/** `true` while the roster is disabled (a save in flight); save/remove are no-ops. */
|
|
29
|
+
disabled: boolean;
|
|
28
30
|
/** Writes the item into the value (add or update) and closes the editor. */
|
|
29
31
|
save: (item: T) => void;
|
|
30
32
|
cancel: () => void;
|
|
@@ -98,6 +100,11 @@ interface CardRosterProps<T extends RosterItem> {
|
|
|
98
100
|
/** Width at/above which the editor becomes a split pane. Default: ui-layout's breakpoint. */
|
|
99
101
|
wideBreakpoint?: number;
|
|
100
102
|
cardWidth?: number;
|
|
103
|
+
/**
|
|
104
|
+
* Disables every mutation (add/rename/remove group, reorder, add/edit/delete card) —
|
|
105
|
+
* pass `true` while a save is in flight. Buttons expose `accessibilityState.disabled`.
|
|
106
|
+
*/
|
|
107
|
+
disabled?: boolean;
|
|
101
108
|
testID?: string;
|
|
102
109
|
}
|
|
103
110
|
|
|
@@ -172,8 +179,11 @@ interface UseRosterEditorResult<T extends RosterItem> {
|
|
|
172
179
|
openNew: (groupKey: string) => void;
|
|
173
180
|
close: () => void;
|
|
174
181
|
}
|
|
175
|
-
/**
|
|
176
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Owns the edit target + the unsaved draft of a new item; writes through `onChange`.
|
|
184
|
+
* While `disabled` nothing opens, and save/remove are no-ops that keep the editor open.
|
|
185
|
+
*/
|
|
186
|
+
declare function useRosterEditor<T extends RosterItem>(value: RosterValue<T>, onChange: (next: RosterValue<T>) => void, createItem?: (groupKey: string) => T, disabled?: boolean): UseRosterEditorResult<T>;
|
|
177
187
|
|
|
178
188
|
interface RosterActions<T extends RosterItem> {
|
|
179
189
|
addGroup: (group: RosterGroup<T>) => void;
|
|
@@ -182,8 +192,11 @@ interface RosterActions<T extends RosterItem> {
|
|
|
182
192
|
moveGroup: (key: string, delta: number) => void;
|
|
183
193
|
moveItem: (groupKey: string, itemId: string, delta: number) => void;
|
|
184
194
|
}
|
|
185
|
-
/**
|
|
186
|
-
|
|
195
|
+
/**
|
|
196
|
+
* Binds the pure helpers to the controlled value; a no-op never calls `onChange`.
|
|
197
|
+
* While `disabled` (a save in flight) every action is a no-op.
|
|
198
|
+
*/
|
|
199
|
+
declare function useRosterActions<T extends RosterItem>(value: RosterValue<T>, onChange: (next: RosterValue<T>) => void, disabled?: boolean): RosterActions<T>;
|
|
187
200
|
|
|
188
201
|
/** Minimum hit box (CSS px) for every interactive element — mobile-first standard. */
|
|
189
202
|
declare const MIN_TOUCH_TARGET = 44;
|
package/dist/index.js
CHANGED
|
@@ -124,10 +124,10 @@ function moveItem(value, groupKey, itemId, delta) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
// src/hooks/useRosterActions.ts
|
|
127
|
-
function useRosterActions(value, onChange) {
|
|
127
|
+
function useRosterActions(value, onChange, disabled = false) {
|
|
128
128
|
return react.useMemo(() => {
|
|
129
129
|
const emit = (next) => {
|
|
130
|
-
if (next !== value) onChange(next);
|
|
130
|
+
if (!disabled && next !== value) onChange(next);
|
|
131
131
|
};
|
|
132
132
|
return {
|
|
133
133
|
addGroup: (group) => emit(addGroup(value, group)),
|
|
@@ -136,7 +136,7 @@ function useRosterActions(value, onChange) {
|
|
|
136
136
|
moveGroup: (key, delta) => emit(moveGroup(value, key, delta)),
|
|
137
137
|
moveItem: (groupKey, itemId, delta) => emit(moveItem(value, groupKey, itemId, delta))
|
|
138
138
|
};
|
|
139
|
-
}, [value, onChange]);
|
|
139
|
+
}, [value, onChange, disabled]);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
// src/utils/editorSession.ts
|
|
@@ -154,7 +154,7 @@ function commitEdit(value, session, next) {
|
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
// src/hooks/useRosterEditor.ts
|
|
157
|
-
function useRosterEditor(value, onChange, createItem) {
|
|
157
|
+
function useRosterEditor(value, onChange, createItem, disabled = false) {
|
|
158
158
|
const [target, setTarget] = react.useState(null);
|
|
159
159
|
const [draft, setDraft] = react.useState(null);
|
|
160
160
|
const close = react.useCallback(() => {
|
|
@@ -162,27 +162,31 @@ function useRosterEditor(value, onChange, createItem) {
|
|
|
162
162
|
setDraft(null);
|
|
163
163
|
}, []);
|
|
164
164
|
const openEdit = react.useCallback((groupKey, itemId) => {
|
|
165
|
+
if (disabled) return;
|
|
165
166
|
setDraft(null);
|
|
166
167
|
setTarget({ groupKey, itemId });
|
|
167
|
-
}, []);
|
|
168
|
+
}, [disabled]);
|
|
168
169
|
const openNew = react.useCallback(
|
|
169
170
|
(groupKey) => {
|
|
170
|
-
if (createItem === void 0) return;
|
|
171
|
+
if (disabled || createItem === void 0) return;
|
|
171
172
|
setDraft(createItem(groupKey));
|
|
172
173
|
setTarget({ groupKey, itemId: null });
|
|
173
174
|
},
|
|
174
|
-
[createItem]
|
|
175
|
+
[createItem, disabled]
|
|
175
176
|
);
|
|
176
177
|
const session = resolveEditSession(value, target, draft);
|
|
177
178
|
const context = session === null ? null : {
|
|
178
179
|
...session,
|
|
180
|
+
disabled,
|
|
179
181
|
save: (next) => {
|
|
182
|
+
if (disabled) return;
|
|
180
183
|
const updated = commitEdit(value, session, next);
|
|
181
184
|
if (updated !== value) onChange(updated);
|
|
182
185
|
close();
|
|
183
186
|
},
|
|
184
187
|
cancel: close,
|
|
185
188
|
remove: () => {
|
|
189
|
+
if (disabled) return;
|
|
186
190
|
if (!session.isNew) onChange(removeItem(value, session.groupKey, session.item.id));
|
|
187
191
|
close();
|
|
188
192
|
}
|
|
@@ -338,6 +342,7 @@ function CardBand({ group, shared }) {
|
|
|
338
342
|
RosterButton,
|
|
339
343
|
{
|
|
340
344
|
accessibilityLabel: labels.editCard(shared.getItemName(item)),
|
|
345
|
+
disabled: shared.disabled,
|
|
341
346
|
hint: labels.editCardHint,
|
|
342
347
|
label: labels.edit,
|
|
343
348
|
testID: `${cardId}-edit`,
|
|
@@ -374,9 +379,10 @@ var styles5 = reactNative.StyleSheet.create({
|
|
|
374
379
|
function GroupHeader({ group, index, shared }) {
|
|
375
380
|
const { theme } = uiFeedback.useUi();
|
|
376
381
|
const [draft, setDraft] = react.useState(null);
|
|
377
|
-
const { labels, actions, reordering } = shared;
|
|
382
|
+
const { labels, actions, reordering, disabled } = shared;
|
|
378
383
|
const gid = shared.ids.group(group.key);
|
|
379
384
|
const commit = () => {
|
|
385
|
+
if (disabled) return;
|
|
380
386
|
if (draft !== null) actions.renameGroup(group.key, draft);
|
|
381
387
|
setDraft(null);
|
|
382
388
|
};
|
|
@@ -385,7 +391,7 @@ function GroupHeader({ group, index, shared }) {
|
|
|
385
391
|
RosterButton,
|
|
386
392
|
{
|
|
387
393
|
accessibilityLabel: labels.moveGroupUp(group.title),
|
|
388
|
-
disabled: index === 0,
|
|
394
|
+
disabled: disabled || index === 0,
|
|
389
395
|
hint: labels.moveGroupHint,
|
|
390
396
|
label: GLYPH_UP,
|
|
391
397
|
testID: `${gid}-up`,
|
|
@@ -396,7 +402,7 @@ function GroupHeader({ group, index, shared }) {
|
|
|
396
402
|
RosterButton,
|
|
397
403
|
{
|
|
398
404
|
accessibilityLabel: labels.moveGroupDown(group.title),
|
|
399
|
-
disabled: index === shared.groupCount - 1,
|
|
405
|
+
disabled: disabled || index === shared.groupCount - 1,
|
|
400
406
|
hint: labels.moveGroupHint,
|
|
401
407
|
label: GLYPH_DOWN,
|
|
402
408
|
testID: `${gid}-down`,
|
|
@@ -410,6 +416,7 @@ function GroupHeader({ group, index, shared }) {
|
|
|
410
416
|
{
|
|
411
417
|
emphasis: true,
|
|
412
418
|
accessibilityLabel: labels.addCard(group.title),
|
|
419
|
+
disabled,
|
|
413
420
|
hint: labels.addCardHint,
|
|
414
421
|
label: labels.add,
|
|
415
422
|
testID: `${gid}-add`,
|
|
@@ -420,6 +427,7 @@ function GroupHeader({ group, index, shared }) {
|
|
|
420
427
|
RosterButton,
|
|
421
428
|
{
|
|
422
429
|
accessibilityLabel: labels.renameGroup(group.title),
|
|
430
|
+
disabled,
|
|
423
431
|
hint: labels.renameGroupHint,
|
|
424
432
|
label: labels.rename,
|
|
425
433
|
testID: `${gid}-rename`,
|
|
@@ -431,6 +439,7 @@ function GroupHeader({ group, index, shared }) {
|
|
|
431
439
|
{
|
|
432
440
|
danger: true,
|
|
433
441
|
accessibilityLabel: labels.removeGroup(group.title),
|
|
442
|
+
disabled,
|
|
434
443
|
hint: labels.removeGroupHint,
|
|
435
444
|
label: labels.remove,
|
|
436
445
|
testID: `${gid}-remove`,
|
|
@@ -445,6 +454,8 @@ function GroupHeader({ group, index, shared }) {
|
|
|
445
454
|
autoFocus: true,
|
|
446
455
|
accessibilityHint: labels.groupTitleInputHint,
|
|
447
456
|
accessibilityLabel: labels.groupTitleInput,
|
|
457
|
+
accessibilityState: { disabled },
|
|
458
|
+
editable: !disabled,
|
|
448
459
|
style: [styles5.input, { color: theme.colors.text, borderColor: theme.palette.primary["500"] }],
|
|
449
460
|
testID: `${gid}-title-input`,
|
|
450
461
|
value: draft,
|
|
@@ -478,7 +489,7 @@ function ReorderList({ group, shared }) {
|
|
|
478
489
|
RosterButton,
|
|
479
490
|
{
|
|
480
491
|
accessibilityLabel: labels.moveCardUp(name),
|
|
481
|
-
disabled: index === 0,
|
|
492
|
+
disabled: shared.disabled || index === 0,
|
|
482
493
|
hint: labels.moveCardHint,
|
|
483
494
|
label: GLYPH_UP,
|
|
484
495
|
testID: `${cardId}-up`,
|
|
@@ -489,7 +500,7 @@ function ReorderList({ group, shared }) {
|
|
|
489
500
|
RosterButton,
|
|
490
501
|
{
|
|
491
502
|
accessibilityLabel: labels.moveCardDown(name),
|
|
492
|
-
disabled: index === last,
|
|
503
|
+
disabled: shared.disabled || index === last,
|
|
493
504
|
hint: labels.moveCardHint,
|
|
494
505
|
label: GLYPH_DOWN,
|
|
495
506
|
testID: `${cardId}-down`,
|
|
@@ -554,6 +565,7 @@ function CardRoster(props) {
|
|
|
554
565
|
getItemState,
|
|
555
566
|
onRetryItem,
|
|
556
567
|
error,
|
|
568
|
+
disabled = false,
|
|
557
569
|
wideBreakpoint = uiLayout.LAYOUT_COLLAPSE_BREAKPOINT,
|
|
558
570
|
cardWidth = DEFAULT_CARD_WIDTH,
|
|
559
571
|
testID = DEFAULT_TEST_ID
|
|
@@ -561,14 +573,15 @@ function CardRoster(props) {
|
|
|
561
573
|
const { width } = reactNative.useWindowDimensions();
|
|
562
574
|
const split = isSplitPane(width, wideBreakpoint);
|
|
563
575
|
const [reordering, setReordering] = react.useState(false);
|
|
564
|
-
const editor = useRosterEditor(value, onChange, createItem);
|
|
565
|
-
const actions = useRosterActions(value, onChange);
|
|
576
|
+
const editor = useRosterEditor(value, onChange, createItem, disabled);
|
|
577
|
+
const actions = useRosterActions(value, onChange, disabled);
|
|
566
578
|
const ids = react.useMemo(() => rosterTestIds(testID), [testID]);
|
|
567
579
|
const { close, openEdit, openNew } = editor;
|
|
568
580
|
const toggleReorder = react.useCallback(() => {
|
|
581
|
+
if (disabled) return;
|
|
569
582
|
close();
|
|
570
583
|
setReordering((on) => !on);
|
|
571
|
-
}, [close]);
|
|
584
|
+
}, [close, disabled]);
|
|
572
585
|
const shared = {
|
|
573
586
|
renderCard,
|
|
574
587
|
getItemName,
|
|
@@ -580,17 +593,19 @@ function CardRoster(props) {
|
|
|
580
593
|
reordering,
|
|
581
594
|
actions,
|
|
582
595
|
canRemoveGroup,
|
|
596
|
+
disabled,
|
|
583
597
|
activeItemId: editor.activeItemId,
|
|
584
598
|
groupCount: value.groups.length,
|
|
585
599
|
onEdit: openEdit,
|
|
586
600
|
onAdd: createItem === void 0 ? void 0 : openNew
|
|
587
601
|
};
|
|
588
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles8.root, split ? styles8.split : null], testID: ids.root, children: [
|
|
602
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { accessibilityState: { busy: disabled }, style: [styles8.root, split ? styles8.split : null], testID: ids.root, children: [
|
|
589
603
|
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles8.list, children: [
|
|
590
604
|
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles8.toolbar, children: [
|
|
591
605
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
592
606
|
RosterButton,
|
|
593
607
|
{
|
|
608
|
+
disabled,
|
|
594
609
|
emphasis: reordering,
|
|
595
610
|
hint: reordering ? labels.doneReorderingHint : labels.reorderHint,
|
|
596
611
|
label: reordering ? labels.doneReordering : labels.reorder,
|
|
@@ -601,6 +616,7 @@ function CardRoster(props) {
|
|
|
601
616
|
createGroup !== void 0 && !reordering ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
602
617
|
RosterButton,
|
|
603
618
|
{
|
|
619
|
+
disabled,
|
|
604
620
|
hint: labels.addGroupHint,
|
|
605
621
|
label: labels.addGroup,
|
|
606
622
|
testID: ids.addGroup,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/utils/rosterOps.ts","../src/hooks/useRosterActions.ts","../src/utils/editorSession.ts","../src/hooks/useRosterEditor.ts","../src/components/EditorPane.tsx","../src/components/RosterButton.tsx","../src/components/ItemFrame.tsx","../src/components/CardBand.tsx","../src/components/GroupHeader.tsx","../src/components/ReorderList.tsx","../src/components/RosterGroupSection.tsx","../src/components/CardRoster.tsx"],"names":["item","useMemo","useState","useCallback","StyleSheet","useUi","ModalShell","jsx","View","Text","jsxs","Fragment","styles","Pressable","ActivityIndicator","ScrollView","TextInput","Reorder","LAYOUT_COLLAPSE_BREAKPOINT","useWindowDimensions","ErrorState"],"mappings":"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","file":"index.js","sourcesContent":["/** Minimum hit box (CSS px) for every interactive element — mobile-first standard. */\nexport const MIN_TOUCH_TARGET = 44;\nexport const DEFAULT_CARD_WIDTH = 168;\nexport const SPLIT_EDITOR_WIDTH = 400;\nexport const SPACE_XS = 4;\nexport const SPACE_S = 8;\nexport const SPACE_M = 12;\nexport const SPACE_L = 16;\nexport const RADIUS_S = 8;\nexport const RADIUS_M = 12;\nexport const BORDER_WIDTH = 1;\nexport const ACTIVE_BORDER_WIDTH = 2;\nexport const TITLE_FONT_SIZE = 17;\nexport const BODY_FONT_SIZE = 15;\nexport const SMALL_FONT_SIZE = 13;\nexport const PRESSED_OPACITY = 0.7;\nexport const DISABLED_OPACITY = 0.4;\nexport const BUSY_OVERLAY_OPACITY = 0.9;\nexport const GROUP_TITLE_MIN_WIDTH = 120;\nexport const REORDER_SPRING = { stiffness: 320, damping: 32 } as const;\n\n/** Move deltas for the reorder helpers. */\nexport const MOVE_UP = -1;\nexport const MOVE_DOWN = 1;\n\n/** Decorative arrow glyphs; the buttons carry translated accessibility labels. */\nexport const GLYPH_UP = '▲';\nexport const GLYPH_DOWN = '▼';\n\nexport const DEFAULT_TEST_ID = 'card-roster';\n\n/** Stable testIDs derived from the roster's root testID. */\nexport const rosterTestIds = (base: string) => ({\n root: base,\n reorderToggle: `${base}-reorder-toggle`,\n addGroup: `${base}-add-group`,\n error: `${base}-error`,\n editor: `${base}-editor`,\n editorPlaceholder: `${base}-editor-placeholder`,\n group: (key: string): string => `${base}-group-${key}`,\n card: (id: string): string => `${base}-card-${id}`,\n});\n\nexport type RosterTestIds = ReturnType<typeof rosterTestIds>;\n","/**\n * Pure, immutable reducer helpers over a `RosterValue`. Every helper returns the SAME\n * reference when the operation is a no-op (unknown key, out-of-range move, duplicate\n * id), so callers can skip `onChange` with a reference check.\n */\nimport type { RosterGroup, RosterItem, RosterValue } from '../types';\n\nexport interface FoundItem<T extends RosterItem> {\n group: RosterGroup<T>;\n item: T;\n index: number;\n}\n\n/** `true` when moving `index` by `delta` stays inside a list of `length`. */\nexport function canMove(length: number, index: number, delta: number): boolean {\n const target = index + delta;\n return delta !== 0 && index >= 0 && index < length && target >= 0 && target < length;\n}\n\n/** Moves one element; returns `list` itself when the move is out of range. */\nexport function moveInArray<X>(list: X[], index: number, delta: number): X[] {\n if (!canMove(list.length, index, delta)) return list;\n const next = [...list];\n const [moved] = next.splice(index, 1);\n next.splice(index + delta, 0, moved as X);\n return next;\n}\n\nexport function isGroupEmpty<T extends RosterItem>(group: RosterGroup<T>): boolean {\n return group.items.length === 0;\n}\n\nfunction mapGroup<T extends RosterItem>(\n value: RosterValue<T>,\n key: string,\n fn: (group: RosterGroup<T>) => RosterGroup<T>,\n): RosterValue<T> {\n let changed = false;\n const groups = value.groups.map((group) => {\n if (group.key !== key) return group;\n const next = fn(group);\n if (next !== group) changed = true;\n return next;\n });\n return changed ? { ...value, groups } : value;\n}\n\nexport function findItem<T extends RosterItem>(value: RosterValue<T>, itemId: string): FoundItem<T> | undefined {\n for (const group of value.groups) {\n const index = group.items.findIndex((item) => item.id === itemId);\n const item = group.items[index];\n if (item !== undefined) return { group, item, index };\n }\n return undefined;\n}\n\nexport function addGroup<T extends RosterItem>(value: RosterValue<T>, group: RosterGroup<T>): RosterValue<T> {\n if (value.groups.some((g) => g.key === group.key)) return value;\n return { ...value, groups: [...value.groups, group] };\n}\n\n/** Trims the title; an empty or unchanged title is a no-op. */\nexport function renameGroup<T extends RosterItem>(value: RosterValue<T>, key: string, title: string): RosterValue<T> {\n const trimmed = title.trim();\n if (trimmed === '') return value;\n return mapGroup(value, key, (group) => (group.title === trimmed ? group : { ...group, title: trimmed }));\n}\n\nexport function removeGroup<T extends RosterItem>(value: RosterValue<T>, key: string): RosterValue<T> {\n if (!value.groups.some((g) => g.key === key)) return value;\n return { ...value, groups: value.groups.filter((g) => g.key !== key) };\n}\n\nexport function moveGroup<T extends RosterItem>(value: RosterValue<T>, key: string, delta: number): RosterValue<T> {\n const index = value.groups.findIndex((g) => g.key === key);\n const groups = moveInArray(value.groups, index, delta);\n return groups === value.groups ? value : { ...value, groups };\n}\n\n/** Appends to the group; refuses an id already present anywhere in the roster. */\nexport function addItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, item: T): RosterValue<T> {\n if (findItem(value, item.id) !== undefined) return value;\n return mapGroup(value, groupKey, (group) => ({ ...group, items: [...group.items, item] }));\n}\n\nexport function updateItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, item: T): RosterValue<T> {\n return mapGroup(value, groupKey, (group) => {\n const index = group.items.findIndex((i) => i.id === item.id);\n if (index === -1) return group;\n const items = [...group.items];\n items[index] = item;\n return { ...group, items };\n });\n}\n\nexport function removeItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, itemId: string): RosterValue<T> {\n return mapGroup(value, groupKey, (group) =>\n group.items.some((i) => i.id === itemId) ? { ...group, items: group.items.filter((i) => i.id !== itemId) } : group,\n );\n}\n\nexport function moveItem<T extends RosterItem>(\n value: RosterValue<T>,\n groupKey: string,\n itemId: string,\n delta: number,\n): RosterValue<T> {\n return mapGroup(value, groupKey, (group) => {\n const items = moveInArray(group.items, group.items.findIndex((i) => i.id === itemId), delta);\n return items === group.items ? group : { ...group, items };\n });\n}\n","import { useMemo } from 'react';\n\nimport type { RosterGroup, RosterItem, RosterValue } from '../types';\nimport { addGroup, moveGroup, moveItem, removeGroup, renameGroup } from '../utils/rosterOps';\n\nexport interface RosterActions<T extends RosterItem> {\n addGroup: (group: RosterGroup<T>) => void;\n renameGroup: (key: string, title: string) => void;\n removeGroup: (key: string) => void;\n moveGroup: (key: string, delta: number) => void;\n moveItem: (groupKey: string, itemId: string, delta: number) => void;\n}\n\n/** Binds the pure helpers to the controlled value; a no-op never calls `onChange`. */\nexport function useRosterActions<T extends RosterItem>(\n value: RosterValue<T>,\n onChange: (next: RosterValue<T>) => void,\n): RosterActions<T> {\n return useMemo(() => {\n const emit = (next: RosterValue<T>): void => {\n if (next !== value) onChange(next);\n };\n return {\n addGroup: (group) => emit(addGroup(value, group)),\n renameGroup: (key, title) => emit(renameGroup(value, key, title)),\n removeGroup: (key) => emit(removeGroup(value, key)),\n moveGroup: (key, delta) => emit(moveGroup(value, key, delta)),\n moveItem: (groupKey, itemId, delta) => emit(moveItem(value, groupKey, itemId, delta)),\n };\n }, [value, onChange]);\n}\n","/**\n * Pure edit-session logic: which item the editor shows, and how a save lands.\n * Kept out of the hook so the rules are unit-tested without React.\n */\nimport type { RosterItem, RosterValue } from '../types';\nimport { addItem, findItem, updateItem } from './rosterOps';\n\n/** What the user opened: an existing item (`itemId`) or a new one (`itemId: null`). */\nexport interface EditTarget {\n groupKey: string;\n itemId: string | null;\n}\n\nexport interface EditSession<T extends RosterItem> {\n item: T;\n groupKey: string;\n isNew: boolean;\n}\n\n/** `true` at/above the breakpoint: the editor renders as a split pane, not a sheet. */\nexport function isSplitPane(width: number, breakpoint: number): boolean {\n return width >= breakpoint;\n}\n\n/**\n * Resolves the target against the CURRENT value. An existing item that has since\n * disappeared (removed elsewhere) resolves to `null`, which closes the editor; an\n * item moved to another group resolves to its new group.\n */\nexport function resolveEditSession<T extends RosterItem>(\n value: RosterValue<T>,\n target: EditTarget | null,\n draft: T | null,\n): EditSession<T> | null {\n if (target === null) return null;\n if (target.itemId === null) return draft === null ? null : { item: draft, groupKey: target.groupKey, isNew: true };\n const found = findItem(value, target.itemId);\n return found === undefined ? null : { item: found.item, groupKey: found.group.key, isNew: false };\n}\n\n/** Applies a save: a new item is appended, an existing one replaced in place. */\nexport function commitEdit<T extends RosterItem>(value: RosterValue<T>, session: EditSession<T>, next: T): RosterValue<T> {\n return session.isNew ? addItem(value, session.groupKey, next) : updateItem(value, session.groupKey, next);\n}\n","import { useCallback, useState } from 'react';\n\nimport type { RosterEditorContext, RosterItem, RosterValue } from '../types';\nimport { commitEdit, resolveEditSession, type EditTarget } from '../utils/editorSession';\nimport { removeItem } from '../utils/rosterOps';\n\nexport interface UseRosterEditorResult<T extends RosterItem> {\n /** `null` when the editor is closed. */\n context: RosterEditorContext<T> | null;\n /** Id of the existing item being edited (for the active-card highlight). */\n activeItemId: string | null;\n openEdit: (groupKey: string, itemId: string) => void;\n openNew: (groupKey: string) => void;\n close: () => void;\n}\n\n/** Owns the edit target + the unsaved draft of a new item; writes through `onChange`. */\nexport function useRosterEditor<T extends RosterItem>(\n value: RosterValue<T>,\n onChange: (next: RosterValue<T>) => void,\n createItem?: (groupKey: string) => T,\n): UseRosterEditorResult<T> {\n const [target, setTarget] = useState<EditTarget | null>(null);\n const [draft, setDraft] = useState<T | null>(null);\n\n const close = useCallback((): void => {\n setTarget(null);\n setDraft(null);\n }, []);\n const openEdit = useCallback((groupKey: string, itemId: string): void => {\n setDraft(null);\n setTarget({ groupKey, itemId });\n }, []);\n const openNew = useCallback(\n (groupKey: string): void => {\n if (createItem === undefined) return;\n setDraft(createItem(groupKey));\n setTarget({ groupKey, itemId: null });\n },\n [createItem],\n );\n\n const session = resolveEditSession(value, target, draft);\n const context: RosterEditorContext<T> | null =\n session === null\n ? null\n : {\n ...session,\n save: (next: T): void => {\n const updated = commitEdit(value, session, next);\n if (updated !== value) onChange(updated);\n close();\n },\n cancel: close,\n remove: (): void => {\n if (!session.isNew) onChange(removeItem(value, session.groupKey, session.item.id));\n close();\n },\n };\n\n const activeItemId = session !== null && !session.isNew ? session.item.id : null;\n return { context, activeItemId, openEdit, openNew, close };\n}\n","/**\n * The edit-sheet slot. Narrow: ui-layout's `ModalShell` sheet. Wide: an inline right\n * pane that shows a prompt until a card is picked (the split pane).\n */\nimport React from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\nimport { ModalShell } from '@dloizides/ui-layout';\n\nimport { BODY_FONT_SIZE, BORDER_WIDTH, RADIUS_M, SPACE_L, SPLIT_EDITOR_WIDTH, TITLE_FONT_SIZE } from '../constants';\nimport type { CardRosterLabels, RosterEditorContext, RosterItem } from '../types';\n\nconst styles = StyleSheet.create({\n pane: { width: SPLIT_EDITOR_WIDTH, borderWidth: BORDER_WIDTH, borderRadius: RADIUS_M, padding: SPACE_L, gap: SPACE_L },\n title: { fontSize: TITLE_FONT_SIZE, fontWeight: '700' },\n prompt: { fontSize: BODY_FONT_SIZE },\n});\n\nexport interface EditorPaneProps<T extends RosterItem> {\n context: RosterEditorContext<T> | null;\n renderEditor: (context: RosterEditorContext<T>) => React.ReactNode;\n split: boolean;\n labels: Pick<CardRosterLabels, 'editorTitleNew' | 'editorTitleEdit' | 'selectPrompt'>;\n onClose: () => void;\n testID: string;\n placeholderTestID: string;\n}\n\nexport function EditorPane<T extends RosterItem>({\n context, renderEditor, split, labels, onClose, testID, placeholderTestID,\n}: EditorPaneProps<T>): React.ReactElement {\n const { theme } = useUi();\n const title = context?.isNew === true ? labels.editorTitleNew : labels.editorTitleEdit;\n\n if (!split)\n return (\n <ModalShell title={title} visible={context !== null} onCancel={onClose}>\n {context === null ? null : <View testID={testID}>{renderEditor(context)}</View>}\n </ModalShell>\n );\n\n return (\n <View style={[styles.pane, { borderColor: theme.colors.border, backgroundColor: theme.colors.surface }]} testID={testID}>\n {context === null ? (\n <Text style={[styles.prompt, { color: theme.colors.textSecondary }]} testID={placeholderTestID}>\n {labels.selectPrompt}\n </Text>\n ) : (\n <>\n <Text accessibilityRole=\"header\" style={[styles.title, { color: theme.colors.text }]}>{title}</Text>\n {renderEditor(context)}\n </>\n )}\n </View>\n );\n}\n","/**\n * The roster's one button. `Pressable`, not `TouchableOpacity` (RN-web drops its hover\n * callbacks), and the 44x44 floor is on the BOX via min sizes — `hitSlop` is inert on\n * RN-web, so it cannot be relied on to grow the target.\n */\nimport React from 'react';\n\nimport { Pressable, StyleSheet, Text } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n BODY_FONT_SIZE, BORDER_WIDTH, DISABLED_OPACITY, MIN_TOUCH_TARGET, PRESSED_OPACITY, RADIUS_S, SPACE_M,\n} from '../constants';\n\nconst styles = StyleSheet.create({\n base: {\n minHeight: MIN_TOUCH_TARGET,\n minWidth: MIN_TOUCH_TARGET,\n paddingHorizontal: SPACE_M,\n borderRadius: RADIUS_S,\n borderWidth: BORDER_WIDTH,\n alignItems: 'center',\n justifyContent: 'center',\n },\n label: { fontSize: BODY_FONT_SIZE, fontWeight: '600' },\n pressed: { opacity: PRESSED_OPACITY },\n disabled: { opacity: DISABLED_OPACITY },\n});\n\nexport interface RosterButtonProps {\n label: string;\n /** Defaults to `label`; pass a fuller one when the visible label is short (\"Edit\"). */\n accessibilityLabel?: string;\n hint: string;\n onPress: () => void;\n testID: string;\n emphasis?: boolean;\n danger?: boolean;\n disabled?: boolean;\n}\n\nexport function RosterButton({\n label, accessibilityLabel, hint, onPress, testID, emphasis = false, danger = false, disabled = false,\n}: RosterButtonProps): React.ReactElement {\n const { theme } = useUi();\n const accent = danger ? theme.semantic.error['500'] : theme.palette.primary['500'];\n const tone = emphasis ? { backgroundColor: accent, borderColor: accent } : { borderColor: theme.colors.border };\n const color = emphasis ? theme.colors.background : accent;\n\n return (\n <Pressable\n accessibilityHint={hint}\n accessibilityLabel={accessibilityLabel ?? label}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled }}\n disabled={disabled}\n style={({ pressed }) => [styles.base, tone, pressed ? styles.pressed : null, disabled ? styles.disabled : null]}\n testID={testID}\n onPress={onPress}\n >\n <Text style={[styles.label, { color }]}>{label}</Text>\n </Pressable>\n );\n}\n","/**\n * Frame around one host-rendered card: border, the uploading overlay (busy) and the\n * upload-error row with retry. The host's card body never has to know about either.\n */\nimport React from 'react';\n\nimport { ActivityIndicator, StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n ACTIVE_BORDER_WIDTH, BORDER_WIDTH, BUSY_OVERLAY_OPACITY, RADIUS_M, SMALL_FONT_SIZE, SPACE_S,\n} from '../constants';\nimport type { CardRosterLabels, RosterItemState } from '../types';\nimport { RosterButton } from './RosterButton';\n\nconst styles = StyleSheet.create({\n frame: { borderRadius: RADIUS_M, padding: SPACE_S, gap: SPACE_S, overflow: 'hidden' },\n fill: { alignSelf: 'stretch' },\n body: { position: 'relative' },\n busy: {\n ...StyleSheet.absoluteFillObject,\n alignItems: 'center',\n justifyContent: 'center',\n gap: SPACE_S,\n opacity: BUSY_OVERLAY_OPACITY,\n },\n small: { fontSize: SMALL_FONT_SIZE },\n errorRow: { gap: SPACE_S },\n footer: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S },\n});\n\nexport type ItemFrameLabels = Pick<CardRosterLabels, 'uploading' | 'retry' | 'retryHint'>;\n\nexport interface ItemFrameProps {\n /** Fixed width in the band; omitted = stretch (reorder list). */\n width?: number;\n active: boolean;\n state: RosterItemState | undefined;\n labels: ItemFrameLabels;\n onRetry?: () => void;\n testID: string;\n children: React.ReactNode;\n footer: React.ReactNode;\n}\n\nexport function ItemFrame({\n width, active, state, labels, onRetry, testID, children, footer,\n}: ItemFrameProps): React.ReactElement {\n const { theme } = useUi();\n const busy = state?.busy === true;\n const error = state?.error ?? '';\n const hasError = error !== '';\n const errorColor = theme.semantic.error['500'];\n const primary = theme.palette.primary['500'];\n const highlighted = active || hasError;\n const borderColor = hasError ? errorColor : active ? primary : theme.colors.border;\n\n return (\n <View\n accessibilityState={{ busy }}\n style={[\n styles.frame,\n width === undefined ? styles.fill : { width },\n { borderColor, backgroundColor: theme.colors.surface, borderWidth: highlighted ? ACTIVE_BORDER_WIDTH : BORDER_WIDTH },\n ]}\n testID={testID}\n >\n <View style={styles.body}>\n {children}\n {busy ? (\n <View style={[styles.busy, { backgroundColor: theme.colors.surfaceElevated }]} testID={`${testID}-busy`}>\n <ActivityIndicator color={primary} />\n <Text accessibilityLiveRegion=\"polite\" style={[styles.small, { color: theme.colors.textSecondary }]}>\n {labels.uploading}\n </Text>\n </View>\n ) : null}\n </View>\n {hasError ? (\n <View style={styles.errorRow} testID={`${testID}-error`}>\n <Text accessibilityRole=\"alert\" style={[styles.small, { color: errorColor }]}>{error}</Text>\n {onRetry !== undefined ? (\n <RosterButton danger hint={labels.retryHint} label={labels.retry} testID={`${testID}-retry`} onPress={onRetry} />\n ) : null}\n </View>\n ) : null}\n <View style={styles.footer}>{footer}</View>\n </View>\n );\n}\n","/** The live band: a horizontal row of framed cards, each with its own Edit button. */\nimport React from 'react';\n\nimport { ScrollView, StyleSheet } from 'react-native';\n\nimport { SPACE_M, SPACE_XS } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { ItemFrame } from './ItemFrame';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n band: { gap: SPACE_M, paddingVertical: SPACE_XS },\n});\n\nexport interface CardBandProps<T extends RosterItem> {\n group: RosterGroup<T>;\n shared: RosterSectionShared<T>;\n}\n\nexport function CardBand<T extends RosterItem>({ group, shared }: CardBandProps<T>): React.ReactElement {\n const { labels, ids, onRetryItem } = shared;\n return (\n <ScrollView\n horizontal\n contentContainerStyle={styles.band}\n showsHorizontalScrollIndicator={false}\n testID={`${ids.group(group.key)}-band`}\n >\n {group.items.map((item) => {\n const cardId = ids.card(item.id);\n return (\n <ItemFrame\n key={item.id}\n active={shared.activeItemId === item.id}\n footer={(\n <RosterButton\n accessibilityLabel={labels.editCard(shared.getItemName(item))}\n hint={labels.editCardHint}\n label={labels.edit}\n testID={`${cardId}-edit`}\n onPress={() => shared.onEdit(group.key, item.id)}\n />\n )}\n labels={labels}\n state={shared.getItemState?.(item)}\n testID={cardId}\n width={shared.cardWidth}\n onRetry={onRetryItem === undefined ? undefined : () => onRetryItem(item)}\n >\n {shared.renderCard(item, group)}\n </ItemFrame>\n );\n })}\n </ScrollView>\n );\n}\n","/** Group title (inline rename) + its actions; in Reorder mode, group up/down instead. */\nimport React, { useState } from 'react';\n\nimport { StyleSheet, Text, TextInput, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n BODY_FONT_SIZE, BORDER_WIDTH, GLYPH_DOWN, GLYPH_UP, GROUP_TITLE_MIN_WIDTH, MIN_TOUCH_TARGET, MOVE_DOWN, MOVE_UP,\n RADIUS_S, SPACE_M, SPACE_S, TITLE_FONT_SIZE,\n} from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n header: { flexDirection: 'row', flexWrap: 'wrap', alignItems: 'center', gap: SPACE_S },\n title: { flexGrow: 1, flexShrink: 1, minWidth: GROUP_TITLE_MIN_WIDTH, fontSize: TITLE_FONT_SIZE, fontWeight: '700' },\n input: {\n flexGrow: 1,\n minWidth: GROUP_TITLE_MIN_WIDTH,\n minHeight: MIN_TOUCH_TARGET,\n paddingHorizontal: SPACE_M,\n borderWidth: BORDER_WIDTH,\n borderRadius: RADIUS_S,\n fontSize: BODY_FONT_SIZE,\n },\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S },\n});\n\nexport interface GroupHeaderProps<T extends RosterItem> {\n group: RosterGroup<T>;\n index: number;\n shared: RosterSectionShared<T>;\n}\n\nexport function GroupHeader<T extends RosterItem>({ group, index, shared }: GroupHeaderProps<T>): React.ReactElement {\n const { theme } = useUi();\n const [draft, setDraft] = useState<string | null>(null);\n const { labels, actions, reordering } = shared;\n const gid = shared.ids.group(group.key);\n\n const commit = (): void => {\n if (draft !== null) actions.renameGroup(group.key, draft);\n setDraft(null);\n };\n\n const reorderActions = (\n <>\n <RosterButton\n accessibilityLabel={labels.moveGroupUp(group.title)}\n disabled={index === 0}\n hint={labels.moveGroupHint}\n label={GLYPH_UP}\n testID={`${gid}-up`}\n onPress={() => actions.moveGroup(group.key, MOVE_UP)}\n />\n <RosterButton\n accessibilityLabel={labels.moveGroupDown(group.title)}\n disabled={index === shared.groupCount - 1}\n hint={labels.moveGroupHint}\n label={GLYPH_DOWN}\n testID={`${gid}-down`}\n onPress={() => actions.moveGroup(group.key, MOVE_DOWN)}\n />\n </>\n );\n\n const editActions = (\n <>\n {shared.onAdd !== undefined ? (\n <RosterButton\n emphasis\n accessibilityLabel={labels.addCard(group.title)}\n hint={labels.addCardHint}\n label={labels.add}\n testID={`${gid}-add`}\n onPress={() => shared.onAdd?.(group.key)}\n />\n ) : null}\n <RosterButton\n accessibilityLabel={labels.renameGroup(group.title)}\n hint={labels.renameGroupHint}\n label={labels.rename}\n testID={`${gid}-rename`}\n onPress={() => setDraft(group.title)}\n />\n {shared.canRemoveGroup(group) ? (\n <RosterButton\n danger\n accessibilityLabel={labels.removeGroup(group.title)}\n hint={labels.removeGroupHint}\n label={labels.remove}\n testID={`${gid}-remove`}\n onPress={() => actions.removeGroup(group.key)}\n />\n ) : null}\n </>\n );\n\n return (\n <View style={styles.header}>\n {draft === null ? (\n <Text accessibilityRole=\"header\" numberOfLines={1} style={[styles.title, { color: theme.colors.text }]}>\n {group.title}\n </Text>\n ) : (\n <TextInput\n autoFocus\n accessibilityHint={labels.groupTitleInputHint}\n accessibilityLabel={labels.groupTitleInput}\n style={[styles.input, { color: theme.colors.text, borderColor: theme.palette.primary['500'] }]}\n testID={`${gid}-title-input`}\n value={draft}\n onBlur={commit}\n onChangeText={setDraft}\n onSubmitEditing={commit}\n />\n )}\n <View style={styles.actions}>{reordering ? reorderActions : editActions}</View>\n </View>\n );\n}\n","/**\n * Reorder mode for one group: a vertical list with explicit up/down buttons (no drag —\n * a drag is not reachable by keyboard or switch access). Moves animate through\n * ui-motion's `Reorder` (FLIP), which collapses to instant under reduced motion.\n */\nimport React, { useMemo } from 'react';\n\nimport { StyleSheet, View } from 'react-native';\n\nimport { Reorder } from '@dloizides/ui-motion';\n\nimport { GLYPH_DOWN, GLYPH_UP, MOVE_DOWN, MOVE_UP, REORDER_SPRING, SPACE_S } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { ItemFrame } from './ItemFrame';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n item: { paddingVertical: SPACE_S / 2 },\n});\n\nexport interface ReorderListProps<T extends RosterItem> {\n group: RosterGroup<T>;\n shared: RosterSectionShared<T>;\n}\n\nexport function ReorderList<T extends RosterItem>({ group, shared }: ReorderListProps<T>): React.ReactElement {\n const { labels, ids, actions } = shared;\n const keys = useMemo(() => group.items.map((item) => item.id), [group.items]);\n const last = group.items.length - 1;\n\n const renderItem = (key: string): React.ReactNode => {\n const index = group.items.findIndex((item) => item.id === key);\n const item = group.items[index];\n if (item === undefined) return null;\n const name = shared.getItemName(item);\n const cardId = ids.card(item.id);\n return (\n <View style={styles.item}>\n <ItemFrame\n active={false}\n footer={(\n <>\n <RosterButton\n accessibilityLabel={labels.moveCardUp(name)}\n disabled={index === 0}\n hint={labels.moveCardHint}\n label={GLYPH_UP}\n testID={`${cardId}-up`}\n onPress={() => actions.moveItem(group.key, item.id, MOVE_UP)}\n />\n <RosterButton\n accessibilityLabel={labels.moveCardDown(name)}\n disabled={index === last}\n hint={labels.moveCardHint}\n label={GLYPH_DOWN}\n testID={`${cardId}-down`}\n onPress={() => actions.moveItem(group.key, item.id, MOVE_DOWN)}\n />\n </>\n )}\n labels={labels}\n state={shared.getItemState?.(item)}\n testID={cardId}\n >\n {shared.renderCard(item, group)}\n </ItemFrame>\n </View>\n );\n };\n\n return (\n <Reorder itemKeys={keys} spring={REORDER_SPRING} testID={`${ids.group(group.key)}-reorder`}>\n {renderItem}\n </Reorder>\n );\n}\n","/** One group: header, then the empty state, the live band, or the reorder list. */\nimport React from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport { BODY_FONT_SIZE, BORDER_WIDTH, RADIUS_M, SPACE_L, SPACE_S } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { CardBand } from './CardBand';\nimport { GroupHeader } from './GroupHeader';\nimport { ReorderList } from './ReorderList';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n section: { gap: SPACE_S },\n empty: {\n borderWidth: BORDER_WIDTH,\n borderStyle: 'dashed',\n borderRadius: RADIUS_M,\n padding: SPACE_L,\n alignItems: 'center',\n },\n emptyText: { fontSize: BODY_FONT_SIZE, textAlign: 'center' },\n});\n\nexport interface RosterGroupSectionProps<T extends RosterItem> {\n group: RosterGroup<T>;\n index: number;\n shared: RosterSectionShared<T>;\n}\n\nexport function RosterGroupSection<T extends RosterItem>({\n group, index, shared,\n}: RosterGroupSectionProps<T>): React.ReactElement {\n const { theme } = useUi();\n const gid = shared.ids.group(group.key);\n\n let body: React.ReactNode;\n if (group.items.length === 0)\n body = (\n <View style={[styles.empty, { borderColor: theme.colors.border }]} testID={`${gid}-empty`}>\n <Text style={[styles.emptyText, { color: theme.colors.textSecondary }]}>{shared.labels.emptyGroup}</Text>\n </View>\n );\n else if (shared.reordering) body = <ReorderList group={group} shared={shared} />;\n else body = <CardBand group={group} shared={shared} />;\n\n return (\n <View style={styles.section} testID={gid}>\n <GroupHeader group={group} index={index} shared={shared} />\n {body}\n </View>\n );\n}\n","/**\n * CardRoster — a generic grouped card editor. Composed narrow-first: one column with the\n * edit form in a sheet; at/above `wideBreakpoint` the form moves into a right-hand pane.\n * The value is controlled; every edit is a pure helper from `utils/rosterOps`.\n */\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { StyleSheet, View, useWindowDimensions } from 'react-native';\n\nimport { ErrorState } from '@dloizides/ui-feedback';\nimport { LAYOUT_COLLAPSE_BREAKPOINT } from '@dloizides/ui-layout';\n\nimport { DEFAULT_CARD_WIDTH, DEFAULT_TEST_ID, SPACE_L, SPACE_S, rosterTestIds } from '../constants';\nimport { useRosterActions } from '../hooks/useRosterActions';\nimport { useRosterEditor } from '../hooks/useRosterEditor';\nimport type { CardRosterProps, RosterItem } from '../types';\nimport { isSplitPane } from '../utils/editorSession';\nimport { isGroupEmpty } from '../utils/rosterOps';\nimport { EditorPane } from './EditorPane';\nimport { RosterButton } from './RosterButton';\nimport { RosterGroupSection } from './RosterGroupSection';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n root: { gap: SPACE_L },\n split: { flexDirection: 'row', alignItems: 'flex-start' },\n list: { flex: 1, minWidth: 0, gap: SPACE_L },\n toolbar: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S, justifyContent: 'flex-end' },\n});\n\nexport function CardRoster<T extends RosterItem>(props: CardRosterProps<T>): React.ReactElement {\n const {\n value, onChange, renderCard, renderEditor, getItemName, labels, createItem, createGroup,\n canRemoveGroup = isGroupEmpty, getItemState, onRetryItem, error,\n wideBreakpoint = LAYOUT_COLLAPSE_BREAKPOINT, cardWidth = DEFAULT_CARD_WIDTH, testID = DEFAULT_TEST_ID,\n } = props;\n const { width } = useWindowDimensions();\n const split = isSplitPane(width, wideBreakpoint);\n const [reordering, setReordering] = useState(false);\n const editor = useRosterEditor(value, onChange, createItem);\n const actions = useRosterActions(value, onChange);\n const ids = useMemo(() => rosterTestIds(testID), [testID]);\n const { close, openEdit, openNew } = editor;\n\n const toggleReorder = useCallback((): void => {\n close();\n setReordering((on) => !on);\n }, [close]);\n\n const shared: RosterSectionShared<T> = {\n renderCard, getItemName, getItemState, onRetryItem, labels, cardWidth, ids, reordering, actions, canRemoveGroup,\n activeItemId: editor.activeItemId,\n groupCount: value.groups.length,\n onEdit: openEdit,\n onAdd: createItem === undefined ? undefined : openNew,\n };\n\n return (\n <View style={[styles.root, split ? styles.split : null]} testID={ids.root}>\n <View style={styles.list}>\n <View style={styles.toolbar}>\n <RosterButton\n emphasis={reordering}\n hint={reordering ? labels.doneReorderingHint : labels.reorderHint}\n label={reordering ? labels.doneReordering : labels.reorder}\n testID={ids.reorderToggle}\n onPress={toggleReorder}\n />\n {createGroup !== undefined && !reordering ? (\n <RosterButton\n hint={labels.addGroupHint}\n label={labels.addGroup}\n testID={ids.addGroup}\n onPress={() => actions.addGroup(createGroup())}\n />\n ) : null}\n </View>\n {error !== undefined ? (\n <ErrorState message={error.message} testID={ids.error} title={error.title} onRetry={error.onRetry} />\n ) : null}\n {value.groups.map((group, index) => (\n <RosterGroupSection key={group.key} group={group} index={index} shared={shared} />\n ))}\n </View>\n {reordering && split ? null : (\n <EditorPane\n context={editor.context}\n labels={labels}\n placeholderTestID={ids.editorPlaceholder}\n renderEditor={renderEditor}\n split={split}\n testID={ids.editor}\n onClose={close}\n />\n )}\n </View>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/utils/rosterOps.ts","../src/hooks/useRosterActions.ts","../src/utils/editorSession.ts","../src/hooks/useRosterEditor.ts","../src/components/EditorPane.tsx","../src/components/RosterButton.tsx","../src/components/ItemFrame.tsx","../src/components/CardBand.tsx","../src/components/GroupHeader.tsx","../src/components/ReorderList.tsx","../src/components/RosterGroupSection.tsx","../src/components/CardRoster.tsx"],"names":["item","useMemo","useState","useCallback","StyleSheet","useUi","ModalShell","jsx","View","Text","jsxs","Fragment","styles","Pressable","ActivityIndicator","ScrollView","TextInput","Reorder","LAYOUT_COLLAPSE_BREAKPOINT","useWindowDimensions","ErrorState"],"mappings":"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","file":"index.js","sourcesContent":["/** Minimum hit box (CSS px) for every interactive element — mobile-first standard. */\nexport const MIN_TOUCH_TARGET = 44;\nexport const DEFAULT_CARD_WIDTH = 168;\nexport const SPLIT_EDITOR_WIDTH = 400;\nexport const SPACE_XS = 4;\nexport const SPACE_S = 8;\nexport const SPACE_M = 12;\nexport const SPACE_L = 16;\nexport const RADIUS_S = 8;\nexport const RADIUS_M = 12;\nexport const BORDER_WIDTH = 1;\nexport const ACTIVE_BORDER_WIDTH = 2;\nexport const TITLE_FONT_SIZE = 17;\nexport const BODY_FONT_SIZE = 15;\nexport const SMALL_FONT_SIZE = 13;\nexport const PRESSED_OPACITY = 0.7;\nexport const DISABLED_OPACITY = 0.4;\nexport const BUSY_OVERLAY_OPACITY = 0.9;\nexport const GROUP_TITLE_MIN_WIDTH = 120;\nexport const REORDER_SPRING = { stiffness: 320, damping: 32 } as const;\n\n/** Move deltas for the reorder helpers. */\nexport const MOVE_UP = -1;\nexport const MOVE_DOWN = 1;\n\n/** Decorative arrow glyphs; the buttons carry translated accessibility labels. */\nexport const GLYPH_UP = '▲';\nexport const GLYPH_DOWN = '▼';\n\nexport const DEFAULT_TEST_ID = 'card-roster';\n\n/** Stable testIDs derived from the roster's root testID. */\nexport const rosterTestIds = (base: string) => ({\n root: base,\n reorderToggle: `${base}-reorder-toggle`,\n addGroup: `${base}-add-group`,\n error: `${base}-error`,\n editor: `${base}-editor`,\n editorPlaceholder: `${base}-editor-placeholder`,\n group: (key: string): string => `${base}-group-${key}`,\n card: (id: string): string => `${base}-card-${id}`,\n});\n\nexport type RosterTestIds = ReturnType<typeof rosterTestIds>;\n","/**\n * Pure, immutable reducer helpers over a `RosterValue`. Every helper returns the SAME\n * reference when the operation is a no-op (unknown key, out-of-range move, duplicate\n * id), so callers can skip `onChange` with a reference check.\n */\nimport type { RosterGroup, RosterItem, RosterValue } from '../types';\n\nexport interface FoundItem<T extends RosterItem> {\n group: RosterGroup<T>;\n item: T;\n index: number;\n}\n\n/** `true` when moving `index` by `delta` stays inside a list of `length`. */\nexport function canMove(length: number, index: number, delta: number): boolean {\n const target = index + delta;\n return delta !== 0 && index >= 0 && index < length && target >= 0 && target < length;\n}\n\n/** Moves one element; returns `list` itself when the move is out of range. */\nexport function moveInArray<X>(list: X[], index: number, delta: number): X[] {\n if (!canMove(list.length, index, delta)) return list;\n const next = [...list];\n const [moved] = next.splice(index, 1);\n next.splice(index + delta, 0, moved as X);\n return next;\n}\n\nexport function isGroupEmpty<T extends RosterItem>(group: RosterGroup<T>): boolean {\n return group.items.length === 0;\n}\n\nfunction mapGroup<T extends RosterItem>(\n value: RosterValue<T>,\n key: string,\n fn: (group: RosterGroup<T>) => RosterGroup<T>,\n): RosterValue<T> {\n let changed = false;\n const groups = value.groups.map((group) => {\n if (group.key !== key) return group;\n const next = fn(group);\n if (next !== group) changed = true;\n return next;\n });\n return changed ? { ...value, groups } : value;\n}\n\nexport function findItem<T extends RosterItem>(value: RosterValue<T>, itemId: string): FoundItem<T> | undefined {\n for (const group of value.groups) {\n const index = group.items.findIndex((item) => item.id === itemId);\n const item = group.items[index];\n if (item !== undefined) return { group, item, index };\n }\n return undefined;\n}\n\nexport function addGroup<T extends RosterItem>(value: RosterValue<T>, group: RosterGroup<T>): RosterValue<T> {\n if (value.groups.some((g) => g.key === group.key)) return value;\n return { ...value, groups: [...value.groups, group] };\n}\n\n/** Trims the title; an empty or unchanged title is a no-op. */\nexport function renameGroup<T extends RosterItem>(value: RosterValue<T>, key: string, title: string): RosterValue<T> {\n const trimmed = title.trim();\n if (trimmed === '') return value;\n return mapGroup(value, key, (group) => (group.title === trimmed ? group : { ...group, title: trimmed }));\n}\n\nexport function removeGroup<T extends RosterItem>(value: RosterValue<T>, key: string): RosterValue<T> {\n if (!value.groups.some((g) => g.key === key)) return value;\n return { ...value, groups: value.groups.filter((g) => g.key !== key) };\n}\n\nexport function moveGroup<T extends RosterItem>(value: RosterValue<T>, key: string, delta: number): RosterValue<T> {\n const index = value.groups.findIndex((g) => g.key === key);\n const groups = moveInArray(value.groups, index, delta);\n return groups === value.groups ? value : { ...value, groups };\n}\n\n/** Appends to the group; refuses an id already present anywhere in the roster. */\nexport function addItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, item: T): RosterValue<T> {\n if (findItem(value, item.id) !== undefined) return value;\n return mapGroup(value, groupKey, (group) => ({ ...group, items: [...group.items, item] }));\n}\n\nexport function updateItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, item: T): RosterValue<T> {\n return mapGroup(value, groupKey, (group) => {\n const index = group.items.findIndex((i) => i.id === item.id);\n if (index === -1) return group;\n const items = [...group.items];\n items[index] = item;\n return { ...group, items };\n });\n}\n\nexport function removeItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, itemId: string): RosterValue<T> {\n return mapGroup(value, groupKey, (group) =>\n group.items.some((i) => i.id === itemId) ? { ...group, items: group.items.filter((i) => i.id !== itemId) } : group,\n );\n}\n\nexport function moveItem<T extends RosterItem>(\n value: RosterValue<T>,\n groupKey: string,\n itemId: string,\n delta: number,\n): RosterValue<T> {\n return mapGroup(value, groupKey, (group) => {\n const items = moveInArray(group.items, group.items.findIndex((i) => i.id === itemId), delta);\n return items === group.items ? group : { ...group, items };\n });\n}\n","import { useMemo } from 'react';\n\nimport type { RosterGroup, RosterItem, RosterValue } from '../types';\nimport { addGroup, moveGroup, moveItem, removeGroup, renameGroup } from '../utils/rosterOps';\n\nexport interface RosterActions<T extends RosterItem> {\n addGroup: (group: RosterGroup<T>) => void;\n renameGroup: (key: string, title: string) => void;\n removeGroup: (key: string) => void;\n moveGroup: (key: string, delta: number) => void;\n moveItem: (groupKey: string, itemId: string, delta: number) => void;\n}\n\n/**\n * Binds the pure helpers to the controlled value; a no-op never calls `onChange`.\n * While `disabled` (a save in flight) every action is a no-op.\n */\nexport function useRosterActions<T extends RosterItem>(\n value: RosterValue<T>,\n onChange: (next: RosterValue<T>) => void,\n disabled = false,\n): RosterActions<T> {\n return useMemo(() => {\n const emit = (next: RosterValue<T>): void => {\n if (!disabled && next !== value) onChange(next);\n };\n return {\n addGroup: (group) => emit(addGroup(value, group)),\n renameGroup: (key, title) => emit(renameGroup(value, key, title)),\n removeGroup: (key) => emit(removeGroup(value, key)),\n moveGroup: (key, delta) => emit(moveGroup(value, key, delta)),\n moveItem: (groupKey, itemId, delta) => emit(moveItem(value, groupKey, itemId, delta)),\n };\n }, [value, onChange, disabled]);\n}\n","/**\n * Pure edit-session logic: which item the editor shows, and how a save lands.\n * Kept out of the hook so the rules are unit-tested without React.\n */\nimport type { RosterItem, RosterValue } from '../types';\nimport { addItem, findItem, updateItem } from './rosterOps';\n\n/** What the user opened: an existing item (`itemId`) or a new one (`itemId: null`). */\nexport interface EditTarget {\n groupKey: string;\n itemId: string | null;\n}\n\nexport interface EditSession<T extends RosterItem> {\n item: T;\n groupKey: string;\n isNew: boolean;\n}\n\n/** `true` at/above the breakpoint: the editor renders as a split pane, not a sheet. */\nexport function isSplitPane(width: number, breakpoint: number): boolean {\n return width >= breakpoint;\n}\n\n/**\n * Resolves the target against the CURRENT value. An existing item that has since\n * disappeared (removed elsewhere) resolves to `null`, which closes the editor; an\n * item moved to another group resolves to its new group.\n */\nexport function resolveEditSession<T extends RosterItem>(\n value: RosterValue<T>,\n target: EditTarget | null,\n draft: T | null,\n): EditSession<T> | null {\n if (target === null) return null;\n if (target.itemId === null) return draft === null ? null : { item: draft, groupKey: target.groupKey, isNew: true };\n const found = findItem(value, target.itemId);\n return found === undefined ? null : { item: found.item, groupKey: found.group.key, isNew: false };\n}\n\n/** Applies a save: a new item is appended, an existing one replaced in place. */\nexport function commitEdit<T extends RosterItem>(value: RosterValue<T>, session: EditSession<T>, next: T): RosterValue<T> {\n return session.isNew ? addItem(value, session.groupKey, next) : updateItem(value, session.groupKey, next);\n}\n","import { useCallback, useState } from 'react';\n\nimport type { RosterEditorContext, RosterItem, RosterValue } from '../types';\nimport { commitEdit, resolveEditSession, type EditTarget } from '../utils/editorSession';\nimport { removeItem } from '../utils/rosterOps';\n\nexport interface UseRosterEditorResult<T extends RosterItem> {\n /** `null` when the editor is closed. */\n context: RosterEditorContext<T> | null;\n /** Id of the existing item being edited (for the active-card highlight). */\n activeItemId: string | null;\n openEdit: (groupKey: string, itemId: string) => void;\n openNew: (groupKey: string) => void;\n close: () => void;\n}\n\n/**\n * Owns the edit target + the unsaved draft of a new item; writes through `onChange`.\n * While `disabled` nothing opens, and save/remove are no-ops that keep the editor open.\n */\nexport function useRosterEditor<T extends RosterItem>(\n value: RosterValue<T>,\n onChange: (next: RosterValue<T>) => void,\n createItem?: (groupKey: string) => T,\n disabled = false,\n): UseRosterEditorResult<T> {\n const [target, setTarget] = useState<EditTarget | null>(null);\n const [draft, setDraft] = useState<T | null>(null);\n\n const close = useCallback((): void => {\n setTarget(null);\n setDraft(null);\n }, []);\n const openEdit = useCallback((groupKey: string, itemId: string): void => {\n if (disabled) return;\n setDraft(null);\n setTarget({ groupKey, itemId });\n }, [disabled]);\n const openNew = useCallback(\n (groupKey: string): void => {\n if (disabled || createItem === undefined) return;\n setDraft(createItem(groupKey));\n setTarget({ groupKey, itemId: null });\n },\n [createItem, disabled],\n );\n\n const session = resolveEditSession(value, target, draft);\n const context: RosterEditorContext<T> | null =\n session === null\n ? null\n : {\n ...session,\n disabled,\n save: (next: T): void => {\n if (disabled) return;\n const updated = commitEdit(value, session, next);\n if (updated !== value) onChange(updated);\n close();\n },\n cancel: close,\n remove: (): void => {\n if (disabled) return;\n if (!session.isNew) onChange(removeItem(value, session.groupKey, session.item.id));\n close();\n },\n };\n\n const activeItemId = session !== null && !session.isNew ? session.item.id : null;\n return { context, activeItemId, openEdit, openNew, close };\n}\n","/**\n * The edit-sheet slot. Narrow: ui-layout's `ModalShell` sheet. Wide: an inline right\n * pane that shows a prompt until a card is picked (the split pane).\n */\nimport React from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\nimport { ModalShell } from '@dloizides/ui-layout';\n\nimport { BODY_FONT_SIZE, BORDER_WIDTH, RADIUS_M, SPACE_L, SPLIT_EDITOR_WIDTH, TITLE_FONT_SIZE } from '../constants';\nimport type { CardRosterLabels, RosterEditorContext, RosterItem } from '../types';\n\nconst styles = StyleSheet.create({\n pane: { width: SPLIT_EDITOR_WIDTH, borderWidth: BORDER_WIDTH, borderRadius: RADIUS_M, padding: SPACE_L, gap: SPACE_L },\n title: { fontSize: TITLE_FONT_SIZE, fontWeight: '700' },\n prompt: { fontSize: BODY_FONT_SIZE },\n});\n\nexport interface EditorPaneProps<T extends RosterItem> {\n context: RosterEditorContext<T> | null;\n renderEditor: (context: RosterEditorContext<T>) => React.ReactNode;\n split: boolean;\n labels: Pick<CardRosterLabels, 'editorTitleNew' | 'editorTitleEdit' | 'selectPrompt'>;\n onClose: () => void;\n testID: string;\n placeholderTestID: string;\n}\n\nexport function EditorPane<T extends RosterItem>({\n context, renderEditor, split, labels, onClose, testID, placeholderTestID,\n}: EditorPaneProps<T>): React.ReactElement {\n const { theme } = useUi();\n const title = context?.isNew === true ? labels.editorTitleNew : labels.editorTitleEdit;\n\n if (!split)\n return (\n <ModalShell title={title} visible={context !== null} onCancel={onClose}>\n {context === null ? null : <View testID={testID}>{renderEditor(context)}</View>}\n </ModalShell>\n );\n\n return (\n <View style={[styles.pane, { borderColor: theme.colors.border, backgroundColor: theme.colors.surface }]} testID={testID}>\n {context === null ? (\n <Text style={[styles.prompt, { color: theme.colors.textSecondary }]} testID={placeholderTestID}>\n {labels.selectPrompt}\n </Text>\n ) : (\n <>\n <Text accessibilityRole=\"header\" style={[styles.title, { color: theme.colors.text }]}>{title}</Text>\n {renderEditor(context)}\n </>\n )}\n </View>\n );\n}\n","/**\n * The roster's one button. `Pressable`, not `TouchableOpacity` (RN-web drops its hover\n * callbacks), and the 44x44 floor is on the BOX via min sizes — `hitSlop` is inert on\n * RN-web, so it cannot be relied on to grow the target.\n */\nimport React from 'react';\n\nimport { Pressable, StyleSheet, Text } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n BODY_FONT_SIZE, BORDER_WIDTH, DISABLED_OPACITY, MIN_TOUCH_TARGET, PRESSED_OPACITY, RADIUS_S, SPACE_M,\n} from '../constants';\n\nconst styles = StyleSheet.create({\n base: {\n minHeight: MIN_TOUCH_TARGET,\n minWidth: MIN_TOUCH_TARGET,\n paddingHorizontal: SPACE_M,\n borderRadius: RADIUS_S,\n borderWidth: BORDER_WIDTH,\n alignItems: 'center',\n justifyContent: 'center',\n },\n label: { fontSize: BODY_FONT_SIZE, fontWeight: '600' },\n pressed: { opacity: PRESSED_OPACITY },\n disabled: { opacity: DISABLED_OPACITY },\n});\n\nexport interface RosterButtonProps {\n label: string;\n /** Defaults to `label`; pass a fuller one when the visible label is short (\"Edit\"). */\n accessibilityLabel?: string;\n hint: string;\n onPress: () => void;\n testID: string;\n emphasis?: boolean;\n danger?: boolean;\n disabled?: boolean;\n}\n\nexport function RosterButton({\n label, accessibilityLabel, hint, onPress, testID, emphasis = false, danger = false, disabled = false,\n}: RosterButtonProps): React.ReactElement {\n const { theme } = useUi();\n const accent = danger ? theme.semantic.error['500'] : theme.palette.primary['500'];\n const tone = emphasis ? { backgroundColor: accent, borderColor: accent } : { borderColor: theme.colors.border };\n const color = emphasis ? theme.colors.background : accent;\n\n return (\n <Pressable\n accessibilityHint={hint}\n accessibilityLabel={accessibilityLabel ?? label}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled }}\n disabled={disabled}\n style={({ pressed }) => [styles.base, tone, pressed ? styles.pressed : null, disabled ? styles.disabled : null]}\n testID={testID}\n onPress={onPress}\n >\n <Text style={[styles.label, { color }]}>{label}</Text>\n </Pressable>\n );\n}\n","/**\n * Frame around one host-rendered card: border, the uploading overlay (busy) and the\n * upload-error row with retry. The host's card body never has to know about either.\n */\nimport React from 'react';\n\nimport { ActivityIndicator, StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n ACTIVE_BORDER_WIDTH, BORDER_WIDTH, BUSY_OVERLAY_OPACITY, RADIUS_M, SMALL_FONT_SIZE, SPACE_S,\n} from '../constants';\nimport type { CardRosterLabels, RosterItemState } from '../types';\nimport { RosterButton } from './RosterButton';\n\nconst styles = StyleSheet.create({\n frame: { borderRadius: RADIUS_M, padding: SPACE_S, gap: SPACE_S, overflow: 'hidden' },\n fill: { alignSelf: 'stretch' },\n body: { position: 'relative' },\n busy: {\n ...StyleSheet.absoluteFillObject,\n alignItems: 'center',\n justifyContent: 'center',\n gap: SPACE_S,\n opacity: BUSY_OVERLAY_OPACITY,\n },\n small: { fontSize: SMALL_FONT_SIZE },\n errorRow: { gap: SPACE_S },\n footer: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S },\n});\n\nexport type ItemFrameLabels = Pick<CardRosterLabels, 'uploading' | 'retry' | 'retryHint'>;\n\nexport interface ItemFrameProps {\n /** Fixed width in the band; omitted = stretch (reorder list). */\n width?: number;\n active: boolean;\n state: RosterItemState | undefined;\n labels: ItemFrameLabels;\n onRetry?: () => void;\n testID: string;\n children: React.ReactNode;\n footer: React.ReactNode;\n}\n\nexport function ItemFrame({\n width, active, state, labels, onRetry, testID, children, footer,\n}: ItemFrameProps): React.ReactElement {\n const { theme } = useUi();\n const busy = state?.busy === true;\n const error = state?.error ?? '';\n const hasError = error !== '';\n const errorColor = theme.semantic.error['500'];\n const primary = theme.palette.primary['500'];\n const highlighted = active || hasError;\n const borderColor = hasError ? errorColor : active ? primary : theme.colors.border;\n\n return (\n <View\n accessibilityState={{ busy }}\n style={[\n styles.frame,\n width === undefined ? styles.fill : { width },\n { borderColor, backgroundColor: theme.colors.surface, borderWidth: highlighted ? ACTIVE_BORDER_WIDTH : BORDER_WIDTH },\n ]}\n testID={testID}\n >\n <View style={styles.body}>\n {children}\n {busy ? (\n <View style={[styles.busy, { backgroundColor: theme.colors.surfaceElevated }]} testID={`${testID}-busy`}>\n <ActivityIndicator color={primary} />\n <Text accessibilityLiveRegion=\"polite\" style={[styles.small, { color: theme.colors.textSecondary }]}>\n {labels.uploading}\n </Text>\n </View>\n ) : null}\n </View>\n {hasError ? (\n <View style={styles.errorRow} testID={`${testID}-error`}>\n <Text accessibilityRole=\"alert\" style={[styles.small, { color: errorColor }]}>{error}</Text>\n {onRetry !== undefined ? (\n <RosterButton danger hint={labels.retryHint} label={labels.retry} testID={`${testID}-retry`} onPress={onRetry} />\n ) : null}\n </View>\n ) : null}\n <View style={styles.footer}>{footer}</View>\n </View>\n );\n}\n","/** The live band: a horizontal row of framed cards, each with its own Edit button. */\nimport React from 'react';\n\nimport { ScrollView, StyleSheet } from 'react-native';\n\nimport { SPACE_M, SPACE_XS } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { ItemFrame } from './ItemFrame';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n band: { gap: SPACE_M, paddingVertical: SPACE_XS },\n});\n\nexport interface CardBandProps<T extends RosterItem> {\n group: RosterGroup<T>;\n shared: RosterSectionShared<T>;\n}\n\nexport function CardBand<T extends RosterItem>({ group, shared }: CardBandProps<T>): React.ReactElement {\n const { labels, ids, onRetryItem } = shared;\n return (\n <ScrollView\n horizontal\n contentContainerStyle={styles.band}\n showsHorizontalScrollIndicator={false}\n testID={`${ids.group(group.key)}-band`}\n >\n {group.items.map((item) => {\n const cardId = ids.card(item.id);\n return (\n <ItemFrame\n key={item.id}\n active={shared.activeItemId === item.id}\n footer={(\n <RosterButton\n accessibilityLabel={labels.editCard(shared.getItemName(item))}\n disabled={shared.disabled}\n hint={labels.editCardHint}\n label={labels.edit}\n testID={`${cardId}-edit`}\n onPress={() => shared.onEdit(group.key, item.id)}\n />\n )}\n labels={labels}\n state={shared.getItemState?.(item)}\n testID={cardId}\n width={shared.cardWidth}\n onRetry={onRetryItem === undefined ? undefined : () => onRetryItem(item)}\n >\n {shared.renderCard(item, group)}\n </ItemFrame>\n );\n })}\n </ScrollView>\n );\n}\n","/** Group title (inline rename) + its actions; in Reorder mode, group up/down instead. */\nimport React, { useState } from 'react';\n\nimport { StyleSheet, Text, TextInput, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n BODY_FONT_SIZE, BORDER_WIDTH, GLYPH_DOWN, GLYPH_UP, GROUP_TITLE_MIN_WIDTH, MIN_TOUCH_TARGET, MOVE_DOWN, MOVE_UP,\n RADIUS_S, SPACE_M, SPACE_S, TITLE_FONT_SIZE,\n} from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n header: { flexDirection: 'row', flexWrap: 'wrap', alignItems: 'center', gap: SPACE_S },\n title: { flexGrow: 1, flexShrink: 1, minWidth: GROUP_TITLE_MIN_WIDTH, fontSize: TITLE_FONT_SIZE, fontWeight: '700' },\n input: {\n flexGrow: 1,\n minWidth: GROUP_TITLE_MIN_WIDTH,\n minHeight: MIN_TOUCH_TARGET,\n paddingHorizontal: SPACE_M,\n borderWidth: BORDER_WIDTH,\n borderRadius: RADIUS_S,\n fontSize: BODY_FONT_SIZE,\n },\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S },\n});\n\nexport interface GroupHeaderProps<T extends RosterItem> {\n group: RosterGroup<T>;\n index: number;\n shared: RosterSectionShared<T>;\n}\n\nexport function GroupHeader<T extends RosterItem>({ group, index, shared }: GroupHeaderProps<T>): React.ReactElement {\n const { theme } = useUi();\n const [draft, setDraft] = useState<string | null>(null);\n const { labels, actions, reordering, disabled } = shared;\n const gid = shared.ids.group(group.key);\n\n const commit = (): void => {\n // Keep the draft while a save is in flight; it commits on the next blur/submit.\n if (disabled) return;\n if (draft !== null) actions.renameGroup(group.key, draft);\n setDraft(null);\n };\n\n const reorderActions = (\n <>\n <RosterButton\n accessibilityLabel={labels.moveGroupUp(group.title)}\n disabled={disabled || index === 0}\n hint={labels.moveGroupHint}\n label={GLYPH_UP}\n testID={`${gid}-up`}\n onPress={() => actions.moveGroup(group.key, MOVE_UP)}\n />\n <RosterButton\n accessibilityLabel={labels.moveGroupDown(group.title)}\n disabled={disabled || index === shared.groupCount - 1}\n hint={labels.moveGroupHint}\n label={GLYPH_DOWN}\n testID={`${gid}-down`}\n onPress={() => actions.moveGroup(group.key, MOVE_DOWN)}\n />\n </>\n );\n\n const editActions = (\n <>\n {shared.onAdd !== undefined ? (\n <RosterButton\n emphasis\n accessibilityLabel={labels.addCard(group.title)}\n disabled={disabled}\n hint={labels.addCardHint}\n label={labels.add}\n testID={`${gid}-add`}\n onPress={() => shared.onAdd?.(group.key)}\n />\n ) : null}\n <RosterButton\n accessibilityLabel={labels.renameGroup(group.title)}\n disabled={disabled}\n hint={labels.renameGroupHint}\n label={labels.rename}\n testID={`${gid}-rename`}\n onPress={() => setDraft(group.title)}\n />\n {shared.canRemoveGroup(group) ? (\n <RosterButton\n danger\n accessibilityLabel={labels.removeGroup(group.title)}\n disabled={disabled}\n hint={labels.removeGroupHint}\n label={labels.remove}\n testID={`${gid}-remove`}\n onPress={() => actions.removeGroup(group.key)}\n />\n ) : null}\n </>\n );\n\n return (\n <View style={styles.header}>\n {draft === null ? (\n <Text accessibilityRole=\"header\" numberOfLines={1} style={[styles.title, { color: theme.colors.text }]}>\n {group.title}\n </Text>\n ) : (\n <TextInput\n autoFocus\n accessibilityHint={labels.groupTitleInputHint}\n accessibilityLabel={labels.groupTitleInput}\n accessibilityState={{ disabled }}\n editable={!disabled}\n style={[styles.input, { color: theme.colors.text, borderColor: theme.palette.primary['500'] }]}\n testID={`${gid}-title-input`}\n value={draft}\n onBlur={commit}\n onChangeText={setDraft}\n onSubmitEditing={commit}\n />\n )}\n <View style={styles.actions}>{reordering ? reorderActions : editActions}</View>\n </View>\n );\n}\n","/**\n * Reorder mode for one group: a vertical list with explicit up/down buttons (no drag —\n * a drag is not reachable by keyboard or switch access). Moves animate through\n * ui-motion's `Reorder` (FLIP), which collapses to instant under reduced motion.\n */\nimport React, { useMemo } from 'react';\n\nimport { StyleSheet, View } from 'react-native';\n\nimport { Reorder } from '@dloizides/ui-motion';\n\nimport { GLYPH_DOWN, GLYPH_UP, MOVE_DOWN, MOVE_UP, REORDER_SPRING, SPACE_S } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { ItemFrame } from './ItemFrame';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n item: { paddingVertical: SPACE_S / 2 },\n});\n\nexport interface ReorderListProps<T extends RosterItem> {\n group: RosterGroup<T>;\n shared: RosterSectionShared<T>;\n}\n\nexport function ReorderList<T extends RosterItem>({ group, shared }: ReorderListProps<T>): React.ReactElement {\n const { labels, ids, actions } = shared;\n const keys = useMemo(() => group.items.map((item) => item.id), [group.items]);\n const last = group.items.length - 1;\n\n const renderItem = (key: string): React.ReactNode => {\n const index = group.items.findIndex((item) => item.id === key);\n const item = group.items[index];\n if (item === undefined) return null;\n const name = shared.getItemName(item);\n const cardId = ids.card(item.id);\n return (\n <View style={styles.item}>\n <ItemFrame\n active={false}\n footer={(\n <>\n <RosterButton\n accessibilityLabel={labels.moveCardUp(name)}\n disabled={shared.disabled || index === 0}\n hint={labels.moveCardHint}\n label={GLYPH_UP}\n testID={`${cardId}-up`}\n onPress={() => actions.moveItem(group.key, item.id, MOVE_UP)}\n />\n <RosterButton\n accessibilityLabel={labels.moveCardDown(name)}\n disabled={shared.disabled || index === last}\n hint={labels.moveCardHint}\n label={GLYPH_DOWN}\n testID={`${cardId}-down`}\n onPress={() => actions.moveItem(group.key, item.id, MOVE_DOWN)}\n />\n </>\n )}\n labels={labels}\n state={shared.getItemState?.(item)}\n testID={cardId}\n >\n {shared.renderCard(item, group)}\n </ItemFrame>\n </View>\n );\n };\n\n return (\n <Reorder itemKeys={keys} spring={REORDER_SPRING} testID={`${ids.group(group.key)}-reorder`}>\n {renderItem}\n </Reorder>\n );\n}\n","/** One group: header, then the empty state, the live band, or the reorder list. */\nimport React from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport { BODY_FONT_SIZE, BORDER_WIDTH, RADIUS_M, SPACE_L, SPACE_S } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { CardBand } from './CardBand';\nimport { GroupHeader } from './GroupHeader';\nimport { ReorderList } from './ReorderList';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n section: { gap: SPACE_S },\n empty: {\n borderWidth: BORDER_WIDTH,\n borderStyle: 'dashed',\n borderRadius: RADIUS_M,\n padding: SPACE_L,\n alignItems: 'center',\n },\n emptyText: { fontSize: BODY_FONT_SIZE, textAlign: 'center' },\n});\n\nexport interface RosterGroupSectionProps<T extends RosterItem> {\n group: RosterGroup<T>;\n index: number;\n shared: RosterSectionShared<T>;\n}\n\nexport function RosterGroupSection<T extends RosterItem>({\n group, index, shared,\n}: RosterGroupSectionProps<T>): React.ReactElement {\n const { theme } = useUi();\n const gid = shared.ids.group(group.key);\n\n let body: React.ReactNode;\n if (group.items.length === 0)\n body = (\n <View style={[styles.empty, { borderColor: theme.colors.border }]} testID={`${gid}-empty`}>\n <Text style={[styles.emptyText, { color: theme.colors.textSecondary }]}>{shared.labels.emptyGroup}</Text>\n </View>\n );\n else if (shared.reordering) body = <ReorderList group={group} shared={shared} />;\n else body = <CardBand group={group} shared={shared} />;\n\n return (\n <View style={styles.section} testID={gid}>\n <GroupHeader group={group} index={index} shared={shared} />\n {body}\n </View>\n );\n}\n","/**\n * CardRoster — a generic grouped card editor. Composed narrow-first: one column with the\n * edit form in a sheet; at/above `wideBreakpoint` the form moves into a right-hand pane.\n * The value is controlled; every edit is a pure helper from `utils/rosterOps`.\n */\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { StyleSheet, View, useWindowDimensions } from 'react-native';\n\nimport { ErrorState } from '@dloizides/ui-feedback';\nimport { LAYOUT_COLLAPSE_BREAKPOINT } from '@dloizides/ui-layout';\n\nimport { DEFAULT_CARD_WIDTH, DEFAULT_TEST_ID, SPACE_L, SPACE_S, rosterTestIds } from '../constants';\nimport { useRosterActions } from '../hooks/useRosterActions';\nimport { useRosterEditor } from '../hooks/useRosterEditor';\nimport type { CardRosterProps, RosterItem } from '../types';\nimport { isSplitPane } from '../utils/editorSession';\nimport { isGroupEmpty } from '../utils/rosterOps';\nimport { EditorPane } from './EditorPane';\nimport { RosterButton } from './RosterButton';\nimport { RosterGroupSection } from './RosterGroupSection';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n root: { gap: SPACE_L },\n split: { flexDirection: 'row', alignItems: 'flex-start' },\n list: { flex: 1, minWidth: 0, gap: SPACE_L },\n toolbar: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S, justifyContent: 'flex-end' },\n});\n\nexport function CardRoster<T extends RosterItem>(props: CardRosterProps<T>): React.ReactElement {\n const {\n value, onChange, renderCard, renderEditor, getItemName, labels, createItem, createGroup,\n canRemoveGroup = isGroupEmpty, getItemState, onRetryItem, error, disabled = false,\n wideBreakpoint = LAYOUT_COLLAPSE_BREAKPOINT, cardWidth = DEFAULT_CARD_WIDTH, testID = DEFAULT_TEST_ID,\n } = props;\n const { width } = useWindowDimensions();\n const split = isSplitPane(width, wideBreakpoint);\n const [reordering, setReordering] = useState(false);\n const editor = useRosterEditor(value, onChange, createItem, disabled);\n const actions = useRosterActions(value, onChange, disabled);\n const ids = useMemo(() => rosterTestIds(testID), [testID]);\n const { close, openEdit, openNew } = editor;\n\n const toggleReorder = useCallback((): void => {\n if (disabled) return;\n close();\n setReordering((on) => !on);\n }, [close, disabled]);\n\n const shared: RosterSectionShared<T> = {\n renderCard, getItemName, getItemState, onRetryItem, labels, cardWidth, ids, reordering, actions, canRemoveGroup, disabled,\n activeItemId: editor.activeItemId,\n groupCount: value.groups.length,\n onEdit: openEdit,\n onAdd: createItem === undefined ? undefined : openNew,\n };\n\n return (\n <View accessibilityState={{ busy: disabled }} style={[styles.root, split ? styles.split : null]} testID={ids.root}>\n <View style={styles.list}>\n <View style={styles.toolbar}>\n <RosterButton\n disabled={disabled}\n emphasis={reordering}\n hint={reordering ? labels.doneReorderingHint : labels.reorderHint}\n label={reordering ? labels.doneReordering : labels.reorder}\n testID={ids.reorderToggle}\n onPress={toggleReorder}\n />\n {createGroup !== undefined && !reordering ? (\n <RosterButton\n disabled={disabled}\n hint={labels.addGroupHint}\n label={labels.addGroup}\n testID={ids.addGroup}\n onPress={() => actions.addGroup(createGroup())}\n />\n ) : null}\n </View>\n {error !== undefined ? (\n <ErrorState message={error.message} testID={ids.error} title={error.title} onRetry={error.onRetry} />\n ) : null}\n {value.groups.map((group, index) => (\n <RosterGroupSection key={group.key} group={group} index={index} shared={shared} />\n ))}\n </View>\n {reordering && split ? null : (\n <EditorPane\n context={editor.context}\n labels={labels}\n placeholderTestID={ids.editorPlaceholder}\n renderEditor={renderEditor}\n split={split}\n testID={ids.editor}\n onClose={close}\n />\n )}\n </View>\n );\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -122,10 +122,10 @@ function moveItem(value, groupKey, itemId, delta) {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
// src/hooks/useRosterActions.ts
|
|
125
|
-
function useRosterActions(value, onChange) {
|
|
125
|
+
function useRosterActions(value, onChange, disabled = false) {
|
|
126
126
|
return useMemo(() => {
|
|
127
127
|
const emit = (next) => {
|
|
128
|
-
if (next !== value) onChange(next);
|
|
128
|
+
if (!disabled && next !== value) onChange(next);
|
|
129
129
|
};
|
|
130
130
|
return {
|
|
131
131
|
addGroup: (group) => emit(addGroup(value, group)),
|
|
@@ -134,7 +134,7 @@ function useRosterActions(value, onChange) {
|
|
|
134
134
|
moveGroup: (key, delta) => emit(moveGroup(value, key, delta)),
|
|
135
135
|
moveItem: (groupKey, itemId, delta) => emit(moveItem(value, groupKey, itemId, delta))
|
|
136
136
|
};
|
|
137
|
-
}, [value, onChange]);
|
|
137
|
+
}, [value, onChange, disabled]);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
// src/utils/editorSession.ts
|
|
@@ -152,7 +152,7 @@ function commitEdit(value, session, next) {
|
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
// src/hooks/useRosterEditor.ts
|
|
155
|
-
function useRosterEditor(value, onChange, createItem) {
|
|
155
|
+
function useRosterEditor(value, onChange, createItem, disabled = false) {
|
|
156
156
|
const [target, setTarget] = useState(null);
|
|
157
157
|
const [draft, setDraft] = useState(null);
|
|
158
158
|
const close = useCallback(() => {
|
|
@@ -160,27 +160,31 @@ function useRosterEditor(value, onChange, createItem) {
|
|
|
160
160
|
setDraft(null);
|
|
161
161
|
}, []);
|
|
162
162
|
const openEdit = useCallback((groupKey, itemId) => {
|
|
163
|
+
if (disabled) return;
|
|
163
164
|
setDraft(null);
|
|
164
165
|
setTarget({ groupKey, itemId });
|
|
165
|
-
}, []);
|
|
166
|
+
}, [disabled]);
|
|
166
167
|
const openNew = useCallback(
|
|
167
168
|
(groupKey) => {
|
|
168
|
-
if (createItem === void 0) return;
|
|
169
|
+
if (disabled || createItem === void 0) return;
|
|
169
170
|
setDraft(createItem(groupKey));
|
|
170
171
|
setTarget({ groupKey, itemId: null });
|
|
171
172
|
},
|
|
172
|
-
[createItem]
|
|
173
|
+
[createItem, disabled]
|
|
173
174
|
);
|
|
174
175
|
const session = resolveEditSession(value, target, draft);
|
|
175
176
|
const context = session === null ? null : {
|
|
176
177
|
...session,
|
|
178
|
+
disabled,
|
|
177
179
|
save: (next) => {
|
|
180
|
+
if (disabled) return;
|
|
178
181
|
const updated = commitEdit(value, session, next);
|
|
179
182
|
if (updated !== value) onChange(updated);
|
|
180
183
|
close();
|
|
181
184
|
},
|
|
182
185
|
cancel: close,
|
|
183
186
|
remove: () => {
|
|
187
|
+
if (disabled) return;
|
|
184
188
|
if (!session.isNew) onChange(removeItem(value, session.groupKey, session.item.id));
|
|
185
189
|
close();
|
|
186
190
|
}
|
|
@@ -336,6 +340,7 @@ function CardBand({ group, shared }) {
|
|
|
336
340
|
RosterButton,
|
|
337
341
|
{
|
|
338
342
|
accessibilityLabel: labels.editCard(shared.getItemName(item)),
|
|
343
|
+
disabled: shared.disabled,
|
|
339
344
|
hint: labels.editCardHint,
|
|
340
345
|
label: labels.edit,
|
|
341
346
|
testID: `${cardId}-edit`,
|
|
@@ -372,9 +377,10 @@ var styles5 = StyleSheet.create({
|
|
|
372
377
|
function GroupHeader({ group, index, shared }) {
|
|
373
378
|
const { theme } = useUi();
|
|
374
379
|
const [draft, setDraft] = useState(null);
|
|
375
|
-
const { labels, actions, reordering } = shared;
|
|
380
|
+
const { labels, actions, reordering, disabled } = shared;
|
|
376
381
|
const gid = shared.ids.group(group.key);
|
|
377
382
|
const commit = () => {
|
|
383
|
+
if (disabled) return;
|
|
378
384
|
if (draft !== null) actions.renameGroup(group.key, draft);
|
|
379
385
|
setDraft(null);
|
|
380
386
|
};
|
|
@@ -383,7 +389,7 @@ function GroupHeader({ group, index, shared }) {
|
|
|
383
389
|
RosterButton,
|
|
384
390
|
{
|
|
385
391
|
accessibilityLabel: labels.moveGroupUp(group.title),
|
|
386
|
-
disabled: index === 0,
|
|
392
|
+
disabled: disabled || index === 0,
|
|
387
393
|
hint: labels.moveGroupHint,
|
|
388
394
|
label: GLYPH_UP,
|
|
389
395
|
testID: `${gid}-up`,
|
|
@@ -394,7 +400,7 @@ function GroupHeader({ group, index, shared }) {
|
|
|
394
400
|
RosterButton,
|
|
395
401
|
{
|
|
396
402
|
accessibilityLabel: labels.moveGroupDown(group.title),
|
|
397
|
-
disabled: index === shared.groupCount - 1,
|
|
403
|
+
disabled: disabled || index === shared.groupCount - 1,
|
|
398
404
|
hint: labels.moveGroupHint,
|
|
399
405
|
label: GLYPH_DOWN,
|
|
400
406
|
testID: `${gid}-down`,
|
|
@@ -408,6 +414,7 @@ function GroupHeader({ group, index, shared }) {
|
|
|
408
414
|
{
|
|
409
415
|
emphasis: true,
|
|
410
416
|
accessibilityLabel: labels.addCard(group.title),
|
|
417
|
+
disabled,
|
|
411
418
|
hint: labels.addCardHint,
|
|
412
419
|
label: labels.add,
|
|
413
420
|
testID: `${gid}-add`,
|
|
@@ -418,6 +425,7 @@ function GroupHeader({ group, index, shared }) {
|
|
|
418
425
|
RosterButton,
|
|
419
426
|
{
|
|
420
427
|
accessibilityLabel: labels.renameGroup(group.title),
|
|
428
|
+
disabled,
|
|
421
429
|
hint: labels.renameGroupHint,
|
|
422
430
|
label: labels.rename,
|
|
423
431
|
testID: `${gid}-rename`,
|
|
@@ -429,6 +437,7 @@ function GroupHeader({ group, index, shared }) {
|
|
|
429
437
|
{
|
|
430
438
|
danger: true,
|
|
431
439
|
accessibilityLabel: labels.removeGroup(group.title),
|
|
440
|
+
disabled,
|
|
432
441
|
hint: labels.removeGroupHint,
|
|
433
442
|
label: labels.remove,
|
|
434
443
|
testID: `${gid}-remove`,
|
|
@@ -443,6 +452,8 @@ function GroupHeader({ group, index, shared }) {
|
|
|
443
452
|
autoFocus: true,
|
|
444
453
|
accessibilityHint: labels.groupTitleInputHint,
|
|
445
454
|
accessibilityLabel: labels.groupTitleInput,
|
|
455
|
+
accessibilityState: { disabled },
|
|
456
|
+
editable: !disabled,
|
|
446
457
|
style: [styles5.input, { color: theme.colors.text, borderColor: theme.palette.primary["500"] }],
|
|
447
458
|
testID: `${gid}-title-input`,
|
|
448
459
|
value: draft,
|
|
@@ -476,7 +487,7 @@ function ReorderList({ group, shared }) {
|
|
|
476
487
|
RosterButton,
|
|
477
488
|
{
|
|
478
489
|
accessibilityLabel: labels.moveCardUp(name),
|
|
479
|
-
disabled: index === 0,
|
|
490
|
+
disabled: shared.disabled || index === 0,
|
|
480
491
|
hint: labels.moveCardHint,
|
|
481
492
|
label: GLYPH_UP,
|
|
482
493
|
testID: `${cardId}-up`,
|
|
@@ -487,7 +498,7 @@ function ReorderList({ group, shared }) {
|
|
|
487
498
|
RosterButton,
|
|
488
499
|
{
|
|
489
500
|
accessibilityLabel: labels.moveCardDown(name),
|
|
490
|
-
disabled: index === last,
|
|
501
|
+
disabled: shared.disabled || index === last,
|
|
491
502
|
hint: labels.moveCardHint,
|
|
492
503
|
label: GLYPH_DOWN,
|
|
493
504
|
testID: `${cardId}-down`,
|
|
@@ -552,6 +563,7 @@ function CardRoster(props) {
|
|
|
552
563
|
getItemState,
|
|
553
564
|
onRetryItem,
|
|
554
565
|
error,
|
|
566
|
+
disabled = false,
|
|
555
567
|
wideBreakpoint = LAYOUT_COLLAPSE_BREAKPOINT,
|
|
556
568
|
cardWidth = DEFAULT_CARD_WIDTH,
|
|
557
569
|
testID = DEFAULT_TEST_ID
|
|
@@ -559,14 +571,15 @@ function CardRoster(props) {
|
|
|
559
571
|
const { width } = useWindowDimensions();
|
|
560
572
|
const split = isSplitPane(width, wideBreakpoint);
|
|
561
573
|
const [reordering, setReordering] = useState(false);
|
|
562
|
-
const editor = useRosterEditor(value, onChange, createItem);
|
|
563
|
-
const actions = useRosterActions(value, onChange);
|
|
574
|
+
const editor = useRosterEditor(value, onChange, createItem, disabled);
|
|
575
|
+
const actions = useRosterActions(value, onChange, disabled);
|
|
564
576
|
const ids = useMemo(() => rosterTestIds(testID), [testID]);
|
|
565
577
|
const { close, openEdit, openNew } = editor;
|
|
566
578
|
const toggleReorder = useCallback(() => {
|
|
579
|
+
if (disabled) return;
|
|
567
580
|
close();
|
|
568
581
|
setReordering((on) => !on);
|
|
569
|
-
}, [close]);
|
|
582
|
+
}, [close, disabled]);
|
|
570
583
|
const shared = {
|
|
571
584
|
renderCard,
|
|
572
585
|
getItemName,
|
|
@@ -578,17 +591,19 @@ function CardRoster(props) {
|
|
|
578
591
|
reordering,
|
|
579
592
|
actions,
|
|
580
593
|
canRemoveGroup,
|
|
594
|
+
disabled,
|
|
581
595
|
activeItemId: editor.activeItemId,
|
|
582
596
|
groupCount: value.groups.length,
|
|
583
597
|
onEdit: openEdit,
|
|
584
598
|
onAdd: createItem === void 0 ? void 0 : openNew
|
|
585
599
|
};
|
|
586
|
-
return /* @__PURE__ */ jsxs(View, { style: [styles8.root, split ? styles8.split : null], testID: ids.root, children: [
|
|
600
|
+
return /* @__PURE__ */ jsxs(View, { accessibilityState: { busy: disabled }, style: [styles8.root, split ? styles8.split : null], testID: ids.root, children: [
|
|
587
601
|
/* @__PURE__ */ jsxs(View, { style: styles8.list, children: [
|
|
588
602
|
/* @__PURE__ */ jsxs(View, { style: styles8.toolbar, children: [
|
|
589
603
|
/* @__PURE__ */ jsx(
|
|
590
604
|
RosterButton,
|
|
591
605
|
{
|
|
606
|
+
disabled,
|
|
592
607
|
emphasis: reordering,
|
|
593
608
|
hint: reordering ? labels.doneReorderingHint : labels.reorderHint,
|
|
594
609
|
label: reordering ? labels.doneReordering : labels.reorder,
|
|
@@ -599,6 +614,7 @@ function CardRoster(props) {
|
|
|
599
614
|
createGroup !== void 0 && !reordering ? /* @__PURE__ */ jsx(
|
|
600
615
|
RosterButton,
|
|
601
616
|
{
|
|
617
|
+
disabled,
|
|
602
618
|
hint: labels.addGroupHint,
|
|
603
619
|
label: labels.addGroup,
|
|
604
620
|
testID: ids.addGroup,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/utils/rosterOps.ts","../src/hooks/useRosterActions.ts","../src/utils/editorSession.ts","../src/hooks/useRosterEditor.ts","../src/components/EditorPane.tsx","../src/components/RosterButton.tsx","../src/components/ItemFrame.tsx","../src/components/CardBand.tsx","../src/components/GroupHeader.tsx","../src/components/ReorderList.tsx","../src/components/RosterGroupSection.tsx","../src/components/CardRoster.tsx"],"names":["item","styles","StyleSheet","useUi","jsx","Text","jsxs","View","useState","Fragment","useMemo","useCallback"],"mappings":"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","file":"index.mjs","sourcesContent":["/** Minimum hit box (CSS px) for every interactive element — mobile-first standard. */\nexport const MIN_TOUCH_TARGET = 44;\nexport const DEFAULT_CARD_WIDTH = 168;\nexport const SPLIT_EDITOR_WIDTH = 400;\nexport const SPACE_XS = 4;\nexport const SPACE_S = 8;\nexport const SPACE_M = 12;\nexport const SPACE_L = 16;\nexport const RADIUS_S = 8;\nexport const RADIUS_M = 12;\nexport const BORDER_WIDTH = 1;\nexport const ACTIVE_BORDER_WIDTH = 2;\nexport const TITLE_FONT_SIZE = 17;\nexport const BODY_FONT_SIZE = 15;\nexport const SMALL_FONT_SIZE = 13;\nexport const PRESSED_OPACITY = 0.7;\nexport const DISABLED_OPACITY = 0.4;\nexport const BUSY_OVERLAY_OPACITY = 0.9;\nexport const GROUP_TITLE_MIN_WIDTH = 120;\nexport const REORDER_SPRING = { stiffness: 320, damping: 32 } as const;\n\n/** Move deltas for the reorder helpers. */\nexport const MOVE_UP = -1;\nexport const MOVE_DOWN = 1;\n\n/** Decorative arrow glyphs; the buttons carry translated accessibility labels. */\nexport const GLYPH_UP = '▲';\nexport const GLYPH_DOWN = '▼';\n\nexport const DEFAULT_TEST_ID = 'card-roster';\n\n/** Stable testIDs derived from the roster's root testID. */\nexport const rosterTestIds = (base: string) => ({\n root: base,\n reorderToggle: `${base}-reorder-toggle`,\n addGroup: `${base}-add-group`,\n error: `${base}-error`,\n editor: `${base}-editor`,\n editorPlaceholder: `${base}-editor-placeholder`,\n group: (key: string): string => `${base}-group-${key}`,\n card: (id: string): string => `${base}-card-${id}`,\n});\n\nexport type RosterTestIds = ReturnType<typeof rosterTestIds>;\n","/**\n * Pure, immutable reducer helpers over a `RosterValue`. Every helper returns the SAME\n * reference when the operation is a no-op (unknown key, out-of-range move, duplicate\n * id), so callers can skip `onChange` with a reference check.\n */\nimport type { RosterGroup, RosterItem, RosterValue } from '../types';\n\nexport interface FoundItem<T extends RosterItem> {\n group: RosterGroup<T>;\n item: T;\n index: number;\n}\n\n/** `true` when moving `index` by `delta` stays inside a list of `length`. */\nexport function canMove(length: number, index: number, delta: number): boolean {\n const target = index + delta;\n return delta !== 0 && index >= 0 && index < length && target >= 0 && target < length;\n}\n\n/** Moves one element; returns `list` itself when the move is out of range. */\nexport function moveInArray<X>(list: X[], index: number, delta: number): X[] {\n if (!canMove(list.length, index, delta)) return list;\n const next = [...list];\n const [moved] = next.splice(index, 1);\n next.splice(index + delta, 0, moved as X);\n return next;\n}\n\nexport function isGroupEmpty<T extends RosterItem>(group: RosterGroup<T>): boolean {\n return group.items.length === 0;\n}\n\nfunction mapGroup<T extends RosterItem>(\n value: RosterValue<T>,\n key: string,\n fn: (group: RosterGroup<T>) => RosterGroup<T>,\n): RosterValue<T> {\n let changed = false;\n const groups = value.groups.map((group) => {\n if (group.key !== key) return group;\n const next = fn(group);\n if (next !== group) changed = true;\n return next;\n });\n return changed ? { ...value, groups } : value;\n}\n\nexport function findItem<T extends RosterItem>(value: RosterValue<T>, itemId: string): FoundItem<T> | undefined {\n for (const group of value.groups) {\n const index = group.items.findIndex((item) => item.id === itemId);\n const item = group.items[index];\n if (item !== undefined) return { group, item, index };\n }\n return undefined;\n}\n\nexport function addGroup<T extends RosterItem>(value: RosterValue<T>, group: RosterGroup<T>): RosterValue<T> {\n if (value.groups.some((g) => g.key === group.key)) return value;\n return { ...value, groups: [...value.groups, group] };\n}\n\n/** Trims the title; an empty or unchanged title is a no-op. */\nexport function renameGroup<T extends RosterItem>(value: RosterValue<T>, key: string, title: string): RosterValue<T> {\n const trimmed = title.trim();\n if (trimmed === '') return value;\n return mapGroup(value, key, (group) => (group.title === trimmed ? group : { ...group, title: trimmed }));\n}\n\nexport function removeGroup<T extends RosterItem>(value: RosterValue<T>, key: string): RosterValue<T> {\n if (!value.groups.some((g) => g.key === key)) return value;\n return { ...value, groups: value.groups.filter((g) => g.key !== key) };\n}\n\nexport function moveGroup<T extends RosterItem>(value: RosterValue<T>, key: string, delta: number): RosterValue<T> {\n const index = value.groups.findIndex((g) => g.key === key);\n const groups = moveInArray(value.groups, index, delta);\n return groups === value.groups ? value : { ...value, groups };\n}\n\n/** Appends to the group; refuses an id already present anywhere in the roster. */\nexport function addItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, item: T): RosterValue<T> {\n if (findItem(value, item.id) !== undefined) return value;\n return mapGroup(value, groupKey, (group) => ({ ...group, items: [...group.items, item] }));\n}\n\nexport function updateItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, item: T): RosterValue<T> {\n return mapGroup(value, groupKey, (group) => {\n const index = group.items.findIndex((i) => i.id === item.id);\n if (index === -1) return group;\n const items = [...group.items];\n items[index] = item;\n return { ...group, items };\n });\n}\n\nexport function removeItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, itemId: string): RosterValue<T> {\n return mapGroup(value, groupKey, (group) =>\n group.items.some((i) => i.id === itemId) ? { ...group, items: group.items.filter((i) => i.id !== itemId) } : group,\n );\n}\n\nexport function moveItem<T extends RosterItem>(\n value: RosterValue<T>,\n groupKey: string,\n itemId: string,\n delta: number,\n): RosterValue<T> {\n return mapGroup(value, groupKey, (group) => {\n const items = moveInArray(group.items, group.items.findIndex((i) => i.id === itemId), delta);\n return items === group.items ? group : { ...group, items };\n });\n}\n","import { useMemo } from 'react';\n\nimport type { RosterGroup, RosterItem, RosterValue } from '../types';\nimport { addGroup, moveGroup, moveItem, removeGroup, renameGroup } from '../utils/rosterOps';\n\nexport interface RosterActions<T extends RosterItem> {\n addGroup: (group: RosterGroup<T>) => void;\n renameGroup: (key: string, title: string) => void;\n removeGroup: (key: string) => void;\n moveGroup: (key: string, delta: number) => void;\n moveItem: (groupKey: string, itemId: string, delta: number) => void;\n}\n\n/** Binds the pure helpers to the controlled value; a no-op never calls `onChange`. */\nexport function useRosterActions<T extends RosterItem>(\n value: RosterValue<T>,\n onChange: (next: RosterValue<T>) => void,\n): RosterActions<T> {\n return useMemo(() => {\n const emit = (next: RosterValue<T>): void => {\n if (next !== value) onChange(next);\n };\n return {\n addGroup: (group) => emit(addGroup(value, group)),\n renameGroup: (key, title) => emit(renameGroup(value, key, title)),\n removeGroup: (key) => emit(removeGroup(value, key)),\n moveGroup: (key, delta) => emit(moveGroup(value, key, delta)),\n moveItem: (groupKey, itemId, delta) => emit(moveItem(value, groupKey, itemId, delta)),\n };\n }, [value, onChange]);\n}\n","/**\n * Pure edit-session logic: which item the editor shows, and how a save lands.\n * Kept out of the hook so the rules are unit-tested without React.\n */\nimport type { RosterItem, RosterValue } from '../types';\nimport { addItem, findItem, updateItem } from './rosterOps';\n\n/** What the user opened: an existing item (`itemId`) or a new one (`itemId: null`). */\nexport interface EditTarget {\n groupKey: string;\n itemId: string | null;\n}\n\nexport interface EditSession<T extends RosterItem> {\n item: T;\n groupKey: string;\n isNew: boolean;\n}\n\n/** `true` at/above the breakpoint: the editor renders as a split pane, not a sheet. */\nexport function isSplitPane(width: number, breakpoint: number): boolean {\n return width >= breakpoint;\n}\n\n/**\n * Resolves the target against the CURRENT value. An existing item that has since\n * disappeared (removed elsewhere) resolves to `null`, which closes the editor; an\n * item moved to another group resolves to its new group.\n */\nexport function resolveEditSession<T extends RosterItem>(\n value: RosterValue<T>,\n target: EditTarget | null,\n draft: T | null,\n): EditSession<T> | null {\n if (target === null) return null;\n if (target.itemId === null) return draft === null ? null : { item: draft, groupKey: target.groupKey, isNew: true };\n const found = findItem(value, target.itemId);\n return found === undefined ? null : { item: found.item, groupKey: found.group.key, isNew: false };\n}\n\n/** Applies a save: a new item is appended, an existing one replaced in place. */\nexport function commitEdit<T extends RosterItem>(value: RosterValue<T>, session: EditSession<T>, next: T): RosterValue<T> {\n return session.isNew ? addItem(value, session.groupKey, next) : updateItem(value, session.groupKey, next);\n}\n","import { useCallback, useState } from 'react';\n\nimport type { RosterEditorContext, RosterItem, RosterValue } from '../types';\nimport { commitEdit, resolveEditSession, type EditTarget } from '../utils/editorSession';\nimport { removeItem } from '../utils/rosterOps';\n\nexport interface UseRosterEditorResult<T extends RosterItem> {\n /** `null` when the editor is closed. */\n context: RosterEditorContext<T> | null;\n /** Id of the existing item being edited (for the active-card highlight). */\n activeItemId: string | null;\n openEdit: (groupKey: string, itemId: string) => void;\n openNew: (groupKey: string) => void;\n close: () => void;\n}\n\n/** Owns the edit target + the unsaved draft of a new item; writes through `onChange`. */\nexport function useRosterEditor<T extends RosterItem>(\n value: RosterValue<T>,\n onChange: (next: RosterValue<T>) => void,\n createItem?: (groupKey: string) => T,\n): UseRosterEditorResult<T> {\n const [target, setTarget] = useState<EditTarget | null>(null);\n const [draft, setDraft] = useState<T | null>(null);\n\n const close = useCallback((): void => {\n setTarget(null);\n setDraft(null);\n }, []);\n const openEdit = useCallback((groupKey: string, itemId: string): void => {\n setDraft(null);\n setTarget({ groupKey, itemId });\n }, []);\n const openNew = useCallback(\n (groupKey: string): void => {\n if (createItem === undefined) return;\n setDraft(createItem(groupKey));\n setTarget({ groupKey, itemId: null });\n },\n [createItem],\n );\n\n const session = resolveEditSession(value, target, draft);\n const context: RosterEditorContext<T> | null =\n session === null\n ? null\n : {\n ...session,\n save: (next: T): void => {\n const updated = commitEdit(value, session, next);\n if (updated !== value) onChange(updated);\n close();\n },\n cancel: close,\n remove: (): void => {\n if (!session.isNew) onChange(removeItem(value, session.groupKey, session.item.id));\n close();\n },\n };\n\n const activeItemId = session !== null && !session.isNew ? session.item.id : null;\n return { context, activeItemId, openEdit, openNew, close };\n}\n","/**\n * The edit-sheet slot. Narrow: ui-layout's `ModalShell` sheet. Wide: an inline right\n * pane that shows a prompt until a card is picked (the split pane).\n */\nimport React from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\nimport { ModalShell } from '@dloizides/ui-layout';\n\nimport { BODY_FONT_SIZE, BORDER_WIDTH, RADIUS_M, SPACE_L, SPLIT_EDITOR_WIDTH, TITLE_FONT_SIZE } from '../constants';\nimport type { CardRosterLabels, RosterEditorContext, RosterItem } from '../types';\n\nconst styles = StyleSheet.create({\n pane: { width: SPLIT_EDITOR_WIDTH, borderWidth: BORDER_WIDTH, borderRadius: RADIUS_M, padding: SPACE_L, gap: SPACE_L },\n title: { fontSize: TITLE_FONT_SIZE, fontWeight: '700' },\n prompt: { fontSize: BODY_FONT_SIZE },\n});\n\nexport interface EditorPaneProps<T extends RosterItem> {\n context: RosterEditorContext<T> | null;\n renderEditor: (context: RosterEditorContext<T>) => React.ReactNode;\n split: boolean;\n labels: Pick<CardRosterLabels, 'editorTitleNew' | 'editorTitleEdit' | 'selectPrompt'>;\n onClose: () => void;\n testID: string;\n placeholderTestID: string;\n}\n\nexport function EditorPane<T extends RosterItem>({\n context, renderEditor, split, labels, onClose, testID, placeholderTestID,\n}: EditorPaneProps<T>): React.ReactElement {\n const { theme } = useUi();\n const title = context?.isNew === true ? labels.editorTitleNew : labels.editorTitleEdit;\n\n if (!split)\n return (\n <ModalShell title={title} visible={context !== null} onCancel={onClose}>\n {context === null ? null : <View testID={testID}>{renderEditor(context)}</View>}\n </ModalShell>\n );\n\n return (\n <View style={[styles.pane, { borderColor: theme.colors.border, backgroundColor: theme.colors.surface }]} testID={testID}>\n {context === null ? (\n <Text style={[styles.prompt, { color: theme.colors.textSecondary }]} testID={placeholderTestID}>\n {labels.selectPrompt}\n </Text>\n ) : (\n <>\n <Text accessibilityRole=\"header\" style={[styles.title, { color: theme.colors.text }]}>{title}</Text>\n {renderEditor(context)}\n </>\n )}\n </View>\n );\n}\n","/**\n * The roster's one button. `Pressable`, not `TouchableOpacity` (RN-web drops its hover\n * callbacks), and the 44x44 floor is on the BOX via min sizes — `hitSlop` is inert on\n * RN-web, so it cannot be relied on to grow the target.\n */\nimport React from 'react';\n\nimport { Pressable, StyleSheet, Text } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n BODY_FONT_SIZE, BORDER_WIDTH, DISABLED_OPACITY, MIN_TOUCH_TARGET, PRESSED_OPACITY, RADIUS_S, SPACE_M,\n} from '../constants';\n\nconst styles = StyleSheet.create({\n base: {\n minHeight: MIN_TOUCH_TARGET,\n minWidth: MIN_TOUCH_TARGET,\n paddingHorizontal: SPACE_M,\n borderRadius: RADIUS_S,\n borderWidth: BORDER_WIDTH,\n alignItems: 'center',\n justifyContent: 'center',\n },\n label: { fontSize: BODY_FONT_SIZE, fontWeight: '600' },\n pressed: { opacity: PRESSED_OPACITY },\n disabled: { opacity: DISABLED_OPACITY },\n});\n\nexport interface RosterButtonProps {\n label: string;\n /** Defaults to `label`; pass a fuller one when the visible label is short (\"Edit\"). */\n accessibilityLabel?: string;\n hint: string;\n onPress: () => void;\n testID: string;\n emphasis?: boolean;\n danger?: boolean;\n disabled?: boolean;\n}\n\nexport function RosterButton({\n label, accessibilityLabel, hint, onPress, testID, emphasis = false, danger = false, disabled = false,\n}: RosterButtonProps): React.ReactElement {\n const { theme } = useUi();\n const accent = danger ? theme.semantic.error['500'] : theme.palette.primary['500'];\n const tone = emphasis ? { backgroundColor: accent, borderColor: accent } : { borderColor: theme.colors.border };\n const color = emphasis ? theme.colors.background : accent;\n\n return (\n <Pressable\n accessibilityHint={hint}\n accessibilityLabel={accessibilityLabel ?? label}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled }}\n disabled={disabled}\n style={({ pressed }) => [styles.base, tone, pressed ? styles.pressed : null, disabled ? styles.disabled : null]}\n testID={testID}\n onPress={onPress}\n >\n <Text style={[styles.label, { color }]}>{label}</Text>\n </Pressable>\n );\n}\n","/**\n * Frame around one host-rendered card: border, the uploading overlay (busy) and the\n * upload-error row with retry. The host's card body never has to know about either.\n */\nimport React from 'react';\n\nimport { ActivityIndicator, StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n ACTIVE_BORDER_WIDTH, BORDER_WIDTH, BUSY_OVERLAY_OPACITY, RADIUS_M, SMALL_FONT_SIZE, SPACE_S,\n} from '../constants';\nimport type { CardRosterLabels, RosterItemState } from '../types';\nimport { RosterButton } from './RosterButton';\n\nconst styles = StyleSheet.create({\n frame: { borderRadius: RADIUS_M, padding: SPACE_S, gap: SPACE_S, overflow: 'hidden' },\n fill: { alignSelf: 'stretch' },\n body: { position: 'relative' },\n busy: {\n ...StyleSheet.absoluteFillObject,\n alignItems: 'center',\n justifyContent: 'center',\n gap: SPACE_S,\n opacity: BUSY_OVERLAY_OPACITY,\n },\n small: { fontSize: SMALL_FONT_SIZE },\n errorRow: { gap: SPACE_S },\n footer: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S },\n});\n\nexport type ItemFrameLabels = Pick<CardRosterLabels, 'uploading' | 'retry' | 'retryHint'>;\n\nexport interface ItemFrameProps {\n /** Fixed width in the band; omitted = stretch (reorder list). */\n width?: number;\n active: boolean;\n state: RosterItemState | undefined;\n labels: ItemFrameLabels;\n onRetry?: () => void;\n testID: string;\n children: React.ReactNode;\n footer: React.ReactNode;\n}\n\nexport function ItemFrame({\n width, active, state, labels, onRetry, testID, children, footer,\n}: ItemFrameProps): React.ReactElement {\n const { theme } = useUi();\n const busy = state?.busy === true;\n const error = state?.error ?? '';\n const hasError = error !== '';\n const errorColor = theme.semantic.error['500'];\n const primary = theme.palette.primary['500'];\n const highlighted = active || hasError;\n const borderColor = hasError ? errorColor : active ? primary : theme.colors.border;\n\n return (\n <View\n accessibilityState={{ busy }}\n style={[\n styles.frame,\n width === undefined ? styles.fill : { width },\n { borderColor, backgroundColor: theme.colors.surface, borderWidth: highlighted ? ACTIVE_BORDER_WIDTH : BORDER_WIDTH },\n ]}\n testID={testID}\n >\n <View style={styles.body}>\n {children}\n {busy ? (\n <View style={[styles.busy, { backgroundColor: theme.colors.surfaceElevated }]} testID={`${testID}-busy`}>\n <ActivityIndicator color={primary} />\n <Text accessibilityLiveRegion=\"polite\" style={[styles.small, { color: theme.colors.textSecondary }]}>\n {labels.uploading}\n </Text>\n </View>\n ) : null}\n </View>\n {hasError ? (\n <View style={styles.errorRow} testID={`${testID}-error`}>\n <Text accessibilityRole=\"alert\" style={[styles.small, { color: errorColor }]}>{error}</Text>\n {onRetry !== undefined ? (\n <RosterButton danger hint={labels.retryHint} label={labels.retry} testID={`${testID}-retry`} onPress={onRetry} />\n ) : null}\n </View>\n ) : null}\n <View style={styles.footer}>{footer}</View>\n </View>\n );\n}\n","/** The live band: a horizontal row of framed cards, each with its own Edit button. */\nimport React from 'react';\n\nimport { ScrollView, StyleSheet } from 'react-native';\n\nimport { SPACE_M, SPACE_XS } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { ItemFrame } from './ItemFrame';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n band: { gap: SPACE_M, paddingVertical: SPACE_XS },\n});\n\nexport interface CardBandProps<T extends RosterItem> {\n group: RosterGroup<T>;\n shared: RosterSectionShared<T>;\n}\n\nexport function CardBand<T extends RosterItem>({ group, shared }: CardBandProps<T>): React.ReactElement {\n const { labels, ids, onRetryItem } = shared;\n return (\n <ScrollView\n horizontal\n contentContainerStyle={styles.band}\n showsHorizontalScrollIndicator={false}\n testID={`${ids.group(group.key)}-band`}\n >\n {group.items.map((item) => {\n const cardId = ids.card(item.id);\n return (\n <ItemFrame\n key={item.id}\n active={shared.activeItemId === item.id}\n footer={(\n <RosterButton\n accessibilityLabel={labels.editCard(shared.getItemName(item))}\n hint={labels.editCardHint}\n label={labels.edit}\n testID={`${cardId}-edit`}\n onPress={() => shared.onEdit(group.key, item.id)}\n />\n )}\n labels={labels}\n state={shared.getItemState?.(item)}\n testID={cardId}\n width={shared.cardWidth}\n onRetry={onRetryItem === undefined ? undefined : () => onRetryItem(item)}\n >\n {shared.renderCard(item, group)}\n </ItemFrame>\n );\n })}\n </ScrollView>\n );\n}\n","/** Group title (inline rename) + its actions; in Reorder mode, group up/down instead. */\nimport React, { useState } from 'react';\n\nimport { StyleSheet, Text, TextInput, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n BODY_FONT_SIZE, BORDER_WIDTH, GLYPH_DOWN, GLYPH_UP, GROUP_TITLE_MIN_WIDTH, MIN_TOUCH_TARGET, MOVE_DOWN, MOVE_UP,\n RADIUS_S, SPACE_M, SPACE_S, TITLE_FONT_SIZE,\n} from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n header: { flexDirection: 'row', flexWrap: 'wrap', alignItems: 'center', gap: SPACE_S },\n title: { flexGrow: 1, flexShrink: 1, minWidth: GROUP_TITLE_MIN_WIDTH, fontSize: TITLE_FONT_SIZE, fontWeight: '700' },\n input: {\n flexGrow: 1,\n minWidth: GROUP_TITLE_MIN_WIDTH,\n minHeight: MIN_TOUCH_TARGET,\n paddingHorizontal: SPACE_M,\n borderWidth: BORDER_WIDTH,\n borderRadius: RADIUS_S,\n fontSize: BODY_FONT_SIZE,\n },\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S },\n});\n\nexport interface GroupHeaderProps<T extends RosterItem> {\n group: RosterGroup<T>;\n index: number;\n shared: RosterSectionShared<T>;\n}\n\nexport function GroupHeader<T extends RosterItem>({ group, index, shared }: GroupHeaderProps<T>): React.ReactElement {\n const { theme } = useUi();\n const [draft, setDraft] = useState<string | null>(null);\n const { labels, actions, reordering } = shared;\n const gid = shared.ids.group(group.key);\n\n const commit = (): void => {\n if (draft !== null) actions.renameGroup(group.key, draft);\n setDraft(null);\n };\n\n const reorderActions = (\n <>\n <RosterButton\n accessibilityLabel={labels.moveGroupUp(group.title)}\n disabled={index === 0}\n hint={labels.moveGroupHint}\n label={GLYPH_UP}\n testID={`${gid}-up`}\n onPress={() => actions.moveGroup(group.key, MOVE_UP)}\n />\n <RosterButton\n accessibilityLabel={labels.moveGroupDown(group.title)}\n disabled={index === shared.groupCount - 1}\n hint={labels.moveGroupHint}\n label={GLYPH_DOWN}\n testID={`${gid}-down`}\n onPress={() => actions.moveGroup(group.key, MOVE_DOWN)}\n />\n </>\n );\n\n const editActions = (\n <>\n {shared.onAdd !== undefined ? (\n <RosterButton\n emphasis\n accessibilityLabel={labels.addCard(group.title)}\n hint={labels.addCardHint}\n label={labels.add}\n testID={`${gid}-add`}\n onPress={() => shared.onAdd?.(group.key)}\n />\n ) : null}\n <RosterButton\n accessibilityLabel={labels.renameGroup(group.title)}\n hint={labels.renameGroupHint}\n label={labels.rename}\n testID={`${gid}-rename`}\n onPress={() => setDraft(group.title)}\n />\n {shared.canRemoveGroup(group) ? (\n <RosterButton\n danger\n accessibilityLabel={labels.removeGroup(group.title)}\n hint={labels.removeGroupHint}\n label={labels.remove}\n testID={`${gid}-remove`}\n onPress={() => actions.removeGroup(group.key)}\n />\n ) : null}\n </>\n );\n\n return (\n <View style={styles.header}>\n {draft === null ? (\n <Text accessibilityRole=\"header\" numberOfLines={1} style={[styles.title, { color: theme.colors.text }]}>\n {group.title}\n </Text>\n ) : (\n <TextInput\n autoFocus\n accessibilityHint={labels.groupTitleInputHint}\n accessibilityLabel={labels.groupTitleInput}\n style={[styles.input, { color: theme.colors.text, borderColor: theme.palette.primary['500'] }]}\n testID={`${gid}-title-input`}\n value={draft}\n onBlur={commit}\n onChangeText={setDraft}\n onSubmitEditing={commit}\n />\n )}\n <View style={styles.actions}>{reordering ? reorderActions : editActions}</View>\n </View>\n );\n}\n","/**\n * Reorder mode for one group: a vertical list with explicit up/down buttons (no drag —\n * a drag is not reachable by keyboard or switch access). Moves animate through\n * ui-motion's `Reorder` (FLIP), which collapses to instant under reduced motion.\n */\nimport React, { useMemo } from 'react';\n\nimport { StyleSheet, View } from 'react-native';\n\nimport { Reorder } from '@dloizides/ui-motion';\n\nimport { GLYPH_DOWN, GLYPH_UP, MOVE_DOWN, MOVE_UP, REORDER_SPRING, SPACE_S } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { ItemFrame } from './ItemFrame';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n item: { paddingVertical: SPACE_S / 2 },\n});\n\nexport interface ReorderListProps<T extends RosterItem> {\n group: RosterGroup<T>;\n shared: RosterSectionShared<T>;\n}\n\nexport function ReorderList<T extends RosterItem>({ group, shared }: ReorderListProps<T>): React.ReactElement {\n const { labels, ids, actions } = shared;\n const keys = useMemo(() => group.items.map((item) => item.id), [group.items]);\n const last = group.items.length - 1;\n\n const renderItem = (key: string): React.ReactNode => {\n const index = group.items.findIndex((item) => item.id === key);\n const item = group.items[index];\n if (item === undefined) return null;\n const name = shared.getItemName(item);\n const cardId = ids.card(item.id);\n return (\n <View style={styles.item}>\n <ItemFrame\n active={false}\n footer={(\n <>\n <RosterButton\n accessibilityLabel={labels.moveCardUp(name)}\n disabled={index === 0}\n hint={labels.moveCardHint}\n label={GLYPH_UP}\n testID={`${cardId}-up`}\n onPress={() => actions.moveItem(group.key, item.id, MOVE_UP)}\n />\n <RosterButton\n accessibilityLabel={labels.moveCardDown(name)}\n disabled={index === last}\n hint={labels.moveCardHint}\n label={GLYPH_DOWN}\n testID={`${cardId}-down`}\n onPress={() => actions.moveItem(group.key, item.id, MOVE_DOWN)}\n />\n </>\n )}\n labels={labels}\n state={shared.getItemState?.(item)}\n testID={cardId}\n >\n {shared.renderCard(item, group)}\n </ItemFrame>\n </View>\n );\n };\n\n return (\n <Reorder itemKeys={keys} spring={REORDER_SPRING} testID={`${ids.group(group.key)}-reorder`}>\n {renderItem}\n </Reorder>\n );\n}\n","/** One group: header, then the empty state, the live band, or the reorder list. */\nimport React from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport { BODY_FONT_SIZE, BORDER_WIDTH, RADIUS_M, SPACE_L, SPACE_S } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { CardBand } from './CardBand';\nimport { GroupHeader } from './GroupHeader';\nimport { ReorderList } from './ReorderList';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n section: { gap: SPACE_S },\n empty: {\n borderWidth: BORDER_WIDTH,\n borderStyle: 'dashed',\n borderRadius: RADIUS_M,\n padding: SPACE_L,\n alignItems: 'center',\n },\n emptyText: { fontSize: BODY_FONT_SIZE, textAlign: 'center' },\n});\n\nexport interface RosterGroupSectionProps<T extends RosterItem> {\n group: RosterGroup<T>;\n index: number;\n shared: RosterSectionShared<T>;\n}\n\nexport function RosterGroupSection<T extends RosterItem>({\n group, index, shared,\n}: RosterGroupSectionProps<T>): React.ReactElement {\n const { theme } = useUi();\n const gid = shared.ids.group(group.key);\n\n let body: React.ReactNode;\n if (group.items.length === 0)\n body = (\n <View style={[styles.empty, { borderColor: theme.colors.border }]} testID={`${gid}-empty`}>\n <Text style={[styles.emptyText, { color: theme.colors.textSecondary }]}>{shared.labels.emptyGroup}</Text>\n </View>\n );\n else if (shared.reordering) body = <ReorderList group={group} shared={shared} />;\n else body = <CardBand group={group} shared={shared} />;\n\n return (\n <View style={styles.section} testID={gid}>\n <GroupHeader group={group} index={index} shared={shared} />\n {body}\n </View>\n );\n}\n","/**\n * CardRoster — a generic grouped card editor. Composed narrow-first: one column with the\n * edit form in a sheet; at/above `wideBreakpoint` the form moves into a right-hand pane.\n * The value is controlled; every edit is a pure helper from `utils/rosterOps`.\n */\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { StyleSheet, View, useWindowDimensions } from 'react-native';\n\nimport { ErrorState } from '@dloizides/ui-feedback';\nimport { LAYOUT_COLLAPSE_BREAKPOINT } from '@dloizides/ui-layout';\n\nimport { DEFAULT_CARD_WIDTH, DEFAULT_TEST_ID, SPACE_L, SPACE_S, rosterTestIds } from '../constants';\nimport { useRosterActions } from '../hooks/useRosterActions';\nimport { useRosterEditor } from '../hooks/useRosterEditor';\nimport type { CardRosterProps, RosterItem } from '../types';\nimport { isSplitPane } from '../utils/editorSession';\nimport { isGroupEmpty } from '../utils/rosterOps';\nimport { EditorPane } from './EditorPane';\nimport { RosterButton } from './RosterButton';\nimport { RosterGroupSection } from './RosterGroupSection';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n root: { gap: SPACE_L },\n split: { flexDirection: 'row', alignItems: 'flex-start' },\n list: { flex: 1, minWidth: 0, gap: SPACE_L },\n toolbar: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S, justifyContent: 'flex-end' },\n});\n\nexport function CardRoster<T extends RosterItem>(props: CardRosterProps<T>): React.ReactElement {\n const {\n value, onChange, renderCard, renderEditor, getItemName, labels, createItem, createGroup,\n canRemoveGroup = isGroupEmpty, getItemState, onRetryItem, error,\n wideBreakpoint = LAYOUT_COLLAPSE_BREAKPOINT, cardWidth = DEFAULT_CARD_WIDTH, testID = DEFAULT_TEST_ID,\n } = props;\n const { width } = useWindowDimensions();\n const split = isSplitPane(width, wideBreakpoint);\n const [reordering, setReordering] = useState(false);\n const editor = useRosterEditor(value, onChange, createItem);\n const actions = useRosterActions(value, onChange);\n const ids = useMemo(() => rosterTestIds(testID), [testID]);\n const { close, openEdit, openNew } = editor;\n\n const toggleReorder = useCallback((): void => {\n close();\n setReordering((on) => !on);\n }, [close]);\n\n const shared: RosterSectionShared<T> = {\n renderCard, getItemName, getItemState, onRetryItem, labels, cardWidth, ids, reordering, actions, canRemoveGroup,\n activeItemId: editor.activeItemId,\n groupCount: value.groups.length,\n onEdit: openEdit,\n onAdd: createItem === undefined ? undefined : openNew,\n };\n\n return (\n <View style={[styles.root, split ? styles.split : null]} testID={ids.root}>\n <View style={styles.list}>\n <View style={styles.toolbar}>\n <RosterButton\n emphasis={reordering}\n hint={reordering ? labels.doneReorderingHint : labels.reorderHint}\n label={reordering ? labels.doneReordering : labels.reorder}\n testID={ids.reorderToggle}\n onPress={toggleReorder}\n />\n {createGroup !== undefined && !reordering ? (\n <RosterButton\n hint={labels.addGroupHint}\n label={labels.addGroup}\n testID={ids.addGroup}\n onPress={() => actions.addGroup(createGroup())}\n />\n ) : null}\n </View>\n {error !== undefined ? (\n <ErrorState message={error.message} testID={ids.error} title={error.title} onRetry={error.onRetry} />\n ) : null}\n {value.groups.map((group, index) => (\n <RosterGroupSection key={group.key} group={group} index={index} shared={shared} />\n ))}\n </View>\n {reordering && split ? null : (\n <EditorPane\n context={editor.context}\n labels={labels}\n placeholderTestID={ids.editorPlaceholder}\n renderEditor={renderEditor}\n split={split}\n testID={ids.editor}\n onClose={close}\n />\n )}\n </View>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/utils/rosterOps.ts","../src/hooks/useRosterActions.ts","../src/utils/editorSession.ts","../src/hooks/useRosterEditor.ts","../src/components/EditorPane.tsx","../src/components/RosterButton.tsx","../src/components/ItemFrame.tsx","../src/components/CardBand.tsx","../src/components/GroupHeader.tsx","../src/components/ReorderList.tsx","../src/components/RosterGroupSection.tsx","../src/components/CardRoster.tsx"],"names":["item","styles","StyleSheet","useUi","jsx","Text","jsxs","View","useState","Fragment","useMemo","useCallback"],"mappings":"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","file":"index.mjs","sourcesContent":["/** Minimum hit box (CSS px) for every interactive element — mobile-first standard. */\nexport const MIN_TOUCH_TARGET = 44;\nexport const DEFAULT_CARD_WIDTH = 168;\nexport const SPLIT_EDITOR_WIDTH = 400;\nexport const SPACE_XS = 4;\nexport const SPACE_S = 8;\nexport const SPACE_M = 12;\nexport const SPACE_L = 16;\nexport const RADIUS_S = 8;\nexport const RADIUS_M = 12;\nexport const BORDER_WIDTH = 1;\nexport const ACTIVE_BORDER_WIDTH = 2;\nexport const TITLE_FONT_SIZE = 17;\nexport const BODY_FONT_SIZE = 15;\nexport const SMALL_FONT_SIZE = 13;\nexport const PRESSED_OPACITY = 0.7;\nexport const DISABLED_OPACITY = 0.4;\nexport const BUSY_OVERLAY_OPACITY = 0.9;\nexport const GROUP_TITLE_MIN_WIDTH = 120;\nexport const REORDER_SPRING = { stiffness: 320, damping: 32 } as const;\n\n/** Move deltas for the reorder helpers. */\nexport const MOVE_UP = -1;\nexport const MOVE_DOWN = 1;\n\n/** Decorative arrow glyphs; the buttons carry translated accessibility labels. */\nexport const GLYPH_UP = '▲';\nexport const GLYPH_DOWN = '▼';\n\nexport const DEFAULT_TEST_ID = 'card-roster';\n\n/** Stable testIDs derived from the roster's root testID. */\nexport const rosterTestIds = (base: string) => ({\n root: base,\n reorderToggle: `${base}-reorder-toggle`,\n addGroup: `${base}-add-group`,\n error: `${base}-error`,\n editor: `${base}-editor`,\n editorPlaceholder: `${base}-editor-placeholder`,\n group: (key: string): string => `${base}-group-${key}`,\n card: (id: string): string => `${base}-card-${id}`,\n});\n\nexport type RosterTestIds = ReturnType<typeof rosterTestIds>;\n","/**\n * Pure, immutable reducer helpers over a `RosterValue`. Every helper returns the SAME\n * reference when the operation is a no-op (unknown key, out-of-range move, duplicate\n * id), so callers can skip `onChange` with a reference check.\n */\nimport type { RosterGroup, RosterItem, RosterValue } from '../types';\n\nexport interface FoundItem<T extends RosterItem> {\n group: RosterGroup<T>;\n item: T;\n index: number;\n}\n\n/** `true` when moving `index` by `delta` stays inside a list of `length`. */\nexport function canMove(length: number, index: number, delta: number): boolean {\n const target = index + delta;\n return delta !== 0 && index >= 0 && index < length && target >= 0 && target < length;\n}\n\n/** Moves one element; returns `list` itself when the move is out of range. */\nexport function moveInArray<X>(list: X[], index: number, delta: number): X[] {\n if (!canMove(list.length, index, delta)) return list;\n const next = [...list];\n const [moved] = next.splice(index, 1);\n next.splice(index + delta, 0, moved as X);\n return next;\n}\n\nexport function isGroupEmpty<T extends RosterItem>(group: RosterGroup<T>): boolean {\n return group.items.length === 0;\n}\n\nfunction mapGroup<T extends RosterItem>(\n value: RosterValue<T>,\n key: string,\n fn: (group: RosterGroup<T>) => RosterGroup<T>,\n): RosterValue<T> {\n let changed = false;\n const groups = value.groups.map((group) => {\n if (group.key !== key) return group;\n const next = fn(group);\n if (next !== group) changed = true;\n return next;\n });\n return changed ? { ...value, groups } : value;\n}\n\nexport function findItem<T extends RosterItem>(value: RosterValue<T>, itemId: string): FoundItem<T> | undefined {\n for (const group of value.groups) {\n const index = group.items.findIndex((item) => item.id === itemId);\n const item = group.items[index];\n if (item !== undefined) return { group, item, index };\n }\n return undefined;\n}\n\nexport function addGroup<T extends RosterItem>(value: RosterValue<T>, group: RosterGroup<T>): RosterValue<T> {\n if (value.groups.some((g) => g.key === group.key)) return value;\n return { ...value, groups: [...value.groups, group] };\n}\n\n/** Trims the title; an empty or unchanged title is a no-op. */\nexport function renameGroup<T extends RosterItem>(value: RosterValue<T>, key: string, title: string): RosterValue<T> {\n const trimmed = title.trim();\n if (trimmed === '') return value;\n return mapGroup(value, key, (group) => (group.title === trimmed ? group : { ...group, title: trimmed }));\n}\n\nexport function removeGroup<T extends RosterItem>(value: RosterValue<T>, key: string): RosterValue<T> {\n if (!value.groups.some((g) => g.key === key)) return value;\n return { ...value, groups: value.groups.filter((g) => g.key !== key) };\n}\n\nexport function moveGroup<T extends RosterItem>(value: RosterValue<T>, key: string, delta: number): RosterValue<T> {\n const index = value.groups.findIndex((g) => g.key === key);\n const groups = moveInArray(value.groups, index, delta);\n return groups === value.groups ? value : { ...value, groups };\n}\n\n/** Appends to the group; refuses an id already present anywhere in the roster. */\nexport function addItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, item: T): RosterValue<T> {\n if (findItem(value, item.id) !== undefined) return value;\n return mapGroup(value, groupKey, (group) => ({ ...group, items: [...group.items, item] }));\n}\n\nexport function updateItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, item: T): RosterValue<T> {\n return mapGroup(value, groupKey, (group) => {\n const index = group.items.findIndex((i) => i.id === item.id);\n if (index === -1) return group;\n const items = [...group.items];\n items[index] = item;\n return { ...group, items };\n });\n}\n\nexport function removeItem<T extends RosterItem>(value: RosterValue<T>, groupKey: string, itemId: string): RosterValue<T> {\n return mapGroup(value, groupKey, (group) =>\n group.items.some((i) => i.id === itemId) ? { ...group, items: group.items.filter((i) => i.id !== itemId) } : group,\n );\n}\n\nexport function moveItem<T extends RosterItem>(\n value: RosterValue<T>,\n groupKey: string,\n itemId: string,\n delta: number,\n): RosterValue<T> {\n return mapGroup(value, groupKey, (group) => {\n const items = moveInArray(group.items, group.items.findIndex((i) => i.id === itemId), delta);\n return items === group.items ? group : { ...group, items };\n });\n}\n","import { useMemo } from 'react';\n\nimport type { RosterGroup, RosterItem, RosterValue } from '../types';\nimport { addGroup, moveGroup, moveItem, removeGroup, renameGroup } from '../utils/rosterOps';\n\nexport interface RosterActions<T extends RosterItem> {\n addGroup: (group: RosterGroup<T>) => void;\n renameGroup: (key: string, title: string) => void;\n removeGroup: (key: string) => void;\n moveGroup: (key: string, delta: number) => void;\n moveItem: (groupKey: string, itemId: string, delta: number) => void;\n}\n\n/**\n * Binds the pure helpers to the controlled value; a no-op never calls `onChange`.\n * While `disabled` (a save in flight) every action is a no-op.\n */\nexport function useRosterActions<T extends RosterItem>(\n value: RosterValue<T>,\n onChange: (next: RosterValue<T>) => void,\n disabled = false,\n): RosterActions<T> {\n return useMemo(() => {\n const emit = (next: RosterValue<T>): void => {\n if (!disabled && next !== value) onChange(next);\n };\n return {\n addGroup: (group) => emit(addGroup(value, group)),\n renameGroup: (key, title) => emit(renameGroup(value, key, title)),\n removeGroup: (key) => emit(removeGroup(value, key)),\n moveGroup: (key, delta) => emit(moveGroup(value, key, delta)),\n moveItem: (groupKey, itemId, delta) => emit(moveItem(value, groupKey, itemId, delta)),\n };\n }, [value, onChange, disabled]);\n}\n","/**\n * Pure edit-session logic: which item the editor shows, and how a save lands.\n * Kept out of the hook so the rules are unit-tested without React.\n */\nimport type { RosterItem, RosterValue } from '../types';\nimport { addItem, findItem, updateItem } from './rosterOps';\n\n/** What the user opened: an existing item (`itemId`) or a new one (`itemId: null`). */\nexport interface EditTarget {\n groupKey: string;\n itemId: string | null;\n}\n\nexport interface EditSession<T extends RosterItem> {\n item: T;\n groupKey: string;\n isNew: boolean;\n}\n\n/** `true` at/above the breakpoint: the editor renders as a split pane, not a sheet. */\nexport function isSplitPane(width: number, breakpoint: number): boolean {\n return width >= breakpoint;\n}\n\n/**\n * Resolves the target against the CURRENT value. An existing item that has since\n * disappeared (removed elsewhere) resolves to `null`, which closes the editor; an\n * item moved to another group resolves to its new group.\n */\nexport function resolveEditSession<T extends RosterItem>(\n value: RosterValue<T>,\n target: EditTarget | null,\n draft: T | null,\n): EditSession<T> | null {\n if (target === null) return null;\n if (target.itemId === null) return draft === null ? null : { item: draft, groupKey: target.groupKey, isNew: true };\n const found = findItem(value, target.itemId);\n return found === undefined ? null : { item: found.item, groupKey: found.group.key, isNew: false };\n}\n\n/** Applies a save: a new item is appended, an existing one replaced in place. */\nexport function commitEdit<T extends RosterItem>(value: RosterValue<T>, session: EditSession<T>, next: T): RosterValue<T> {\n return session.isNew ? addItem(value, session.groupKey, next) : updateItem(value, session.groupKey, next);\n}\n","import { useCallback, useState } from 'react';\n\nimport type { RosterEditorContext, RosterItem, RosterValue } from '../types';\nimport { commitEdit, resolveEditSession, type EditTarget } from '../utils/editorSession';\nimport { removeItem } from '../utils/rosterOps';\n\nexport interface UseRosterEditorResult<T extends RosterItem> {\n /** `null` when the editor is closed. */\n context: RosterEditorContext<T> | null;\n /** Id of the existing item being edited (for the active-card highlight). */\n activeItemId: string | null;\n openEdit: (groupKey: string, itemId: string) => void;\n openNew: (groupKey: string) => void;\n close: () => void;\n}\n\n/**\n * Owns the edit target + the unsaved draft of a new item; writes through `onChange`.\n * While `disabled` nothing opens, and save/remove are no-ops that keep the editor open.\n */\nexport function useRosterEditor<T extends RosterItem>(\n value: RosterValue<T>,\n onChange: (next: RosterValue<T>) => void,\n createItem?: (groupKey: string) => T,\n disabled = false,\n): UseRosterEditorResult<T> {\n const [target, setTarget] = useState<EditTarget | null>(null);\n const [draft, setDraft] = useState<T | null>(null);\n\n const close = useCallback((): void => {\n setTarget(null);\n setDraft(null);\n }, []);\n const openEdit = useCallback((groupKey: string, itemId: string): void => {\n if (disabled) return;\n setDraft(null);\n setTarget({ groupKey, itemId });\n }, [disabled]);\n const openNew = useCallback(\n (groupKey: string): void => {\n if (disabled || createItem === undefined) return;\n setDraft(createItem(groupKey));\n setTarget({ groupKey, itemId: null });\n },\n [createItem, disabled],\n );\n\n const session = resolveEditSession(value, target, draft);\n const context: RosterEditorContext<T> | null =\n session === null\n ? null\n : {\n ...session,\n disabled,\n save: (next: T): void => {\n if (disabled) return;\n const updated = commitEdit(value, session, next);\n if (updated !== value) onChange(updated);\n close();\n },\n cancel: close,\n remove: (): void => {\n if (disabled) return;\n if (!session.isNew) onChange(removeItem(value, session.groupKey, session.item.id));\n close();\n },\n };\n\n const activeItemId = session !== null && !session.isNew ? session.item.id : null;\n return { context, activeItemId, openEdit, openNew, close };\n}\n","/**\n * The edit-sheet slot. Narrow: ui-layout's `ModalShell` sheet. Wide: an inline right\n * pane that shows a prompt until a card is picked (the split pane).\n */\nimport React from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\nimport { ModalShell } from '@dloizides/ui-layout';\n\nimport { BODY_FONT_SIZE, BORDER_WIDTH, RADIUS_M, SPACE_L, SPLIT_EDITOR_WIDTH, TITLE_FONT_SIZE } from '../constants';\nimport type { CardRosterLabels, RosterEditorContext, RosterItem } from '../types';\n\nconst styles = StyleSheet.create({\n pane: { width: SPLIT_EDITOR_WIDTH, borderWidth: BORDER_WIDTH, borderRadius: RADIUS_M, padding: SPACE_L, gap: SPACE_L },\n title: { fontSize: TITLE_FONT_SIZE, fontWeight: '700' },\n prompt: { fontSize: BODY_FONT_SIZE },\n});\n\nexport interface EditorPaneProps<T extends RosterItem> {\n context: RosterEditorContext<T> | null;\n renderEditor: (context: RosterEditorContext<T>) => React.ReactNode;\n split: boolean;\n labels: Pick<CardRosterLabels, 'editorTitleNew' | 'editorTitleEdit' | 'selectPrompt'>;\n onClose: () => void;\n testID: string;\n placeholderTestID: string;\n}\n\nexport function EditorPane<T extends RosterItem>({\n context, renderEditor, split, labels, onClose, testID, placeholderTestID,\n}: EditorPaneProps<T>): React.ReactElement {\n const { theme } = useUi();\n const title = context?.isNew === true ? labels.editorTitleNew : labels.editorTitleEdit;\n\n if (!split)\n return (\n <ModalShell title={title} visible={context !== null} onCancel={onClose}>\n {context === null ? null : <View testID={testID}>{renderEditor(context)}</View>}\n </ModalShell>\n );\n\n return (\n <View style={[styles.pane, { borderColor: theme.colors.border, backgroundColor: theme.colors.surface }]} testID={testID}>\n {context === null ? (\n <Text style={[styles.prompt, { color: theme.colors.textSecondary }]} testID={placeholderTestID}>\n {labels.selectPrompt}\n </Text>\n ) : (\n <>\n <Text accessibilityRole=\"header\" style={[styles.title, { color: theme.colors.text }]}>{title}</Text>\n {renderEditor(context)}\n </>\n )}\n </View>\n );\n}\n","/**\n * The roster's one button. `Pressable`, not `TouchableOpacity` (RN-web drops its hover\n * callbacks), and the 44x44 floor is on the BOX via min sizes — `hitSlop` is inert on\n * RN-web, so it cannot be relied on to grow the target.\n */\nimport React from 'react';\n\nimport { Pressable, StyleSheet, Text } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n BODY_FONT_SIZE, BORDER_WIDTH, DISABLED_OPACITY, MIN_TOUCH_TARGET, PRESSED_OPACITY, RADIUS_S, SPACE_M,\n} from '../constants';\n\nconst styles = StyleSheet.create({\n base: {\n minHeight: MIN_TOUCH_TARGET,\n minWidth: MIN_TOUCH_TARGET,\n paddingHorizontal: SPACE_M,\n borderRadius: RADIUS_S,\n borderWidth: BORDER_WIDTH,\n alignItems: 'center',\n justifyContent: 'center',\n },\n label: { fontSize: BODY_FONT_SIZE, fontWeight: '600' },\n pressed: { opacity: PRESSED_OPACITY },\n disabled: { opacity: DISABLED_OPACITY },\n});\n\nexport interface RosterButtonProps {\n label: string;\n /** Defaults to `label`; pass a fuller one when the visible label is short (\"Edit\"). */\n accessibilityLabel?: string;\n hint: string;\n onPress: () => void;\n testID: string;\n emphasis?: boolean;\n danger?: boolean;\n disabled?: boolean;\n}\n\nexport function RosterButton({\n label, accessibilityLabel, hint, onPress, testID, emphasis = false, danger = false, disabled = false,\n}: RosterButtonProps): React.ReactElement {\n const { theme } = useUi();\n const accent = danger ? theme.semantic.error['500'] : theme.palette.primary['500'];\n const tone = emphasis ? { backgroundColor: accent, borderColor: accent } : { borderColor: theme.colors.border };\n const color = emphasis ? theme.colors.background : accent;\n\n return (\n <Pressable\n accessibilityHint={hint}\n accessibilityLabel={accessibilityLabel ?? label}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled }}\n disabled={disabled}\n style={({ pressed }) => [styles.base, tone, pressed ? styles.pressed : null, disabled ? styles.disabled : null]}\n testID={testID}\n onPress={onPress}\n >\n <Text style={[styles.label, { color }]}>{label}</Text>\n </Pressable>\n );\n}\n","/**\n * Frame around one host-rendered card: border, the uploading overlay (busy) and the\n * upload-error row with retry. The host's card body never has to know about either.\n */\nimport React from 'react';\n\nimport { ActivityIndicator, StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n ACTIVE_BORDER_WIDTH, BORDER_WIDTH, BUSY_OVERLAY_OPACITY, RADIUS_M, SMALL_FONT_SIZE, SPACE_S,\n} from '../constants';\nimport type { CardRosterLabels, RosterItemState } from '../types';\nimport { RosterButton } from './RosterButton';\n\nconst styles = StyleSheet.create({\n frame: { borderRadius: RADIUS_M, padding: SPACE_S, gap: SPACE_S, overflow: 'hidden' },\n fill: { alignSelf: 'stretch' },\n body: { position: 'relative' },\n busy: {\n ...StyleSheet.absoluteFillObject,\n alignItems: 'center',\n justifyContent: 'center',\n gap: SPACE_S,\n opacity: BUSY_OVERLAY_OPACITY,\n },\n small: { fontSize: SMALL_FONT_SIZE },\n errorRow: { gap: SPACE_S },\n footer: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S },\n});\n\nexport type ItemFrameLabels = Pick<CardRosterLabels, 'uploading' | 'retry' | 'retryHint'>;\n\nexport interface ItemFrameProps {\n /** Fixed width in the band; omitted = stretch (reorder list). */\n width?: number;\n active: boolean;\n state: RosterItemState | undefined;\n labels: ItemFrameLabels;\n onRetry?: () => void;\n testID: string;\n children: React.ReactNode;\n footer: React.ReactNode;\n}\n\nexport function ItemFrame({\n width, active, state, labels, onRetry, testID, children, footer,\n}: ItemFrameProps): React.ReactElement {\n const { theme } = useUi();\n const busy = state?.busy === true;\n const error = state?.error ?? '';\n const hasError = error !== '';\n const errorColor = theme.semantic.error['500'];\n const primary = theme.palette.primary['500'];\n const highlighted = active || hasError;\n const borderColor = hasError ? errorColor : active ? primary : theme.colors.border;\n\n return (\n <View\n accessibilityState={{ busy }}\n style={[\n styles.frame,\n width === undefined ? styles.fill : { width },\n { borderColor, backgroundColor: theme.colors.surface, borderWidth: highlighted ? ACTIVE_BORDER_WIDTH : BORDER_WIDTH },\n ]}\n testID={testID}\n >\n <View style={styles.body}>\n {children}\n {busy ? (\n <View style={[styles.busy, { backgroundColor: theme.colors.surfaceElevated }]} testID={`${testID}-busy`}>\n <ActivityIndicator color={primary} />\n <Text accessibilityLiveRegion=\"polite\" style={[styles.small, { color: theme.colors.textSecondary }]}>\n {labels.uploading}\n </Text>\n </View>\n ) : null}\n </View>\n {hasError ? (\n <View style={styles.errorRow} testID={`${testID}-error`}>\n <Text accessibilityRole=\"alert\" style={[styles.small, { color: errorColor }]}>{error}</Text>\n {onRetry !== undefined ? (\n <RosterButton danger hint={labels.retryHint} label={labels.retry} testID={`${testID}-retry`} onPress={onRetry} />\n ) : null}\n </View>\n ) : null}\n <View style={styles.footer}>{footer}</View>\n </View>\n );\n}\n","/** The live band: a horizontal row of framed cards, each with its own Edit button. */\nimport React from 'react';\n\nimport { ScrollView, StyleSheet } from 'react-native';\n\nimport { SPACE_M, SPACE_XS } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { ItemFrame } from './ItemFrame';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n band: { gap: SPACE_M, paddingVertical: SPACE_XS },\n});\n\nexport interface CardBandProps<T extends RosterItem> {\n group: RosterGroup<T>;\n shared: RosterSectionShared<T>;\n}\n\nexport function CardBand<T extends RosterItem>({ group, shared }: CardBandProps<T>): React.ReactElement {\n const { labels, ids, onRetryItem } = shared;\n return (\n <ScrollView\n horizontal\n contentContainerStyle={styles.band}\n showsHorizontalScrollIndicator={false}\n testID={`${ids.group(group.key)}-band`}\n >\n {group.items.map((item) => {\n const cardId = ids.card(item.id);\n return (\n <ItemFrame\n key={item.id}\n active={shared.activeItemId === item.id}\n footer={(\n <RosterButton\n accessibilityLabel={labels.editCard(shared.getItemName(item))}\n disabled={shared.disabled}\n hint={labels.editCardHint}\n label={labels.edit}\n testID={`${cardId}-edit`}\n onPress={() => shared.onEdit(group.key, item.id)}\n />\n )}\n labels={labels}\n state={shared.getItemState?.(item)}\n testID={cardId}\n width={shared.cardWidth}\n onRetry={onRetryItem === undefined ? undefined : () => onRetryItem(item)}\n >\n {shared.renderCard(item, group)}\n </ItemFrame>\n );\n })}\n </ScrollView>\n );\n}\n","/** Group title (inline rename) + its actions; in Reorder mode, group up/down instead. */\nimport React, { useState } from 'react';\n\nimport { StyleSheet, Text, TextInput, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport {\n BODY_FONT_SIZE, BORDER_WIDTH, GLYPH_DOWN, GLYPH_UP, GROUP_TITLE_MIN_WIDTH, MIN_TOUCH_TARGET, MOVE_DOWN, MOVE_UP,\n RADIUS_S, SPACE_M, SPACE_S, TITLE_FONT_SIZE,\n} from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n header: { flexDirection: 'row', flexWrap: 'wrap', alignItems: 'center', gap: SPACE_S },\n title: { flexGrow: 1, flexShrink: 1, minWidth: GROUP_TITLE_MIN_WIDTH, fontSize: TITLE_FONT_SIZE, fontWeight: '700' },\n input: {\n flexGrow: 1,\n minWidth: GROUP_TITLE_MIN_WIDTH,\n minHeight: MIN_TOUCH_TARGET,\n paddingHorizontal: SPACE_M,\n borderWidth: BORDER_WIDTH,\n borderRadius: RADIUS_S,\n fontSize: BODY_FONT_SIZE,\n },\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S },\n});\n\nexport interface GroupHeaderProps<T extends RosterItem> {\n group: RosterGroup<T>;\n index: number;\n shared: RosterSectionShared<T>;\n}\n\nexport function GroupHeader<T extends RosterItem>({ group, index, shared }: GroupHeaderProps<T>): React.ReactElement {\n const { theme } = useUi();\n const [draft, setDraft] = useState<string | null>(null);\n const { labels, actions, reordering, disabled } = shared;\n const gid = shared.ids.group(group.key);\n\n const commit = (): void => {\n // Keep the draft while a save is in flight; it commits on the next blur/submit.\n if (disabled) return;\n if (draft !== null) actions.renameGroup(group.key, draft);\n setDraft(null);\n };\n\n const reorderActions = (\n <>\n <RosterButton\n accessibilityLabel={labels.moveGroupUp(group.title)}\n disabled={disabled || index === 0}\n hint={labels.moveGroupHint}\n label={GLYPH_UP}\n testID={`${gid}-up`}\n onPress={() => actions.moveGroup(group.key, MOVE_UP)}\n />\n <RosterButton\n accessibilityLabel={labels.moveGroupDown(group.title)}\n disabled={disabled || index === shared.groupCount - 1}\n hint={labels.moveGroupHint}\n label={GLYPH_DOWN}\n testID={`${gid}-down`}\n onPress={() => actions.moveGroup(group.key, MOVE_DOWN)}\n />\n </>\n );\n\n const editActions = (\n <>\n {shared.onAdd !== undefined ? (\n <RosterButton\n emphasis\n accessibilityLabel={labels.addCard(group.title)}\n disabled={disabled}\n hint={labels.addCardHint}\n label={labels.add}\n testID={`${gid}-add`}\n onPress={() => shared.onAdd?.(group.key)}\n />\n ) : null}\n <RosterButton\n accessibilityLabel={labels.renameGroup(group.title)}\n disabled={disabled}\n hint={labels.renameGroupHint}\n label={labels.rename}\n testID={`${gid}-rename`}\n onPress={() => setDraft(group.title)}\n />\n {shared.canRemoveGroup(group) ? (\n <RosterButton\n danger\n accessibilityLabel={labels.removeGroup(group.title)}\n disabled={disabled}\n hint={labels.removeGroupHint}\n label={labels.remove}\n testID={`${gid}-remove`}\n onPress={() => actions.removeGroup(group.key)}\n />\n ) : null}\n </>\n );\n\n return (\n <View style={styles.header}>\n {draft === null ? (\n <Text accessibilityRole=\"header\" numberOfLines={1} style={[styles.title, { color: theme.colors.text }]}>\n {group.title}\n </Text>\n ) : (\n <TextInput\n autoFocus\n accessibilityHint={labels.groupTitleInputHint}\n accessibilityLabel={labels.groupTitleInput}\n accessibilityState={{ disabled }}\n editable={!disabled}\n style={[styles.input, { color: theme.colors.text, borderColor: theme.palette.primary['500'] }]}\n testID={`${gid}-title-input`}\n value={draft}\n onBlur={commit}\n onChangeText={setDraft}\n onSubmitEditing={commit}\n />\n )}\n <View style={styles.actions}>{reordering ? reorderActions : editActions}</View>\n </View>\n );\n}\n","/**\n * Reorder mode for one group: a vertical list with explicit up/down buttons (no drag —\n * a drag is not reachable by keyboard or switch access). Moves animate through\n * ui-motion's `Reorder` (FLIP), which collapses to instant under reduced motion.\n */\nimport React, { useMemo } from 'react';\n\nimport { StyleSheet, View } from 'react-native';\n\nimport { Reorder } from '@dloizides/ui-motion';\n\nimport { GLYPH_DOWN, GLYPH_UP, MOVE_DOWN, MOVE_UP, REORDER_SPRING, SPACE_S } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { ItemFrame } from './ItemFrame';\nimport { RosterButton } from './RosterButton';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n item: { paddingVertical: SPACE_S / 2 },\n});\n\nexport interface ReorderListProps<T extends RosterItem> {\n group: RosterGroup<T>;\n shared: RosterSectionShared<T>;\n}\n\nexport function ReorderList<T extends RosterItem>({ group, shared }: ReorderListProps<T>): React.ReactElement {\n const { labels, ids, actions } = shared;\n const keys = useMemo(() => group.items.map((item) => item.id), [group.items]);\n const last = group.items.length - 1;\n\n const renderItem = (key: string): React.ReactNode => {\n const index = group.items.findIndex((item) => item.id === key);\n const item = group.items[index];\n if (item === undefined) return null;\n const name = shared.getItemName(item);\n const cardId = ids.card(item.id);\n return (\n <View style={styles.item}>\n <ItemFrame\n active={false}\n footer={(\n <>\n <RosterButton\n accessibilityLabel={labels.moveCardUp(name)}\n disabled={shared.disabled || index === 0}\n hint={labels.moveCardHint}\n label={GLYPH_UP}\n testID={`${cardId}-up`}\n onPress={() => actions.moveItem(group.key, item.id, MOVE_UP)}\n />\n <RosterButton\n accessibilityLabel={labels.moveCardDown(name)}\n disabled={shared.disabled || index === last}\n hint={labels.moveCardHint}\n label={GLYPH_DOWN}\n testID={`${cardId}-down`}\n onPress={() => actions.moveItem(group.key, item.id, MOVE_DOWN)}\n />\n </>\n )}\n labels={labels}\n state={shared.getItemState?.(item)}\n testID={cardId}\n >\n {shared.renderCard(item, group)}\n </ItemFrame>\n </View>\n );\n };\n\n return (\n <Reorder itemKeys={keys} spring={REORDER_SPRING} testID={`${ids.group(group.key)}-reorder`}>\n {renderItem}\n </Reorder>\n );\n}\n","/** One group: header, then the empty state, the live band, or the reorder list. */\nimport React from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport { BODY_FONT_SIZE, BORDER_WIDTH, RADIUS_M, SPACE_L, SPACE_S } from '../constants';\nimport type { RosterGroup, RosterItem } from '../types';\nimport { CardBand } from './CardBand';\nimport { GroupHeader } from './GroupHeader';\nimport { ReorderList } from './ReorderList';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n section: { gap: SPACE_S },\n empty: {\n borderWidth: BORDER_WIDTH,\n borderStyle: 'dashed',\n borderRadius: RADIUS_M,\n padding: SPACE_L,\n alignItems: 'center',\n },\n emptyText: { fontSize: BODY_FONT_SIZE, textAlign: 'center' },\n});\n\nexport interface RosterGroupSectionProps<T extends RosterItem> {\n group: RosterGroup<T>;\n index: number;\n shared: RosterSectionShared<T>;\n}\n\nexport function RosterGroupSection<T extends RosterItem>({\n group, index, shared,\n}: RosterGroupSectionProps<T>): React.ReactElement {\n const { theme } = useUi();\n const gid = shared.ids.group(group.key);\n\n let body: React.ReactNode;\n if (group.items.length === 0)\n body = (\n <View style={[styles.empty, { borderColor: theme.colors.border }]} testID={`${gid}-empty`}>\n <Text style={[styles.emptyText, { color: theme.colors.textSecondary }]}>{shared.labels.emptyGroup}</Text>\n </View>\n );\n else if (shared.reordering) body = <ReorderList group={group} shared={shared} />;\n else body = <CardBand group={group} shared={shared} />;\n\n return (\n <View style={styles.section} testID={gid}>\n <GroupHeader group={group} index={index} shared={shared} />\n {body}\n </View>\n );\n}\n","/**\n * CardRoster — a generic grouped card editor. Composed narrow-first: one column with the\n * edit form in a sheet; at/above `wideBreakpoint` the form moves into a right-hand pane.\n * The value is controlled; every edit is a pure helper from `utils/rosterOps`.\n */\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { StyleSheet, View, useWindowDimensions } from 'react-native';\n\nimport { ErrorState } from '@dloizides/ui-feedback';\nimport { LAYOUT_COLLAPSE_BREAKPOINT } from '@dloizides/ui-layout';\n\nimport { DEFAULT_CARD_WIDTH, DEFAULT_TEST_ID, SPACE_L, SPACE_S, rosterTestIds } from '../constants';\nimport { useRosterActions } from '../hooks/useRosterActions';\nimport { useRosterEditor } from '../hooks/useRosterEditor';\nimport type { CardRosterProps, RosterItem } from '../types';\nimport { isSplitPane } from '../utils/editorSession';\nimport { isGroupEmpty } from '../utils/rosterOps';\nimport { EditorPane } from './EditorPane';\nimport { RosterButton } from './RosterButton';\nimport { RosterGroupSection } from './RosterGroupSection';\nimport type { RosterSectionShared } from './sectionTypes';\n\nconst styles = StyleSheet.create({\n root: { gap: SPACE_L },\n split: { flexDirection: 'row', alignItems: 'flex-start' },\n list: { flex: 1, minWidth: 0, gap: SPACE_L },\n toolbar: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_S, justifyContent: 'flex-end' },\n});\n\nexport function CardRoster<T extends RosterItem>(props: CardRosterProps<T>): React.ReactElement {\n const {\n value, onChange, renderCard, renderEditor, getItemName, labels, createItem, createGroup,\n canRemoveGroup = isGroupEmpty, getItemState, onRetryItem, error, disabled = false,\n wideBreakpoint = LAYOUT_COLLAPSE_BREAKPOINT, cardWidth = DEFAULT_CARD_WIDTH, testID = DEFAULT_TEST_ID,\n } = props;\n const { width } = useWindowDimensions();\n const split = isSplitPane(width, wideBreakpoint);\n const [reordering, setReordering] = useState(false);\n const editor = useRosterEditor(value, onChange, createItem, disabled);\n const actions = useRosterActions(value, onChange, disabled);\n const ids = useMemo(() => rosterTestIds(testID), [testID]);\n const { close, openEdit, openNew } = editor;\n\n const toggleReorder = useCallback((): void => {\n if (disabled) return;\n close();\n setReordering((on) => !on);\n }, [close, disabled]);\n\n const shared: RosterSectionShared<T> = {\n renderCard, getItemName, getItemState, onRetryItem, labels, cardWidth, ids, reordering, actions, canRemoveGroup, disabled,\n activeItemId: editor.activeItemId,\n groupCount: value.groups.length,\n onEdit: openEdit,\n onAdd: createItem === undefined ? undefined : openNew,\n };\n\n return (\n <View accessibilityState={{ busy: disabled }} style={[styles.root, split ? styles.split : null]} testID={ids.root}>\n <View style={styles.list}>\n <View style={styles.toolbar}>\n <RosterButton\n disabled={disabled}\n emphasis={reordering}\n hint={reordering ? labels.doneReorderingHint : labels.reorderHint}\n label={reordering ? labels.doneReordering : labels.reorder}\n testID={ids.reorderToggle}\n onPress={toggleReorder}\n />\n {createGroup !== undefined && !reordering ? (\n <RosterButton\n disabled={disabled}\n hint={labels.addGroupHint}\n label={labels.addGroup}\n testID={ids.addGroup}\n onPress={() => actions.addGroup(createGroup())}\n />\n ) : null}\n </View>\n {error !== undefined ? (\n <ErrorState message={error.message} testID={ids.error} title={error.title} onRetry={error.onRetry} />\n ) : null}\n {value.groups.map((group, index) => (\n <RosterGroupSection key={group.key} group={group} index={index} shared={shared} />\n ))}\n </View>\n {reordering && split ? null : (\n <EditorPane\n context={editor.context}\n labels={labels}\n placeholderTestID={ids.editorPlaceholder}\n renderEditor={renderEditor}\n split={split}\n testID={ids.editor}\n onClose={close}\n />\n )}\n </View>\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dloizides/ui-card-roster",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Generic, brand-agnostic React Native (RN-web) grouped card roster editor: groups add/rename/remove, a card band per group, a Reorder mode, an edit-sheet slot (ModalShell) that becomes a split pane on wide screens, and pure reducer helpers. Cards and the edit form are render props. Part of the dloizides.com shared UI kit.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|