panelui-native 0.22.5 → 0.25.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.
Files changed (135) hide show
  1. package/README.md +8 -3
  2. package/lib/module/components/area-chart/index.js +826 -0
  3. package/lib/module/components/area-chart/index.js.map +1 -0
  4. package/lib/module/components/avatar/index.js +1 -1
  5. package/lib/module/components/avatar/index.js.map +1 -1
  6. package/lib/module/components/bar-chart/index.js +853 -0
  7. package/lib/module/components/bar-chart/index.js.map +1 -0
  8. package/lib/module/components/bottom-sheet/index.js +207 -23
  9. package/lib/module/components/bottom-sheet/index.js.map +1 -1
  10. package/lib/module/components/breadcrumb/index.js +275 -0
  11. package/lib/module/components/breadcrumb/index.js.map +1 -0
  12. package/lib/module/components/chip/index.js +2 -2
  13. package/lib/module/components/direction/index.js +13 -19
  14. package/lib/module/components/direction/index.js.map +1 -1
  15. package/lib/module/components/frame/index.js +17 -0
  16. package/lib/module/components/frame/index.js.map +1 -1
  17. package/lib/module/components/heatmap-chart/index.js +28 -8
  18. package/lib/module/components/heatmap-chart/index.js.map +1 -1
  19. package/lib/module/components/input-group/index.js +2 -2
  20. package/lib/module/components/input-group/index.js.map +1 -1
  21. package/lib/module/components/line-chart/index.js +4 -146
  22. package/lib/module/components/line-chart/index.js.map +1 -1
  23. package/lib/module/components/loader/index.js +758 -0
  24. package/lib/module/components/loader/index.js.map +1 -0
  25. package/lib/module/components/map/basemap.js +265 -0
  26. package/lib/module/components/map/basemap.js.map +1 -0
  27. package/lib/module/components/map/index.js +850 -0
  28. package/lib/module/components/map/index.js.map +1 -0
  29. package/lib/module/components/map/maplibre.js +87 -0
  30. package/lib/module/components/map/maplibre.js.map +1 -0
  31. package/lib/module/components/message/index.js +8 -7
  32. package/lib/module/components/message/index.js.map +1 -1
  33. package/lib/module/components/otp-input/index.js +2 -2
  34. package/lib/module/components/progress/index.js +8 -2
  35. package/lib/module/components/progress/index.js.map +1 -1
  36. package/lib/module/components/ring-chart/index.js +423 -0
  37. package/lib/module/components/ring-chart/index.js.map +1 -0
  38. package/lib/module/components/section-rail/index.js +2 -2
  39. package/lib/module/components/separator/index.js +76 -22
  40. package/lib/module/components/separator/index.js.map +1 -1
  41. package/lib/module/components/shimmer/index.js +10 -1
  42. package/lib/module/components/shimmer/index.js.map +1 -1
  43. package/lib/module/components/slider/index.js +19 -5
  44. package/lib/module/components/slider/index.js.map +1 -1
  45. package/lib/module/components/steps/index.js +1 -1
  46. package/lib/module/components/switch/index.js +6 -1
  47. package/lib/module/components/switch/index.js.map +1 -1
  48. package/lib/module/components/typography/index.js +5 -0
  49. package/lib/module/components/typography/index.js.map +1 -1
  50. package/lib/module/hooks/use-direction.js +43 -0
  51. package/lib/module/hooks/use-direction.js.map +1 -0
  52. package/lib/module/icons/index.js +117 -2
  53. package/lib/module/icons/index.js.map +1 -1
  54. package/lib/module/index.js +8 -2
  55. package/lib/module/index.js.map +1 -1
  56. package/lib/module/primitives/text.js +30 -10
  57. package/lib/module/primitives/text.js.map +1 -1
  58. package/lib/module/utils/chart.js +279 -0
  59. package/lib/module/utils/chart.js.map +1 -0
  60. package/lib/typescript/src/components/area-chart/index.d.ts +197 -0
  61. package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -0
  62. package/lib/typescript/src/components/bar-chart/index.d.ts +228 -0
  63. package/lib/typescript/src/components/bar-chart/index.d.ts.map +1 -0
  64. package/lib/typescript/src/components/bottom-sheet/index.d.ts +75 -4
  65. package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
  66. package/lib/typescript/src/components/breadcrumb/index.d.ts +100 -0
  67. package/lib/typescript/src/components/breadcrumb/index.d.ts.map +1 -0
  68. package/lib/typescript/src/components/direction/index.d.ts +11 -10
  69. package/lib/typescript/src/components/direction/index.d.ts.map +1 -1
  70. package/lib/typescript/src/components/frame/index.d.ts +17 -0
  71. package/lib/typescript/src/components/frame/index.d.ts.map +1 -1
  72. package/lib/typescript/src/components/heatmap-chart/index.d.ts +22 -3
  73. package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
  74. package/lib/typescript/src/components/line-chart/index.d.ts +1 -0
  75. package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
  76. package/lib/typescript/src/components/loader/index.d.ts +38 -0
  77. package/lib/typescript/src/components/loader/index.d.ts.map +1 -0
  78. package/lib/typescript/src/components/map/basemap.d.ts +76 -0
  79. package/lib/typescript/src/components/map/basemap.d.ts.map +1 -0
  80. package/lib/typescript/src/components/map/index.d.ts +367 -0
  81. package/lib/typescript/src/components/map/index.d.ts.map +1 -0
  82. package/lib/typescript/src/components/map/maplibre.d.ts +193 -0
  83. package/lib/typescript/src/components/map/maplibre.d.ts.map +1 -0
  84. package/lib/typescript/src/components/message/index.d.ts.map +1 -1
  85. package/lib/typescript/src/components/progress/index.d.ts.map +1 -1
  86. package/lib/typescript/src/components/ring-chart/index.d.ts +156 -0
  87. package/lib/typescript/src/components/ring-chart/index.d.ts.map +1 -0
  88. package/lib/typescript/src/components/separator/index.d.ts +36 -1
  89. package/lib/typescript/src/components/separator/index.d.ts.map +1 -1
  90. package/lib/typescript/src/components/shimmer/index.d.ts.map +1 -1
  91. package/lib/typescript/src/components/slider/index.d.ts.map +1 -1
  92. package/lib/typescript/src/components/switch/index.d.ts.map +1 -1
  93. package/lib/typescript/src/components/typography/index.d.ts +6 -0
  94. package/lib/typescript/src/components/typography/index.d.ts.map +1 -1
  95. package/lib/typescript/src/hooks/use-direction.d.ts +20 -0
  96. package/lib/typescript/src/hooks/use-direction.d.ts.map +1 -0
  97. package/lib/typescript/src/icons/index.d.ts +5 -0
  98. package/lib/typescript/src/icons/index.d.ts.map +1 -1
  99. package/lib/typescript/src/index.d.ts +9 -3
  100. package/lib/typescript/src/index.d.ts.map +1 -1
  101. package/lib/typescript/src/primitives/text.d.ts.map +1 -1
  102. package/lib/typescript/src/utils/chart.d.ts +96 -0
  103. package/lib/typescript/src/utils/chart.d.ts.map +1 -0
  104. package/package.json +9 -1
  105. package/src/components/area-chart/index.tsx +994 -0
  106. package/src/components/avatar/index.tsx +1 -1
  107. package/src/components/bar-chart/index.tsx +1048 -0
  108. package/src/components/bottom-sheet/index.tsx +280 -20
  109. package/src/components/breadcrumb/index.tsx +365 -0
  110. package/src/components/chip/index.tsx +2 -2
  111. package/src/components/direction/index.tsx +20 -21
  112. package/src/components/frame/index.tsx +17 -0
  113. package/src/components/heatmap-chart/index.tsx +58 -11
  114. package/src/components/input-group/index.tsx +2 -2
  115. package/src/components/line-chart/index.tsx +13 -181
  116. package/src/components/loader/index.tsx +812 -0
  117. package/src/components/map/basemap.ts +304 -0
  118. package/src/components/map/index.tsx +1118 -0
  119. package/src/components/map/maplibre.ts +201 -0
  120. package/src/components/message/index.tsx +8 -7
  121. package/src/components/otp-input/index.tsx +2 -2
  122. package/src/components/progress/index.tsx +10 -2
  123. package/src/components/ring-chart/index.tsx +543 -0
  124. package/src/components/section-rail/index.tsx +2 -2
  125. package/src/components/separator/index.tsx +77 -19
  126. package/src/components/shimmer/index.tsx +10 -1
  127. package/src/components/slider/index.tsx +20 -5
  128. package/src/components/steps/index.tsx +1 -1
  129. package/src/components/switch/index.tsx +6 -1
  130. package/src/components/typography/index.tsx +5 -0
  131. package/src/hooks/use-direction.ts +45 -0
  132. package/src/icons/index.tsx +66 -0
  133. package/src/index.ts +84 -0
  134. package/src/primitives/text.tsx +25 -7
  135. package/src/utils/chart.ts +355 -0
