panelui-native 0.25.0 → 0.30.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.
- package/README.md +18 -1
- 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 +182 -50
- package/lib/module/components/area-chart/index.js.map +1 -1
- 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 +3 -3
- 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 +197 -56
- package/lib/module/components/bar-chart/index.js.map +1 -1
- package/lib/module/components/bottom-sheet/index.js +15 -10
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/breadcrumb/index.js +6 -6
- package/lib/module/components/breadcrumb/index.js.map +1 -1
- 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 +792 -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 +4 -4
- package/lib/module/components/chip/index.js.map +1 -1
- package/lib/module/components/code-block/highlight.js +363 -0
- package/lib/module/components/code-block/highlight.js.map +1 -0
- package/lib/module/components/code-block/index.js +313 -0
- package/lib/module/components/code-block/index.js.map +1 -0
- package/lib/module/components/date-picker/index.js +165 -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 +2 -1
- 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 +5 -5
- package/lib/module/components/frame/index.js.map +1 -1
- package/lib/module/components/input-group/index.js +3 -2
- 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 +167 -44
- package/lib/module/components/line-chart/index.js.map +1 -1
- package/lib/module/components/map/index.js +7 -7
- package/lib/module/components/map/index.js.map +1 -1
- package/lib/module/components/marker/index.js +3 -3
- package/lib/module/components/marker/index.js.map +1 -1
- package/lib/module/components/menu/index.js +714 -0
- package/lib/module/components/menu/index.js.map +1 -0
- package/lib/module/components/message/index.js +7 -7
- 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/plan/index.js +296 -0
- package/lib/module/components/plan/index.js.map +1 -0
- package/lib/module/components/popover/index.js +73 -10
- package/lib/module/components/popover/index.js.map +1 -1
- package/lib/module/components/radio-group/index.js +15 -10
- package/lib/module/components/radio-group/index.js.map +1 -1
- package/lib/module/components/reasoning/index.js +244 -0
- package/lib/module/components/reasoning/index.js.map +1 -0
- package/lib/module/components/section-rail/index.js +4 -4
- 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/sources/index.js +221 -0
- package/lib/module/components/sources/index.js.map +1 -0
- package/lib/module/components/steps/index.js +4 -4
- package/lib/module/components/steps/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/task/index.js +300 -0
- package/lib/module/components/task/index.js.map +1 -0
- package/lib/module/components/textarea/index.js +295 -0
- package/lib/module/components/textarea/index.js.map +1 -0
- 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 +648 -0
- package/lib/module/components/tooltip/index.js.map +1 -0
- package/lib/module/components/typography/index.js +2 -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/icons/index.js +202 -0
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/index.js +13 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/primitives/collapse.js +112 -0
- package/lib/module/primitives/collapse.js.map +1 -0
- 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 +25 -1
- package/lib/module/primitives/text.js.map +1 -1
- 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 +41 -1
- package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/attachment/index.d.ts.map +1 -1
- package/lib/typescript/src/components/bar-chart/index.d.ts +44 -2
- package/lib/typescript/src/components/bar-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/src/components/breadcrumb/index.d.ts.map +1 -1
- package/lib/typescript/src/components/button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/calendar/index.d.ts +173 -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/code-block/highlight.d.ts +39 -0
- package/lib/typescript/src/components/code-block/highlight.d.ts.map +1 -0
- package/lib/typescript/src/components/code-block/index.d.ts +113 -0
- package/lib/typescript/src/components/code-block/index.d.ts.map +1 -0
- package/lib/typescript/src/components/date-picker/index.d.ts +97 -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.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.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 +41 -2
- package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/map/index.d.ts.map +1 -1
- package/lib/typescript/src/components/marker/index.d.ts.map +1 -1
- package/lib/typescript/src/components/menu/index.d.ts +261 -0
- package/lib/typescript/src/components/menu/index.d.ts.map +1 -0
- 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/plan/index.d.ts +127 -0
- package/lib/typescript/src/components/plan/index.d.ts.map +1 -0
- package/lib/typescript/src/components/popover/index.d.ts +35 -1
- package/lib/typescript/src/components/popover/index.d.ts.map +1 -1
- package/lib/typescript/src/components/radio-group/index.d.ts.map +1 -1
- package/lib/typescript/src/components/reasoning/index.d.ts +97 -0
- package/lib/typescript/src/components/reasoning/index.d.ts.map +1 -0
- package/lib/typescript/src/components/select/index.d.ts.map +1 -1
- package/lib/typescript/src/components/sources/index.d.ts +85 -0
- package/lib/typescript/src/components/sources/index.d.ts.map +1 -0
- package/lib/typescript/src/components/steps/index.d.ts.map +1 -1
- package/lib/typescript/src/components/tabs/index.d.ts.map +1 -1
- package/lib/typescript/src/components/task/index.d.ts +103 -0
- package/lib/typescript/src/components/task/index.d.ts.map +1 -0
- package/lib/typescript/src/components/textarea/index.d.ts +175 -0
- package/lib/typescript/src/components/textarea/index.d.ts.map +1 -0
- 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 +180 -0
- package/lib/typescript/src/components/tooltip/index.d.ts.map +1 -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/icons/index.d.ts +17 -0
- package/lib/typescript/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +16 -4
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/primitives/collapse.d.ts +42 -0
- package/lib/typescript/src/primitives/collapse.d.ts.map +1 -0
- 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/date.d.ts +116 -0
- package/lib/typescript/src/utils/date.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/accordion/index.tsx +8 -12
- package/src/components/alert/index.tsx +2 -2
- package/src/components/area-chart/index.tsx +208 -55
- package/src/components/attachment/index.tsx +2 -2
- package/src/components/avatar/index.tsx +3 -3
- package/src/components/badge/index.tsx +6 -6
- package/src/components/bar-chart/index.tsx +214 -54
- package/src/components/bottom-sheet/index.tsx +17 -16
- package/src/components/breadcrumb/index.tsx +6 -8
- package/src/components/button/index.tsx +12 -8
- package/src/components/calendar/index.tsx +970 -0
- package/src/components/carousel/index.tsx +788 -0
- package/src/components/chip/index.tsx +4 -6
- package/src/components/code-block/highlight.ts +278 -0
- package/src/components/code-block/index.tsx +341 -0
- package/src/components/date-picker/index.tsx +255 -0
- package/src/components/dialog/index.tsx +7 -2
- package/src/components/direction/index.tsx +2 -1
- 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 +5 -7
- package/src/components/input-group/index.tsx +3 -2
- package/src/components/item/index.tsx +9 -9
- package/src/components/label/index.tsx +2 -2
- package/src/components/line-chart/index.tsx +189 -50
- package/src/components/map/index.tsx +7 -9
- package/src/components/marker/index.tsx +3 -3
- package/src/components/menu/index.tsx +812 -0
- package/src/components/message/index.tsx +7 -7
- package/src/components/message-scroller/index.tsx +5 -4
- package/src/components/plan/index.tsx +325 -0
- package/src/components/popover/index.tsx +111 -8
- package/src/components/radio-group/index.tsx +13 -4
- package/src/components/reasoning/index.tsx +297 -0
- package/src/components/section-rail/index.tsx +4 -4
- package/src/components/select/index.tsx +10 -4
- package/src/components/sources/index.tsx +278 -0
- package/src/components/steps/index.tsx +4 -4
- package/src/components/tabs/index.tsx +7 -9
- package/src/components/task/index.tsx +329 -0
- package/src/components/textarea/index.tsx +381 -0
- 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 +793 -0
- package/src/components/typography/index.tsx +2 -2
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-back-handler.ts +37 -0
- package/src/icons/index.tsx +147 -0
- package/src/index.ts +116 -0
- package/src/primitives/collapse.tsx +128 -0
- package/src/primitives/keyboard-avoider.tsx +2 -1
- package/src/primitives/text.tsx +28 -1
- package/src/utils/date.ts +446 -0
- package/theme.css +112 -0
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
import { Children, forwardRef, type ReactNode } from 'react';
|
|
26
26
|
import { View, type Text as RNText, type ViewProps } from 'react-native';
|
|
27
27
|
import { tv, type VariantProps } from 'tailwind-variants';
|
|
28
|
-
import { Text, type TextProps } from '../../primitives/text';
|
|
28
|
+
import { Text, type TextProps, textChildren } from '../../primitives/text';
|
|
29
29
|
import { cn } from '../../utils/cn';
|
|
30
30
|
|
|
31
31
|
const typographyVariants = tv({
|
|
@@ -300,7 +300,7 @@ const TypographyList = forwardRef<View, TypographyListProps>(
|
|
|
300
300
|
// platform font, and a view does not.
|
|
301
301
|
<View className="mt-2.5 size-1.5 shrink-0 rounded-full bg-muted-foreground" />
|
|
302
302
|
)}
|
|
303
|
-
<View className="flex-1">{child}</View>
|
|
303
|
+
<View className="flex-1">{textChildren(child)}</View>
|
|
304
304
|
</View>
|
|
305
305
|
))}
|
|
306
306
|
</View>
|
package/src/hooks/index.ts
CHANGED
|
@@ -31,5 +31,6 @@ export {
|
|
|
31
31
|
type UseScrollSectionsOptions,
|
|
32
32
|
type UseScrollSectionsResult,
|
|
33
33
|
} from './use-scroll-sections';
|
|
34
|
+
export { useBackHandler } from './use-back-handler';
|
|
34
35
|
export { useDebouncedValue } from './use-debounced-value';
|
|
35
36
|
export { usePrevious } from './use-previous';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { BackHandler, Platform } from 'react-native';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Runs a handler when the Android hardware back button is pressed.
|
|
6
|
+
*
|
|
7
|
+
* An open overlay owns the back button while it is up: pressing back should
|
|
8
|
+
* dismiss the overlay, not pop the screen behind it. Without this, the back
|
|
9
|
+
* gesture navigates away and the overlay is orphaned — the same mistake as a
|
|
10
|
+
* modal that stays put when you tap outside it.
|
|
11
|
+
*
|
|
12
|
+
* The listener is Android-only and gated on `enabled`, so an overlay wires it
|
|
13
|
+
* to `open && dismissible` and nothing runs while the overlay is closed or
|
|
14
|
+
* pinned. Returning `true` from the handler tells the platform the press was
|
|
15
|
+
* consumed, which is what stops the navigation.
|
|
16
|
+
*
|
|
17
|
+
* ```tsx
|
|
18
|
+
* useBackHandler(open && dismissible, () => setOpen(false));
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function useBackHandler(enabled: boolean, onBack: () => void): void {
|
|
22
|
+
// Held in a ref so a caller passing an inline `() => setOpen(false)` does not
|
|
23
|
+
// resubscribe the listener on every render — only a change in `enabled` does.
|
|
24
|
+
const onBackRef = useRef(onBack);
|
|
25
|
+
onBackRef.current = onBack;
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (Platform.OS !== 'android' || !enabled) return;
|
|
29
|
+
|
|
30
|
+
const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
|
|
31
|
+
onBackRef.current();
|
|
32
|
+
return true;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return () => subscription.remove();
|
|
36
|
+
}, [enabled]);
|
|
37
|
+
}
|
package/src/icons/index.tsx
CHANGED
|
@@ -103,6 +103,51 @@ export function MinusIcon({ size = 14, color, strokeWidth = 3, ...props }: IconP
|
|
|
103
103
|
);
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
export function ChevronUpIcon({ size = 16, color, ...props }: IconProps) {
|
|
107
|
+
const resolved = useResolvedColor(color, '#737373');
|
|
108
|
+
return (
|
|
109
|
+
<Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
|
|
110
|
+
<Path
|
|
111
|
+
d="m18 15-6-6-6 6"
|
|
112
|
+
stroke={resolved}
|
|
113
|
+
strokeWidth={2}
|
|
114
|
+
strokeLinecap="round"
|
|
115
|
+
strokeLinejoin="round"
|
|
116
|
+
/>
|
|
117
|
+
</Svg>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function CalendarIcon({ size = 16, color, ...props }: IconProps) {
|
|
122
|
+
const resolved = useResolvedColor(color, '#737373');
|
|
123
|
+
return (
|
|
124
|
+
<Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
|
|
125
|
+
<Path
|
|
126
|
+
d="M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z"
|
|
127
|
+
stroke={resolved}
|
|
128
|
+
strokeWidth={2}
|
|
129
|
+
strokeLinecap="round"
|
|
130
|
+
strokeLinejoin="round"
|
|
131
|
+
/>
|
|
132
|
+
</Svg>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function BookmarkIcon({ size = 16, color, ...props }: IconProps) {
|
|
137
|
+
const resolved = useResolvedColor(color, '#737373');
|
|
138
|
+
return (
|
|
139
|
+
<Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
|
|
140
|
+
<Path
|
|
141
|
+
d="m19 21-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2Z"
|
|
142
|
+
stroke={resolved}
|
|
143
|
+
strokeWidth={2}
|
|
144
|
+
strokeLinecap="round"
|
|
145
|
+
strokeLinejoin="round"
|
|
146
|
+
/>
|
|
147
|
+
</Svg>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
106
151
|
export function ChevronDownIcon({ size = 16, color, ...props }: IconProps) {
|
|
107
152
|
const resolved = useResolvedColor(color, '#737373');
|
|
108
153
|
return (
|
|
@@ -827,3 +872,105 @@ export function UnlockIcon({ size = 16, color, ...props }: IconProps) {
|
|
|
827
872
|
</Svg>
|
|
828
873
|
);
|
|
829
874
|
}
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* Four-pointed sparkles. The mark for a model doing something on your behalf —
|
|
878
|
+
* a reasoning step, a generated plan — where a gear or a brain reads as
|
|
879
|
+
* machinery rather than as assistance.
|
|
880
|
+
*/
|
|
881
|
+
export function SparklesIcon({ size = 16, color, ...props }: IconProps) {
|
|
882
|
+
const resolved = useResolvedColor(color, '#737373');
|
|
883
|
+
return (
|
|
884
|
+
<Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
|
|
885
|
+
<Path
|
|
886
|
+
d="M11 3 12.6 8.4 18 10l-5.4 1.6L11 17l-1.6-5.4L4 10l5.4-1.6z"
|
|
887
|
+
stroke={resolved}
|
|
888
|
+
strokeWidth={2}
|
|
889
|
+
strokeLinejoin="round"
|
|
890
|
+
/>
|
|
891
|
+
<Path
|
|
892
|
+
d="M18 15.5 18.7 18l2.3.7-2.3.7-.7 2.3-.7-2.3-2.3-.7 2.3-.7z"
|
|
893
|
+
stroke={resolved}
|
|
894
|
+
strokeWidth={1.6}
|
|
895
|
+
strokeLinejoin="round"
|
|
896
|
+
/>
|
|
897
|
+
</Svg>
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/** Two stacked sheets — the copy action, paired with CheckIcon once it has run. */
|
|
902
|
+
export function CopyIcon({ size = 16, color, ...props }: IconProps) {
|
|
903
|
+
const resolved = useResolvedColor(color, '#737373');
|
|
904
|
+
return (
|
|
905
|
+
<Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
|
|
906
|
+
<Path
|
|
907
|
+
d="M9 9h10v12H9z"
|
|
908
|
+
stroke={resolved}
|
|
909
|
+
strokeWidth={2}
|
|
910
|
+
strokeLinejoin="round"
|
|
911
|
+
/>
|
|
912
|
+
<Path
|
|
913
|
+
d="M15 5H5v12h2"
|
|
914
|
+
stroke={resolved}
|
|
915
|
+
strokeWidth={2}
|
|
916
|
+
strokeLinecap="round"
|
|
917
|
+
strokeLinejoin="round"
|
|
918
|
+
/>
|
|
919
|
+
</Svg>
|
|
920
|
+
);
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
/** Two links of a chain, for a row that opens somewhere outside the app. */
|
|
924
|
+
export function LinkIcon({ size = 16, color, ...props }: IconProps) {
|
|
925
|
+
const resolved = useResolvedColor(color, '#737373');
|
|
926
|
+
return (
|
|
927
|
+
<Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
|
|
928
|
+
<Path
|
|
929
|
+
d="M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7"
|
|
930
|
+
stroke={resolved}
|
|
931
|
+
strokeWidth={2}
|
|
932
|
+
strokeLinecap="round"
|
|
933
|
+
strokeLinejoin="round"
|
|
934
|
+
/>
|
|
935
|
+
<Path
|
|
936
|
+
d="M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7"
|
|
937
|
+
stroke={resolved}
|
|
938
|
+
strokeWidth={2}
|
|
939
|
+
strokeLinecap="round"
|
|
940
|
+
strokeLinejoin="round"
|
|
941
|
+
/>
|
|
942
|
+
</Svg>
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
/** A list with its items ticked off — a plan, or a run of steps. */
|
|
947
|
+
export function ListChecksIcon({ size = 16, color, ...props }: IconProps) {
|
|
948
|
+
const resolved = useResolvedColor(color, '#737373');
|
|
949
|
+
return (
|
|
950
|
+
<Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
|
|
951
|
+
<Path
|
|
952
|
+
d="m3 6 1.8 1.8L8 4.5M3 16l1.8 1.8L8 14.5"
|
|
953
|
+
stroke={resolved}
|
|
954
|
+
strokeWidth={2}
|
|
955
|
+
strokeLinecap="round"
|
|
956
|
+
strokeLinejoin="round"
|
|
957
|
+
/>
|
|
958
|
+
<Path
|
|
959
|
+
d="M12 6.5h9M12 17.5h9"
|
|
960
|
+
stroke={resolved}
|
|
961
|
+
strokeWidth={2}
|
|
962
|
+
strokeLinecap="round"
|
|
963
|
+
/>
|
|
964
|
+
</Svg>
|
|
965
|
+
);
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/** A hollow ring, for a step that has not started. */
|
|
969
|
+
export function CircleIcon({ size = 16, color, ...props }: IconProps) {
|
|
970
|
+
const resolved = useResolvedColor(color, '#737373');
|
|
971
|
+
return (
|
|
972
|
+
<Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
|
|
973
|
+
<Circle cx={12} cy={12} r={8} stroke={resolved} strokeWidth={2} />
|
|
974
|
+
</Svg>
|
|
975
|
+
);
|
|
976
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -21,6 +21,7 @@ export { Portal, PortalHost, PortalProvider } from './primitives/portal';
|
|
|
21
21
|
// graceful fall back from blur to dim — as the built-in ones.
|
|
22
22
|
export { Scrim, hasBlur, type ScrimProps } from './primitives/scrim';
|
|
23
23
|
export { Text, type TextProps } from './primitives/text';
|
|
24
|
+
export { Collapse, type CollapseProps } from './primitives/collapse';
|
|
24
25
|
export {
|
|
25
26
|
KeyboardAvoider,
|
|
26
27
|
type KeyboardAvoiderProps,
|
|
@@ -79,6 +80,7 @@ export {
|
|
|
79
80
|
type AreaChartProps,
|
|
80
81
|
type AreaChartHandle,
|
|
81
82
|
type AreaChartGridProps,
|
|
83
|
+
type AreaChartHeaderProps,
|
|
82
84
|
type AreaChartAreaProps,
|
|
83
85
|
type AreaChartXAxisProps,
|
|
84
86
|
type AreaChartYAxisProps,
|
|
@@ -93,6 +95,7 @@ export {
|
|
|
93
95
|
useBarChart,
|
|
94
96
|
type BarChartProps,
|
|
95
97
|
type BarChartHandle,
|
|
98
|
+
type BarChartHeaderProps,
|
|
96
99
|
type BarChartGridProps,
|
|
97
100
|
type BarChartBarProps,
|
|
98
101
|
type BarChartXAxisProps,
|
|
@@ -133,6 +136,11 @@ export {
|
|
|
133
136
|
type ToggleButtonVariant,
|
|
134
137
|
type ToggleSelectionMode,
|
|
135
138
|
} from './components/toggle-button';
|
|
139
|
+
export {
|
|
140
|
+
DatePicker,
|
|
141
|
+
type DatePickerProps,
|
|
142
|
+
type DatePickerMode,
|
|
143
|
+
} from './components/date-picker';
|
|
136
144
|
export {
|
|
137
145
|
Dialog,
|
|
138
146
|
type DialogProps,
|
|
@@ -246,6 +254,32 @@ export {
|
|
|
246
254
|
type TabsTriggerProps,
|
|
247
255
|
type TabsContentProps,
|
|
248
256
|
} from './components/tabs';
|
|
257
|
+
export {
|
|
258
|
+
Carousel,
|
|
259
|
+
useCarouselState,
|
|
260
|
+
type CarouselProps,
|
|
261
|
+
type CarouselHandle,
|
|
262
|
+
type CarouselContentProps,
|
|
263
|
+
type CarouselItemProps,
|
|
264
|
+
type CarouselCaptionProps,
|
|
265
|
+
type CarouselDotsProps,
|
|
266
|
+
type CarouselArrowProps,
|
|
267
|
+
type CarouselControlsProps,
|
|
268
|
+
type CarouselVariant,
|
|
269
|
+
type CarouselOrientation,
|
|
270
|
+
type CarouselAlign,
|
|
271
|
+
} from './components/carousel';
|
|
272
|
+
export {
|
|
273
|
+
Calendar,
|
|
274
|
+
type CalendarProps,
|
|
275
|
+
type CalendarHeaderProps,
|
|
276
|
+
type CalendarNavProps,
|
|
277
|
+
type CalendarMode,
|
|
278
|
+
type CalendarCaptionLayout,
|
|
279
|
+
type CalendarDisabled,
|
|
280
|
+
type CalendarSelection,
|
|
281
|
+
type DateRange,
|
|
282
|
+
} from './components/calendar';
|
|
249
283
|
export { Card, type CardProps } from './components/card';
|
|
250
284
|
export { Checkbox, type CheckboxProps } from './components/checkbox';
|
|
251
285
|
export {
|
|
@@ -301,6 +335,7 @@ export {
|
|
|
301
335
|
type NumberInputProps,
|
|
302
336
|
} from './components/number-input';
|
|
303
337
|
export { OtpInput, type OtpInputProps } from './components/otp-input';
|
|
338
|
+
export { Textarea, type TextareaProps } from './components/textarea';
|
|
304
339
|
export {
|
|
305
340
|
Item,
|
|
306
341
|
type ItemProps,
|
|
@@ -320,6 +355,7 @@ export {
|
|
|
320
355
|
useLineChart,
|
|
321
356
|
type LineChartProps,
|
|
322
357
|
type LineChartHandle,
|
|
358
|
+
type LineChartHeaderProps,
|
|
323
359
|
type LineChartGridProps,
|
|
324
360
|
type LineChartLineProps,
|
|
325
361
|
type LineChartAreaProps,
|
|
@@ -343,6 +379,24 @@ export {
|
|
|
343
379
|
type MarkerIconProps,
|
|
344
380
|
type MarkerContentProps,
|
|
345
381
|
} from './components/marker';
|
|
382
|
+
export {
|
|
383
|
+
Menu,
|
|
384
|
+
type MenuProps,
|
|
385
|
+
type MenuTriggerProps,
|
|
386
|
+
type MenuContentProps,
|
|
387
|
+
type MenuBackgroundProps,
|
|
388
|
+
type MenuLabelProps,
|
|
389
|
+
type MenuItemProps,
|
|
390
|
+
type MenuCheckboxItemProps,
|
|
391
|
+
type MenuRadioGroupProps,
|
|
392
|
+
type MenuRadioItemProps,
|
|
393
|
+
type MenuSeparatorProps,
|
|
394
|
+
type MenuSubProps,
|
|
395
|
+
type MenuSubTriggerProps,
|
|
396
|
+
type MenuSubContentProps,
|
|
397
|
+
type MenuItemVariant,
|
|
398
|
+
type MenuRadioIndicator,
|
|
399
|
+
} from './components/menu';
|
|
346
400
|
export {
|
|
347
401
|
MessageScroller,
|
|
348
402
|
useMessageScroller,
|
|
@@ -416,6 +470,52 @@ export {
|
|
|
416
470
|
type SignatureButtonProps,
|
|
417
471
|
} from './components/signature';
|
|
418
472
|
export { Shimmer, type ShimmerProps } from './components/shimmer';
|
|
473
|
+
export {
|
|
474
|
+
Reasoning,
|
|
475
|
+
type ReasoningProps,
|
|
476
|
+
type ReasoningTriggerProps,
|
|
477
|
+
type ReasoningContentProps,
|
|
478
|
+
} from './components/reasoning';
|
|
479
|
+
export {
|
|
480
|
+
Sources,
|
|
481
|
+
type SourcesProps,
|
|
482
|
+
type SourcesTriggerProps,
|
|
483
|
+
type SourcesContentProps,
|
|
484
|
+
type SourcesSourceProps,
|
|
485
|
+
} from './components/sources';
|
|
486
|
+
export {
|
|
487
|
+
Task,
|
|
488
|
+
type TaskProps,
|
|
489
|
+
type TaskTriggerProps,
|
|
490
|
+
type TaskContentProps,
|
|
491
|
+
type TaskItemProps,
|
|
492
|
+
type TaskFileProps,
|
|
493
|
+
type TaskStatus,
|
|
494
|
+
} from './components/task';
|
|
495
|
+
export {
|
|
496
|
+
CodeBlock,
|
|
497
|
+
resolveLanguage,
|
|
498
|
+
type CodeBlockProps,
|
|
499
|
+
type CodeBlockHeaderProps,
|
|
500
|
+
type CodeBlockFilenameProps,
|
|
501
|
+
type CodeBlockLanguageProps,
|
|
502
|
+
type CodeBlockActionsProps,
|
|
503
|
+
type CodeBlockCopyButtonProps,
|
|
504
|
+
type CodeLanguage,
|
|
505
|
+
type Token,
|
|
506
|
+
type TokenKind,
|
|
507
|
+
} from './components/code-block';
|
|
508
|
+
export {
|
|
509
|
+
Plan,
|
|
510
|
+
type PlanProps,
|
|
511
|
+
type PlanHeaderProps,
|
|
512
|
+
type PlanTitleProps,
|
|
513
|
+
type PlanDescriptionProps,
|
|
514
|
+
type PlanActionProps,
|
|
515
|
+
type PlanTriggerProps,
|
|
516
|
+
type PlanContentProps,
|
|
517
|
+
type PlanFooterProps,
|
|
518
|
+
} from './components/plan';
|
|
419
519
|
export {
|
|
420
520
|
ScrollText,
|
|
421
521
|
type ScrollTextProps,
|
|
@@ -470,6 +570,19 @@ export {
|
|
|
470
570
|
type ToastIndicatorProps,
|
|
471
571
|
type ToastCloseProps,
|
|
472
572
|
} from './components/toast';
|
|
573
|
+
export {
|
|
574
|
+
Tooltip,
|
|
575
|
+
type TooltipProps,
|
|
576
|
+
type TooltipTriggerProps,
|
|
577
|
+
type TooltipContentProps,
|
|
578
|
+
type TooltipArrowProps,
|
|
579
|
+
type TooltipTitleProps,
|
|
580
|
+
type TooltipDescriptionProps,
|
|
581
|
+
type TooltipPlacement,
|
|
582
|
+
type TooltipAlign,
|
|
583
|
+
type TooltipOpenOn,
|
|
584
|
+
type TooltipVariant,
|
|
585
|
+
} from './components/tooltip';
|
|
473
586
|
export {
|
|
474
587
|
Typography,
|
|
475
588
|
type TypographyProps,
|
|
@@ -485,12 +598,15 @@ export {
|
|
|
485
598
|
AppleIcon,
|
|
486
599
|
ArrowUpRightIcon,
|
|
487
600
|
BellIcon,
|
|
601
|
+
BookmarkIcon,
|
|
602
|
+
CalendarIcon,
|
|
488
603
|
CardIcon,
|
|
489
604
|
CheckCircleIcon,
|
|
490
605
|
CheckIcon,
|
|
491
606
|
ChevronDownIcon,
|
|
492
607
|
ChevronLeftIcon,
|
|
493
608
|
ChevronRightIcon,
|
|
609
|
+
ChevronUpIcon,
|
|
494
610
|
DownloadIcon,
|
|
495
611
|
EllipsisIcon,
|
|
496
612
|
FacebookIcon,
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collapse — a body that opens and closes by animating its own height.
|
|
3
|
+
*
|
|
4
|
+
* Height cannot be animated from `auto`, so the content is measured first and
|
|
5
|
+
* the measurement is what gets animated to. While that is happening the content
|
|
6
|
+
* is taken out of the flow, because a child of a view whose height is
|
|
7
|
+
* mid-animation reports that animated height back and the panel then settles on
|
|
8
|
+
* whatever it happened to measure.
|
|
9
|
+
*
|
|
10
|
+
* The moment the animation finishes, both go away and the content lays out
|
|
11
|
+
* normally again. That is what lets a Collapse hold another Collapse — or hold
|
|
12
|
+
* content that is still streaming in — without either of them being clipped to
|
|
13
|
+
* a number that was true a frame ago.
|
|
14
|
+
*
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <Collapse open={open}>
|
|
17
|
+
* <Text>Anything, of any height.</Text>
|
|
18
|
+
* </Collapse>
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* The alternative — unmounting the body and letting a layout transition on the
|
|
22
|
+
* parent carry the change — is what `Accordion` does, and it is right when the
|
|
23
|
+
* closed state should cost nothing. This is for a body that opens and closes
|
|
24
|
+
* repeatedly and often while its content is still arriving, where remounting
|
|
25
|
+
* would throw away scroll position and restart every animation inside it.
|
|
26
|
+
*/
|
|
27
|
+
import { useEffect, useRef, useState, type ReactNode } from 'react';
|
|
28
|
+
import { View, type LayoutChangeEvent, type ViewProps } from 'react-native';
|
|
29
|
+
import Animated, {
|
|
30
|
+
runOnJS,
|
|
31
|
+
useAnimatedStyle,
|
|
32
|
+
useReducedMotion,
|
|
33
|
+
useSharedValue,
|
|
34
|
+
withTiming,
|
|
35
|
+
} from 'react-native-reanimated';
|
|
36
|
+
import { cn } from '../utils/cn';
|
|
37
|
+
|
|
38
|
+
/** Long enough to read as the panel opening, short enough not to be waited on. */
|
|
39
|
+
export const COLLAPSE_DURATION = 200;
|
|
40
|
+
|
|
41
|
+
export interface CollapseProps extends Omit<ViewProps, 'children'> {
|
|
42
|
+
open: boolean;
|
|
43
|
+
/** Classes on the measured content, not on the clipping frame. */
|
|
44
|
+
className?: string;
|
|
45
|
+
duration?: number;
|
|
46
|
+
children?: ReactNode;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function Collapse({
|
|
50
|
+
open,
|
|
51
|
+
className,
|
|
52
|
+
duration = COLLAPSE_DURATION,
|
|
53
|
+
children,
|
|
54
|
+
...props
|
|
55
|
+
}: CollapseProps) {
|
|
56
|
+
const reducedMotion = useReducedMotion();
|
|
57
|
+
const [height, setHeight] = useState(0);
|
|
58
|
+
const [animating, setAnimating] = useState(false);
|
|
59
|
+
const progress = useSharedValue(open ? 1 : 0);
|
|
60
|
+
const mounted = useRef(false);
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
// The first pass is not a transition — a body that starts open should be
|
|
64
|
+
// open, not play its own entrance at nobody.
|
|
65
|
+
if (!mounted.current) {
|
|
66
|
+
mounted.current = true;
|
|
67
|
+
progress.value = open ? 1 : 0;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (reducedMotion) {
|
|
71
|
+
progress.value = open ? 1 : 0;
|
|
72
|
+
setAnimating(false);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
setAnimating(true);
|
|
76
|
+
progress.value = withTiming(open ? 1 : 0, { duration }, (finished) => {
|
|
77
|
+
if (finished) runOnJS(setAnimating)(false);
|
|
78
|
+
});
|
|
79
|
+
}, [open, reducedMotion, duration, progress]);
|
|
80
|
+
|
|
81
|
+
const style = useAnimatedStyle(() => ({
|
|
82
|
+
height: progress.value * height,
|
|
83
|
+
opacity: progress.value,
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
// Re-measured rather than measured once: a body whose content is still
|
|
87
|
+
// streaming in grows, and a height captured on the first frame would crop it.
|
|
88
|
+
const onLayout = (event: LayoutChangeEvent) => {
|
|
89
|
+
const next = event.nativeEvent.layout.height;
|
|
90
|
+
setHeight((current) => (Math.abs(current - next) < 1 ? current : next));
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/*
|
|
94
|
+
* Once it has finished opening, the measured height and the absolute
|
|
95
|
+
* positioning are both dropped and the content lays out normally.
|
|
96
|
+
*
|
|
97
|
+
* They are only needed *while* the height is being animated to a number, and
|
|
98
|
+
* keeping them costs real bugs: a Collapse whose content is itself a Collapse
|
|
99
|
+
* measures a child that has not settled yet, and settles on that wrong
|
|
100
|
+
* number, so the inner body ends up clipped to nothing. Content that is still
|
|
101
|
+
* streaming in has the same problem against itself. In natural flow both are
|
|
102
|
+
* simply laid out, and the measurement carries on in the background against
|
|
103
|
+
* the next time it closes.
|
|
104
|
+
*/
|
|
105
|
+
const natural = open && !animating;
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<Animated.View
|
|
109
|
+
style={natural ? undefined : style}
|
|
110
|
+
className={natural ? undefined : 'overflow-hidden'}
|
|
111
|
+
>
|
|
112
|
+
{/*
|
|
113
|
+
The same two elements in both modes, so switching between them is a
|
|
114
|
+
style change rather than a remount — a remount would throw away the
|
|
115
|
+
state of everything inside.
|
|
116
|
+
*/}
|
|
117
|
+
<View
|
|
118
|
+
onLayout={onLayout}
|
|
119
|
+
style={natural ? undefined : { position: 'absolute', left: 0, right: 0, top: 0 }}
|
|
120
|
+
className={cn(className)}
|
|
121
|
+
{...props}
|
|
122
|
+
>
|
|
123
|
+
{children}
|
|
124
|
+
</View>
|
|
125
|
+
</Animated.View>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
Collapse.displayName = 'Collapse';
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
useKeyboardAvoidance,
|
|
28
28
|
type KeyboardAvoidanceMode,
|
|
29
29
|
} from '../hooks/use-keyboard-avoidance';
|
|
30
|
+
import { textChildren } from './text';
|
|
30
31
|
|
|
31
32
|
export interface KeyboardAvoiderProps extends ViewProps {
|
|
32
33
|
className?: string;
|
|
@@ -86,7 +87,7 @@ export function KeyboardAvoider({
|
|
|
86
87
|
className={className}
|
|
87
88
|
style={[style, avoidance.animatedStyle]}
|
|
88
89
|
>
|
|
89
|
-
{children}
|
|
90
|
+
{textChildren(children)}
|
|
90
91
|
</Animated.View>
|
|
91
92
|
);
|
|
92
93
|
}
|
package/src/primitives/text.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef } from 'react';
|
|
1
|
+
import { Children, forwardRef, type ReactElement, type ReactNode } 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
4
|
import { useDirection } from '../hooks/use-direction';
|
|
@@ -63,3 +63,30 @@ export const Text = forwardRef<RNTextType, TextProps>(
|
|
|
63
63
|
);
|
|
64
64
|
|
|
65
65
|
Text.displayName = 'Text';
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Wraps the bare text among `children` so it can live in a plain view.
|
|
69
|
+
*
|
|
70
|
+
* React Native will not render a string outside a `<Text>`, and a component
|
|
71
|
+
* that takes `children` has no say in whether it is handed one — so anything
|
|
72
|
+
* putting `children` into a `View`, a `Pressable` or a scroller has to allow
|
|
73
|
+
* for it. Every part in the library that does runs its children through here.
|
|
74
|
+
*
|
|
75
|
+
* Per child, and not all-or-nothing. A part is nearly always given an element
|
|
76
|
+
* and some text together — an icon and a label, an arrow and a line of text —
|
|
77
|
+
* which makes `children` an *array*, so a `typeof children === 'string'` check
|
|
78
|
+
* never matches and the text underneath reaches the view bare. That is the
|
|
79
|
+
* shape this exists to make impossible.
|
|
80
|
+
*
|
|
81
|
+
* `render` is there because the wrapper is rarely the plain default: a button
|
|
82
|
+
* wants its own label variant, a sheet header wants a heading. Pass one, and
|
|
83
|
+
* the text arrives dressed the way the part would have dressed it anyway.
|
|
84
|
+
*/
|
|
85
|
+
export function textChildren(
|
|
86
|
+
children: ReactNode,
|
|
87
|
+
render: (text: string | number) => ReactElement = (text) => <Text>{text}</Text>
|
|
88
|
+
): ReactNode {
|
|
89
|
+
return Children.map(children, (child) =>
|
|
90
|
+
typeof child === 'string' || typeof child === 'number' ? render(child) : child
|
|
91
|
+
);
|
|
92
|
+
}
|