@dloizides/ui-card-roster 0.1.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.
@@ -0,0 +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"]}
package/package.json ADDED
@@ -0,0 +1,114 @@
1
+ {
2
+ "name": "@dloizides/ui-card-roster",
3
+ "version": "0.1.0",
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
+ "keywords": [
6
+ "react",
7
+ "react-native",
8
+ "react-native-web",
9
+ "ui",
10
+ "roster",
11
+ "cards",
12
+ "editor",
13
+ "reorder",
14
+ "dloizides"
15
+ ],
16
+ "author": "dloizides",
17
+ "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/openmindednewby/ui-card-roster.git"
21
+ },
22
+ "homepage": "https://github.com/openmindednewby/ui-card-roster#readme",
23
+ "bugs": {
24
+ "url": "https://github.com/openmindednewby/ui-card-roster/issues"
25
+ },
26
+ "main": "./dist/index.js",
27
+ "module": "./dist/index.mjs",
28
+ "types": "./dist/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "react-native": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ },
35
+ "browser": {
36
+ "types": "./dist/index.d.ts",
37
+ "default": "./dist/index.js"
38
+ },
39
+ "require": {
40
+ "types": "./dist/index.d.ts",
41
+ "default": "./dist/index.js"
42
+ },
43
+ "import": {
44
+ "types": "./dist/index.d.mts",
45
+ "default": "./dist/index.mjs"
46
+ },
47
+ "default": {
48
+ "types": "./dist/index.d.ts",
49
+ "default": "./dist/index.js"
50
+ }
51
+ }
52
+ },
53
+ "files": [
54
+ "dist",
55
+ "README.md",
56
+ "CHANGELOG.md"
57
+ ],
58
+ "sideEffects": false,
59
+ "engines": {
60
+ "node": ">=18.0.0"
61
+ },
62
+ "scripts": {
63
+ "build": "rimraf dist && tsup",
64
+ "build:watch": "tsup --watch",
65
+ "test": "jest",
66
+ "test:coverage": "jest --coverage",
67
+ "lint": "eslint src --ext .ts,.tsx",
68
+ "lint:fix": "eslint src --ext .ts,.tsx --fix",
69
+ "typecheck": "tsc --noEmit",
70
+ "clean": "rimraf dist",
71
+ "security:audit": "npm audit --audit-level=high",
72
+ "deps:outdated": "npm outdated || exit 0",
73
+ "deps:unused": "npx depcheck --ignores \"@types/jest,@types/node,@types/react,@types/react-dom,rimraf,react-native\"",
74
+ "prepublishOnly": "npm run clean && npm run build && npm run test",
75
+ "version": "npm run build"
76
+ },
77
+ "dependencies": {
78
+ "@dloizides/ui-motion": "^1.1.0"
79
+ },
80
+ "peerDependencies": {
81
+ "@dloizides/ui-feedback": ">=1.12.0",
82
+ "@dloizides/ui-layout": ">=1.28.0",
83
+ "react": ">=18.0.0",
84
+ "react-native": ">=0.74.0"
85
+ },
86
+ "devDependencies": {
87
+ "@dloizides/ui-buttons": "^1.18.0",
88
+ "@dloizides/ui-feedback": "^1.12.0",
89
+ "@dloizides/ui-icons": "^1.3.1",
90
+ "@dloizides/ui-layout": "^1.28.1",
91
+ "@testing-library/dom": "^10.4.0",
92
+ "@testing-library/jest-dom": "^6.6.3",
93
+ "@testing-library/react": "^16.1.0",
94
+ "@types/jest": "^29.5.0",
95
+ "@types/node": "^20.19.32",
96
+ "@types/react": "^19.0.0",
97
+ "@types/react-dom": "^19.0.0",
98
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
99
+ "@typescript-eslint/parser": "^7.0.0",
100
+ "eslint": "^8.57.0",
101
+ "eslint-plugin-react": "^7.34.0",
102
+ "eslint-plugin-react-hooks": "^4.6.0",
103
+ "jest": "^29.7.0",
104
+ "jest-environment-jsdom": "^29.7.0",
105
+ "react": "^19.2.4",
106
+ "react-dom": "^19.2.4",
107
+ "react-native": "0.81.5",
108
+ "react-native-web": "^0.21.0",
109
+ "rimraf": "^5.0.0",
110
+ "ts-jest": "^29.1.0",
111
+ "tsup": "^8.0.0",
112
+ "typescript": "^5.4.0"
113
+ }
114
+ }