pixelize-native-library 1.0.6 → 1.0.7
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/lib/module/core/icon/index.js +68 -1
- package/lib/module/core/icon/index.js.map +1 -1
- package/lib/module/modules/bottom-nav/BottomNav.js +25 -15
- package/lib/module/modules/bottom-nav/BottomNav.js.map +1 -1
- package/lib/module/modules/bottom-nav/BottomNav.variants.js +65 -0
- package/lib/module/modules/bottom-nav/BottomNav.variants.js.map +1 -1
- package/lib/module/modules/bottom-nav/BottomNavIconWithBadge.js +75 -0
- package/lib/module/modules/bottom-nav/BottomNavIconWithBadge.js.map +1 -0
- package/lib/module/modules/bottom-nav/BottomNavOverflowSheet.js +13 -6
- package/lib/module/modules/bottom-nav/BottomNavOverflowSheet.js.map +1 -1
- package/lib/module/modules/bottom-nav/MODULE.md +25 -10
- package/lib/module/modules/charts/BarList.js +79 -0
- package/lib/module/modules/charts/BarList.js.map +1 -0
- package/lib/module/modules/charts/Charts.variants.js +59 -0
- package/lib/module/modules/charts/Charts.variants.js.map +1 -0
- package/lib/module/modules/charts/DonutChart.js +98 -0
- package/lib/module/modules/charts/DonutChart.js.map +1 -0
- package/lib/module/modules/charts/MODULE.md +52 -0
- package/lib/module/modules/charts/Sparkline.js +79 -0
- package/lib/module/modules/charts/Sparkline.js.map +1 -0
- package/lib/module/modules/charts/index.js +12 -0
- package/lib/module/modules/charts/index.js.map +1 -0
- package/lib/module/modules/list-item/ListItem.js +75 -0
- package/lib/module/modules/list-item/ListItem.js.map +1 -0
- package/lib/module/modules/list-item/ListItem.variants.js +53 -0
- package/lib/module/modules/list-item/ListItem.variants.js.map +1 -0
- package/lib/module/modules/list-item/MODULE.md +47 -0
- package/lib/module/modules/list-item/index.js +10 -0
- package/lib/module/modules/list-item/index.js.map +1 -0
- package/lib/module/modules/markdown/MODULE.md +44 -0
- package/lib/module/modules/markdown/Markdown.js +149 -0
- package/lib/module/modules/markdown/Markdown.js.map +1 -0
- package/lib/module/modules/markdown/Markdown.variants.js +68 -0
- package/lib/module/modules/markdown/Markdown.variants.js.map +1 -0
- package/lib/module/modules/markdown/index.js +11 -0
- package/lib/module/modules/markdown/index.js.map +1 -0
- package/lib/module/modules/markdown/parseMarkdown.js +153 -0
- package/lib/module/modules/markdown/parseMarkdown.js.map +1 -0
- package/lib/module/modules/multi-select/MODULE.md +1 -1
- package/lib/module/modules/multi-select/MultiSelect.js +1 -1
- package/lib/module/modules/multi-select/MultiSelect.js.map +1 -1
- package/lib/module/modules/select/MODULE.md +1 -1
- package/lib/module/modules/select/Select.js +13 -10
- package/lib/module/modules/select/Select.js.map +1 -1
- package/lib/module/modules/select/Select.variants.js +11 -0
- package/lib/module/modules/select/Select.variants.js.map +1 -1
- package/lib/module/modules/stat-tile/MODULE.md +44 -0
- package/lib/module/modules/stat-tile/StatTile.js +87 -0
- package/lib/module/modules/stat-tile/StatTile.js.map +1 -0
- package/lib/module/modules/stat-tile/StatTile.variants.js +55 -0
- package/lib/module/modules/stat-tile/StatTile.variants.js.map +1 -0
- package/lib/module/modules/stat-tile/index.js +10 -0
- package/lib/module/modules/stat-tile/index.js.map +1 -0
- package/lib/module/modules/timeline/MODULE.md +10 -1
- package/lib/module/modules/timeline/Timeline.js +4 -1
- package/lib/module/modules/timeline/Timeline.js.map +1 -1
- package/lib/module/theme/tokens/builders/accentText.js +9 -0
- package/lib/module/theme/tokens/builders/accentText.js.map +1 -1
- package/lib/typescript/core/icon/index.d.ts +38 -1
- package/lib/typescript/core/icon/index.d.ts.map +1 -1
- package/lib/typescript/modules/bottom-nav/BottomNav.d.ts +5 -1
- package/lib/typescript/modules/bottom-nav/BottomNav.d.ts.map +1 -1
- package/lib/typescript/modules/bottom-nav/BottomNav.variants.d.ts +50 -0
- package/lib/typescript/modules/bottom-nav/BottomNav.variants.d.ts.map +1 -1
- package/lib/typescript/modules/bottom-nav/BottomNavIconWithBadge.d.ts +25 -0
- package/lib/typescript/modules/bottom-nav/BottomNavIconWithBadge.d.ts.map +1 -0
- package/lib/typescript/modules/bottom-nav/BottomNavOverflowSheet.d.ts.map +1 -1
- package/lib/typescript/modules/charts/BarList.d.ts +18 -0
- package/lib/typescript/modules/charts/BarList.d.ts.map +1 -0
- package/lib/typescript/modules/charts/Charts.variants.d.ts +26 -0
- package/lib/typescript/modules/charts/Charts.variants.d.ts.map +1 -0
- package/lib/typescript/modules/charts/DonutChart.d.ts +18 -0
- package/lib/typescript/modules/charts/DonutChart.d.ts.map +1 -0
- package/lib/typescript/modules/charts/Sparkline.d.ts +13 -0
- package/lib/typescript/modules/charts/Sparkline.d.ts.map +1 -0
- package/lib/typescript/modules/charts/index.d.ts +13 -0
- package/lib/typescript/modules/charts/index.d.ts.map +1 -0
- package/lib/typescript/modules/list-item/ListItem.d.ts +15 -0
- package/lib/typescript/modules/list-item/ListItem.d.ts.map +1 -0
- package/lib/typescript/modules/list-item/ListItem.variants.d.ts +29 -0
- package/lib/typescript/modules/list-item/ListItem.variants.d.ts.map +1 -0
- package/lib/typescript/modules/list-item/index.d.ts +8 -0
- package/lib/typescript/modules/list-item/index.d.ts.map +1 -0
- package/lib/typescript/modules/markdown/Markdown.d.ts +10 -0
- package/lib/typescript/modules/markdown/Markdown.d.ts.map +1 -0
- package/lib/typescript/modules/markdown/Markdown.variants.d.ts +27 -0
- package/lib/typescript/modules/markdown/Markdown.variants.d.ts.map +1 -0
- package/lib/typescript/modules/markdown/index.d.ts +10 -0
- package/lib/typescript/modules/markdown/index.d.ts.map +1 -0
- package/lib/typescript/modules/markdown/parseMarkdown.d.ts +43 -0
- package/lib/typescript/modules/markdown/parseMarkdown.d.ts.map +1 -0
- package/lib/typescript/modules/multi-select/MultiSelect.d.ts +6 -0
- package/lib/typescript/modules/multi-select/MultiSelect.d.ts.map +1 -1
- package/lib/typescript/modules/select/Select.d.ts +6 -0
- package/lib/typescript/modules/select/Select.d.ts.map +1 -1
- package/lib/typescript/modules/select/Select.variants.d.ts +3 -0
- package/lib/typescript/modules/select/Select.variants.d.ts.map +1 -1
- package/lib/typescript/modules/stat-tile/StatTile.d.ts +16 -0
- package/lib/typescript/modules/stat-tile/StatTile.d.ts.map +1 -0
- package/lib/typescript/modules/stat-tile/StatTile.variants.d.ts +34 -0
- package/lib/typescript/modules/stat-tile/StatTile.variants.d.ts.map +1 -0
- package/lib/typescript/modules/stat-tile/index.d.ts +9 -0
- package/lib/typescript/modules/stat-tile/index.d.ts.map +1 -0
- package/lib/typescript/modules/timeline/Timeline.d.ts +4 -0
- package/lib/typescript/modules/timeline/Timeline.d.ts.map +1 -1
- package/lib/typescript/theme/tokens/builders/accentText.d.ts +6 -0
- package/lib/typescript/theme/tokens/builders/accentText.d.ts.map +1 -1
- package/package.json +22 -1
- package/registry.json +20 -0
|
@@ -15,12 +15,13 @@ stability contract" below, the actual deliverable of this module.
|
|
|
15
15
|
|------|------|
|
|
16
16
|
| `BottomNav.tsx` | The component. The fixed bar: per-tab focus tracking, the active-indicator render, press → `onDestinationPress` wiring, composing `Drawer` as the sheet's shell. Data types (`BottomNavDestination`, `BottomNavOverflowSection`, `BottomNavActiveState`, `BottomNavEditConfig`) live here, same precedent as Select's `SelectOption`. |
|
|
17
17
|
| `BottomNavOverflowSheet.tsx` | PRIVATE (not exported) — the sheet's content: search (reuses `../input`'s `Input`), pre-search Recent row, grouped sections, edit mode, no-results state. |
|
|
18
|
-
| `
|
|
18
|
+
| `BottomNavIconWithBadge.tsx` | PRIVATE — a destination icon + its optional badge (count pill, or the More trigger's presence-only dot), shared by the bar tabs, the More trigger, and every sheet row so the badge renders identically everywhere. |
|
|
19
|
+
| `BottomNav.variants.ts` | Pure resolvers (`resolveBottomNavTabColors`, `resolveBottomNavAccessibility`, `resolveEditRowState`, `resolveBottomNavBottomInset`, `resolveOverflowSheetHeight`; badge: `resolveBottomNavBadge`, `resolveBottomNavBadgeColors`, `resolveBottomNavOverflowBadgeTotal`, `resolveBottomNavDestinationAccessibilityLabel`) + themed structural resolvers (`bottomNavBarStructure`, `bottomNavTabStructure`, `overflowRowStructure`, `overflowSectionHeaderStructure`, `editRowStructure`, `bottomNavBadgePillStructure`). No React, no lucide. |
|
|
19
20
|
| `BottomNav.search.ts` | Pure, framework-free (no React, no `react-native` import): `normalizeQuery`, `levenshteinDistance`, `typoBudget`, `fuzzyScore`, `matchDestinations`. Own file — ranking correctness is orthogonal to colour/structure. |
|
|
20
21
|
| `index.ts` | Public surface: `BottomNav`, `BottomNavProps`, `BottomNavActiveState`, `BottomNavDestination`, `BottomNavOverflowSection`, `BottomNavEditConfig`. Re-exports `MenuItem` (from `../menu`) and `IconName`. |
|
|
21
|
-
| `__tests__/BottomNav.test.ts` | Pure: WCAG contrast (8 brands × both modes), touch-target floor, accessibility/edit-row/inset/detent resolvers. |
|
|
22
|
+
| `__tests__/BottomNav.test.ts` | Pure: WCAG contrast (8 brands × both modes, tab + badge colours), touch-target floor, accessibility/edit-row/inset/detent/badge resolvers. |
|
|
22
23
|
| `__tests__/BottomNav.search.test.ts` | Pure: levenshtein/typo-budget arithmetic, `fuzzyScore` tiering, `matchDestinations` ranking/stability/empty-query. |
|
|
23
|
-
| `__tests__/BottomNav.render.test.tsx` | Render: press wiring, sheet open/close, live typo-tolerant search, Recent/grouped/no-results, edit-mode flow, opt-in quick-actions trigger. |
|
|
24
|
+
| `__tests__/BottomNav.render.test.tsx` | Render: press wiring, sheet open/close, live typo-tolerant search, Recent/grouped/no-results, edit-mode flow, opt-in quick-actions trigger, badges (pill / 0 / 99+ cap / sheet rows / More dot / a11y-label override). |
|
|
24
25
|
|
|
25
26
|
## Props
|
|
26
27
|
|
|
@@ -39,7 +40,7 @@ stability contract" below, the actual deliverable of this module.
|
|
|
39
40
|
| `moreQuickActions` | `MenuItem[]` (from `../menu`) | — | Omit → no quick-actions trigger renders at all. |
|
|
40
41
|
| `moreQuickActionsLabel` | `string` | `"More options"` | `accessibilityLabel` for the trigger badge. |
|
|
41
42
|
| `style` | `LayoutStyle` | — | Layout-only, outermost, applied exactly once, last. |
|
|
42
|
-
| `testID` | `string` | — | Seeds `-tab-${id}[-indicator]`, `-more[-indicator]`, `-more-quick-actions[-menu]`, `-sheet` (+ Drawer's own `-panel`/`-backdrop`), `-sheet-search`, `-sheet-recent-${id}`, `-sheet-result-${id}`, `-sheet-edit-toggle`, `-sheet-edit-slots`, `-sheet-edit-slot-${i}`, `-sheet-reset`, `-sheet-no-results`. |
|
|
43
|
+
| `testID` | `string` | — | Seeds `-tab-${id}[-indicator\|-badge]`, `-more[-indicator\|-badge]`, `-more-quick-actions[-menu]`, `-sheet` (+ Drawer's own `-panel`/`-backdrop`), `-sheet-search`, `-sheet-recent-${id}[-badge]`, `-sheet-result-${id}[-badge]`, `-sheet-edit-toggle`, `-sheet-edit-slots`, `-sheet-edit-slot-${i}`, `-sheet-reset`, `-sheet-no-results`. |
|
|
43
44
|
|
|
44
45
|
`BottomNavEditConfig`: `editing` / `onEditingChange` (controlled), `onPinChange(slotIndex, destination)`,
|
|
45
46
|
optional `onResetToDefault` (omit → no reset row), optional `editLabel`/`doneLabel`/`resetLabel`
|
|
@@ -47,6 +48,19 @@ optional `onResetToDefault` (omit → no reset row), optional `editLabel`/`doneL
|
|
|
47
48
|
|
|
48
49
|
No `variant`/`size`/`tone` in v1 — one fixed shape, same stance Drawer takes for itself.
|
|
49
50
|
|
|
51
|
+
## Badges
|
|
52
|
+
|
|
53
|
+
`BottomNavDestination.badge?: number` — an attention/unread count. `0`/omitted (or any non-positive)
|
|
54
|
+
renders nothing. A small `accent.solid` pill (16dp, display capped at "99+") overlays the
|
|
55
|
+
destination's icon in the bar AND in every sheet row (Recent, grouped, search results) via the
|
|
56
|
+
private `BottomNavIconWithBadge`. The More trigger shows a presence-only dot — the bar's own
|
|
57
|
+
active-dot idiom — whenever any overflow destination is badged. Accessible names fold the TRUE
|
|
58
|
+
count in automatically ("Tasks, 5 new items"; the More trigger announces the summed overflow count,
|
|
59
|
+
"More, 120 new items" — never the capped form); an explicit `accessibilityLabel` overrides the
|
|
60
|
+
whole name and suppresses the automatic fold. Pill colours are measured, never eyeballed: count vs
|
|
61
|
+
fill ≥ 4.5:1 and fill vs bar surface ≥ 3:1, all 8 brands × both modes (`BottomNav.test.ts`).
|
|
62
|
+
Edit-mode slot chips deliberately stay badge-free.
|
|
63
|
+
|
|
50
64
|
## Interaction model
|
|
51
65
|
|
|
52
66
|
- **Core tab press**: `onDestinationPress(id)`. **More press**: `onMoreVisibleChange(true)`.
|
|
@@ -101,7 +115,8 @@ imports `@react-native-async-storage/async-storage` and never reads a value it w
|
|
|
101
115
|
- **4.1.2** — bar container `accessibilityRole="tablist"`; each core tab and the More slot
|
|
102
116
|
`accessibilityRole="tab"` with `accessibilityState={{ selected, expanded }}` (`expanded` on More
|
|
103
117
|
only, tracking `moreVisible`). Sheet rows are `accessibilityRole="menuitem"`; section headers are
|
|
104
|
-
`accessibilityRole="header"` (same role Modal uses for its title).
|
|
118
|
+
`accessibilityRole="header"` (same role Modal uses for its title). Badged tabs/rows announce ONE
|
|
119
|
+
folded name (see Badges) — the pill's own text never leaks as a separate announcement.
|
|
105
120
|
- **2.5.x target size** — `BOTTOM_NAV_HEIGHT` (56dp) asserted ≥ 44dp in a pure unit test, same
|
|
106
121
|
`height ≥ MIN_TOUCH_TARGET` idiom Button/Select/Reorder use. Tab WIDTH is screen-width-dependent
|
|
107
122
|
(`flex: 1` across `coreTabs.length + 1`) — see Known gaps.
|
|
@@ -132,17 +147,17 @@ and `BottomNavOverflowSection`'s (`id`, `destinations`) are likewise frozen.
|
|
|
132
147
|
|
|
133
148
|
**Documented extension points (purely additive, safe defaults):** `recent`, `searchPlaceholder`,
|
|
134
149
|
`searchAccessibilityLabel`, `recentLabel`, `noResultsLabel`, `edit`, `moreQuickActions`,
|
|
135
|
-
`moreQuickActionsLabel`, `style`, `testID` — every one optional; a
|
|
136
|
-
working, unchanged, forever. `BottomNavOverflowSection.label` is optional — an unlabelled single
|
|
150
|
+
`moreQuickActionsLabel`, `style`, `testID`, `BottomNavDestination.badge` — every one optional; a
|
|
151
|
+
caller who never passes them keeps working, unchanged, forever. `BottomNavOverflowSection.label` is optional — an unlabelled single
|
|
137
152
|
section is first-class v1, not a workaround. `edit`/`moreQuickActions` are this library's first
|
|
138
153
|
"opt-in feature bundle" props (a config object / typed array, not a flat prop) — worth a second look
|
|
139
154
|
at future build time, not a silent precedent-break.
|
|
140
155
|
|
|
141
156
|
**The rule for landing new capability without a version-bump breaking anyone:**
|
|
142
157
|
1. New capability = a new OPTIONAL prop (or optional field) whose absence reproduces today's exact
|
|
143
|
-
behaviour — never a new required prop/field.
|
|
144
|
-
`BottomNavDestination.badge?:
|
|
145
|
-
"compact"` defaulting `"regular"`.
|
|
158
|
+
behaviour — never a new required prop/field. The unread-count badge landed exactly this way
|
|
159
|
+
(`BottomNavDestination.badge?: number`, 2026-07-21 — see Badges); a compact bar lands as
|
|
160
|
+
`size?: "regular" | "compact"` defaulting `"regular"`.
|
|
146
161
|
2. Closed unions (`BottomNavActiveState.kind`) may gain NEW MEMBERS, never rename/remove one. A future
|
|
147
162
|
`{ kind: "search" }` is additive at runtime — existing callers never construct it. The one caveat:
|
|
148
163
|
an exhaustive `switch` over `.kind` fails to compile until a case is added — TypeScript correctly
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { memo } from "react";
|
|
4
|
+
import { Pressable, StyleSheet, Text, View } from "react-native";
|
|
5
|
+
import { useTheme } from "../../theme/index.js";
|
|
6
|
+
import { barListHeaderStructure, barListRowStructure, barListStructure, barListTrackStructure, resolveBarListColors } from "./Charts.variants.js";
|
|
7
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
+
function barFraction(value, max) {
|
|
9
|
+
if (!Number.isFinite(value) || !Number.isFinite(max) || max <= 0) return 0;
|
|
10
|
+
return Math.min(Math.max(value / max, 0), 1);
|
|
11
|
+
}
|
|
12
|
+
export const BarList = /*#__PURE__*/memo(function BarList({
|
|
13
|
+
items,
|
|
14
|
+
maxValue,
|
|
15
|
+
onPressItem,
|
|
16
|
+
style,
|
|
17
|
+
testID
|
|
18
|
+
}) {
|
|
19
|
+
const theme = useTheme();
|
|
20
|
+
const colors = resolveBarListColors(theme.colors);
|
|
21
|
+
const max = maxValue ?? items.reduce((highest, item) => Math.max(highest, Number.isFinite(item.value) ? item.value : 0), 0);
|
|
22
|
+
return /*#__PURE__*/_jsx(View, {
|
|
23
|
+
testID: testID,
|
|
24
|
+
style: [barListStructure(theme), style],
|
|
25
|
+
children: items.map((item, index) => {
|
|
26
|
+
const rowTestID = testID === undefined ? undefined : `${testID}-item-${index}`;
|
|
27
|
+
const Row = onPressItem === undefined ? View : Pressable;
|
|
28
|
+
return /*#__PURE__*/_jsxs(Row, {
|
|
29
|
+
testID: rowTestID,
|
|
30
|
+
accessible: true,
|
|
31
|
+
accessibilityRole: onPressItem === undefined ? "text" : "button",
|
|
32
|
+
accessibilityLabel: `${item.label}, ${item.value}`,
|
|
33
|
+
onPress: onPressItem === undefined ? undefined : () => onPressItem(item, index),
|
|
34
|
+
style: barListRowStructure(theme),
|
|
35
|
+
children: [/*#__PURE__*/_jsxs(View, {
|
|
36
|
+
style: barListHeaderStructure(theme),
|
|
37
|
+
children: [item.icon, /*#__PURE__*/_jsx(Text, {
|
|
38
|
+
numberOfLines: 1,
|
|
39
|
+
style: [theme.fontStyleForWeight(theme.fontWeights.medium), styles.label, {
|
|
40
|
+
fontSize: theme.fontSizes.sm,
|
|
41
|
+
color: colors.label
|
|
42
|
+
}],
|
|
43
|
+
children: item.label
|
|
44
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
45
|
+
numberOfLines: 1,
|
|
46
|
+
style: [theme.fontStyleForWeight(theme.fontWeights.regular), {
|
|
47
|
+
fontSize: theme.fontSizes.sm,
|
|
48
|
+
color: colors.value
|
|
49
|
+
}],
|
|
50
|
+
children: item.value
|
|
51
|
+
})]
|
|
52
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
53
|
+
testID: rowTestID === undefined ? undefined : `${rowTestID}-track`,
|
|
54
|
+
accessibilityElementsHidden: true,
|
|
55
|
+
importantForAccessibility: "no-hide-descendants",
|
|
56
|
+
style: [barListTrackStructure(theme), {
|
|
57
|
+
backgroundColor: colors.track
|
|
58
|
+
}],
|
|
59
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
60
|
+
testID: rowTestID === undefined ? undefined : `${rowTestID}-fill`,
|
|
61
|
+
style: [styles.fill, {
|
|
62
|
+
width: `${barFraction(item.value, max) * 100}%`,
|
|
63
|
+
backgroundColor: item.color ?? colors.fill
|
|
64
|
+
}]
|
|
65
|
+
})
|
|
66
|
+
})]
|
|
67
|
+
}, `${index}-${item.label}`);
|
|
68
|
+
})
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
const styles = StyleSheet.create({
|
|
72
|
+
label: {
|
|
73
|
+
flex: 1
|
|
74
|
+
},
|
|
75
|
+
fill: {
|
|
76
|
+
height: "100%"
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=BarList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["memo","Pressable","StyleSheet","Text","View","useTheme","barListHeaderStructure","barListRowStructure","barListStructure","barListTrackStructure","resolveBarListColors","jsx","_jsx","jsxs","_jsxs","barFraction","value","max","Number","isFinite","Math","min","BarList","items","maxValue","onPressItem","style","testID","theme","colors","reduce","highest","item","children","map","index","rowTestID","undefined","Row","accessible","accessibilityRole","accessibilityLabel","label","onPress","icon","numberOfLines","fontStyleForWeight","fontWeights","medium","styles","fontSize","fontSizes","sm","color","regular","accessibilityElementsHidden","importantForAccessibility","backgroundColor","track","fill","width","create","flex","height"],"sourceRoot":"../../../../src","sources":["modules/charts/BarList.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pure resolvers for the charts module — no React, no svg, so the WCAG tests import this directly
|
|
5
|
+
* (mocking only `react-native`'s `StyleSheet`, as every sibling module's tests do).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createThemedVariants } from "../../core/style/index.js";
|
|
9
|
+
export const BAR_LIST_TRACK_HEIGHT = 6;
|
|
10
|
+
export function resolveBarListColors(colors) {
|
|
11
|
+
return {
|
|
12
|
+
label: colors.fg.default,
|
|
13
|
+
value: colors.fg.muted,
|
|
14
|
+
track: colors.bg.sunken,
|
|
15
|
+
fill: colors.accent.solid
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function resolveDonutChartColors(colors) {
|
|
19
|
+
return {
|
|
20
|
+
track: colors.bg.sunken,
|
|
21
|
+
centerLabel: colors.fg.default,
|
|
22
|
+
centerSublabel: colors.fg.muted
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function resolveSparklineTone(colors, tone) {
|
|
26
|
+
switch (tone) {
|
|
27
|
+
case "accent":
|
|
28
|
+
return colors.accent.solid;
|
|
29
|
+
case "neutral":
|
|
30
|
+
return colors.fg.muted;
|
|
31
|
+
default:
|
|
32
|
+
return colors.status[tone].solid;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export const barListStructure = createThemedVariants(theme => ({
|
|
36
|
+
base: {
|
|
37
|
+
rowGap: theme.space[3]
|
|
38
|
+
}
|
|
39
|
+
}));
|
|
40
|
+
export const barListRowStructure = createThemedVariants(theme => ({
|
|
41
|
+
base: {
|
|
42
|
+
rowGap: theme.space[1]
|
|
43
|
+
}
|
|
44
|
+
}));
|
|
45
|
+
export const barListHeaderStructure = createThemedVariants(theme => ({
|
|
46
|
+
base: {
|
|
47
|
+
flexDirection: "row",
|
|
48
|
+
alignItems: "center",
|
|
49
|
+
columnGap: theme.space[2]
|
|
50
|
+
}
|
|
51
|
+
}));
|
|
52
|
+
export const barListTrackStructure = createThemedVariants(theme => ({
|
|
53
|
+
base: {
|
|
54
|
+
height: BAR_LIST_TRACK_HEIGHT,
|
|
55
|
+
borderRadius: theme.radii.full,
|
|
56
|
+
overflow: "hidden"
|
|
57
|
+
}
|
|
58
|
+
}));
|
|
59
|
+
//# sourceMappingURL=Charts.variants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createThemedVariants","BAR_LIST_TRACK_HEIGHT","resolveBarListColors","colors","label","fg","default","value","muted","track","bg","sunken","fill","accent","solid","resolveDonutChartColors","centerLabel","centerSublabel","resolveSparklineTone","tone","status","barListStructure","theme","base","rowGap","space","barListRowStructure","barListHeaderStructure","flexDirection","alignItems","columnGap","barListTrackStructure","height","borderRadius","radii","full","overflow"],"sourceRoot":"../../../../src","sources":["modules/charts/Charts.variants.ts"],"mappings":";;AAAA;AACA;AACA;AACA;;AAGA,SAASA,oBAAoB,QAAQ,2BAAkB;AAIvD,OAAO,MAAMC,qBAAqB,GAAG,CAAC;AAStC,OAAO,SAASC,oBAAoBA,CAACC,MAAkB,EAAiB;EACtE,OAAO;IACLC,KAAK,EAAED,MAAM,CAACE,EAAE,CAACC,OAAO;IACxBC,KAAK,EAAEJ,MAAM,CAACE,EAAE,CAACG,KAAK;IACtBC,KAAK,EAAEN,MAAM,CAACO,EAAE,CAACC,MAAM;IACvBC,IAAI,EAAET,MAAM,CAACU,MAAM,CAACC;EACtB,CAAC;AACH;AAQA,OAAO,SAASC,uBAAuBA,CAACZ,MAAkB,EAAoB;EAC5E,OAAO;IACLM,KAAK,EAAEN,MAAM,CAACO,EAAE,CAACC,MAAM;IACvBK,WAAW,EAAEb,MAAM,CAACE,EAAE,CAACC,OAAO;IAC9BW,cAAc,EAAEd,MAAM,CAACE,EAAE,CAACG;EAC5B,CAAC;AACH;AAEA,OAAO,SAASU,oBAAoBA,CAACf,MAAkB,EAAEgB,IAAmB,EAAU;EACpF,QAAQA,IAAI;IACV,KAAK,QAAQ;MACX,OAAOhB,MAAM,CAACU,MAAM,CAACC,KAAK;IAC5B,KAAK,SAAS;MACZ,OAAOX,MAAM,CAACE,EAAE,CAACG,KAAK;IACxB;MACE,OAAOL,MAAM,CAACiB,MAAM,CAACD,IAAI,CAAC,CAACL,KAAK;EACpC;AACF;AAEA,OAAO,MAAMO,gBAAgB,GAAGrB,oBAAoB,CAAEsB,KAAY,KAAM;EACtEC,IAAI,EAAE;IACJC,MAAM,EAAEF,KAAK,CAACG,KAAK,CAAC,CAAC;EACvB;AACF,CAAC,CAAC,CAAC;AAEH,OAAO,MAAMC,mBAAmB,GAAG1B,oBAAoB,CAAEsB,KAAY,KAAM;EACzEC,IAAI,EAAE;IACJC,MAAM,EAAEF,KAAK,CAACG,KAAK,CAAC,CAAC;EACvB;AACF,CAAC,CAAC,CAAC;AAEH,OAAO,MAAME,sBAAsB,GAAG3B,oBAAoB,CAAEsB,KAAY,KAAM;EAC5EC,IAAI,EAAE;IACJK,aAAa,EAAE,KAAK;IACpBC,UAAU,EAAE,QAAQ;IACpBC,SAAS,EAAER,KAAK,CAACG,KAAK,CAAC,CAAC;EAC1B;AACF,CAAC,CAAC,CAAC;AAEH,OAAO,MAAMM,qBAAqB,GAAG/B,oBAAoB,CAAEsB,KAAY,KAAM;EAC3EC,IAAI,EAAE;IACJS,MAAM,EAAE/B,qBAAqB;IAC7BgC,YAAY,EAAEX,KAAK,CAACY,KAAK,CAACC,IAAI;IAC9BC,QAAQ,EAAE;EACZ;AACF,CAAC,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { memo } from "react";
|
|
4
|
+
import { StyleSheet, Text, View } from "react-native";
|
|
5
|
+
import Svg, { Circle, G } from "react-native-svg";
|
|
6
|
+
import { useTheme } from "../../theme/index.js";
|
|
7
|
+
import { resolveDonutChartColors } from "./Charts.variants.js";
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
export const DonutChart = /*#__PURE__*/memo(function DonutChart({
|
|
10
|
+
segments,
|
|
11
|
+
size = 160,
|
|
12
|
+
thickness = 20,
|
|
13
|
+
centerLabel,
|
|
14
|
+
centerSublabel,
|
|
15
|
+
style,
|
|
16
|
+
testID
|
|
17
|
+
}) {
|
|
18
|
+
const theme = useTheme();
|
|
19
|
+
const colors = resolveDonutChartColors(theme.colors);
|
|
20
|
+
const center = size / 2;
|
|
21
|
+
const radius = Math.max((size - thickness) / 2, 0);
|
|
22
|
+
const circumference = 2 * Math.PI * radius;
|
|
23
|
+
const valid = segments.filter(segment => Number.isFinite(segment.value) && segment.value > 0);
|
|
24
|
+
const total = valid.reduce((sum, segment) => sum + segment.value, 0);
|
|
25
|
+
const arcs = [];
|
|
26
|
+
let start = 0;
|
|
27
|
+
for (const segment of valid) {
|
|
28
|
+
const fraction = total > 0 ? segment.value / total : 0;
|
|
29
|
+
arcs.push({
|
|
30
|
+
color: segment.color,
|
|
31
|
+
fraction,
|
|
32
|
+
start
|
|
33
|
+
});
|
|
34
|
+
start += fraction;
|
|
35
|
+
}
|
|
36
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
37
|
+
testID: testID,
|
|
38
|
+
style: [{
|
|
39
|
+
width: size,
|
|
40
|
+
height: size
|
|
41
|
+
}, style],
|
|
42
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
43
|
+
accessibilityElementsHidden: true,
|
|
44
|
+
importantForAccessibility: "no-hide-descendants",
|
|
45
|
+
children: /*#__PURE__*/_jsx(Svg, {
|
|
46
|
+
width: size,
|
|
47
|
+
height: size,
|
|
48
|
+
children: /*#__PURE__*/_jsxs(G, {
|
|
49
|
+
transform: `rotate(-90 ${center} ${center})`,
|
|
50
|
+
children: [/*#__PURE__*/_jsx(Circle, {
|
|
51
|
+
testID: testID === undefined ? undefined : `${testID}-track`,
|
|
52
|
+
cx: center,
|
|
53
|
+
cy: center,
|
|
54
|
+
r: radius,
|
|
55
|
+
stroke: colors.track,
|
|
56
|
+
strokeWidth: thickness,
|
|
57
|
+
fill: "none"
|
|
58
|
+
}), arcs.map((arc, index) => /*#__PURE__*/_jsx(Circle, {
|
|
59
|
+
testID: testID === undefined ? undefined : `${testID}-segment-${index}`,
|
|
60
|
+
cx: center,
|
|
61
|
+
cy: center,
|
|
62
|
+
r: radius,
|
|
63
|
+
stroke: arc.color,
|
|
64
|
+
strokeWidth: thickness,
|
|
65
|
+
fill: "none",
|
|
66
|
+
strokeDasharray: `${arc.fraction * circumference} ${circumference}`,
|
|
67
|
+
strokeDashoffset: -arc.start * circumference
|
|
68
|
+
}, index))]
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
}), (centerLabel !== undefined || centerSublabel !== undefined) && /*#__PURE__*/_jsxs(View, {
|
|
72
|
+
pointerEvents: "none",
|
|
73
|
+
style: [StyleSheet.absoluteFill, styles.center],
|
|
74
|
+
children: [centerLabel !== undefined && /*#__PURE__*/_jsx(Text, {
|
|
75
|
+
numberOfLines: 1,
|
|
76
|
+
style: [theme.fontStyleForWeight(theme.fontWeights.semibold), {
|
|
77
|
+
fontSize: theme.fontSizes.xl,
|
|
78
|
+
color: colors.centerLabel
|
|
79
|
+
}],
|
|
80
|
+
children: centerLabel
|
|
81
|
+
}), centerSublabel !== undefined && /*#__PURE__*/_jsx(Text, {
|
|
82
|
+
numberOfLines: 1,
|
|
83
|
+
style: [theme.fontStyleForWeight(theme.fontWeights.regular), {
|
|
84
|
+
fontSize: theme.fontSizes.xs,
|
|
85
|
+
color: colors.centerSublabel
|
|
86
|
+
}],
|
|
87
|
+
children: centerSublabel
|
|
88
|
+
})]
|
|
89
|
+
})]
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
const styles = StyleSheet.create({
|
|
93
|
+
center: {
|
|
94
|
+
alignItems: "center",
|
|
95
|
+
justifyContent: "center"
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=DonutChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["memo","StyleSheet","Text","View","Svg","Circle","G","useTheme","resolveDonutChartColors","jsx","_jsx","jsxs","_jsxs","DonutChart","segments","size","thickness","centerLabel","centerSublabel","style","testID","theme","colors","center","radius","Math","max","circumference","PI","valid","filter","segment","Number","isFinite","value","total","reduce","sum","arcs","start","fraction","push","color","width","height","children","accessibilityElementsHidden","importantForAccessibility","transform","undefined","cx","cy","r","stroke","track","strokeWidth","fill","map","arc","index","strokeDasharray","strokeDashoffset","pointerEvents","absoluteFill","styles","numberOfLines","fontStyleForWeight","fontWeights","semibold","fontSize","fontSizes","xl","regular","xs","create","alignItems","justifyContent"],"sourceRoot":"../../../../src","sources":["modules/charts/DonutChart.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# charts/ — small data-display primitives (BarList, DonutChart, Sparkline)
|
|
2
|
+
|
|
3
|
+
Three theme-aware chart primitives for dashboards and KPI screens. `DonutChart` and `Sparkline`
|
|
4
|
+
render through `react-native-svg` (optional peer — a consumer using only `BarList` never pays for
|
|
5
|
+
it at runtime, though the import is module-level: importing this subpath requires the peer
|
|
6
|
+
installed).
|
|
7
|
+
|
|
8
|
+
## Files
|
|
9
|
+
|
|
10
|
+
| File | Role |
|
|
11
|
+
|------|------|
|
|
12
|
+
| `BarList.tsx` | Horizontal labeled breakdown bars — plain Views, no svg. |
|
|
13
|
+
| `DonutChart.tsx` | Svg donut: stacked `Circle` strokes via dasharray/dashoffset, optional center label. |
|
|
14
|
+
| `Sparkline.tsx` | Svg line + area under it, tone-driven stroke. |
|
|
15
|
+
| `Charts.variants.ts` | Pure resolvers (colors from role tokens, BarList structure). No React, no svg. |
|
|
16
|
+
| `__tests__/Charts.test.ts` | Pure: WCAG contrast (all brands × modes) + role-mapping contract. |
|
|
17
|
+
| `__tests__/Charts.render.test.tsx` | Render: rows/segments/paths, a11y, svg mocked. |
|
|
18
|
+
|
|
19
|
+
## Props
|
|
20
|
+
|
|
21
|
+
**BarList** — `items: { label, value, color?, icon?: ReactNode }[]`, `maxValue?` (defaults to the
|
|
22
|
+
largest item value), `onPressItem?(item, index)`, `style?: LayoutStyle`, `testID?`.
|
|
23
|
+
Bar fill defaults to `accent.solid`; per-item `color` exists for data-driven series (categorical
|
|
24
|
+
breakdowns have no closed-union role) — a deliberate, documented exception to the closed-union rule.
|
|
25
|
+
|
|
26
|
+
**DonutChart** — `segments: { value, color, label? }[]`, `size?` (160), `thickness?` (20),
|
|
27
|
+
`centerLabel?`, `centerSublabel?`, `style?`, `testID?`. Non-finite / ≤ 0 segment values are dropped;
|
|
28
|
+
with no valid segments only the `bg.sunken` track ring renders.
|
|
29
|
+
|
|
30
|
+
**Sparkline** — `data: number[]`, `width?` (120), `height?` (32),
|
|
31
|
+
`tone?: accent | neutral | success | warning | danger | info` (accent), `style?`, `testID?`.
|
|
32
|
+
Non-finite samples are dropped; a single sample draws a flat line; empty data renders an empty box.
|
|
33
|
+
|
|
34
|
+
## Accessibility
|
|
35
|
+
|
|
36
|
+
- Each BarList row is ONE accessible node announcing `"label, value"` (`text` role, or `button`
|
|
37
|
+
when `onPressItem` is set); the bar track is decorative and hidden from AT — the value text
|
|
38
|
+
already carries the information.
|
|
39
|
+
- Donut/sparkline graphics are hidden from AT (decorative, same contract as Timeline's connector);
|
|
40
|
+
DonutChart's center labels stay in the normal accessibility tree.
|
|
41
|
+
- BarList label (`fg.default`) and value (`fg.muted`) are measured ≥ 4.5:1 on the canvas for all
|
|
42
|
+
8 brands × both modes (`Charts.test.ts`).
|
|
43
|
+
|
|
44
|
+
## Known gaps
|
|
45
|
+
|
|
46
|
+
- Segment/bar `color` values come from the consumer — contrast of consumer-picked series colors
|
|
47
|
+
against the canvas is the consumer's to verify.
|
|
48
|
+
- No animation, no labels-on-arc, no axes — these are primitives, not a charting library.
|
|
49
|
+
|
|
50
|
+
## Performance
|
|
51
|
+
|
|
52
|
+
All three components wrapped in `React.memo` (root `CLAUDE.md` performance rule).
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { memo } from "react";
|
|
4
|
+
import { View } from "react-native";
|
|
5
|
+
import Svg, { Path } from "react-native-svg";
|
|
6
|
+
import { useTheme } from "../../theme/index.js";
|
|
7
|
+
import { resolveSparklineTone } from "./Charts.variants.js";
|
|
8
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
const STROKE_WIDTH = 2;
|
|
10
|
+
const AREA_OPACITY = 0.15;
|
|
11
|
+
function buildPaths(data, width, height) {
|
|
12
|
+
const clean = data.filter(value => Number.isFinite(value));
|
|
13
|
+
if (clean.length === 0) return undefined;
|
|
14
|
+
|
|
15
|
+
// A single sample still draws as a flat line across the full width.
|
|
16
|
+
const values = clean.length === 1 ? [clean[0], clean[0]] : clean;
|
|
17
|
+
const min = Math.min(...values);
|
|
18
|
+
const range = Math.max(...values) - min || 1;
|
|
19
|
+
const pad = STROKE_WIDTH / 2;
|
|
20
|
+
const drawable = Math.max(height - STROKE_WIDTH, 0);
|
|
21
|
+
const stepX = width / (values.length - 1);
|
|
22
|
+
const points = values.map((value, index) => {
|
|
23
|
+
const x = index * stepX;
|
|
24
|
+
const y = pad + drawable - (value - min) / range * drawable;
|
|
25
|
+
return `${round(x)} ${round(y)}`;
|
|
26
|
+
});
|
|
27
|
+
const line = `M ${points.join(" L ")}`;
|
|
28
|
+
const area = `${line} L ${round(width)} ${round(height)} L 0 ${round(height)} Z`;
|
|
29
|
+
return {
|
|
30
|
+
line,
|
|
31
|
+
area
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function round(value) {
|
|
35
|
+
return Math.round(value * 100) / 100;
|
|
36
|
+
}
|
|
37
|
+
export const Sparkline = /*#__PURE__*/memo(function Sparkline({
|
|
38
|
+
data,
|
|
39
|
+
width = 120,
|
|
40
|
+
height = 32,
|
|
41
|
+
tone = "accent",
|
|
42
|
+
style,
|
|
43
|
+
testID
|
|
44
|
+
}) {
|
|
45
|
+
const theme = useTheme();
|
|
46
|
+
const stroke = resolveSparklineTone(theme.colors, tone);
|
|
47
|
+
const paths = buildPaths(data, width, height);
|
|
48
|
+
return /*#__PURE__*/_jsx(View, {
|
|
49
|
+
testID: testID,
|
|
50
|
+
accessibilityElementsHidden: true,
|
|
51
|
+
importantForAccessibility: "no-hide-descendants",
|
|
52
|
+
style: [{
|
|
53
|
+
width,
|
|
54
|
+
height
|
|
55
|
+
}, style],
|
|
56
|
+
children: /*#__PURE__*/_jsx(Svg, {
|
|
57
|
+
width: width,
|
|
58
|
+
height: height,
|
|
59
|
+
children: paths !== undefined && /*#__PURE__*/_jsxs(_Fragment, {
|
|
60
|
+
children: [/*#__PURE__*/_jsx(Path, {
|
|
61
|
+
testID: testID === undefined ? undefined : `${testID}-area`,
|
|
62
|
+
d: paths.area,
|
|
63
|
+
fill: stroke,
|
|
64
|
+
fillOpacity: AREA_OPACITY,
|
|
65
|
+
stroke: "none"
|
|
66
|
+
}), /*#__PURE__*/_jsx(Path, {
|
|
67
|
+
testID: testID === undefined ? undefined : `${testID}-line`,
|
|
68
|
+
d: paths.line,
|
|
69
|
+
fill: "none",
|
|
70
|
+
stroke: stroke,
|
|
71
|
+
strokeWidth: STROKE_WIDTH,
|
|
72
|
+
strokeLinecap: "round",
|
|
73
|
+
strokeLinejoin: "round"
|
|
74
|
+
})]
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=Sparkline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["memo","View","Svg","Path","useTheme","resolveSparklineTone","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","STROKE_WIDTH","AREA_OPACITY","buildPaths","data","width","height","clean","filter","value","Number","isFinite","length","undefined","values","min","Math","range","max","pad","drawable","stepX","points","map","index","x","y","round","line","join","area","Sparkline","tone","style","testID","theme","stroke","colors","paths","accessibilityElementsHidden","importantForAccessibility","children","d","fill","fillOpacity","strokeWidth","strokeLinecap","strokeLinejoin"],"sourceRoot":"../../../../src","sources":["modules/charts/Sparkline.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Public surface of `pixelize-native-library/charts`. Value exports and type exports are split for
|
|
5
|
+
* `verbatimModuleSyntax`. The resolvers stay internal — a consumer configures a chart through its
|
|
6
|
+
* props, never by importing its internals.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export { BarList } from "./BarList.js";
|
|
10
|
+
export { DonutChart } from "./DonutChart.js";
|
|
11
|
+
export { Sparkline } from "./Sparkline.js";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["BarList","DonutChart","Sparkline"],"sourceRoot":"../../../../src","sources":["modules/charts/index.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,OAAO,QAAQ,cAAW;AAGnC,SAASC,UAAU,QAAQ,iBAAc;AAGzC,SAASC,SAAS,QAAQ,gBAAa","ignoreList":[]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { memo, useCallback } from "react";
|
|
4
|
+
import { Pressable, Text, View } from "react-native";
|
|
5
|
+
import { useTheme } from "../../theme/index.js";
|
|
6
|
+
import { listItemBodyStructure, listItemDotStructure, listItemStructure, resolveListItemAccessibility, resolveListItemColors } from "./ListItem.variants.js";
|
|
7
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
8
|
+
export const ListItem = /*#__PURE__*/memo(function ListItem({
|
|
9
|
+
leading,
|
|
10
|
+
title,
|
|
11
|
+
subtitle,
|
|
12
|
+
trailing,
|
|
13
|
+
unread = false,
|
|
14
|
+
onPress,
|
|
15
|
+
style,
|
|
16
|
+
testID
|
|
17
|
+
}) {
|
|
18
|
+
const theme = useTheme();
|
|
19
|
+
const colors = resolveListItemColors(theme.colors, unread);
|
|
20
|
+
const a11y = resolveListItemAccessibility({
|
|
21
|
+
title,
|
|
22
|
+
subtitle,
|
|
23
|
+
unread
|
|
24
|
+
});
|
|
25
|
+
const rootStyle = useCallback(({
|
|
26
|
+
pressed
|
|
27
|
+
}) => [listItemStructure(theme), {
|
|
28
|
+
backgroundColor: pressed ? colors.pressed : colors.background
|
|
29
|
+
}, style], [theme, colors, style]);
|
|
30
|
+
const body = /*#__PURE__*/_jsxs(_Fragment, {
|
|
31
|
+
children: [unread && /*#__PURE__*/_jsx(View, {
|
|
32
|
+
testID: testID === undefined ? undefined : `${testID}-dot`,
|
|
33
|
+
accessibilityElementsHidden: true,
|
|
34
|
+
importantForAccessibility: "no-hide-descendants",
|
|
35
|
+
style: [listItemDotStructure(theme), {
|
|
36
|
+
backgroundColor: colors.dot
|
|
37
|
+
}]
|
|
38
|
+
}), leading, /*#__PURE__*/_jsxs(View, {
|
|
39
|
+
style: listItemBodyStructure(theme),
|
|
40
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
41
|
+
numberOfLines: 1,
|
|
42
|
+
style: [theme.fontStyleForWeight(unread ? theme.fontWeights.semibold : theme.fontWeights.medium), {
|
|
43
|
+
fontSize: theme.fontSizes.md,
|
|
44
|
+
color: colors.title
|
|
45
|
+
}],
|
|
46
|
+
children: title
|
|
47
|
+
}), subtitle !== undefined && /*#__PURE__*/_jsx(Text, {
|
|
48
|
+
numberOfLines: 2,
|
|
49
|
+
style: [theme.fontStyleForWeight(theme.fontWeights.regular), {
|
|
50
|
+
fontSize: theme.fontSizes.sm,
|
|
51
|
+
color: colors.subtitle
|
|
52
|
+
}],
|
|
53
|
+
children: subtitle
|
|
54
|
+
})]
|
|
55
|
+
}), trailing]
|
|
56
|
+
});
|
|
57
|
+
if (onPress === undefined) {
|
|
58
|
+
return /*#__PURE__*/_jsx(View, {
|
|
59
|
+
testID: testID,
|
|
60
|
+
style: [listItemStructure(theme), {
|
|
61
|
+
backgroundColor: colors.background
|
|
62
|
+
}, style],
|
|
63
|
+
children: body
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return /*#__PURE__*/_jsx(Pressable, {
|
|
67
|
+
testID: testID,
|
|
68
|
+
accessibilityRole: "button",
|
|
69
|
+
accessibilityLabel: a11y.accessibilityLabel,
|
|
70
|
+
onPress: onPress,
|
|
71
|
+
style: rootStyle,
|
|
72
|
+
children: body
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=ListItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["memo","useCallback","Pressable","Text","View","useTheme","listItemBodyStructure","listItemDotStructure","listItemStructure","resolveListItemAccessibility","resolveListItemColors","jsx","_jsx","jsxs","_jsxs","Fragment","_Fragment","ListItem","leading","title","subtitle","trailing","unread","onPress","style","testID","theme","colors","a11y","rootStyle","pressed","backgroundColor","background","body","children","undefined","accessibilityElementsHidden","importantForAccessibility","dot","numberOfLines","fontStyleForWeight","fontWeights","semibold","medium","fontSize","fontSizes","md","color","regular","sm","accessibilityRole","accessibilityLabel"],"sourceRoot":"../../../../src","sources":["modules/list-item/ListItem.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pure resolvers for ListItem — no React, so the WCAG tests import this directly (mocking only
|
|
5
|
+
* `react-native`'s `StyleSheet`, as every sibling module's tests do).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createThemedVariants } from "../../core/style/index.js";
|
|
9
|
+
export const LIST_ITEM_DOT_SIZE = 8;
|
|
10
|
+
export const LIST_ITEM_MIN_HEIGHT = 44;
|
|
11
|
+
export function resolveListItemColors(colors, unread) {
|
|
12
|
+
return {
|
|
13
|
+
background: unread ? colors.bg.surface : undefined,
|
|
14
|
+
// NOT `bg.hover`: measured, `fg.default` falls to 3.87:1 against it on 4 of 8 light brands
|
|
15
|
+
// (lavender/radiant/skyline/rosewood) — `bg.sunken` clears AA everywhere (`ListItem.test.ts`).
|
|
16
|
+
pressed: colors.bg.sunken,
|
|
17
|
+
title: colors.fg.default,
|
|
18
|
+
subtitle: colors.fg.muted,
|
|
19
|
+
dot: colors.accent.solid
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function resolveListItemAccessibility(input) {
|
|
23
|
+
const parts = [input.title];
|
|
24
|
+
if (input.subtitle !== undefined) parts.push(input.subtitle);
|
|
25
|
+
if (input.unread) parts.push("unread");
|
|
26
|
+
return {
|
|
27
|
+
accessibilityLabel: parts.join(", ")
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export const listItemStructure = createThemedVariants(theme => ({
|
|
31
|
+
base: {
|
|
32
|
+
flexDirection: "row",
|
|
33
|
+
alignItems: "center",
|
|
34
|
+
columnGap: theme.space[3],
|
|
35
|
+
minHeight: LIST_ITEM_MIN_HEIGHT,
|
|
36
|
+
paddingVertical: theme.space[3],
|
|
37
|
+
paddingHorizontal: theme.space[4]
|
|
38
|
+
}
|
|
39
|
+
}));
|
|
40
|
+
export const listItemBodyStructure = createThemedVariants(theme => ({
|
|
41
|
+
base: {
|
|
42
|
+
flex: 1,
|
|
43
|
+
rowGap: theme.space[1]
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
export const listItemDotStructure = createThemedVariants(theme => ({
|
|
47
|
+
base: {
|
|
48
|
+
width: LIST_ITEM_DOT_SIZE,
|
|
49
|
+
height: LIST_ITEM_DOT_SIZE,
|
|
50
|
+
borderRadius: theme.radii.full
|
|
51
|
+
}
|
|
52
|
+
}));
|
|
53
|
+
//# sourceMappingURL=ListItem.variants.js.map
|