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.
Files changed (109) hide show
  1. package/lib/module/core/icon/index.js +68 -1
  2. package/lib/module/core/icon/index.js.map +1 -1
  3. package/lib/module/modules/bottom-nav/BottomNav.js +25 -15
  4. package/lib/module/modules/bottom-nav/BottomNav.js.map +1 -1
  5. package/lib/module/modules/bottom-nav/BottomNav.variants.js +65 -0
  6. package/lib/module/modules/bottom-nav/BottomNav.variants.js.map +1 -1
  7. package/lib/module/modules/bottom-nav/BottomNavIconWithBadge.js +75 -0
  8. package/lib/module/modules/bottom-nav/BottomNavIconWithBadge.js.map +1 -0
  9. package/lib/module/modules/bottom-nav/BottomNavOverflowSheet.js +13 -6
  10. package/lib/module/modules/bottom-nav/BottomNavOverflowSheet.js.map +1 -1
  11. package/lib/module/modules/bottom-nav/MODULE.md +25 -10
  12. package/lib/module/modules/charts/BarList.js +79 -0
  13. package/lib/module/modules/charts/BarList.js.map +1 -0
  14. package/lib/module/modules/charts/Charts.variants.js +59 -0
  15. package/lib/module/modules/charts/Charts.variants.js.map +1 -0
  16. package/lib/module/modules/charts/DonutChart.js +98 -0
  17. package/lib/module/modules/charts/DonutChart.js.map +1 -0
  18. package/lib/module/modules/charts/MODULE.md +52 -0
  19. package/lib/module/modules/charts/Sparkline.js +79 -0
  20. package/lib/module/modules/charts/Sparkline.js.map +1 -0
  21. package/lib/module/modules/charts/index.js +12 -0
  22. package/lib/module/modules/charts/index.js.map +1 -0
  23. package/lib/module/modules/list-item/ListItem.js +75 -0
  24. package/lib/module/modules/list-item/ListItem.js.map +1 -0
  25. package/lib/module/modules/list-item/ListItem.variants.js +53 -0
  26. package/lib/module/modules/list-item/ListItem.variants.js.map +1 -0
  27. package/lib/module/modules/list-item/MODULE.md +47 -0
  28. package/lib/module/modules/list-item/index.js +10 -0
  29. package/lib/module/modules/list-item/index.js.map +1 -0
  30. package/lib/module/modules/markdown/MODULE.md +44 -0
  31. package/lib/module/modules/markdown/Markdown.js +149 -0
  32. package/lib/module/modules/markdown/Markdown.js.map +1 -0
  33. package/lib/module/modules/markdown/Markdown.variants.js +68 -0
  34. package/lib/module/modules/markdown/Markdown.variants.js.map +1 -0
  35. package/lib/module/modules/markdown/index.js +11 -0
  36. package/lib/module/modules/markdown/index.js.map +1 -0
  37. package/lib/module/modules/markdown/parseMarkdown.js +153 -0
  38. package/lib/module/modules/markdown/parseMarkdown.js.map +1 -0
  39. package/lib/module/modules/multi-select/MODULE.md +1 -1
  40. package/lib/module/modules/multi-select/MultiSelect.js +1 -1
  41. package/lib/module/modules/multi-select/MultiSelect.js.map +1 -1
  42. package/lib/module/modules/select/MODULE.md +1 -1
  43. package/lib/module/modules/select/Select.js +13 -10
  44. package/lib/module/modules/select/Select.js.map +1 -1
  45. package/lib/module/modules/select/Select.variants.js +11 -0
  46. package/lib/module/modules/select/Select.variants.js.map +1 -1
  47. package/lib/module/modules/stat-tile/MODULE.md +44 -0
  48. package/lib/module/modules/stat-tile/StatTile.js +87 -0
  49. package/lib/module/modules/stat-tile/StatTile.js.map +1 -0
  50. package/lib/module/modules/stat-tile/StatTile.variants.js +55 -0
  51. package/lib/module/modules/stat-tile/StatTile.variants.js.map +1 -0
  52. package/lib/module/modules/stat-tile/index.js +10 -0
  53. package/lib/module/modules/stat-tile/index.js.map +1 -0
  54. package/lib/module/modules/timeline/MODULE.md +10 -1
  55. package/lib/module/modules/timeline/Timeline.js +4 -1
  56. package/lib/module/modules/timeline/Timeline.js.map +1 -1
  57. package/lib/module/theme/tokens/builders/accentText.js +9 -0
  58. package/lib/module/theme/tokens/builders/accentText.js.map +1 -1
  59. package/lib/typescript/core/icon/index.d.ts +38 -1
  60. package/lib/typescript/core/icon/index.d.ts.map +1 -1
  61. package/lib/typescript/modules/bottom-nav/BottomNav.d.ts +5 -1
  62. package/lib/typescript/modules/bottom-nav/BottomNav.d.ts.map +1 -1
  63. package/lib/typescript/modules/bottom-nav/BottomNav.variants.d.ts +50 -0
  64. package/lib/typescript/modules/bottom-nav/BottomNav.variants.d.ts.map +1 -1
  65. package/lib/typescript/modules/bottom-nav/BottomNavIconWithBadge.d.ts +25 -0
  66. package/lib/typescript/modules/bottom-nav/BottomNavIconWithBadge.d.ts.map +1 -0
  67. package/lib/typescript/modules/bottom-nav/BottomNavOverflowSheet.d.ts.map +1 -1
  68. package/lib/typescript/modules/charts/BarList.d.ts +18 -0
  69. package/lib/typescript/modules/charts/BarList.d.ts.map +1 -0
  70. package/lib/typescript/modules/charts/Charts.variants.d.ts +26 -0
  71. package/lib/typescript/modules/charts/Charts.variants.d.ts.map +1 -0
  72. package/lib/typescript/modules/charts/DonutChart.d.ts +18 -0
  73. package/lib/typescript/modules/charts/DonutChart.d.ts.map +1 -0
  74. package/lib/typescript/modules/charts/Sparkline.d.ts +13 -0
  75. package/lib/typescript/modules/charts/Sparkline.d.ts.map +1 -0
  76. package/lib/typescript/modules/charts/index.d.ts +13 -0
  77. package/lib/typescript/modules/charts/index.d.ts.map +1 -0
  78. package/lib/typescript/modules/list-item/ListItem.d.ts +15 -0
  79. package/lib/typescript/modules/list-item/ListItem.d.ts.map +1 -0
  80. package/lib/typescript/modules/list-item/ListItem.variants.d.ts +29 -0
  81. package/lib/typescript/modules/list-item/ListItem.variants.d.ts.map +1 -0
  82. package/lib/typescript/modules/list-item/index.d.ts +8 -0
  83. package/lib/typescript/modules/list-item/index.d.ts.map +1 -0
  84. package/lib/typescript/modules/markdown/Markdown.d.ts +10 -0
  85. package/lib/typescript/modules/markdown/Markdown.d.ts.map +1 -0
  86. package/lib/typescript/modules/markdown/Markdown.variants.d.ts +27 -0
  87. package/lib/typescript/modules/markdown/Markdown.variants.d.ts.map +1 -0
  88. package/lib/typescript/modules/markdown/index.d.ts +10 -0
  89. package/lib/typescript/modules/markdown/index.d.ts.map +1 -0
  90. package/lib/typescript/modules/markdown/parseMarkdown.d.ts +43 -0
  91. package/lib/typescript/modules/markdown/parseMarkdown.d.ts.map +1 -0
  92. package/lib/typescript/modules/multi-select/MultiSelect.d.ts +6 -0
  93. package/lib/typescript/modules/multi-select/MultiSelect.d.ts.map +1 -1
  94. package/lib/typescript/modules/select/Select.d.ts +6 -0
  95. package/lib/typescript/modules/select/Select.d.ts.map +1 -1
  96. package/lib/typescript/modules/select/Select.variants.d.ts +3 -0
  97. package/lib/typescript/modules/select/Select.variants.d.ts.map +1 -1
  98. package/lib/typescript/modules/stat-tile/StatTile.d.ts +16 -0
  99. package/lib/typescript/modules/stat-tile/StatTile.d.ts.map +1 -0
  100. package/lib/typescript/modules/stat-tile/StatTile.variants.d.ts +34 -0
  101. package/lib/typescript/modules/stat-tile/StatTile.variants.d.ts.map +1 -0
  102. package/lib/typescript/modules/stat-tile/index.d.ts +9 -0
  103. package/lib/typescript/modules/stat-tile/index.d.ts.map +1 -0
  104. package/lib/typescript/modules/timeline/Timeline.d.ts +4 -0
  105. package/lib/typescript/modules/timeline/Timeline.d.ts.map +1 -1
  106. package/lib/typescript/theme/tokens/builders/accentText.d.ts +6 -0
  107. package/lib/typescript/theme/tokens/builders/accentText.d.ts.map +1 -1
  108. package/package.json +22 -1
  109. 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
- | `BottomNav.variants.ts` | Pure resolvers (`resolveBottomNavTabColors`, `resolveBottomNavAccessibility`, `resolveEditRowState`, `resolveBottomNavBottomInset`, `resolveOverflowSheetHeight`) + themed structural resolvers (`bottomNavBarStructure`, `bottomNavTabStructure`, `overflowRowStructure`, `overflowSectionHeaderStructure`, `editRowStructure`). No React, no lucide. |
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 caller who never passes them keeps
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. E.g. an unread-count badge lands as
144
- `BottomNavDestination.badge?: { count: number }`; a compact bar lands as `size?: "regular" |
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