@@ -34,6 +34,7 @@ import Animated, {
34
34
  withTiming,
35
35
  } from 'react-native-reanimated';
36
36
  import { useCSSVariable } from 'uniwind';
37
+ import { useDirectionSign } from '../../hooks/use-direction';
37
38
  import { Text } from '../../primitives/text';
38
39
  import { cn } from '../../utils/cn';
39
40
 
@@ -97,6 +98,8 @@ export function Shimmer({
97
98
  const [width, setWidth] = useState(0);
98
99
  const progress = useSharedValue(0);
99
100
  const reducedMotion = useReducedMotion();
101
+ // The sweep follows the reading direction; `reverse` then flips it again.
102
+ const sign = useDirectionSign();
100
103
 
101
104
  const themeMuted = useCSSVariable('--color-muted-foreground');
102
105
  const themeForeground = useCSSVariable('--color-foreground');
@@ -134,7 +137,13 @@ export function Shimmer({
134
137
  // Travel from fully off one edge to fully off the other.
135
138
  const from = -bandWidth;
136
139
  const to = width;
137
- const x = reverse
140
+ /*
141
+ * The sweep follows the reading direction. It is standing in for text
142
+ * arriving, and text arrives from the side you start reading on — a band
143
+ * travelling against the script reads as something leaving.
144
+ */
145
+ const backwards = reverse !== (sign === -1);
146
+ const x = backwards
138
147
  ? to - progress.value * (to - from)
139
148
  : from + progress.value * (to - from);
140
149
  return { transform: [{ translateX: x }] };
@@ -34,6 +34,7 @@ import Animated, {
34
34
  withSpring,
35
35
  } from 'react-native-reanimated';
36
36
  import { tv, type VariantProps } from 'tailwind-variants';
37
+ import { useDirectionSign } from '../../hooks/use-direction';
37
38
  import { getNativeUI } from '../../native';
38
39
  import { Text } from '../../primitives/text';
39
40
  import { selectionTick } from '../../utils/haptics';
@@ -60,8 +61,8 @@ const sliderVariants = tv({
60
61
  // The track is the full height of the control, so the thumb has somewhere
61
62
  // to sit rather than somewhere to stick out of.
62
63
  track: 'w-full justify-center rounded-full bg-muted',
63
- fill: 'absolute bottom-0 left-0 top-0 rounded-full',
64
- thumb: 'absolute left-0 rounded-full p-0.5',
64
+ fill: 'absolute bottom-0 start-0 top-0 rounded-full',
65
+ thumb: 'absolute start-0 rounded-full p-0.5',
65
66
  // `background`, not a per-colour on-token: the status foregrounds are the
66
67
  // darker text hues meant for soft fills, so a green-700 knob on a green-500
67
68
  // pill would barely show. The page background reads against every fill in
@@ -193,6 +194,9 @@ export const Slider = forwardRef<View, SliderProps>(
193
194
 
194
195
  // Measured on layout; the thumb travels across (trackWidth - thumbWidth) so
195
196
  // it stays inside the track at both ends.
197
+ // `1` left to right, `-1` right to left. Everything below that is a raw
198
+ // pixel offset rather than a laid-out box multiplies through it.
199
+ const sign = useDirectionSign();
196
200
  const trackWidth = useSharedValue(0);
197
201
  // Fraction 0..1 that drives the fill and the thumb, animated on the UI thread.
198
202
  const progress = useSharedValue(max > min ? (value - min) / (max - min) : 0);
@@ -253,7 +257,12 @@ export const Slider = forwardRef<View, SliderProps>(
253
257
  })
254
258
  .onUpdate((event) => {
255
259
  const travel = Math.max(trackWidth.value - thumbWidth, 1);
256
- const delta = event.translationX / travel;
260
+ /*
261
+ * Yoga mirrors the track but not a translation: a finger moving right
262
+ * in a right-to-left subtree is moving *back* along the scale, and
263
+ * without the sign the thumb runs away from the finger.
264
+ */
265
+ const delta = (event.translationX * sign) / travel;
257
266
  const next = Math.min(Math.max(startProgress.value + delta, 0), 1);
258
267
  progress.value = next;
259
268
  runOnJS(commitFromProgress)(next, false);
@@ -268,7 +277,11 @@ export const Slider = forwardRef<View, SliderProps>(
268
277
  .maxDuration(250)
269
278
  .onEnd((event) => {
270
279
  const travel = Math.max(trackWidth.value - thumbWidth, 1);
271
- const next = Math.min(Math.max((event.x - thumbWidth / 2) / travel, 0), 1);
280
+ // `event.x` is measured from the physical left edge either way, so
281
+ // right-to-left counts back from the far end of the track.
282
+ const along =
283
+ sign === 1 ? event.x : trackWidth.value - event.x;
284
+ const next = Math.min(Math.max((along - thumbWidth / 2) / travel, 0), 1);
272
285
  progress.value = withSpring(next, SPRING);
273
286
  runOnJS(commitFromProgress)(next, true);
274
287
  });
@@ -284,7 +297,9 @@ export const Slider = forwardRef<View, SliderProps>(
284
297
 
285
298
  const thumbStyle = useAnimatedStyle(() => {
286
299
  const travel = Math.max(trackWidth.value - thumbWidth, 0);
287
- return { transform: [{ translateX: progress.value * travel }] };
300
+ // A transform is not laid out, so Yoga does not mirror it — the thumb
301
+ // has to travel the other way itself.
302
+ return { transform: [{ translateX: progress.value * travel * sign }] };
288
303
  });
289
304
 
290
305
  const knobStyle = useAnimatedStyle(() => ({
@@ -53,7 +53,7 @@ const stepsVariants = tv({
53
53
  vertical: {
54
54
  root: 'flex-col',
55
55
  item: 'flex-col items-start',
56
- separator: 'ml-3.5 h-8 w-0.5',
56
+ separator: 'ms-3.5 h-8 w-0.5',
57
57
  },
58
58
  },
59
59
  state: {
@@ -7,6 +7,7 @@ import Animated, {
7
7
  withSpring,
8
8
  } from 'react-native-reanimated';
9
9
  import { tv, type VariantProps } from 'tailwind-variants';
10
+ import { useDirectionSign } from '../../hooks/use-direction';
10
11
  import { getNativeUI } from '../../native';
11
12
  import { selectionTick } from '../../utils/haptics';
12
13
 
@@ -68,6 +69,10 @@ export const Switch = forwardRef<View, SwitchProps>(
68
69
  ref
69
70
  ) => {
70
71
  const progress = useSharedValue(value ? 1 : 0);
72
+ // The track is mirrored by Yoga, but a transform is not — so "on" would
73
+ // otherwise still be on the right in a right-to-left subtree, which reads
74
+ // as the toggle running backwards.
75
+ const sign = useDirectionSign();
71
76
  const nativeUI = native ? getNativeUI() : null;
72
77
  const slots = switchVariants({ size, disabled: !!disabled });
73
78
 
@@ -77,7 +82,7 @@ export const Switch = forwardRef<View, SwitchProps>(
77
82
 
78
83
  const thumbStyle = useAnimatedStyle(() => ({
79
84
  transform: [
80
- { translateX: interpolate(progress.value, [0, 1], [0, TRAVEL[size]]) },
85
+ { translateX: interpolate(progress.value, [0, 1], [0, TRAVEL[size] * sign]) },
81
86
  ],
82
87
  }));
83
88
 
@@ -57,6 +57,11 @@ const typographyVariants = tv({
57
57
  bold: 'font-bold',
58
58
  },
59
59
  align: {
60
+ // `start` and `end` follow the reading direction; `left` and `right`
61
+ // are the physical edges, for the rare line that has to stay put
62
+ // whichever way the script runs — a figure in a table, a code caption.
63
+ start: 'text-start',
64
+ end: 'text-end',
60
65
  left: 'text-left',
61
66
  center: 'text-center',
62
67
  right: 'text-right',
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The reading direction in force.
3
+ *
4
+ * The context lives here rather than beside the `Direction` component so that
5
+ * anything can read it cheaply. `Text` in particular has to: `direction` is a
6
+ * Yoga *layout* property, and React Native resolves a paragraph's alignment
7
+ * from the process-wide `I18nManager.isRTL` instead — so without this, an
8
+ * Arabic paragraph inside `<Direction dir="rtl">` mirrors the furniture around
9
+ * it and then sits left-aligned inside it.
10
+ *
11
+ * Keeping it in a hook also keeps the dependency the right way round: a
12
+ * component that only needs to know the direction pulls in a hook, not the
13
+ * whole provider.
14
+ */
15
+ import { createContext, useContext } from 'react';
16
+ import { I18nManager } from 'react-native';
17
+
18
+ export type DirectionValue = 'ltr' | 'rtl';
19
+
20
+ /** What the device is set to, for anything outside a provider. */
21
+ export const deviceDirection = (): DirectionValue =>
22
+ I18nManager.isRTL ? 'rtl' : 'ltr';
23
+
24
+ export const DirectionContext = createContext<DirectionValue | null>(null);
25
+
26
+ /**
27
+ * The reading direction in force, for a component that has to flip maths Yoga
28
+ * cannot flip for it. Safe with no provider mounted: it falls back to the
29
+ * device's own setting.
30
+ */
31
+ export function useDirection(): DirectionValue {
32
+ return useContext(DirectionContext) ?? deviceDirection();
33
+ }
34
+
35
+ /**
36
+ * `-1` in a right-to-left subtree, `1` otherwise.
37
+ *
38
+ * The form most of the pixel maths actually wants. A drag translation, an
39
+ * indicator offset and a sweep are all a number that has to change sign, and
40
+ * writing `dir === 'rtl' ? -x : x` at every one of them is where the sign
41
+ * errors live.
42
+ */
43
+ export function useDirectionSign(): 1 | -1 {
44
+ return useDirection() === 'rtl' ? -1 : 1;
45
+ }
@@ -18,6 +18,7 @@
18
18
  */
19
19
  import { createContext, useContext, type ReactNode } from 'react';
20
20
  import Svg, { Circle, G, Path, type SvgProps } from 'react-native-svg';
21
+ import { useDirection } from '../hooks/use-direction';
21
22
 
22
23
  export interface IconProps extends SvgProps {
23
24
  size?: number;
@@ -117,8 +118,26 @@ export function ChevronDownIcon({ size = 16, color, ...props }: IconProps) {
117
118
  );
118
119
  }
119
120
 
121
+ /**
122
+ * Mirrors a directional glyph in a right-to-left subtree.
123
+ *
124
+ * Yoga moves a chevron to the other end of its row, but it cannot turn the
125
+ * glyph around — so an RTL list row ends up with a right-pointing chevron on
126
+ * its left edge, pointing back at the text. These arrows mean "onward" and
127
+ * "back", and which way that is depends on which way you read.
128
+ *
129
+ * Only for glyphs whose meaning *is* a direction. An icon that happens to be
130
+ * asymmetric — a pencil, a magnifier — means the same thing either way round,
131
+ * and flipping it is just a wrong drawing.
132
+ */
133
+ function useFlip(): { transform?: string } {
134
+ const rtl = useDirection() === 'rtl';
135
+ return rtl ? { transform: 'scale(-1 1) translate(-24 0)' } : {};
136
+ }
137
+
120
138
  export function ChevronLeftIcon({ size = 16, color, ...props }: IconProps) {
121
139
  const resolved = useResolvedColor(color, '#737373');
140
+ const flip = useFlip();
122
141
  return (
123
142
  <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
124
143
  <Path
@@ -127,6 +146,7 @@ export function ChevronLeftIcon({ size = 16, color, ...props }: IconProps) {
127
146
  strokeWidth={2}
128
147
  strokeLinecap="round"
129
148
  strokeLinejoin="round"
149
+ {...flip}
130
150
  />
131
151
  </Svg>
132
152
  );
@@ -134,6 +154,7 @@ export function ChevronLeftIcon({ size = 16, color, ...props }: IconProps) {
134
154
 
135
155
  export function ChevronRightIcon({ size = 16, color, ...props }: IconProps) {
136
156
  const resolved = useResolvedColor(color, '#737373');
157
+ const flip = useFlip();
137
158
  return (
138
159
  <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
139
160
  <Path
@@ -142,11 +163,23 @@ export function ChevronRightIcon({ size = 16, color, ...props }: IconProps) {
142
163
  strokeWidth={2}
143
164
  strokeLinecap="round"
144
165
  strokeLinejoin="round"
166
+ {...flip}
145
167
  />
146
168
  </Svg>
147
169
  );
148
170
  }
149
171
 
172
+ export function EllipsisIcon({ size = 16, color, ...props }: IconProps) {
173
+ const resolved = useResolvedColor(color, '#737373');
174
+ return (
175
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
176
+ <Circle cx={5} cy={12} r={1.6} fill={resolved} />
177
+ <Circle cx={12} cy={12} r={1.6} fill={resolved} />
178
+ <Circle cx={19} cy={12} r={1.6} fill={resolved} />
179
+ </Svg>
180
+ );
181
+ }
182
+
150
183
  export function XIcon({ size = 16, color, ...props }: IconProps) {
151
184
  const resolved = useResolvedColor(color, '#737373');
152
185
  return (
@@ -720,6 +753,39 @@ export function MaximizeIcon({ size = 16, color, ...props }: IconProps) {
720
753
  );
721
754
  }
722
755
 
756
+ /** Crosshairs on a centre dot — put me where I actually am. */
757
+ export function CrosshairIcon({ size = 16, color, ...props }: IconProps) {
758
+ const resolved = useResolvedColor(color, '#737373');
759
+ return (
760
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
761
+ <Circle cx={12} cy={12} r={7} stroke={resolved} strokeWidth={2} />
762
+ <Path
763
+ d="M12 2v3M12 19v3M2 12h3M19 12h3"
764
+ stroke={resolved}
765
+ strokeWidth={2}
766
+ strokeLinecap="round"
767
+ />
768
+ <Circle cx={12} cy={12} r={1.5} fill={resolved} />
769
+ </Svg>
770
+ );
771
+ }
772
+
773
+ /** A compass needle — which way is north. */
774
+ export function CompassIcon({ size = 16, color, ...props }: IconProps) {
775
+ const resolved = useResolvedColor(color, '#737373');
776
+ return (
777
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
778
+ <Circle cx={12} cy={12} r={9} stroke={resolved} strokeWidth={2} />
779
+ <Path
780
+ d="M15.5 8.5l-2 5-5 2 2-5 5-2z"
781
+ stroke={resolved}
782
+ strokeWidth={2}
783
+ strokeLinejoin="round"
784
+ />
785
+ </Svg>
786
+ );
787
+ }
788
+
723
789
  /** A closed padlock — the thing behind it cannot be moved. */
724
790
  export function LockIcon({ size = 16, color, ...props }: IconProps) {
725
791
  const resolved = useResolvedColor(color, '#737373');
package/src/index.ts CHANGED
@@ -73,12 +73,54 @@ export {
73
73
  type AttachmentActionProps,
74
74
  type AttachmentState,
75
75
  } from './components/attachment';
76
+ export {
77
+ AreaChart,
78
+ useAreaChart,
79
+ type AreaChartProps,
80
+ type AreaChartHandle,
81
+ type AreaChartGridProps,
82
+ type AreaChartAreaProps,
83
+ type AreaChartXAxisProps,
84
+ type AreaChartYAxisProps,
85
+ type AreaChartTooltipProps,
86
+ type AreaChartLegendProps,
87
+ type AreaChartDatum,
88
+ type AreaChartStatus,
89
+ } from './components/area-chart';
76
90
  export { Badge, type BadgeProps } from './components/badge';
91
+ export {
92
+ BarChart,
93
+ useBarChart,
94
+ type BarChartProps,
95
+ type BarChartHandle,
96
+ type BarChartGridProps,
97
+ type BarChartBarProps,
98
+ type BarChartXAxisProps,
99
+ type BarChartYAxisProps,
100
+ type BarChartTooltipProps,
101
+ type BarChartLegendProps,
102
+ type BarChartDatum,
103
+ type BarChartStatus,
104
+ type BarChartOrientation,
105
+ } from './components/bar-chart';
77
106
  export {
78
107
  BottomSheet,
79
108
  type BottomSheetProps,
80
109
  type BottomSheetContentProps,
110
+ type BottomSheetHeaderProps,
111
+ type BottomSheetBodyProps,
112
+ type BottomSheetFooterProps,
81
113
  } from './components/bottom-sheet';
114
+ export {
115
+ Breadcrumb,
116
+ type BreadcrumbProps,
117
+ type BreadcrumbListProps,
118
+ type BreadcrumbItemProps,
119
+ type BreadcrumbLinkProps,
120
+ type BreadcrumbPageProps,
121
+ type BreadcrumbSeparatorProps,
122
+ type BreadcrumbEllipsisProps,
123
+ } from './components/breadcrumb';
82
124
  export { Button, type ButtonProps } from './components/button';
83
125
  export {
84
126
  ToggleButton,
@@ -105,6 +147,7 @@ export {
105
147
  export {
106
148
  Direction,
107
149
  useDirection,
150
+ useDirectionSign,
108
151
  type DirectionProps,
109
152
  type DirectionValue,
110
153
  } from './components/direction';
@@ -156,6 +199,30 @@ export {
156
199
  type HeatmapCell,
157
200
  type HeatmapLayout,
158
201
  } from './components/heatmap-chart';
202
+ export {
203
+ Map,
204
+ useMap,
205
+ hasMapLibre,
206
+ CARTO_SOURCE,
207
+ type MapProps,
208
+ type MapHandle,
209
+ type MapMarkerProps,
210
+ type MapLabelProps,
211
+ type MapPopupProps,
212
+ type MapControlsProps,
213
+ type MapControlsPosition,
214
+ type MapRouteProps,
215
+ type MapArcProps,
216
+ type MapGeoJSONProps,
217
+ type MapClusterProps,
218
+ type MapHeatmapProps,
219
+ type MapUserLocationProps,
220
+ type BasemapSource,
221
+ type BasemapTokens,
222
+ type LngLat,
223
+ type LngLatBounds,
224
+ type ViewState,
225
+ } from './components/map';
159
226
  export {
160
227
  Select,
161
228
  type SelectProps,
@@ -264,6 +331,12 @@ export {
264
331
  type LineChartStatus,
265
332
  type LineChartCurve,
266
333
  } from './components/line-chart';
334
+ export {
335
+ Loader,
336
+ type LoaderProps,
337
+ type LoaderVariant,
338
+ type LoaderSize,
339
+ } from './components/loader';
267
340
  export {
268
341
  Marker,
269
342
  type MarkerProps,
@@ -316,6 +389,16 @@ export {
316
389
  type RatingColor,
317
390
  type RatingSize,
318
391
  } from './components/rating';
392
+ export {
393
+ RingChart,
394
+ useRingChart,
395
+ type RingChartProps,
396
+ type RingChartHandle,
397
+ type RingChartRingProps,
398
+ type RingChartCenterProps,
399
+ type RingChartLegendProps,
400
+ type RingDatum,
401
+ } from './components/ring-chart';
319
402
  export {
320
403
  ScrollFade,
321
404
  type ScrollFadeProps,
@@ -409,6 +492,7 @@ export {
409
492
  ChevronLeftIcon,
410
493
  ChevronRightIcon,
411
494
  DownloadIcon,
495
+ EllipsisIcon,
412
496
  FacebookIcon,
413
497
  FileIcon,
414
498
  GoogleIcon,
@@ -1,6 +1,7 @@
1
1
  import { forwardRef } from 'react';
2
2
  import { Text as RNText, type Text as RNTextType, type TextProps as RNTextProps } from 'react-native';
3
3
  import { tv, type VariantProps } from 'tailwind-variants';
4
+ import { useDirection } from '../hooks/use-direction';
4
5
 
5
6
  const textVariants = tv({
6
7
  base: 'text-foreground',
@@ -35,13 +36,30 @@ export interface TextProps extends RNTextProps, VariantProps<typeof textVariants
35
36
  }
36
37
 
37
38
  export const Text = forwardRef<RNTextType, TextProps>(
38
- ({ className, size, weight, muted, ...props }, ref) => (
39
- <RNText
40
- ref={ref}
41
- className={textVariants({ size, weight, muted, className })}
42
- {...props}
43
- />
44
- )
39
+ ({ className, size, weight, muted, style, ...props }, ref) => {
40
+ /*
41
+ * `direction` is a Yoga *layout* property, and React Native resolves a
42
+ * paragraph's own alignment from the process-wide `I18nManager.isRTL`
43
+ * instead — so a `<Direction dir="rtl">` mirrors the furniture around this
44
+ * text and leaves the text itself left-aligned inside it. Setting
45
+ * `writingDirection` is what closes that gap, and it also puts bidi
46
+ * punctuation on the correct end of a mixed line.
47
+ *
48
+ * Only the direction, not the alignment: `textAlign` stays whatever the
49
+ * caller asked for, or unset. A component that centres its label means it
50
+ * in both directions.
51
+ */
52
+ const direction = useDirection();
53
+
54
+ return (
55
+ <RNText
56
+ ref={ref}
57
+ className={textVariants({ size, weight, muted, className })}
58
+ style={[{ writingDirection: direction }, style]}
59
+ {...props}
60
+ />
61
+ );
62
+ }
45
63
  );
46
64
 
47
65
  Text.displayName = 'Text';