panelui-native 0.22.6 → 0.28.1
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/README.md +1 -0
- package/lib/module/components/accordion/index.js +8 -8
- package/lib/module/components/accordion/index.js.map +1 -1
- package/lib/module/components/alert/index.js +2 -2
- package/lib/module/components/alert/index.js.map +1 -1
- package/lib/module/components/area-chart/index.js +958 -0
- package/lib/module/components/area-chart/index.js.map +1 -0
- package/lib/module/components/attachment/index.js +2 -1
- package/lib/module/components/attachment/index.js.map +1 -1
- package/lib/module/components/avatar/index.js +4 -4
- package/lib/module/components/avatar/index.js.map +1 -1
- package/lib/module/components/badge/index.js +4 -4
- package/lib/module/components/badge/index.js.map +1 -1
- package/lib/module/components/bar-chart/index.js +994 -0
- package/lib/module/components/bar-chart/index.js.map +1 -0
- package/lib/module/components/bottom-sheet/index.js +213 -24
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/breadcrumb/index.js +275 -0
- package/lib/module/components/breadcrumb/index.js.map +1 -0
- package/lib/module/components/button/index.js +11 -6
- package/lib/module/components/button/index.js.map +1 -1
- package/lib/module/components/calendar/index.js +557 -0
- package/lib/module/components/calendar/index.js.map +1 -0
- package/lib/module/components/carousel/index.js +680 -0
- package/lib/module/components/carousel/index.js.map +1 -0
- package/lib/module/components/chip/index.js +6 -6
- package/lib/module/components/chip/index.js.map +1 -1
- package/lib/module/components/date-picker/index.js +158 -0
- package/lib/module/components/date-picker/index.js.map +1 -0
- package/lib/module/components/dialog/index.js +7 -2
- package/lib/module/components/dialog/index.js.map +1 -1
- package/lib/module/components/direction/index.js +15 -20
- package/lib/module/components/direction/index.js.map +1 -1
- package/lib/module/components/empty-state/index.js +2 -2
- package/lib/module/components/empty-state/index.js.map +1 -1
- package/lib/module/components/field/index.js +5 -5
- package/lib/module/components/field/index.js.map +1 -1
- package/lib/module/components/flow/index.js +3 -3
- package/lib/module/components/flow/index.js.map +1 -1
- package/lib/module/components/frame/index.js +22 -5
- package/lib/module/components/frame/index.js.map +1 -1
- package/lib/module/components/heatmap-chart/index.js +28 -8
- package/lib/module/components/heatmap-chart/index.js.map +1 -1
- package/lib/module/components/input-group/index.js +5 -4
- package/lib/module/components/input-group/index.js.map +1 -1
- package/lib/module/components/item/index.js +9 -9
- package/lib/module/components/item/index.js.map +1 -1
- package/lib/module/components/label/index.js +4 -4
- package/lib/module/components/label/index.js.map +1 -1
- package/lib/module/components/line-chart/index.js +165 -184
- package/lib/module/components/line-chart/index.js.map +1 -1
- package/lib/module/components/loader/index.js +758 -0
- package/lib/module/components/loader/index.js.map +1 -0
- package/lib/module/components/map/basemap.js +265 -0
- package/lib/module/components/map/basemap.js.map +1 -0
- package/lib/module/components/map/index.js +850 -0
- package/lib/module/components/map/index.js.map +1 -0
- package/lib/module/components/map/maplibre.js +87 -0
- package/lib/module/components/map/maplibre.js.map +1 -0
- package/lib/module/components/marker/index.js +3 -3
- package/lib/module/components/marker/index.js.map +1 -1
- package/lib/module/components/message/index.js +15 -14
- package/lib/module/components/message/index.js.map +1 -1
- package/lib/module/components/message-scroller/index.js +5 -4
- package/lib/module/components/message-scroller/index.js.map +1 -1
- package/lib/module/components/otp-input/index.js +2 -2
- package/lib/module/components/popover/index.js +39 -7
- package/lib/module/components/popover/index.js.map +1 -1
- package/lib/module/components/progress/index.js +8 -2
- package/lib/module/components/progress/index.js.map +1 -1
- package/lib/module/components/radio-group/index.js +2 -2
- package/lib/module/components/radio-group/index.js.map +1 -1
- package/lib/module/components/ring-chart/index.js +423 -0
- package/lib/module/components/ring-chart/index.js.map +1 -0
- package/lib/module/components/section-rail/index.js +6 -6
- package/lib/module/components/section-rail/index.js.map +1 -1
- package/lib/module/components/select/index.js +10 -4
- package/lib/module/components/select/index.js.map +1 -1
- package/lib/module/components/separator/index.js +76 -22
- package/lib/module/components/separator/index.js.map +1 -1
- package/lib/module/components/shimmer/index.js +10 -1
- package/lib/module/components/shimmer/index.js.map +1 -1
- package/lib/module/components/slider/index.js +19 -5
- package/lib/module/components/slider/index.js.map +1 -1
- package/lib/module/components/steps/index.js +5 -5
- package/lib/module/components/steps/index.js.map +1 -1
- package/lib/module/components/switch/index.js +6 -1
- package/lib/module/components/switch/index.js.map +1 -1
- package/lib/module/components/tabs/index.js +7 -7
- package/lib/module/components/tabs/index.js.map +1 -1
- package/lib/module/components/timeline/index.js +4 -4
- package/lib/module/components/timeline/index.js.map +1 -1
- package/lib/module/components/toast/index.js +2 -2
- package/lib/module/components/toast/index.js.map +1 -1
- package/lib/module/components/toggle-button/index.js +5 -5
- package/lib/module/components/toggle-button/index.js.map +1 -1
- package/lib/module/components/tooltip/index.js +492 -0
- package/lib/module/components/tooltip/index.js.map +1 -0
- package/lib/module/components/typography/index.js +7 -2
- package/lib/module/components/typography/index.js.map +1 -1
- package/lib/module/hooks/index.js +1 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/use-back-handler.js +37 -0
- package/lib/module/hooks/use-back-handler.js.map +1 -0
- package/lib/module/hooks/use-direction.js +43 -0
- package/lib/module/hooks/use-direction.js.map +1 -0
- package/lib/module/icons/index.js +180 -2
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/index.js +12 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/primitives/keyboard-avoider.js +2 -1
- package/lib/module/primitives/keyboard-avoider.js.map +1 -1
- package/lib/module/primitives/text.js +55 -11
- package/lib/module/primitives/text.js.map +1 -1
- package/lib/module/utils/chart.js +279 -0
- package/lib/module/utils/chart.js.map +1 -0
- package/lib/module/utils/date.js +386 -0
- package/lib/module/utils/date.js.map +1 -0
- package/lib/typescript/src/components/accordion/index.d.ts.map +1 -1
- package/lib/typescript/src/components/alert/index.d.ts.map +1 -1
- package/lib/typescript/src/components/area-chart/index.d.ts +237 -0
- package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -0
- package/lib/typescript/src/components/attachment/index.d.ts.map +1 -1
- package/lib/typescript/src/components/bar-chart/index.d.ts +270 -0
- package/lib/typescript/src/components/bar-chart/index.d.ts.map +1 -0
- package/lib/typescript/src/components/bottom-sheet/index.d.ts +75 -4
- package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/src/components/breadcrumb/index.d.ts +100 -0
- package/lib/typescript/src/components/breadcrumb/index.d.ts.map +1 -0
- package/lib/typescript/src/components/button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/calendar/index.d.ts +108 -0
- package/lib/typescript/src/components/calendar/index.d.ts.map +1 -0
- package/lib/typescript/src/components/carousel/index.d.ts +179 -0
- package/lib/typescript/src/components/carousel/index.d.ts.map +1 -0
- package/lib/typescript/src/components/chip/index.d.ts.map +1 -1
- package/lib/typescript/src/components/date-picker/index.d.ts +91 -0
- package/lib/typescript/src/components/date-picker/index.d.ts.map +1 -0
- package/lib/typescript/src/components/dialog/index.d.ts.map +1 -1
- package/lib/typescript/src/components/direction/index.d.ts +11 -10
- package/lib/typescript/src/components/direction/index.d.ts.map +1 -1
- package/lib/typescript/src/components/empty-state/index.d.ts.map +1 -1
- package/lib/typescript/src/components/field/index.d.ts.map +1 -1
- package/lib/typescript/src/components/frame/index.d.ts +17 -0
- package/lib/typescript/src/components/frame/index.d.ts.map +1 -1
- package/lib/typescript/src/components/heatmap-chart/index.d.ts +22 -3
- package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/input-group/index.d.ts.map +1 -1
- package/lib/typescript/src/components/item/index.d.ts.map +1 -1
- package/lib/typescript/src/components/label/index.d.ts.map +1 -1
- package/lib/typescript/src/components/line-chart/index.d.ts +42 -2
- package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/loader/index.d.ts +38 -0
- package/lib/typescript/src/components/loader/index.d.ts.map +1 -0
- package/lib/typescript/src/components/map/basemap.d.ts +76 -0
- package/lib/typescript/src/components/map/basemap.d.ts.map +1 -0
- package/lib/typescript/src/components/map/index.d.ts +367 -0
- package/lib/typescript/src/components/map/index.d.ts.map +1 -0
- package/lib/typescript/src/components/map/maplibre.d.ts +193 -0
- package/lib/typescript/src/components/map/maplibre.d.ts.map +1 -0
- package/lib/typescript/src/components/marker/index.d.ts.map +1 -1
- package/lib/typescript/src/components/message/index.d.ts.map +1 -1
- package/lib/typescript/src/components/message-scroller/index.d.ts.map +1 -1
- package/lib/typescript/src/components/popover/index.d.ts.map +1 -1
- package/lib/typescript/src/components/progress/index.d.ts.map +1 -1
- package/lib/typescript/src/components/ring-chart/index.d.ts +156 -0
- package/lib/typescript/src/components/ring-chart/index.d.ts.map +1 -0
- package/lib/typescript/src/components/select/index.d.ts.map +1 -1
- package/lib/typescript/src/components/separator/index.d.ts +36 -1
- package/lib/typescript/src/components/separator/index.d.ts.map +1 -1
- package/lib/typescript/src/components/shimmer/index.d.ts.map +1 -1
- package/lib/typescript/src/components/slider/index.d.ts.map +1 -1
- package/lib/typescript/src/components/steps/index.d.ts.map +1 -1
- package/lib/typescript/src/components/switch/index.d.ts.map +1 -1
- package/lib/typescript/src/components/tabs/index.d.ts.map +1 -1
- package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
- package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
- package/lib/typescript/src/components/toggle-button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/tooltip/index.d.ts +125 -0
- package/lib/typescript/src/components/tooltip/index.d.ts.map +1 -0
- package/lib/typescript/src/components/typography/index.d.ts +6 -0
- package/lib/typescript/src/components/typography/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/index.d.ts +1 -0
- package/lib/typescript/src/hooks/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/use-back-handler.d.ts +19 -0
- package/lib/typescript/src/hooks/use-back-handler.d.ts.map +1 -0
- package/lib/typescript/src/hooks/use-direction.d.ts +20 -0
- package/lib/typescript/src/hooks/use-direction.d.ts.map +1 -0
- package/lib/typescript/src/icons/index.d.ts +8 -0
- package/lib/typescript/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +14 -4
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/primitives/keyboard-avoider.d.ts.map +1 -1
- package/lib/typescript/src/primitives/text.d.ts +20 -0
- package/lib/typescript/src/primitives/text.d.ts.map +1 -1
- package/lib/typescript/src/utils/chart.d.ts +96 -0
- package/lib/typescript/src/utils/chart.d.ts.map +1 -0
- package/lib/typescript/src/utils/date.d.ts +116 -0
- package/lib/typescript/src/utils/date.d.ts.map +1 -0
- package/package.json +9 -1
- package/src/components/accordion/index.tsx +8 -12
- package/src/components/alert/index.tsx +2 -2
- package/src/components/area-chart/index.tsx +1147 -0
- package/src/components/attachment/index.tsx +2 -2
- package/src/components/avatar/index.tsx +4 -4
- package/src/components/badge/index.tsx +6 -6
- package/src/components/bar-chart/index.tsx +1208 -0
- package/src/components/bottom-sheet/index.tsx +282 -21
- package/src/components/breadcrumb/index.tsx +363 -0
- package/src/components/button/index.tsx +12 -8
- package/src/components/calendar/index.tsx +703 -0
- package/src/components/carousel/index.tsx +788 -0
- package/src/components/chip/index.tsx +6 -8
- package/src/components/date-picker/index.tsx +237 -0
- package/src/components/dialog/index.tsx +7 -2
- package/src/components/direction/index.tsx +22 -22
- package/src/components/empty-state/index.tsx +2 -2
- package/src/components/field/index.tsx +3 -5
- package/src/components/flow/index.tsx +3 -3
- package/src/components/frame/index.tsx +22 -7
- package/src/components/heatmap-chart/index.tsx +58 -11
- package/src/components/input-group/index.tsx +5 -4
- package/src/components/item/index.tsx +9 -9
- package/src/components/label/index.tsx +2 -2
- package/src/components/line-chart/index.tsx +194 -223
- package/src/components/loader/index.tsx +812 -0
- package/src/components/map/basemap.ts +304 -0
- package/src/components/map/index.tsx +1116 -0
- package/src/components/map/maplibre.ts +201 -0
- package/src/components/marker/index.tsx +3 -3
- package/src/components/message/index.tsx +15 -14
- package/src/components/message-scroller/index.tsx +5 -4
- package/src/components/otp-input/index.tsx +2 -2
- package/src/components/popover/index.tsx +43 -7
- package/src/components/progress/index.tsx +10 -2
- package/src/components/radio-group/index.tsx +2 -2
- package/src/components/ring-chart/index.tsx +543 -0
- package/src/components/section-rail/index.tsx +6 -6
- package/src/components/select/index.tsx +10 -4
- package/src/components/separator/index.tsx +77 -19
- package/src/components/shimmer/index.tsx +10 -1
- package/src/components/slider/index.tsx +20 -5
- package/src/components/steps/index.tsx +5 -5
- package/src/components/switch/index.tsx +6 -1
- package/src/components/tabs/index.tsx +7 -9
- package/src/components/timeline/index.tsx +4 -4
- package/src/components/toast/index.tsx +2 -2
- package/src/components/toggle-button/index.tsx +5 -7
- package/src/components/tooltip/index.tsx +610 -0
- package/src/components/typography/index.tsx +7 -2
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-back-handler.ts +37 -0
- package/src/hooks/use-direction.ts +45 -0
- package/src/icons/index.tsx +111 -0
- package/src/index.ts +129 -0
- package/src/primitives/keyboard-avoider.tsx +2 -1
- package/src/primitives/text.tsx +53 -8
- package/src/utils/chart.ts +355 -0
- package/src/utils/date.ts +446 -0
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
AnimatedPressable,
|
|
39
39
|
type AnimatedPressableProps,
|
|
40
40
|
} from '../../primitives/animated-pressable';
|
|
41
|
-
import { Text } from '../../primitives/text';
|
|
41
|
+
import { Text, textChildren } from '../../primitives/text';
|
|
42
42
|
import { cn } from '../../utils/cn';
|
|
43
43
|
import { selectionTick } from '../../utils/haptics';
|
|
44
44
|
|
|
@@ -47,7 +47,7 @@ const chipVariants = tv({
|
|
|
47
47
|
root: 'flex-row items-center self-start rounded-full border border-transparent',
|
|
48
48
|
label: 'font-medium',
|
|
49
49
|
close:
|
|
50
|
-
'items-center justify-center rounded-full -
|
|
50
|
+
'items-center justify-center rounded-full -me-1 aspect-square opacity-70',
|
|
51
51
|
},
|
|
52
52
|
variants: {
|
|
53
53
|
variant: {
|
|
@@ -88,7 +88,7 @@ const chipVariants = tv({
|
|
|
88
88
|
},
|
|
89
89
|
/** Trims the trailing padding so the close target hugs the right edge. */
|
|
90
90
|
closable: {
|
|
91
|
-
true: { root: '
|
|
91
|
+
true: { root: 'pe-1' },
|
|
92
92
|
},
|
|
93
93
|
disabled: {
|
|
94
94
|
true: { root: 'opacity-[0.56]' },
|
|
@@ -246,13 +246,11 @@ const ChipRoot = forwardRef<View, ChipProps>(
|
|
|
246
246
|
const body = (
|
|
247
247
|
<>
|
|
248
248
|
{start}
|
|
249
|
-
{
|
|
249
|
+
{textChildren(children, (text) => (
|
|
250
250
|
<Text className={slots.label({ className: labelClassName })}>
|
|
251
|
-
{
|
|
251
|
+
{text}
|
|
252
252
|
</Text>
|
|
253
|
-
)
|
|
254
|
-
children
|
|
255
|
-
)}
|
|
253
|
+
))}
|
|
256
254
|
{closable ? (
|
|
257
255
|
<Pressable
|
|
258
256
|
accessibilityRole="button"
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DatePicker — a calendar behind a button.
|
|
3
|
+
*
|
|
4
|
+
* ```tsx
|
|
5
|
+
* const [day, setDay] = useState<Date>();
|
|
6
|
+
*
|
|
7
|
+
* <DatePicker selected={day} onSelect={setDay} placeholder="Pick a date" />
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* It is the `Calendar` in a `Popover` with a trigger that reads back what was
|
|
11
|
+
* chosen, and it is a separate component from the calendar for the same reason
|
|
12
|
+
* `Select` is separate from a list: the hard parts are the ones around the
|
|
13
|
+
* grid — what a closed field says, when the panel closes, and what a range
|
|
14
|
+
* shows while only half of it has been picked.
|
|
15
|
+
*
|
|
16
|
+
* ## It closes when the selection is finished, not when it changes
|
|
17
|
+
*
|
|
18
|
+
* A single date is done in one tap, so the panel closes on it. A range needs
|
|
19
|
+
* two, so it stays open until the second — closing on the first would put
|
|
20
|
+
* someone back where they started with half a range on screen. Multiple never
|
|
21
|
+
* closes on its own; only the caller knows when a set is complete.
|
|
22
|
+
*
|
|
23
|
+
* ## An anchored panel, not a sheet
|
|
24
|
+
*
|
|
25
|
+
* A month grid is a fixed size that fits beside its trigger on any phone, and
|
|
26
|
+
* a sheet is the right container for a list of unknown length rather than for
|
|
27
|
+
* a shape that is always the same. Pass `presentation="bottom-sheet"` where the
|
|
28
|
+
* screen is busy — a form with the keyboard up is the usual case.
|
|
29
|
+
*/
|
|
30
|
+
import { useCallback, useMemo, useState, type ReactElement, type ReactNode } from 'react';
|
|
31
|
+
import { View } from 'react-native';
|
|
32
|
+
import { CalendarIcon } from '../../icons';
|
|
33
|
+
import { Text } from '../../primitives/text';
|
|
34
|
+
import { cn } from '../../utils/cn';
|
|
35
|
+
import { calendarShortDate, resolveCalendar, type CalendarSystem } from '../../utils/date';
|
|
36
|
+
import { Button } from '../button';
|
|
37
|
+
import {
|
|
38
|
+
Calendar,
|
|
39
|
+
type CalendarCaptionLayout,
|
|
40
|
+
type CalendarDisabled,
|
|
41
|
+
type CalendarMode,
|
|
42
|
+
type CalendarSelection,
|
|
43
|
+
type DateRange,
|
|
44
|
+
} from '../calendar';
|
|
45
|
+
import { Popover, type PopoverPresentation } from '../popover';
|
|
46
|
+
|
|
47
|
+
export type DatePickerMode = CalendarMode;
|
|
48
|
+
|
|
49
|
+
/** What a closed picker shows when nothing has been chosen yet. */
|
|
50
|
+
const DEFAULT_PLACEHOLDER = 'Pick a date';
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The chosen value as one line of text.
|
|
54
|
+
*
|
|
55
|
+
* A half-picked range reads as its start followed by a dash rather than as
|
|
56
|
+
* just the start: the dash is what says the picker is waiting for the other
|
|
57
|
+
* end, and without it a half range looks like a finished single date.
|
|
58
|
+
*/
|
|
59
|
+
function describe<Mode extends DatePickerMode>(
|
|
60
|
+
mode: Mode,
|
|
61
|
+
value: CalendarSelection[Mode] | undefined,
|
|
62
|
+
locale: string | undefined,
|
|
63
|
+
system: 'gregory' | 'islamic'
|
|
64
|
+
): string | null {
|
|
65
|
+
if (!value) return null;
|
|
66
|
+
const write = (date: Date) => calendarShortDate(date, system, locale);
|
|
67
|
+
|
|
68
|
+
if (mode === 'range') {
|
|
69
|
+
const range = value as DateRange;
|
|
70
|
+
if (!range.from) return null;
|
|
71
|
+
return range.to ? `${write(range.from)} – ${write(range.to)}` : `${write(range.from)} –`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (mode === 'multiple') {
|
|
75
|
+
const days = value as Date[];
|
|
76
|
+
if (!days.length) return null;
|
|
77
|
+
if (days.length === 1) return write(days[0]!);
|
|
78
|
+
return `${days.length} dates`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return write(value as Date);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface DatePickerProps<Mode extends DatePickerMode = 'single'> {
|
|
85
|
+
/** One day, several, or a span with two ends. */
|
|
86
|
+
mode?: Mode;
|
|
87
|
+
/** Controlled selection. Its shape follows `mode`. */
|
|
88
|
+
selected?: CalendarSelection[Mode];
|
|
89
|
+
/** Starting selection when uncontrolled. */
|
|
90
|
+
defaultSelected?: CalendarSelection[Mode];
|
|
91
|
+
onSelect?: (selected: CalendarSelection[Mode]) => void;
|
|
92
|
+
/** Controlled open state of the panel. */
|
|
93
|
+
open?: boolean;
|
|
94
|
+
onOpenChange?: (open: boolean) => void;
|
|
95
|
+
/** What the trigger reads when nothing has been chosen. */
|
|
96
|
+
placeholder?: string;
|
|
97
|
+
/** Override how the chosen value is written on the trigger. */
|
|
98
|
+
format?: (selected: CalendarSelection[Mode]) => string;
|
|
99
|
+
/** Anchored panel, or a sheet from the bottom of the screen. */
|
|
100
|
+
presentation?: PopoverPresentation;
|
|
101
|
+
/** Stop the trigger opening it. */
|
|
102
|
+
disabled?: boolean;
|
|
103
|
+
/** Days that cannot be picked: a list, a span, or a rule. */
|
|
104
|
+
disabledDates?: CalendarDisabled;
|
|
105
|
+
/** Earliest selectable day. */
|
|
106
|
+
minDate?: Date;
|
|
107
|
+
/** Latest selectable day. */
|
|
108
|
+
maxDate?: Date;
|
|
109
|
+
/** Months side by side inside the panel. */
|
|
110
|
+
numberOfMonths?: number;
|
|
111
|
+
/** `dropdown` swaps the month caption for month and year pickers. */
|
|
112
|
+
captionLayout?: CalendarCaptionLayout;
|
|
113
|
+
/** `0` is Sunday. */
|
|
114
|
+
weekStartsOn?: number;
|
|
115
|
+
/** BCP 47 tag for the month and weekday names, and for the trigger's text. */
|
|
116
|
+
locale?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Which calendar the months and day numbers are counted in. Forwarded to the
|
|
119
|
+
* grid, and used for the trigger's own text so the two always agree.
|
|
120
|
+
*/
|
|
121
|
+
calendar?: CalendarSystem;
|
|
122
|
+
className?: string;
|
|
123
|
+
/**
|
|
124
|
+
* A trigger of your own. Given one, it is cloned with an `onPress` that opens
|
|
125
|
+
* the panel — so a field row or an icon button can stand in for the default
|
|
126
|
+
* button without this component knowing what either looks like.
|
|
127
|
+
*/
|
|
128
|
+
children?: ReactElement<{ onPress?: () => void }> | ReactNode;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function DatePickerRoot<Mode extends DatePickerMode = 'single'>({
|
|
132
|
+
mode = 'single' as Mode,
|
|
133
|
+
selected,
|
|
134
|
+
defaultSelected,
|
|
135
|
+
onSelect,
|
|
136
|
+
open: openProp,
|
|
137
|
+
onOpenChange,
|
|
138
|
+
placeholder = DEFAULT_PLACEHOLDER,
|
|
139
|
+
format,
|
|
140
|
+
presentation = 'popover',
|
|
141
|
+
disabled = false,
|
|
142
|
+
disabledDates,
|
|
143
|
+
minDate,
|
|
144
|
+
maxDate,
|
|
145
|
+
numberOfMonths = 1,
|
|
146
|
+
captionLayout = 'label',
|
|
147
|
+
weekStartsOn = 0,
|
|
148
|
+
locale,
|
|
149
|
+
calendar = 'gregory',
|
|
150
|
+
className,
|
|
151
|
+
children,
|
|
152
|
+
}: DatePickerProps<Mode>) {
|
|
153
|
+
// Resolved here as well as in the grid, because the trigger's text has to be
|
|
154
|
+
// written in the same calendar the cells were tapped in.
|
|
155
|
+
const system = useMemo(() => resolveCalendar(calendar, locale), [calendar, locale]);
|
|
156
|
+
const [internalOpen, setInternalOpen] = useState(false);
|
|
157
|
+
const [internalSelected, setInternalSelected] = useState<CalendarSelection[Mode] | undefined>(
|
|
158
|
+
defaultSelected
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
const isOpenControlled = openProp !== undefined;
|
|
162
|
+
const open = isOpenControlled ? openProp : internalOpen;
|
|
163
|
+
|
|
164
|
+
const isControlled = selected !== undefined;
|
|
165
|
+
const value = (isControlled ? selected : internalSelected) as CalendarSelection[Mode];
|
|
166
|
+
|
|
167
|
+
const setOpen = useCallback(
|
|
168
|
+
(next: boolean) => {
|
|
169
|
+
if (!isOpenControlled) setInternalOpen(next);
|
|
170
|
+
onOpenChange?.(next);
|
|
171
|
+
},
|
|
172
|
+
[isOpenControlled, onOpenChange]
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
const handleSelect = useCallback(
|
|
176
|
+
(next: CalendarSelection[Mode]) => {
|
|
177
|
+
if (!isControlled) setInternalSelected(next);
|
|
178
|
+
onSelect?.(next);
|
|
179
|
+
|
|
180
|
+
// Done in one tap, so it closes on one. A range waits for its second end,
|
|
181
|
+
// and a set of dates is only the caller's to call finished.
|
|
182
|
+
if (mode === 'single' && next) setOpen(false);
|
|
183
|
+
if (mode === 'range' && (next as DateRange | undefined)?.to) setOpen(false);
|
|
184
|
+
},
|
|
185
|
+
[isControlled, onSelect, mode, setOpen]
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const label = useMemo(() => {
|
|
189
|
+
if (format && value) return format(value);
|
|
190
|
+
return describe(mode, value, locale, system);
|
|
191
|
+
}, [format, value, mode, locale, system]);
|
|
192
|
+
|
|
193
|
+
const trigger = children ?? (
|
|
194
|
+
<Button
|
|
195
|
+
variant="outline"
|
|
196
|
+
disabled={disabled}
|
|
197
|
+
className={cn('justify-start gap-2', className)}
|
|
198
|
+
>
|
|
199
|
+
<CalendarIcon size={16} />
|
|
200
|
+
<Text className={label ? undefined : 'text-muted-foreground'}>
|
|
201
|
+
{label ?? placeholder}
|
|
202
|
+
</Text>
|
|
203
|
+
</Button>
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
<Popover open={open} onOpenChange={setOpen} presentation={presentation}>
|
|
208
|
+
<Popover.Trigger>{trigger as ReactElement<{ onPress?: () => void }>}</Popover.Trigger>
|
|
209
|
+
{/* The padding is on the inner view, not the panel: in sheet mode a
|
|
210
|
+
className on the panel is merged into the sheet's own padding and
|
|
211
|
+
would replace it. `self-center` for the same reason — the panel does
|
|
212
|
+
not have to know which presentation it ended up in. */}
|
|
213
|
+
<Popover.Content width="content-fit">
|
|
214
|
+
<View className="w-[300px] max-w-full self-center p-3">
|
|
215
|
+
<Calendar
|
|
216
|
+
mode={mode}
|
|
217
|
+
selected={value}
|
|
218
|
+
onSelect={handleSelect}
|
|
219
|
+
disabled={disabledDates}
|
|
220
|
+
minDate={minDate}
|
|
221
|
+
maxDate={maxDate}
|
|
222
|
+
numberOfMonths={numberOfMonths}
|
|
223
|
+
captionLayout={captionLayout}
|
|
224
|
+
weekStartsOn={weekStartsOn}
|
|
225
|
+
locale={locale}
|
|
226
|
+
calendar={calendar}
|
|
227
|
+
/>
|
|
228
|
+
</View>
|
|
229
|
+
</Popover.Content>
|
|
230
|
+
</Popover>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
DatePickerRoot.displayName = 'DatePicker';
|
|
234
|
+
|
|
235
|
+
export const DatePicker = Object.assign(DatePickerRoot, {
|
|
236
|
+
Trigger: Popover.Trigger,
|
|
237
|
+
});
|
|
@@ -14,7 +14,8 @@ import { Pressable, View, type ViewProps } from 'react-native';
|
|
|
14
14
|
import Animated, { FadeIn, FadeOut, ZoomIn } from 'react-native-reanimated';
|
|
15
15
|
import { Portal } from '../../primitives/portal';
|
|
16
16
|
import { Scrim } from '../../primitives/scrim';
|
|
17
|
-
import { Text, type TextProps } from '../../primitives/text';
|
|
17
|
+
import { Text, type TextProps, textChildren } from '../../primitives/text';
|
|
18
|
+
import { useBackHandler } from '../../hooks/use-back-handler';
|
|
18
19
|
import { cn } from '../../utils/cn';
|
|
19
20
|
|
|
20
21
|
interface DialogContextValue {
|
|
@@ -102,6 +103,10 @@ function DialogContent({
|
|
|
102
103
|
const context = useDialog('Dialog.Content');
|
|
103
104
|
const { open, setOpen } = context;
|
|
104
105
|
|
|
106
|
+
// While the dialog is up, the Android back button closes it rather than
|
|
107
|
+
// popping the screen behind — but only when tapping outside would too.
|
|
108
|
+
useBackHandler(open && dismissible, () => setOpen(false));
|
|
109
|
+
|
|
105
110
|
if (!open) return null;
|
|
106
111
|
|
|
107
112
|
return (
|
|
@@ -130,7 +135,7 @@ function DialogContent({
|
|
|
130
135
|
)}
|
|
131
136
|
{...props}
|
|
132
137
|
>
|
|
133
|
-
{children}
|
|
138
|
+
{textChildren(children)}
|
|
134
139
|
</Animated.View>
|
|
135
140
|
</Animated.View>
|
|
136
141
|
</DialogContext.Provider>
|
|
@@ -33,16 +33,19 @@
|
|
|
33
33
|
* comes from the device — so an app that did force RTL the old way still reads
|
|
34
34
|
* back the truth.
|
|
35
35
|
*/
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
36
|
+
import { useContext, useMemo, type ReactNode } from 'react';
|
|
37
|
+
import { View, type ViewProps } from 'react-native';
|
|
38
|
+
import {
|
|
39
|
+
DirectionContext,
|
|
40
|
+
deviceDirection,
|
|
41
|
+
useDirection,
|
|
42
|
+
useDirectionSign,
|
|
43
|
+
type DirectionValue,
|
|
44
|
+
} from '../../hooks/use-direction';
|
|
45
|
+
import { textChildren } from '../../primitives/text';
|
|
39
46
|
|
|
40
|
-
export
|
|
41
|
-
|
|
42
|
-
/** What the device is set to, for anything outside a provider. */
|
|
43
|
-
const deviceDirection = (): DirectionValue => (I18nManager.isRTL ? 'rtl' : 'ltr');
|
|
44
|
-
|
|
45
|
-
const DirectionContext = createContext<DirectionValue | null>(null);
|
|
47
|
+
export { useDirection, useDirectionSign };
|
|
48
|
+
export type { DirectionValue };
|
|
46
49
|
|
|
47
50
|
export interface DirectionProps extends ViewProps {
|
|
48
51
|
className?: string;
|
|
@@ -56,9 +59,14 @@ export interface DirectionProps extends ViewProps {
|
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
/**
|
|
59
|
-
* Provider. Renders one `View` — it has to, since the flip is a style
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
+
* Provider. Renders one `View` — it has to, since the flip is a style.
|
|
63
|
+
*
|
|
64
|
+
* The view takes no layout of its own: it is as big as what is inside it, and
|
|
65
|
+
* `className` says otherwise. Wrapping a whole app therefore wants `flex-1`
|
|
66
|
+
* explicitly. It used to carry that by default, and every use inside a screen
|
|
67
|
+
* had to undo it with `flex-none` — a default that is wrong for one of its two
|
|
68
|
+
* uses is worse than no default, because the wrong one fails silently by
|
|
69
|
+
* swallowing the rest of the screen.
|
|
62
70
|
*/
|
|
63
71
|
export function Direction({ className, children, dir, style, ...props }: DirectionProps) {
|
|
64
72
|
const inherited = useContext(DirectionContext);
|
|
@@ -71,8 +79,8 @@ export function Direction({ className, children, dir, style, ...props }: Directi
|
|
|
71
79
|
|
|
72
80
|
return (
|
|
73
81
|
<DirectionContext.Provider value={value}>
|
|
74
|
-
<View className={
|
|
75
|
-
{children}
|
|
82
|
+
<View className={className} style={[directionStyle, style]} {...props}>
|
|
83
|
+
{textChildren(children)}
|
|
76
84
|
</View>
|
|
77
85
|
</DirectionContext.Provider>
|
|
78
86
|
);
|
|
@@ -80,11 +88,3 @@ export function Direction({ className, children, dir, style, ...props }: Directi
|
|
|
80
88
|
|
|
81
89
|
Direction.displayName = 'Direction';
|
|
82
90
|
|
|
83
|
-
/**
|
|
84
|
-
* The reading direction in force, for a component that has to flip maths Yoga
|
|
85
|
-
* cannot flip for it. Safe with no provider mounted: it falls back to the
|
|
86
|
-
* device's own setting.
|
|
87
|
-
*/
|
|
88
|
-
export function useDirection(): DirectionValue {
|
|
89
|
-
return useContext(DirectionContext) ?? deviceDirection();
|
|
90
|
-
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { createContext, forwardRef, useContext, type ReactNode } from 'react';
|
|
10
10
|
import { View, type Text as RNText, type ViewProps } from 'react-native';
|
|
11
11
|
import { tv, type VariantProps } from 'tailwind-variants';
|
|
12
|
-
import { Text, type TextProps } from '../../primitives/text';
|
|
12
|
+
import { Text, type TextProps, textChildren } from '../../primitives/text';
|
|
13
13
|
|
|
14
14
|
type EmptyStateSize = 'sm' | 'default' | 'lg';
|
|
15
15
|
|
|
@@ -140,7 +140,7 @@ const EmptyStateMedia = forwardRef<View, EmptyStateMediaProps>(
|
|
|
140
140
|
/>
|
|
141
141
|
</>
|
|
142
142
|
) : null}
|
|
143
|
-
<View className={card()}>{children}</View>
|
|
143
|
+
<View className={card()}>{textChildren(children)}</View>
|
|
144
144
|
</View>
|
|
145
145
|
);
|
|
146
146
|
}
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
} from 'react';
|
|
32
32
|
import { View, type Text as RNText, type ViewProps } from 'react-native';
|
|
33
33
|
import { tv } from 'tailwind-variants';
|
|
34
|
-
import { Text, type TextProps } from '../../primitives/text';
|
|
34
|
+
import { Text, type TextProps, textChildren } from '../../primitives/text';
|
|
35
35
|
import { Label, type LabelProps } from '../label';
|
|
36
36
|
import { Separator } from '../separator';
|
|
37
37
|
|
|
@@ -121,7 +121,7 @@ const FieldRoot = forwardRef<View, FieldProps>(
|
|
|
121
121
|
className={root({ className })}
|
|
122
122
|
{...props}
|
|
123
123
|
>
|
|
124
|
-
{children}
|
|
124
|
+
{textChildren(children)}
|
|
125
125
|
</View>
|
|
126
126
|
</FieldContext.Provider>
|
|
127
127
|
);
|
|
@@ -227,10 +227,8 @@ const FieldError = forwardRef<View, FieldErrorProps>(
|
|
|
227
227
|
</View>
|
|
228
228
|
))
|
|
229
229
|
)
|
|
230
|
-
) : typeof children === 'string' ? (
|
|
231
|
-
<Text className={errorText()}>{children}</Text>
|
|
232
230
|
) : (
|
|
233
|
-
children
|
|
231
|
+
textChildren(children, (text) => <Text className={errorText()}>{text}</Text>)
|
|
234
232
|
)}
|
|
235
233
|
</View>
|
|
236
234
|
);
|
|
@@ -84,7 +84,7 @@ import Svg, {
|
|
|
84
84
|
import { tv } from 'tailwind-variants';
|
|
85
85
|
import { LockIcon, MaximizeIcon, MinusIcon, PlusIcon, UnlockIcon } from '../../icons';
|
|
86
86
|
import { AnimatedPressable } from '../../primitives/animated-pressable';
|
|
87
|
-
import { Text } from '../../primitives/text';
|
|
87
|
+
import { Text, textChildren } from '../../primitives/text';
|
|
88
88
|
import { cn } from '../../utils/cn';
|
|
89
89
|
import {
|
|
90
90
|
anchorOf,
|
|
@@ -1160,7 +1160,7 @@ function FlowNode({
|
|
|
1160
1160
|
accessibilityState={{ selected }}
|
|
1161
1161
|
{...props}
|
|
1162
1162
|
>
|
|
1163
|
-
{children}
|
|
1163
|
+
{textChildren(children)}
|
|
1164
1164
|
</Animated.View>
|
|
1165
1165
|
</GestureDetector>
|
|
1166
1166
|
</FlowNodeContext.Provider>
|
|
@@ -1772,7 +1772,7 @@ function FlowGroup({
|
|
|
1772
1772
|
inside an absolutely-positioned box would be positioned against that
|
|
1773
1773
|
box, and every graph coordinate would mean something different
|
|
1774
1774
|
depending on which group it happened to be in. */}
|
|
1775
|
-
{children}
|
|
1775
|
+
{textChildren(children)}
|
|
1776
1776
|
</FlowGroupContext.Provider>
|
|
1777
1777
|
);
|
|
1778
1778
|
}
|
|
@@ -14,6 +14,23 @@
|
|
|
14
14
|
* surfaces read as one misdrawn shape. The panel's bottom corners are not set
|
|
15
15
|
* at all — the shell clips them, so they take its radius exactly.
|
|
16
16
|
*
|
|
17
|
+
* That clip follows the shell's *border box*, not the box inside its border.
|
|
18
|
+
* Along the straight edges the panel is held off by the border width and the
|
|
19
|
+
* edge shows through, but at the corner arcs the panel's square corner is
|
|
20
|
+
* clipped to the outer radius and paints across the border. At the default
|
|
21
|
+
* hairline that is a sliver nobody sees. Give the shell a thicker border and
|
|
22
|
+
* the corners visibly eat it, so a Frame with `border-2` or more needs the
|
|
23
|
+
* panel told where to stop:
|
|
24
|
+
*
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <Frame className="rounded-[28px] border-2 border-dashed">
|
|
27
|
+
* <Frame.Panel className="rounded-b-[26px]">…</Frame.Panel>
|
|
28
|
+
* </Frame>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* The radius to use is the shell's less its border width. It is on the caller
|
|
32
|
+
* because both arrive as `className` strings, which the component cannot read.
|
|
33
|
+
*
|
|
17
34
|
* ```tsx
|
|
18
35
|
* <Frame>
|
|
19
36
|
* <Frame.Header>
|
|
@@ -63,7 +80,7 @@ import {
|
|
|
63
80
|
} from 'react-native';
|
|
64
81
|
import { tv } from 'tailwind-variants';
|
|
65
82
|
import { ChevronRightIcon } from '../../icons';
|
|
66
|
-
import { Text, type TextProps } from '../../primitives/text';
|
|
83
|
+
import { Text, type TextProps, textChildren } from '../../primitives/text';
|
|
67
84
|
import { cn } from '../../utils/cn';
|
|
68
85
|
|
|
69
86
|
const frameVariants = tv({
|
|
@@ -191,13 +208,11 @@ const FrameAction = forwardRef<View, FrameActionProps>(
|
|
|
191
208
|
className={cn('shrink-0 flex-row items-center gap-2', className)}
|
|
192
209
|
{...props}
|
|
193
210
|
>
|
|
194
|
-
{
|
|
211
|
+
{textChildren(children, (text) => (
|
|
195
212
|
<Text size="sm" muted>
|
|
196
|
-
{
|
|
213
|
+
{text}
|
|
197
214
|
</Text>
|
|
198
|
-
)
|
|
199
|
-
children
|
|
200
|
-
)}
|
|
215
|
+
))}
|
|
201
216
|
</View>
|
|
202
217
|
)
|
|
203
218
|
);
|
|
@@ -376,7 +391,7 @@ const FrameRow = forwardRef<View, FrameRowProps>(
|
|
|
376
391
|
|
|
377
392
|
const body = (
|
|
378
393
|
<>
|
|
379
|
-
{children}
|
|
394
|
+
{textChildren(children)}
|
|
380
395
|
{chevron ? <ChevronRightIcon size={16} /> : null}
|
|
381
396
|
</>
|
|
382
397
|
);
|
|
@@ -65,14 +65,23 @@ const AnimatedRect = Animated.createAnimatedComponent(Rect);
|
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* Rows in a week — the default, and what the calendar helper and the weekday
|
|
68
|
-
* labels assume. The grid itself takes a `rows` prop, so
|
|
69
|
-
*
|
|
68
|
+
* labels assume. The grid itself takes a `rows` prop, so a grid whose bins are
|
|
69
|
+
* hours rather than days is the same component with a different number.
|
|
70
70
|
*/
|
|
71
71
|
const DAYS_IN_WEEK = 7;
|
|
72
72
|
|
|
73
73
|
/** Opacity of the base colour at each activity level. Index 0 is "nothing". */
|
|
74
74
|
const LEVEL_OPACITY = [1, 0.28, 0.5, 0.74, 1] as const;
|
|
75
75
|
|
|
76
|
+
/**
|
|
77
|
+
* A theme token rather than a colour. Tokens are named, not written, so the
|
|
78
|
+
* leading `--` tells the two apart without the caller having to say which
|
|
79
|
+
* kind they passed.
|
|
80
|
+
*/
|
|
81
|
+
function isToken(value: string | undefined): value is string {
|
|
82
|
+
return typeof value === 'string' && value.startsWith('--');
|
|
83
|
+
}
|
|
84
|
+
|
|
76
85
|
/** Room left for the weekday labels when the y-axis does not ask for its own. */
|
|
77
86
|
const DEFAULT_AXIS_WIDTH = 26;
|
|
78
87
|
|
|
@@ -317,8 +326,8 @@ export interface HeatmapChartProps extends ViewProps {
|
|
|
317
326
|
/** Which weekday is the top row. `0` is Sunday. Labels follow it. */
|
|
318
327
|
weekStartDay?: number;
|
|
319
328
|
/**
|
|
320
|
-
* Rows per column. Seven for a calendar; use another number
|
|
321
|
-
*
|
|
329
|
+
* Rows per column. Seven for a calendar; use another number when the bins
|
|
330
|
+
* are not weekdays — twenty-four for a grid of hours.
|
|
322
331
|
*/
|
|
323
332
|
rows?: number;
|
|
324
333
|
/**
|
|
@@ -333,8 +342,27 @@ export interface HeatmapChartProps extends ViewProps {
|
|
|
333
342
|
* opacities, which follows the theme.
|
|
334
343
|
*/
|
|
335
344
|
levelColors?: string[];
|
|
336
|
-
/**
|
|
345
|
+
/**
|
|
346
|
+
* Base colour for the derived ramp — the colour the busiest cells are drawn
|
|
347
|
+
* in, with the quieter levels the same colour at lower opacity.
|
|
348
|
+
*
|
|
349
|
+
* Takes a theme token by name as well as a literal, so `"--color-chart-3"`
|
|
350
|
+
* recolours the chart and keeps following the theme through light and dark.
|
|
351
|
+
* Defaults to `--color-chart-1`.
|
|
352
|
+
*/
|
|
337
353
|
color?: string;
|
|
354
|
+
/**
|
|
355
|
+
* Colour of a cell with nothing in it. Takes a token name too. Defaults to
|
|
356
|
+
* `--color-muted`, which is the right weight for "measured, and empty" —
|
|
357
|
+
* override it for a chart that should read as denser or fainter than that.
|
|
358
|
+
*/
|
|
359
|
+
emptyColor?: string;
|
|
360
|
+
/**
|
|
361
|
+
* Opacity of the base colour at each of the five levels, quietest first.
|
|
362
|
+
* The way to retune the ramp's contrast without having to name five colours.
|
|
363
|
+
* Ignored when `levelColors` is given, which sets the colours outright.
|
|
364
|
+
*/
|
|
365
|
+
levelOpacity?: number[];
|
|
338
366
|
/** Milliseconds for the reveal on mount. */
|
|
339
367
|
animationDuration?: number;
|
|
340
368
|
/** Opacity of every cell that is not the one under the finger. */
|
|
@@ -361,6 +389,8 @@ const HeatmapChartRoot = forwardRef<View, HeatmapChartProps>(function HeatmapCha
|
|
|
361
389
|
levels,
|
|
362
390
|
levelColors,
|
|
363
391
|
color,
|
|
392
|
+
emptyColor,
|
|
393
|
+
levelOpacity,
|
|
364
394
|
animationDuration = 900,
|
|
365
395
|
inactiveOpacity = 1,
|
|
366
396
|
onActiveCellChange,
|
|
@@ -378,10 +408,24 @@ const HeatmapChartRoot = forwardRef<View, HeatmapChartProps>(function HeatmapCha
|
|
|
378
408
|
const reveal = useSharedValue(0);
|
|
379
409
|
const reducedMotion = useReducedMotion();
|
|
380
410
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
411
|
+
/*
|
|
412
|
+
* `color` and `emptyColor` take a token name as readily as a literal. A
|
|
413
|
+
* literal is a colour frozen at the moment it was written — it cannot follow
|
|
414
|
+
* the theme into dark mode — so naming the token is almost always what the
|
|
415
|
+
* caller meant, and having to resolve it themselves is the reason they did
|
|
416
|
+
* not. The hooks run unconditionally; which of the two answers is used is
|
|
417
|
+
* decided after.
|
|
418
|
+
*/
|
|
419
|
+
const baseToken = useCSSVariable(isToken(color) ? color : '--color-chart-1');
|
|
420
|
+
const emptyToken = useCSSVariable(
|
|
421
|
+
isToken(emptyColor) ? emptyColor : '--color-muted'
|
|
422
|
+
);
|
|
423
|
+
const base =
|
|
424
|
+
(isToken(color) ? undefined : color) ??
|
|
425
|
+
(typeof baseToken === 'string' ? baseToken : '#262626');
|
|
426
|
+
const empty =
|
|
427
|
+
(isToken(emptyColor) ? undefined : emptyColor) ??
|
|
428
|
+
(typeof emptyToken === 'string' ? emptyToken : 'rgba(128,128,128,0.16)');
|
|
385
429
|
|
|
386
430
|
const parts = useMemo(() => splitParts(children), [children]);
|
|
387
431
|
// The y-axis is laid out beside the grid rather than over it, so its width
|
|
@@ -419,8 +463,11 @@ const HeatmapChartRoot = forwardRef<View, HeatmapChartProps>(function HeatmapCha
|
|
|
419
463
|
() =>
|
|
420
464
|
levelColors
|
|
421
465
|
? { ramp: levelColors, opacities: levelColors.map(() => 1) }
|
|
422
|
-
: {
|
|
423
|
-
|
|
466
|
+
: {
|
|
467
|
+
ramp: [empty, base, base, base, base],
|
|
468
|
+
opacities: levelOpacity ?? [...LEVEL_OPACITY],
|
|
469
|
+
},
|
|
470
|
+
[levelColors, levelOpacity, empty, base]
|
|
424
471
|
);
|
|
425
472
|
|
|
426
473
|
const levelOf = useMemo(
|
|
@@ -22,12 +22,13 @@ import {
|
|
|
22
22
|
} from 'react-native';
|
|
23
23
|
import { tv } from 'tailwind-variants';
|
|
24
24
|
import { Input, type InputProps } from '../input';
|
|
25
|
+
import { textChildren } from '../../primitives/text';
|
|
25
26
|
|
|
26
27
|
const inputGroupVariants = tv({
|
|
27
28
|
slots: {
|
|
28
29
|
root: 'w-full',
|
|
29
|
-
prefix: 'absolute bottom-0
|
|
30
|
-
suffix: 'absolute bottom-0
|
|
30
|
+
prefix: 'absolute bottom-0 start-0 top-0 z-10 flex-row items-center justify-center gap-2 px-3',
|
|
31
|
+
suffix: 'absolute bottom-0 end-0 top-0 z-10 flex-row items-center justify-center gap-2 px-3',
|
|
31
32
|
},
|
|
32
33
|
variants: {
|
|
33
34
|
isDisabled: {
|
|
@@ -71,7 +72,7 @@ const InputGroupRoot = forwardRef<View, InputGroupProps>(
|
|
|
71
72
|
return (
|
|
72
73
|
<InputGroupContext.Provider value={value}>
|
|
73
74
|
<View ref={ref} className={root({ className })} {...props}>
|
|
74
|
-
{children}
|
|
75
|
+
{textChildren(children)}
|
|
75
76
|
</View>
|
|
76
77
|
</InputGroupContext.Provider>
|
|
77
78
|
);
|
|
@@ -116,7 +117,7 @@ function createDecorator(side: 'prefix' | 'suffix') {
|
|
|
116
117
|
className={slots[side]({ className })}
|
|
117
118
|
{...props}
|
|
118
119
|
>
|
|
119
|
-
{children}
|
|
120
|
+
{textChildren(children)}
|
|
120
121
|
</View>
|
|
121
122
|
);
|
|
122
123
|
}
|