@agimon-ai/po-native-components 0.0.0-alpha.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/LICENSE +22 -0
- package/README.md +71 -0
- package/dist/components/Badge.d.mts +17 -0
- package/dist/components/Badge.d.mts.map +1 -0
- package/dist/components/Badge.mjs +106 -0
- package/dist/components/Badge.mjs.map +1 -0
- package/dist/components/Button.d.mts +20 -0
- package/dist/components/Button.d.mts.map +1 -0
- package/dist/components/Button.mjs +278 -0
- package/dist/components/Button.mjs.map +1 -0
- package/dist/components/CodeBlock.d.mts +10 -0
- package/dist/components/CodeBlock.d.mts.map +1 -0
- package/dist/components/CodeBlock.mjs +88 -0
- package/dist/components/CodeBlock.mjs.map +1 -0
- package/dist/components/Dialog.d.mts +52 -0
- package/dist/components/Dialog.d.mts.map +1 -0
- package/dist/components/Dialog.mjs +257 -0
- package/dist/components/Dialog.mjs.map +1 -0
- package/dist/components/Dot.d.mts +17 -0
- package/dist/components/Dot.d.mts.map +1 -0
- package/dist/components/Dot.mjs +94 -0
- package/dist/components/Dot.mjs.map +1 -0
- package/dist/components/DropdownMenu.d.mts +63 -0
- package/dist/components/DropdownMenu.d.mts.map +1 -0
- package/dist/components/DropdownMenu.mjs +256 -0
- package/dist/components/DropdownMenu.mjs.map +1 -0
- package/dist/components/EmptyState.d.mts +14 -0
- package/dist/components/EmptyState.d.mts.map +1 -0
- package/dist/components/EmptyState.mjs +64 -0
- package/dist/components/EmptyState.mjs.map +1 -0
- package/dist/components/Input.d.mts +19 -0
- package/dist/components/Input.d.mts.map +1 -0
- package/dist/components/Input.mjs +123 -0
- package/dist/components/Input.mjs.map +1 -0
- package/dist/components/Label.d.mts +13 -0
- package/dist/components/Label.d.mts.map +1 -0
- package/dist/components/Label.mjs +36 -0
- package/dist/components/Label.mjs.map +1 -0
- package/dist/components/List.d.mts +48 -0
- package/dist/components/List.d.mts.map +1 -0
- package/dist/components/List.mjs +156 -0
- package/dist/components/List.mjs.map +1 -0
- package/dist/components/Markdown.d.mts +15 -0
- package/dist/components/Markdown.d.mts.map +1 -0
- package/dist/components/Markdown.mjs +219 -0
- package/dist/components/Markdown.mjs.map +1 -0
- package/dist/components/MessageItem.d.mts +87 -0
- package/dist/components/MessageItem.d.mts.map +1 -0
- package/dist/components/MessageItem.mjs +361 -0
- package/dist/components/MessageItem.mjs.map +1 -0
- package/dist/components/Panel.d.mts +15 -0
- package/dist/components/Panel.d.mts.map +1 -0
- package/dist/components/Panel.mjs +77 -0
- package/dist/components/Panel.mjs.map +1 -0
- package/dist/components/PoNativeProvider.d.mts +15 -0
- package/dist/components/PoNativeProvider.d.mts.map +1 -0
- package/dist/components/PoNativeProvider.mjs +22 -0
- package/dist/components/PoNativeProvider.mjs.map +1 -0
- package/dist/components/SectionLabel.d.mts +6 -0
- package/dist/components/SectionLabel.d.mts.map +1 -0
- package/dist/components/SectionLabel.mjs +40 -0
- package/dist/components/SectionLabel.mjs.map +1 -0
- package/dist/components/SegmentedControl.d.mts +26 -0
- package/dist/components/SegmentedControl.d.mts.map +1 -0
- package/dist/components/SegmentedControl.mjs +56 -0
- package/dist/components/SegmentedControl.mjs.map +1 -0
- package/dist/components/Sheet.d.mts +39 -0
- package/dist/components/Sheet.d.mts.map +1 -0
- package/dist/components/Sheet.mjs +166 -0
- package/dist/components/Sheet.mjs.map +1 -0
- package/dist/components/SheetFrame.mjs +84 -0
- package/dist/components/SheetFrame.mjs.map +1 -0
- package/dist/components/Spinner.d.mts +19 -0
- package/dist/components/Spinner.d.mts.map +1 -0
- package/dist/components/Spinner.mjs +34 -0
- package/dist/components/Spinner.mjs.map +1 -0
- package/dist/components/StatusBadge.d.mts +23 -0
- package/dist/components/StatusBadge.d.mts.map +1 -0
- package/dist/components/StatusBadge.mjs +116 -0
- package/dist/components/StatusBadge.mjs.map +1 -0
- package/dist/components/Tabs.d.mts +44 -0
- package/dist/components/Tabs.d.mts.map +1 -0
- package/dist/components/Tabs.mjs +197 -0
- package/dist/components/Tabs.mjs.map +1 -0
- package/dist/components/Textarea.d.mts +10 -0
- package/dist/components/Textarea.d.mts.map +1 -0
- package/dist/components/Textarea.mjs +29 -0
- package/dist/components/Textarea.mjs.map +1 -0
- package/dist/icons/IconColorContext.d.mts +10 -0
- package/dist/icons/IconColorContext.d.mts.map +1 -0
- package/dist/icons/IconColorContext.mjs +13 -0
- package/dist/icons/IconColorContext.mjs.map +1 -0
- package/dist/icons/iconGlyphs.d.mts +120 -0
- package/dist/icons/iconGlyphs.d.mts.map +1 -0
- package/dist/icons/iconGlyphs.mjs +121 -0
- package/dist/icons/iconGlyphs.mjs.map +1 -0
- package/dist/icons/icons.d.mts +122 -0
- package/dist/icons/icons.d.mts.map +1 -0
- package/dist/icons/icons.mjs +79 -0
- package/dist/icons/icons.mjs.map +1 -0
- package/dist/index.d.mts +27 -0
- package/dist/index.mjs +27 -0
- package/dist/lib/fonts.d.mts +13 -0
- package/dist/lib/fonts.d.mts.map +1 -0
- package/dist/lib/fonts.mjs +22 -0
- package/dist/lib/fonts.mjs.map +1 -0
- package/dist/lib/haptics.d.mts +7 -0
- package/dist/lib/haptics.d.mts.map +1 -0
- package/dist/lib/haptics.mjs +25 -0
- package/dist/lib/haptics.mjs.map +1 -0
- package/dist/lib/insideSheet.mjs +16 -0
- package/dist/lib/insideSheet.mjs.map +1 -0
- package/dist/lib/markdown.mjs +271 -0
- package/dist/lib/markdown.mjs.map +1 -0
- package/dist/lib/tone.mjs +50 -0
- package/dist/lib/tone.mjs.map +1 -0
- package/dist/lib/useControllable.mjs +22 -0
- package/dist/lib/useControllable.mjs.map +1 -0
- package/dist/lib/wrapText.mjs +20 -0
- package/dist/lib/wrapText.mjs.map +1 -0
- package/llms.txt +8 -0
- package/package.json +104 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { fontOf } from "../lib/fonts.mjs";
|
|
2
|
+
import { wrapText } from "../lib/wrapText.mjs";
|
|
3
|
+
import { selectionTick } from "../lib/haptics.mjs";
|
|
4
|
+
import { Button } from "./Button.mjs";
|
|
5
|
+
import { CheckIcon } from "../icons/icons.mjs";
|
|
6
|
+
import { useControllable } from "../lib/useControllable.mjs";
|
|
7
|
+
import { SheetFrame } from "./SheetFrame.mjs";
|
|
8
|
+
import { View } from "react-native-unistyles/components/native/View";
|
|
9
|
+
import { StyleSheet } from "react-native-unistyles";
|
|
10
|
+
import { Text } from "react-native-unistyles/components/native/Text";
|
|
11
|
+
import { createContext, useContext } from "react";
|
|
12
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { Pressable } from "react-native-unistyles/components/native/Pressable";
|
|
14
|
+
|
|
15
|
+
//#region src/components/DropdownMenu.tsx
|
|
16
|
+
/** A row that carries a check or bullet keeps a gutter for it, so labels line up whether or not one is set. */
|
|
17
|
+
const INDICATOR_GUTTER = 28;
|
|
18
|
+
const MIN_ROW_HEIGHT = 44;
|
|
19
|
+
const DISABLED_OPACITY = .4;
|
|
20
|
+
const RADIO_DOT = 6;
|
|
21
|
+
const MenuContext = createContext({
|
|
22
|
+
open: false,
|
|
23
|
+
setOpen: () => void 0
|
|
24
|
+
});
|
|
25
|
+
const RadioContext = createContext({
|
|
26
|
+
value: void 0,
|
|
27
|
+
onValueChange: void 0
|
|
28
|
+
});
|
|
29
|
+
function DropdownMenu({ open, defaultOpen = false, onOpenChange, children }) {
|
|
30
|
+
const [current, setOpen] = useControllable(open, defaultOpen, onOpenChange);
|
|
31
|
+
return /* @__PURE__ */ jsx(MenuContext.Provider, {
|
|
32
|
+
value: {
|
|
33
|
+
open: current,
|
|
34
|
+
setOpen
|
|
35
|
+
},
|
|
36
|
+
children
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** A Button that opens the menu; announces that it opens a menu. */
|
|
40
|
+
function DropdownMenuTrigger({ onPress, accessibilityState, ...props }) {
|
|
41
|
+
const { open, setOpen } = useContext(MenuContext);
|
|
42
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
43
|
+
accessibilityState: {
|
|
44
|
+
...accessibilityState,
|
|
45
|
+
expanded: open
|
|
46
|
+
},
|
|
47
|
+
onPress: (event) => {
|
|
48
|
+
onPress?.(event);
|
|
49
|
+
setOpen(true);
|
|
50
|
+
},
|
|
51
|
+
...props
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/** The action list, in a bottom sheet. */
|
|
55
|
+
function DropdownMenuContent({ children }) {
|
|
56
|
+
const { open, setOpen } = useContext(MenuContext);
|
|
57
|
+
return /* @__PURE__ */ jsx(SheetFrame, {
|
|
58
|
+
open,
|
|
59
|
+
onClose: () => setOpen(false),
|
|
60
|
+
children: /* @__PURE__ */ jsx(View, {
|
|
61
|
+
accessibilityRole: "menu",
|
|
62
|
+
style: styles.content,
|
|
63
|
+
children
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/** A run of items under one label, so the separator between groups is structural. */
|
|
68
|
+
function DropdownMenuGroup({ children, ...props }) {
|
|
69
|
+
return /* @__PURE__ */ jsx(View, {
|
|
70
|
+
...props,
|
|
71
|
+
children
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function ItemRow({ variant = "default", indented = false, disabled = false, onSelect, role, checked, indicator, children, style }) {
|
|
75
|
+
const { setOpen } = useContext(MenuContext);
|
|
76
|
+
const _styles = styles;
|
|
77
|
+
{
|
|
78
|
+
const styles = _styles.useVariants({ variant: variant === "destructive" ? "destructive" : void 0 });
|
|
79
|
+
return /* @__PURE__ */ jsxs(Pressable, {
|
|
80
|
+
accessibilityRole: role,
|
|
81
|
+
accessibilityState: {
|
|
82
|
+
disabled,
|
|
83
|
+
checked
|
|
84
|
+
},
|
|
85
|
+
disabled,
|
|
86
|
+
onPress: () => {
|
|
87
|
+
selectionTick();
|
|
88
|
+
onSelect?.();
|
|
89
|
+
setOpen(false);
|
|
90
|
+
},
|
|
91
|
+
style: ({ pressed }) => [
|
|
92
|
+
styles.item,
|
|
93
|
+
(indented || indicator !== void 0) && styles.indented,
|
|
94
|
+
pressed && styles.pressed,
|
|
95
|
+
disabled && styles.disabled,
|
|
96
|
+
style
|
|
97
|
+
],
|
|
98
|
+
children: [indicator !== void 0 ? /* @__PURE__ */ jsx(View, {
|
|
99
|
+
style: styles.indicator,
|
|
100
|
+
children: indicator
|
|
101
|
+
}) : null, wrapText(children, styles.label)]
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function DropdownMenuItem(props) {
|
|
106
|
+
return /* @__PURE__ */ jsx(ItemRow, {
|
|
107
|
+
role: "menuitem",
|
|
108
|
+
...props
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/** A row that toggles: the check lives in the gutter so the label never shifts. */
|
|
112
|
+
function DropdownMenuCheckboxItem({ checked = false, onCheckedChange, onSelect, ...props }) {
|
|
113
|
+
return /* @__PURE__ */ jsx(ItemRow, {
|
|
114
|
+
role: "checkbox",
|
|
115
|
+
checked,
|
|
116
|
+
indicator: checked ? /* @__PURE__ */ jsx(CheckIcon, {
|
|
117
|
+
size: 12,
|
|
118
|
+
color: "blue"
|
|
119
|
+
}) : null,
|
|
120
|
+
onSelect: () => {
|
|
121
|
+
onCheckedChange?.(!checked);
|
|
122
|
+
onSelect?.();
|
|
123
|
+
},
|
|
124
|
+
...props
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/** The exclusive-choice group; pair it with DropdownMenuRadioItem. */
|
|
128
|
+
function DropdownMenuRadioGroup({ value, onValueChange, children, ...props }) {
|
|
129
|
+
return /* @__PURE__ */ jsx(RadioContext.Provider, {
|
|
130
|
+
value: {
|
|
131
|
+
value,
|
|
132
|
+
onValueChange
|
|
133
|
+
},
|
|
134
|
+
children: /* @__PURE__ */ jsx(View, {
|
|
135
|
+
accessibilityRole: "radiogroup",
|
|
136
|
+
...props,
|
|
137
|
+
children
|
|
138
|
+
})
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function DropdownMenuRadioItem({ value, onSelect, ...props }) {
|
|
142
|
+
const radio = useContext(RadioContext);
|
|
143
|
+
const checked = radio.value === value;
|
|
144
|
+
return /* @__PURE__ */ jsx(ItemRow, {
|
|
145
|
+
role: "radio",
|
|
146
|
+
checked,
|
|
147
|
+
indicator: checked ? /* @__PURE__ */ jsx(View, { style: styles.radioDot }) : null,
|
|
148
|
+
onSelect: () => {
|
|
149
|
+
radio.onValueChange?.(value);
|
|
150
|
+
onSelect?.();
|
|
151
|
+
},
|
|
152
|
+
...props
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/** The heading over a run of items, raised to sentence case as the web's `first-letter:uppercase`. */
|
|
156
|
+
function DropdownMenuLabel({ style, children, ...props }) {
|
|
157
|
+
const label = typeof children === "string" ? children.charAt(0).toUpperCase() + children.slice(1) : children;
|
|
158
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
159
|
+
accessibilityRole: "header",
|
|
160
|
+
style: [styles.menuLabel, style],
|
|
161
|
+
...props,
|
|
162
|
+
children: label
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/** The keystroke printed at the right of a row; the row supplies the gap. */
|
|
166
|
+
function DropdownMenuShortcut({ style, ...props }) {
|
|
167
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
168
|
+
style: [styles.shortcut, style],
|
|
169
|
+
...props
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
function DropdownMenuSeparator({ style }) {
|
|
173
|
+
return /* @__PURE__ */ jsx(View, {
|
|
174
|
+
accessible: false,
|
|
175
|
+
style: [styles.separator, style]
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
const styles = StyleSheet.create((theme) => ({
|
|
179
|
+
content: {
|
|
180
|
+
paddingVertical: theme.spacing(1),
|
|
181
|
+
uni__dependencies: [0]
|
|
182
|
+
},
|
|
183
|
+
item: {
|
|
184
|
+
flexDirection: "row",
|
|
185
|
+
alignItems: "center",
|
|
186
|
+
gap: theme.spacing(2),
|
|
187
|
+
minHeight: MIN_ROW_HEIGHT,
|
|
188
|
+
paddingHorizontal: theme.spacing(4),
|
|
189
|
+
uni__dependencies: [0]
|
|
190
|
+
},
|
|
191
|
+
indented: {
|
|
192
|
+
paddingLeft: theme.spacing(4) + INDICATOR_GUTTER,
|
|
193
|
+
uni__dependencies: [0]
|
|
194
|
+
},
|
|
195
|
+
indicator: {
|
|
196
|
+
position: "absolute",
|
|
197
|
+
left: theme.spacing(4),
|
|
198
|
+
width: theme.spacing(3),
|
|
199
|
+
height: theme.spacing(3),
|
|
200
|
+
alignItems: "center",
|
|
201
|
+
justifyContent: "center",
|
|
202
|
+
uni__dependencies: [0]
|
|
203
|
+
},
|
|
204
|
+
radioDot: {
|
|
205
|
+
width: RADIO_DOT,
|
|
206
|
+
height: RADIO_DOT,
|
|
207
|
+
borderRadius: theme.borderRadius.full,
|
|
208
|
+
backgroundColor: theme.colors.blue,
|
|
209
|
+
uni__dependencies: [0]
|
|
210
|
+
},
|
|
211
|
+
pressed: {
|
|
212
|
+
backgroundColor: theme.colors.deep,
|
|
213
|
+
uni__dependencies: [0]
|
|
214
|
+
},
|
|
215
|
+
disabled: { opacity: DISABLED_OPACITY },
|
|
216
|
+
label: {
|
|
217
|
+
flexShrink: 1,
|
|
218
|
+
fontFamily: fontOf(theme.fontFamily.sans),
|
|
219
|
+
fontSize: theme.fontSize.base,
|
|
220
|
+
lineHeight: theme.lineHeight.base,
|
|
221
|
+
variants: { variant: {
|
|
222
|
+
default: { color: theme.colors.hi },
|
|
223
|
+
destructive: { color: theme.colors.red }
|
|
224
|
+
} },
|
|
225
|
+
uni__dependencies: [0, 4]
|
|
226
|
+
},
|
|
227
|
+
menuLabel: {
|
|
228
|
+
paddingHorizontal: theme.spacing(4),
|
|
229
|
+
paddingVertical: theme.spacing(1),
|
|
230
|
+
color: theme.colors.dim,
|
|
231
|
+
fontFamily: fontOf(theme.fontFamily.sans),
|
|
232
|
+
fontSize: theme.fontSize.sm,
|
|
233
|
+
lineHeight: theme.lineHeight.sm,
|
|
234
|
+
fontWeight: theme.fontWeight.semibold,
|
|
235
|
+
uni__dependencies: [0]
|
|
236
|
+
},
|
|
237
|
+
shortcut: {
|
|
238
|
+
marginLeft: "auto",
|
|
239
|
+
flexShrink: 0,
|
|
240
|
+
color: theme.colors.dim,
|
|
241
|
+
fontFamily: fontOf(theme.fontFamily.sans),
|
|
242
|
+
fontSize: theme.fontSize.sm,
|
|
243
|
+
lineHeight: theme.lineHeight.sm,
|
|
244
|
+
uni__dependencies: [0]
|
|
245
|
+
},
|
|
246
|
+
separator: {
|
|
247
|
+
height: 1,
|
|
248
|
+
marginVertical: theme.spacing(1),
|
|
249
|
+
backgroundColor: theme.colors["border-soft"],
|
|
250
|
+
uni__dependencies: [0]
|
|
251
|
+
}
|
|
252
|
+
}));
|
|
253
|
+
|
|
254
|
+
//#endregion
|
|
255
|
+
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger };
|
|
256
|
+
//# sourceMappingURL=DropdownMenu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DropdownMenu.mjs","names":["createContext","ReactNode","useContext","StyleProp","TextProps","ViewProps","ViewStyle","StyleSheet","CheckIcon","fontOf","selectionTick","useControllable","wrapText","Button","ButtonProps","SheetFrame","INDICATOR_GUTTER","MIN_ROW_HEIGHT","DISABLED_OPACITY","RADIO_DOT","MenuState","open","setOpen","MenuContext","undefined","RadioState","value","onValueChange","RadioContext","DropdownMenuProps","defaultOpen","onOpenChange","children","DropdownMenu","current","DropdownMenuTrigger","onPress","accessibilityState","props","expanded","event","DropdownMenuContentProps","DropdownMenuContent","styles","content","DropdownMenuPartProps","Omit","style","DropdownMenuGroup","DropdownMenuItemVariant","DropdownMenuItemProps","variant","indented","disabled","onSelect","ItemRowProps","role","checked","indicator","ItemRow","_styles","useVariants","pressed","item","label","DropdownMenuItem","DropdownMenuCheckboxItemProps","onCheckedChange","DropdownMenuCheckboxItem","DropdownMenuRadioGroupProps","DropdownMenuRadioGroup","DropdownMenuRadioItemProps","DropdownMenuRadioItem","radio","radioDot","DropdownMenuLabel","charAt","toUpperCase","slice","menuLabel","DropdownMenuShortcut","shortcut","DropdownMenuSeparator","separator","create","theme","paddingVertical","spacing","uni__dependencies","flexDirection","alignItems","gap","minHeight","paddingHorizontal","paddingLeft","position","left","width","height","justifyContent","borderRadius","full","backgroundColor","colors","blue","deep","opacity","flexShrink","fontFamily","sans","fontSize","base","lineHeight","variants","default","color","hi","destructive","red","dim","sm","fontWeight","semibold","marginLeft","marginVertical"],"sources":["../../src/components/DropdownMenu.tsx"],"sourcesContent":["import { createContext, type ReactNode, useContext } from 'react';\nimport { Pressable, type StyleProp, Text, type TextProps, View, type ViewProps, type ViewStyle } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { CheckIcon } from '../icons/icons';\nimport { fontOf } from '../lib/fonts';\nimport { selectionTick } from '../lib/haptics';\nimport { useControllable } from '../lib/useControllable';\nimport { wrapText } from '../lib/wrapText';\nimport { Button, type ButtonProps } from './Button';\nimport { SheetFrame } from './SheetFrame';\n\n/*\n * The web DropdownMenu as an action sheet: the same items rise in a bottom\n * sheet, each a full-width 44pt row, choosing one ticks once and closes the\n * menu, and destructive rows are red.\n *\n * ponytail: submenus are not ported; a native action list nests by opening a\n * second menu from an item.\n */\n\n/** A row that carries a check or bullet keeps a gutter for it, so labels line up whether or not one is set. */\nconst INDICATOR_GUTTER = 28;\nconst MIN_ROW_HEIGHT = 44;\nconst DISABLED_OPACITY = 0.4;\nconst RADIO_DOT = 6;\n\ninterface MenuState {\n open: boolean;\n setOpen: (open: boolean) => void;\n}\n\nconst MenuContext = createContext<MenuState>({ open: false, setOpen: () => undefined });\n\ninterface RadioState {\n value: string | undefined;\n onValueChange: ((value: string) => void) | undefined;\n}\n\nconst RadioContext = createContext<RadioState>({ value: undefined, onValueChange: undefined });\n\nexport interface DropdownMenuProps {\n /** Controlled mode; pair with onOpenChange. Omit it and the menu keeps its own state. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: ReactNode;\n}\n\nexport function DropdownMenu({ open, defaultOpen = false, onOpenChange, children }: DropdownMenuProps) {\n const [current, setOpen] = useControllable(open, defaultOpen, onOpenChange);\n return <MenuContext.Provider value={{ open: current, setOpen }}>{children}</MenuContext.Provider>;\n}\n\n/** A Button that opens the menu; announces that it opens a menu. */\nexport function DropdownMenuTrigger({ onPress, accessibilityState, ...props }: ButtonProps) {\n const { open, setOpen } = useContext(MenuContext);\n return (\n <Button\n accessibilityState={{ ...accessibilityState, expanded: open }}\n onPress={(event) => {\n onPress?.(event);\n setOpen(true);\n }}\n {...props}\n />\n );\n}\n\nexport interface DropdownMenuContentProps {\n children?: ReactNode;\n}\n\n/** The action list, in a bottom sheet. */\nexport function DropdownMenuContent({ children }: DropdownMenuContentProps) {\n const { open, setOpen } = useContext(MenuContext);\n return (\n <SheetFrame open={open} onClose={() => setOpen(false)}>\n <View accessibilityRole=\"menu\" style={styles.content}>\n {children}\n </View>\n </SheetFrame>\n );\n}\n\nexport interface DropdownMenuPartProps extends Omit<ViewProps, 'children' | 'style'> {\n children?: ReactNode;\n style?: StyleProp<ViewStyle>;\n}\n\n/** A run of items under one label, so the separator between groups is structural. */\nexport function DropdownMenuGroup({ children, ...props }: DropdownMenuPartProps) {\n return <View {...props}>{children}</View>;\n}\n\nexport type DropdownMenuItemVariant = 'default' | 'destructive';\n\nexport interface DropdownMenuItemProps {\n variant?: DropdownMenuItemVariant;\n /** Keep the indicator gutter, so the label lines up with checkbox and radio rows. */\n indented?: boolean;\n disabled?: boolean;\n /** Chosen: the menu ticks, runs this, then closes. */\n onSelect?: () => void;\n /** The label, optionally followed by a DropdownMenuShortcut. */\n children?: ReactNode;\n style?: StyleProp<ViewStyle>;\n}\n\ninterface ItemRowProps extends DropdownMenuItemProps {\n role: 'menuitem' | 'checkbox' | 'radio';\n checked?: boolean;\n indicator?: ReactNode;\n}\n\nfunction ItemRow({\n variant = 'default',\n indented = false,\n disabled = false,\n onSelect,\n role,\n checked,\n indicator,\n children,\n style,\n}: ItemRowProps) {\n const { setOpen } = useContext(MenuContext);\n styles.useVariants({ variant: variant === 'destructive' ? 'destructive' : undefined });\n return (\n <Pressable\n accessibilityRole={role}\n accessibilityState={{ disabled, checked }}\n disabled={disabled}\n onPress={() => {\n selectionTick();\n onSelect?.();\n setOpen(false);\n }}\n style={({ pressed }) => [\n styles.item,\n (indented || indicator !== undefined) && styles.indented,\n pressed && styles.pressed,\n disabled && styles.disabled,\n style,\n ]}\n >\n {indicator !== undefined ? <View style={styles.indicator}>{indicator}</View> : null}\n {wrapText(children, styles.label)}\n </Pressable>\n );\n}\n\nexport function DropdownMenuItem(props: DropdownMenuItemProps) {\n return <ItemRow role=\"menuitem\" {...props} />;\n}\n\nexport interface DropdownMenuCheckboxItemProps extends Omit<DropdownMenuItemProps, 'indented'> {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\n/** A row that toggles: the check lives in the gutter so the label never shifts. */\nexport function DropdownMenuCheckboxItem({\n checked = false,\n onCheckedChange,\n onSelect,\n ...props\n}: DropdownMenuCheckboxItemProps) {\n return (\n <ItemRow\n role=\"checkbox\"\n checked={checked}\n indicator={checked ? <CheckIcon size={12} color=\"blue\" /> : null}\n onSelect={() => {\n onCheckedChange?.(!checked);\n onSelect?.();\n }}\n {...props}\n />\n );\n}\n\nexport interface DropdownMenuRadioGroupProps extends DropdownMenuPartProps {\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\n/** The exclusive-choice group; pair it with DropdownMenuRadioItem. */\nexport function DropdownMenuRadioGroup({ value, onValueChange, children, ...props }: DropdownMenuRadioGroupProps) {\n return (\n <RadioContext.Provider value={{ value, onValueChange }}>\n <View accessibilityRole=\"radiogroup\" {...props}>\n {children}\n </View>\n </RadioContext.Provider>\n );\n}\n\nexport interface DropdownMenuRadioItemProps extends Omit<DropdownMenuItemProps, 'indented'> {\n value: string;\n}\n\nexport function DropdownMenuRadioItem({ value, onSelect, ...props }: DropdownMenuRadioItemProps) {\n const radio = useContext(RadioContext);\n const checked = radio.value === value;\n return (\n <ItemRow\n role=\"radio\"\n checked={checked}\n indicator={checked ? <View style={styles.radioDot} /> : null}\n onSelect={() => {\n radio.onValueChange?.(value);\n onSelect?.();\n }}\n {...props}\n />\n );\n}\n\n/** The heading over a run of items, raised to sentence case as the web's `first-letter:uppercase`. */\nexport function DropdownMenuLabel({ style, children, ...props }: TextProps) {\n const label = typeof children === 'string' ? children.charAt(0).toUpperCase() + children.slice(1) : children;\n return (\n <Text accessibilityRole=\"header\" style={[styles.menuLabel, style]} {...props}>\n {label}\n </Text>\n );\n}\n\n/** The keystroke printed at the right of a row; the row supplies the gap. */\nexport function DropdownMenuShortcut({ style, ...props }: TextProps) {\n return <Text style={[styles.shortcut, style]} {...props} />;\n}\n\nexport function DropdownMenuSeparator({ style }: { style?: StyleProp<ViewStyle> }) {\n return <View accessible={false} style={[styles.separator, style]} />;\n}\n\nconst styles = StyleSheet.create((theme) => ({\n content: { paddingVertical: theme.spacing(1) },\n item: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(2),\n minHeight: MIN_ROW_HEIGHT,\n paddingHorizontal: theme.spacing(4),\n },\n indented: { paddingLeft: theme.spacing(4) + INDICATOR_GUTTER },\n indicator: {\n position: 'absolute',\n left: theme.spacing(4),\n width: theme.spacing(3),\n height: theme.spacing(3),\n alignItems: 'center',\n justifyContent: 'center',\n },\n radioDot: {\n width: RADIO_DOT,\n height: RADIO_DOT,\n borderRadius: theme.borderRadius.full,\n backgroundColor: theme.colors.blue,\n },\n pressed: { backgroundColor: theme.colors.deep },\n disabled: { opacity: DISABLED_OPACITY },\n label: {\n flexShrink: 1,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n variants: {\n variant: {\n default: { color: theme.colors.hi },\n destructive: { color: theme.colors.red },\n },\n },\n },\n menuLabel: {\n paddingHorizontal: theme.spacing(4),\n paddingVertical: theme.spacing(1),\n color: theme.colors.dim,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n fontWeight: theme.fontWeight.semibold,\n },\n shortcut: {\n marginLeft: 'auto',\n flexShrink: 0,\n color: theme.colors.dim,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n },\n separator: { height: 1, marginVertical: theme.spacing(1), backgroundColor: theme.colors['border-soft'] },\n}));\n"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
//#region src/components/EmptyState.d.ts
|
|
4
|
+
export interface EmptyStateProps {
|
|
5
|
+
title: ReactNode;
|
|
6
|
+
description?: ReactNode;
|
|
7
|
+
/** Optional calls to action under the copy. */
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
style?: StyleProp<ViewStyle>;
|
|
10
|
+
}
|
|
11
|
+
/** The centred "nothing here yet" block every empty screen and panel shares. */
|
|
12
|
+
export declare function EmptyState({ title, description, children, style }: EmptyStateProps): import("react").JSX.Element;
|
|
13
|
+
//#endregion
|
|
14
|
+
//# sourceMappingURL=EmptyState.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmptyState.d.mts","names":[],"sources":["../../src/components/EmptyState.tsx"],"mappings":";;;iBAOiB;EACf,OAAO;EACP,cAAc;;EAEd,WAAW;EACX,QAAQ,UAAU;;;wBAIJ,aAAa,OAAO,aAAa,UAAU,SAAS,kCAAe,IAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { fontOf } from "../lib/fonts.mjs";
|
|
2
|
+
import { wrapText } from "../lib/wrapText.mjs";
|
|
3
|
+
import { View } from "react-native-unistyles/components/native/View";
|
|
4
|
+
import { StyleSheet } from "react-native-unistyles";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/components/EmptyState.tsx
|
|
8
|
+
/** The centred "nothing here yet" block every empty screen and panel shares. */
|
|
9
|
+
function EmptyState({ title, description, children, style }) {
|
|
10
|
+
return /* @__PURE__ */ jsx(View, {
|
|
11
|
+
style: [styles.frame, style],
|
|
12
|
+
children: /* @__PURE__ */ jsxs(View, {
|
|
13
|
+
style: styles.column,
|
|
14
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ jsx(View, {
|
|
16
|
+
accessibilityRole: "header",
|
|
17
|
+
children: wrapText(title, styles.title)
|
|
18
|
+
}),
|
|
19
|
+
description ? wrapText(description, styles.description) : null,
|
|
20
|
+
children
|
|
21
|
+
]
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const styles = StyleSheet.create((theme) => ({
|
|
26
|
+
frame: {
|
|
27
|
+
flex: 1,
|
|
28
|
+
minWidth: 0,
|
|
29
|
+
alignItems: "center",
|
|
30
|
+
justifyContent: "center",
|
|
31
|
+
paddingHorizontal: theme.spacing(3),
|
|
32
|
+
paddingVertical: theme.spacing(4),
|
|
33
|
+
uni__dependencies: [0]
|
|
34
|
+
},
|
|
35
|
+
column: {
|
|
36
|
+
width: "100%",
|
|
37
|
+
maxWidth: 520,
|
|
38
|
+
minWidth: 0,
|
|
39
|
+
alignItems: "center",
|
|
40
|
+
gap: theme.spacing(3),
|
|
41
|
+
uni__dependencies: [0]
|
|
42
|
+
},
|
|
43
|
+
title: {
|
|
44
|
+
color: theme.colors.hi,
|
|
45
|
+
fontFamily: fontOf(theme.fontFamily.sans),
|
|
46
|
+
fontSize: theme.fontSize.lg,
|
|
47
|
+
lineHeight: theme.lineHeight.lg,
|
|
48
|
+
fontWeight: theme.fontWeight.semibold,
|
|
49
|
+
textAlign: "center",
|
|
50
|
+
uni__dependencies: [0]
|
|
51
|
+
},
|
|
52
|
+
description: {
|
|
53
|
+
color: theme.colors.dim,
|
|
54
|
+
fontFamily: fontOf(theme.fontFamily.sans),
|
|
55
|
+
fontSize: theme.fontSize.base,
|
|
56
|
+
lineHeight: theme.lineHeightRelaxed.base,
|
|
57
|
+
textAlign: "center",
|
|
58
|
+
uni__dependencies: [0]
|
|
59
|
+
}
|
|
60
|
+
}));
|
|
61
|
+
|
|
62
|
+
//#endregion
|
|
63
|
+
export { EmptyState };
|
|
64
|
+
//# sourceMappingURL=EmptyState.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmptyState.mjs","names":["ReactNode","StyleProp","ViewStyle","StyleSheet","fontOf","wrapText","EmptyStateProps","title","description","children","style","EmptyState","styles","frame","column","create","theme","flex","minWidth","alignItems","justifyContent","paddingHorizontal","spacing","paddingVertical","uni__dependencies","width","maxWidth","gap","color","colors","hi","fontFamily","sans","fontSize","lg","lineHeight","fontWeight","semibold","textAlign","dim","base","lineHeightRelaxed"],"sources":["../../src/components/EmptyState.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { type StyleProp, View, type ViewStyle } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\nimport { wrapText } from '../lib/wrapText';\n\nexport interface EmptyStateProps {\n title: ReactNode;\n description?: ReactNode;\n /** Optional calls to action under the copy. */\n children?: ReactNode;\n style?: StyleProp<ViewStyle>;\n}\n\n/** The centred \"nothing here yet\" block every empty screen and panel shares. */\nexport function EmptyState({ title, description, children, style }: EmptyStateProps) {\n return (\n <View style={[styles.frame, style]}>\n <View style={styles.column}>\n <View accessibilityRole=\"header\">{wrapText(title, styles.title)}</View>\n {description ? wrapText(description, styles.description) : null}\n {children}\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n frame: {\n flex: 1,\n minWidth: 0,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: theme.spacing(3),\n paddingVertical: theme.spacing(4),\n },\n column: {\n width: '100%',\n maxWidth: 520,\n minWidth: 0,\n alignItems: 'center',\n gap: theme.spacing(3),\n },\n title: {\n color: theme.colors.hi,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.lg,\n lineHeight: theme.lineHeight.lg,\n fontWeight: theme.fontWeight.semibold,\n textAlign: 'center',\n },\n description: {\n color: theme.colors.dim,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeightRelaxed.base,\n textAlign: 'center',\n },\n}));\n"],"mappings":";;;;;;;;AAgBA,SAAgBW,WAAW,EAAEJ,OAAOC,aAAaC,UAAUC,SAA0B;CACnF,OACE,oBAAC,MAAD;EAAM,OAAO,CAACE,OAAOC,OAAOH,KAAK;YAC/B,qBAAC,MAAD;GAAM,OAAOE,OAAOE;aAApB;IACE,oBAAC,MAAD;KAAM,mBAAkB;eAAUT,SAASE,OAAOK,OAAOL,KAAK;IAAQ;IACrEC,cAAcH,SAASG,aAAaI,OAAOJ,WAAW,IAAI;IAC1DC;GACG;;CACF;AAEV;AAEA,MAAMG,SAAST,WAAWY,QAAQC,WAAW;CAC3CH,OAAO;EACLI,MAAM;EACNC,UAAU;EACVC,YAAY;EACZC,gBAAgB;EAChBC,mBAAmBL,MAAMM,QAAQ,CAAC;EAClCC,iBAAiBP,MAAMM,QAAQ,CAAC;EAACE,mBAAA,CAAA,CAAA;CACnC;CACAV,QAAQ;EACNW,OAAO;EACPC,UAAU;EACVR,UAAU;EACVC,YAAY;EACZQ,KAAKX,MAAMM,QAAQ,CAAC;EAACE,mBAAA,CAAA,CAAA;CACvB;CACAjB,OAAO;EACLqB,OAAOZ,MAAMa,OAAOC;EACpBC,YAAY3B,OAAOY,MAAMe,WAAWC,IAAI;EACxCC,UAAUjB,MAAMiB,SAASC;EACzBC,YAAYnB,MAAMmB,WAAWD;EAC7BE,YAAYpB,MAAMoB,WAAWC;EAC7BC,WAAW;EAAQd,mBAAA,CAAA,CAAA;CACrB;CACAhB,aAAa;EACXoB,OAAOZ,MAAMa,OAAOU;EACpBR,YAAY3B,OAAOY,MAAMe,WAAWC,IAAI;EACxCC,UAAUjB,MAAMiB,SAASO;EACzBL,YAAYnB,MAAMyB,kBAAkBD;EACpCF,WAAW;EAAQd,mBAAA,CAAA,CAAA;CACrB;AACF,EAAE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TextInputProps } from "react-native";
|
|
2
|
+
//#region src/components/Input.d.ts
|
|
3
|
+
export type FieldVariant = 'default' | 'bare';
|
|
4
|
+
export type FieldSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
5
|
+
export interface InputProps extends Omit<TextInputProps, 'editable'> {
|
|
6
|
+
variant?: FieldVariant;
|
|
7
|
+
/** The same rungs Button names, so a field and the button beside it line up. */
|
|
8
|
+
size?: FieldSize;
|
|
9
|
+
/** The value is wrong: red edge and red text, as `aria-invalid` on the web. */
|
|
10
|
+
invalid?: boolean;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The one text field: deep well, quiet border, jade edge and cursor on focus,
|
|
15
|
+
* red edge when invalid. Inside a Sheet it becomes the sheet's own input.
|
|
16
|
+
*/
|
|
17
|
+
export declare function Input({ variant, size, invalid, disabled, style, onFocus, onBlur, accessibilityState, ...props }: InputProps): import("react").JSX.Element;
|
|
18
|
+
//#endregion
|
|
19
|
+
//# sourceMappingURL=Input.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.d.mts","names":[],"sources":["../../src/components/Input.tsx"],"mappings":";;YASY;YACA;iBAOK,mBAAmB,KAAK;EACvC,UAAU;;EAEV,OAAO;;EAEP;EACA;;;;;;wBAOc,QACd,SACA,MACA,SACA,UACA,OACA,SACA,QACA,uBACG,SACF,6BAAU,IAAA"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { fontOf } from "../lib/fonts.mjs";
|
|
2
|
+
import { useInsideSheet } from "../lib/insideSheet.mjs";
|
|
3
|
+
import { withAlpha } from "@agimon-ai/po-web-components/nativeTheme";
|
|
4
|
+
import { StyleSheet, useUnistyles, withUnistyles } from "react-native-unistyles";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
import { BottomSheetTextInput } from "@gorhom/bottom-sheet";
|
|
8
|
+
import { TextInput } from "react-native-unistyles/components/native/TextInput";
|
|
9
|
+
|
|
10
|
+
//#region src/components/Input.tsx
|
|
11
|
+
/** `focus:border-doom-green/60`. */
|
|
12
|
+
const FOCUS_EDGE_ALPHA_PERCENT = 60;
|
|
13
|
+
const DISABLED_OPACITY = .5;
|
|
14
|
+
const ThemedSheetTextInput = withUnistyles(BottomSheetTextInput);
|
|
15
|
+
/**
|
|
16
|
+
* The one text field: deep well, quiet border, jade edge and cursor on focus,
|
|
17
|
+
* red edge when invalid. Inside a Sheet it becomes the sheet's own input.
|
|
18
|
+
*/
|
|
19
|
+
function Input({ variant = "default", size = "md", invalid = false, disabled = false, style, onFocus, onBlur, accessibilityState, ...props }) {
|
|
20
|
+
const { theme } = useUnistyles();
|
|
21
|
+
const [focused, setFocused] = useState(false);
|
|
22
|
+
const Field = useInsideSheet() ? ThemedSheetTextInput : TextInput;
|
|
23
|
+
const _styles = styles;
|
|
24
|
+
{
|
|
25
|
+
const styles = _styles.useVariants({
|
|
26
|
+
variant: variant === "bare" ? "bare" : void 0,
|
|
27
|
+
size
|
|
28
|
+
});
|
|
29
|
+
return /* @__PURE__ */ jsx(Field, {
|
|
30
|
+
autoCorrect: false,
|
|
31
|
+
spellCheck: false,
|
|
32
|
+
placeholderTextColor: theme.colors.faint,
|
|
33
|
+
selectionColor: theme.colors.green,
|
|
34
|
+
cursorColor: theme.colors.green,
|
|
35
|
+
editable: !disabled,
|
|
36
|
+
accessibilityState: {
|
|
37
|
+
...accessibilityState,
|
|
38
|
+
disabled
|
|
39
|
+
},
|
|
40
|
+
onFocus: (event) => {
|
|
41
|
+
setFocused(true);
|
|
42
|
+
onFocus?.(event);
|
|
43
|
+
},
|
|
44
|
+
onBlur: (event) => {
|
|
45
|
+
setFocused(false);
|
|
46
|
+
onBlur?.(event);
|
|
47
|
+
},
|
|
48
|
+
style: [
|
|
49
|
+
styles.field,
|
|
50
|
+
focused && variant === "default" && { borderColor: withAlpha(theme.colors.green, FOCUS_EDGE_ALPHA_PERCENT) },
|
|
51
|
+
invalid && styles.invalid,
|
|
52
|
+
disabled && styles.disabled,
|
|
53
|
+
style
|
|
54
|
+
],
|
|
55
|
+
...props
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const styles = StyleSheet.create((theme) => ({
|
|
60
|
+
field: {
|
|
61
|
+
minWidth: 0,
|
|
62
|
+
minHeight: 44,
|
|
63
|
+
color: theme.colors.hi,
|
|
64
|
+
fontFamily: fontOf(theme.fontFamily.sans),
|
|
65
|
+
variants: {
|
|
66
|
+
variant: {
|
|
67
|
+
default: {
|
|
68
|
+
borderRadius: theme.borderRadius.DEFAULT,
|
|
69
|
+
borderWidth: 1,
|
|
70
|
+
borderColor: theme.colors.border,
|
|
71
|
+
backgroundColor: theme.colors.deep
|
|
72
|
+
},
|
|
73
|
+
/** No well: a composer or a search that draws its own surface keeps the type and drops the box. */
|
|
74
|
+
bare: {
|
|
75
|
+
borderWidth: 0,
|
|
76
|
+
backgroundColor: "transparent",
|
|
77
|
+
padding: 0
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
size: {
|
|
81
|
+
xs: {
|
|
82
|
+
paddingHorizontal: theme.spacing(1.5),
|
|
83
|
+
paddingVertical: theme.spacing(.5),
|
|
84
|
+
fontSize: theme.fontSize.sm
|
|
85
|
+
},
|
|
86
|
+
sm: {
|
|
87
|
+
paddingHorizontal: theme.spacing(2),
|
|
88
|
+
paddingVertical: theme.spacing(1),
|
|
89
|
+
fontSize: theme.fontSize.sm
|
|
90
|
+
},
|
|
91
|
+
md: {
|
|
92
|
+
paddingHorizontal: theme.spacing(2.5),
|
|
93
|
+
paddingVertical: theme.spacing(1.5),
|
|
94
|
+
fontSize: theme.fontSize.base
|
|
95
|
+
},
|
|
96
|
+
lg: {
|
|
97
|
+
paddingHorizontal: theme.spacing(3),
|
|
98
|
+
paddingVertical: theme.spacing(1.5),
|
|
99
|
+
fontSize: theme.fontSize.base
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
compoundVariants: [{
|
|
104
|
+
variant: "bare",
|
|
105
|
+
styles: {
|
|
106
|
+
padding: 0,
|
|
107
|
+
paddingHorizontal: 0,
|
|
108
|
+
paddingVertical: 0
|
|
109
|
+
}
|
|
110
|
+
}],
|
|
111
|
+
uni__dependencies: [0, 4]
|
|
112
|
+
},
|
|
113
|
+
invalid: {
|
|
114
|
+
borderColor: theme.colors["edge-red"],
|
|
115
|
+
color: theme.colors.red,
|
|
116
|
+
uni__dependencies: [0]
|
|
117
|
+
},
|
|
118
|
+
disabled: { opacity: DISABLED_OPACITY }
|
|
119
|
+
}));
|
|
120
|
+
|
|
121
|
+
//#endregion
|
|
122
|
+
export { Input };
|
|
123
|
+
//# sourceMappingURL=Input.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.mjs","names":["withAlpha","BottomSheetTextInput","useState","TextInputProps","StyleSheet","useUnistyles","withUnistyles","fontOf","useInsideSheet","FieldVariant","FieldSize","FOCUS_EDGE_ALPHA_PERCENT","DISABLED_OPACITY","ThemedSheetTextInput","InputProps","Omit","variant","size","invalid","disabled","Input","style","onFocus","onBlur","accessibilityState","props","theme","focused","setFocused","Field","TextInput","_styles","styles","useVariants","undefined","colors","faint","green","event","field","borderColor","create","minWidth","minHeight","color","hi","fontFamily","sans","variants","default","borderRadius","DEFAULT","borderWidth","border","backgroundColor","deep","bare","padding","xs","paddingHorizontal","spacing","paddingVertical","fontSize","sm","md","base","lg","compoundVariants","uni__dependencies","red","opacity"],"sources":["../../src/components/Input.tsx"],"sourcesContent":["import { withAlpha } from '@agimon-ai/po-web-components/nativeTheme';\nimport { BottomSheetTextInput } from '@gorhom/bottom-sheet';\nimport { useState } from 'react';\nimport { TextInput, type TextInputProps } from 'react-native';\nimport { StyleSheet, useUnistyles, withUnistyles } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\nimport { useInsideSheet } from '../lib/insideSheet';\n\nexport type FieldVariant = 'default' | 'bare';\nexport type FieldSize = 'xs' | 'sm' | 'md' | 'lg';\n\n/** `focus:border-doom-green/60`. */\nconst FOCUS_EDGE_ALPHA_PERCENT = 60;\nconst DISABLED_OPACITY = 0.5;\n\nconst ThemedSheetTextInput = withUnistyles(BottomSheetTextInput);\nexport interface InputProps extends Omit<TextInputProps, 'editable'> {\n variant?: FieldVariant;\n /** The same rungs Button names, so a field and the button beside it line up. */\n size?: FieldSize;\n /** The value is wrong: red edge and red text, as `aria-invalid` on the web. */\n invalid?: boolean;\n disabled?: boolean;\n}\n\n/**\n * The one text field: deep well, quiet border, jade edge and cursor on focus,\n * red edge when invalid. Inside a Sheet it becomes the sheet's own input.\n */\nexport function Input({\n variant = 'default',\n size = 'md',\n invalid = false,\n disabled = false,\n style,\n onFocus,\n onBlur,\n accessibilityState,\n ...props\n}: InputProps) {\n const { theme } = useUnistyles();\n const [focused, setFocused] = useState(false);\n // Inside a Sheet the field must be the sheet's own input, so the sheet rises with the keyboard.\n const Field = useInsideSheet() ? ThemedSheetTextInput : TextInput;\n // Unistyles reserves a variant named `default` as the fallback for an unset variant.\n styles.useVariants({ variant: variant === 'bare' ? 'bare' : undefined, size });\n return (\n <Field\n autoCorrect={false}\n spellCheck={false}\n placeholderTextColor={theme.colors.faint}\n selectionColor={theme.colors.green}\n cursorColor={theme.colors.green}\n editable={!disabled}\n accessibilityState={{ ...accessibilityState, disabled }}\n onFocus={(event) => {\n setFocused(true);\n onFocus?.(event);\n }}\n onBlur={(event) => {\n setFocused(false);\n onBlur?.(event);\n }}\n style={[\n styles.field,\n // Alpha mixes are computed in render from useUnistyles(), not in StyleSheet.create: on web Unistyles hands\n // the stylesheet CSS variables, which withAlpha cannot read.\n focused && variant === 'default' && { borderColor: withAlpha(theme.colors.green, FOCUS_EDGE_ALPHA_PERCENT) },\n invalid && styles.invalid,\n disabled && styles.disabled,\n style,\n ]}\n {...props}\n />\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n field: {\n minWidth: 0,\n minHeight: 44,\n color: theme.colors.hi,\n fontFamily: fontOf(theme.fontFamily.sans),\n variants: {\n variant: {\n default: {\n borderRadius: theme.borderRadius.DEFAULT,\n borderWidth: 1,\n borderColor: theme.colors.border,\n backgroundColor: theme.colors.deep,\n },\n /** No well: a composer or a search that draws its own surface keeps the type and drops the box. */\n bare: { borderWidth: 0, backgroundColor: 'transparent', padding: 0 },\n },\n size: {\n xs: {\n paddingHorizontal: theme.spacing(1.5),\n paddingVertical: theme.spacing(0.5),\n fontSize: theme.fontSize.sm,\n },\n sm: {\n paddingHorizontal: theme.spacing(2),\n paddingVertical: theme.spacing(1),\n fontSize: theme.fontSize.sm,\n },\n md: {\n paddingHorizontal: theme.spacing(2.5),\n paddingVertical: theme.spacing(1.5),\n fontSize: theme.fontSize.base,\n },\n lg: {\n paddingHorizontal: theme.spacing(3),\n paddingVertical: theme.spacing(1.5),\n fontSize: theme.fontSize.base,\n },\n },\n },\n compoundVariants: [{ variant: 'bare', styles: { padding: 0, paddingHorizontal: 0, paddingVertical: 0 } }],\n },\n invalid: { borderColor: theme.colors['edge-red'], color: theme.colors.red },\n disabled: { opacity: DISABLED_OPACITY },\n}));\n"],"mappings":";;;;;;;;;;;AAaA,MAAMW,2BAA2B;AACjC,MAAMC,mBAAmB;AAEzB,MAAMC,uBAAuBP,cAAcL,oBAAoB;;;;;AAc/D,SAAgBmB,MAAM,EACpBJ,UAAU,WACVC,OAAO,MACPC,UAAU,OACVC,WAAW,OACXE,OACAC,SACAC,QACAC,oBACA,GAAGC,SACU;CACb,MAAM,EAAEC,UAAUrB,aAAa;CAC/B,MAAM,CAACsB,SAASC,cAAc1B,SAAS,KAAK;CAE5C,MAAM2B,QAAQrB,eAAe,IAAIK,uBAAuBiB;CACxD,MAAAC,UAAAC;CAAA;EAAA,MAAAA,SAAAD,QAAAE,YACmB;GAAEjB,SAASA,YAAY,SAAS,SAASkB;GAAWjB;EAAK,CAAC;EAC7E,OACE,oBAAC,OAAD;GACE,aAAa;GACb,YAAY;GACZ,sBAAsBS,MAAMS,OAAOC;GACnC,gBAAgBV,MAAMS,OAAOE;GAC7B,aAAaX,MAAMS,OAAOE;GAC1B,UAAU,CAAClB;GACX,oBAAoB;IAAE,GAAGK;IAAoBL;GAAS;GACtD,UAAUmB,UAAU;IAClBV,WAAW,IAAI;IACfN,UAAUgB,KAAK;GACjB;GACA,SAASA,UAAU;IACjBV,WAAW,KAAK;IAChBL,SAASe,KAAK;GAChB;GACA,OAAO;IACLN,OAAOO;IAGPZ,WAAWX,YAAY,aAAa,EAAEwB,aAAaxC,UAAU0B,MAAMS,OAAOE,OAAO1B,wBAAwB,EAAE;IAC3GO,WAAWc,OAAOd;IAClBC,YAAYa,OAAOb;IACnBE;GAAK;GAEP,GAAII;EAAM;CAEZ;AACJ;AAEA,MAAMO,SAAS5B,WAAWqC,QAAQf,WAAW;CAC3Ca,OAAO;EACLG,UAAU;EACVC,WAAW;EACXC,OAAOlB,MAAMS,OAAOU;EACpBC,YAAYvC,OAAOmB,MAAMoB,WAAWC,IAAI;EACxCC,UAAU;GACRhC,SAAS;IACPiC,SAAS;KACPC,cAAcxB,MAAMwB,aAAaC;KACjCC,aAAa;KACbZ,aAAad,MAAMS,OAAOkB;KAC1BC,iBAAiB5B,MAAMS,OAAOoB;IAChC;;IAEAC,MAAM;KAAEJ,aAAa;KAAGE,iBAAiB;KAAeG,SAAS;IAAE;GACrE;GACAxC,MAAM;IACJyC,IAAI;KACFC,mBAAmBjC,MAAMkC,QAAQ,GAAG;KACpCC,iBAAiBnC,MAAMkC,QAAQ,EAAG;KAClCE,UAAUpC,MAAMoC,SAASC;IAC3B;IACAA,IAAI;KACFJ,mBAAmBjC,MAAMkC,QAAQ,CAAC;KAClCC,iBAAiBnC,MAAMkC,QAAQ,CAAC;KAChCE,UAAUpC,MAAMoC,SAASC;IAC3B;IACAC,IAAI;KACFL,mBAAmBjC,MAAMkC,QAAQ,GAAG;KACpCC,iBAAiBnC,MAAMkC,QAAQ,GAAG;KAClCE,UAAUpC,MAAMoC,SAASG;IAC3B;IACAC,IAAI;KACFP,mBAAmBjC,MAAMkC,QAAQ,CAAC;KAClCC,iBAAiBnC,MAAMkC,QAAQ,GAAG;KAClCE,UAAUpC,MAAMoC,SAASG;IAC3B;GACF;EACF;EACAE,kBAAkB,CAAC;GAAEnD,SAAS;GAAQgB,QAAQ;IAAEyB,SAAS;IAAGE,mBAAmB;IAAGE,iBAAiB;GAAE;EAAE,CAAC;EAACO,mBAAA,CAAA,GAAA,CAAA;CAC3G;CACAlD,SAAS;EAAEsB,aAAad,MAAMS,OAAO;EAAaS,OAAOlB,MAAMS,OAAOkC;EAAGD,mBAAA,CAAA,CAAA;CAAC;CAC1EjD,UAAU,EAAEmD,SAAS1D,iBAAiB;AACxC,EAAE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TextProps } from "react-native";
|
|
2
|
+
//#region src/components/Label.d.ts
|
|
3
|
+
export interface LabelProps extends TextProps {
|
|
4
|
+
/** The field it names is disabled; the label fades with it. */
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A field's name. Give it a `nativeID` and point the field's
|
|
9
|
+
* `accessibilityLabelledBy` at it so a screen reader reads the two together.
|
|
10
|
+
*/
|
|
11
|
+
export declare function Label({ disabled, style, ...props }: LabelProps): import("react").JSX.Element;
|
|
12
|
+
//#endregion
|
|
13
|
+
//# sourceMappingURL=Label.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Label.d.mts","names":[],"sources":["../../src/components/Label.tsx"],"mappings":";;iBAKiB,mBAAmB;;EAElC;;;;;;wBAOc,QAAQ,UAAkB,UAAU,SAAS,6BAAU,IAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { fontOf } from "../lib/fonts.mjs";
|
|
2
|
+
import { StyleSheet } from "react-native-unistyles";
|
|
3
|
+
import { Text } from "react-native-unistyles/components/native/Text";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/components/Label.tsx
|
|
7
|
+
/**
|
|
8
|
+
* A field's name. Give it a `nativeID` and point the field's
|
|
9
|
+
* `accessibilityLabelledBy` at it so a screen reader reads the two together.
|
|
10
|
+
*/
|
|
11
|
+
function Label({ disabled = false, style, ...props }) {
|
|
12
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
13
|
+
style: [
|
|
14
|
+
styles.label,
|
|
15
|
+
disabled && styles.disabled,
|
|
16
|
+
style
|
|
17
|
+
],
|
|
18
|
+
...props
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const DISABLED_OPACITY = .5;
|
|
22
|
+
const styles = StyleSheet.create((theme) => ({
|
|
23
|
+
label: {
|
|
24
|
+
color: theme.colors.text,
|
|
25
|
+
fontFamily: fontOf(theme.fontFamily.sans),
|
|
26
|
+
fontSize: theme.fontSize.base,
|
|
27
|
+
lineHeight: theme.lineHeight.base,
|
|
28
|
+
fontWeight: theme.fontWeight.medium,
|
|
29
|
+
uni__dependencies: [0]
|
|
30
|
+
},
|
|
31
|
+
disabled: { opacity: DISABLED_OPACITY }
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { Label };
|
|
36
|
+
//# sourceMappingURL=Label.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Label.mjs","names":["TextProps","StyleSheet","fontOf","LabelProps","disabled","Label","style","props","styles","label","DISABLED_OPACITY","create","theme","color","colors","text","fontFamily","sans","fontSize","base","lineHeight","fontWeight","medium","uni__dependencies","opacity"],"sources":["../../src/components/Label.tsx"],"sourcesContent":["import { Text, type TextProps } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\n\nexport interface LabelProps extends TextProps {\n /** The field it names is disabled; the label fades with it. */\n disabled?: boolean;\n}\n\n/**\n * A field's name. Give it a `nativeID` and point the field's\n * `accessibilityLabelledBy` at it so a screen reader reads the two together.\n */\nexport function Label({ disabled = false, style, ...props }: LabelProps) {\n return <Text style={[styles.label, disabled && styles.disabled, style]} {...props} />;\n}\n\nconst DISABLED_OPACITY = 0.5;\n\nconst styles = StyleSheet.create((theme) => ({\n label: {\n color: theme.colors.text,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n fontWeight: theme.fontWeight.medium,\n },\n disabled: { opacity: DISABLED_OPACITY },\n}));\n"],"mappings":";;;;;;;;;;AAcA,SAAgBK,MAAM,EAAED,WAAW,OAAOE,OAAO,GAAGC,SAAqB;CACvE,OAAO,oBAAC,MAAD;EAAM,OAAO;GAACC,OAAOC;GAAOL,YAAYI,OAAOJ;GAAUE;EAAK;EAAG,GAAIC;CAAM;AACpF;AAEA,MAAMG,mBAAmB;AAEzB,MAAMF,SAASP,WAAWU,QAAQC,WAAW;CAC3CH,OAAO;EACLI,OAAOD,MAAME,OAAOC;EACpBC,YAAYd,OAAOU,MAAMI,WAAWC,IAAI;EACxCC,UAAUN,MAAMM,SAASC;EACzBC,YAAYR,MAAMQ,WAAWD;EAC7BE,YAAYT,MAAMS,WAAWC;EAAMC,mBAAA,CAAA,CAAA;CACrC;CACAnB,UAAU,EAAEoB,SAASd,iBAAiB;AACxC,EAAE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
2
|
+
import { ReactElement, ReactNode } from "react";
|
|
3
|
+
//#region src/components/List.d.ts
|
|
4
|
+
export interface ListProps<T> {
|
|
5
|
+
data: readonly T[];
|
|
6
|
+
renderItem: (item: T, index: number) => ReactElement | null;
|
|
7
|
+
/** A stable key per row; FlashList recycles views by it. */
|
|
8
|
+
keyExtractor: (item: T, index: number) => string;
|
|
9
|
+
/**
|
|
10
|
+
* A chat list: render from the bottom and keep the newest row in view as
|
|
11
|
+
* rows arrive, while the reader is near the bottom.
|
|
12
|
+
*/
|
|
13
|
+
startAtBottom?: boolean;
|
|
14
|
+
/** Hairline separators between rows. On by default. */
|
|
15
|
+
separators?: boolean;
|
|
16
|
+
/** Shown when `data` is empty. */
|
|
17
|
+
empty?: ReactNode;
|
|
18
|
+
header?: ReactNode;
|
|
19
|
+
footer?: ReactNode;
|
|
20
|
+
onEndReached?: () => void;
|
|
21
|
+
accessibilityLabel?: string;
|
|
22
|
+
/** The list's frame; give it a height or a flex parent, since a virtualised list needs bounds. */
|
|
23
|
+
style?: StyleProp<ViewStyle>;
|
|
24
|
+
/** Padding around the rows. */
|
|
25
|
+
contentPadding?: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function List<T>({ data, renderItem, keyExtractor, startAtBottom, separators, empty, header, footer, onEndReached, accessibilityLabel, style, contentPadding }: ListProps<T>): import("react").JSX.Element;
|
|
28
|
+
export interface ListRowProps {
|
|
29
|
+
title: ReactNode;
|
|
30
|
+
/** A second, quieter line under the title. */
|
|
31
|
+
description?: ReactNode;
|
|
32
|
+
/** Before the text: a Dot, an icon. */
|
|
33
|
+
leading?: ReactNode;
|
|
34
|
+
/** After the text: a Badge, a ghost button, a count. */
|
|
35
|
+
trailing?: ReactNode;
|
|
36
|
+
/** Selected rows sit on a green tint. */
|
|
37
|
+
selected?: boolean;
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
onPress?: () => void;
|
|
40
|
+
/** The iOS disclosure chevron. Defaults to on for a pressable row on iOS, where rows that navigate wear one. */
|
|
41
|
+
disclosure?: boolean;
|
|
42
|
+
accessibilityLabel?: string;
|
|
43
|
+
style?: StyleProp<ViewStyle>;
|
|
44
|
+
}
|
|
45
|
+
/** One list row: 44pt tall, optional leading and trailing slots, pressable when it navigates. */
|
|
46
|
+
export declare function ListRow({ title, description, leading, trailing, selected, disabled, onPress, disclosure, accessibilityLabel, style }: ListRowProps): import("react").JSX.Element;
|
|
47
|
+
//#endregion
|
|
48
|
+
//# sourceMappingURL=List.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"List.d.mts","names":[],"sources":["../../src/components/List.tsx"],"mappings":";;;iBAoBiB,UAAU;EACzB,eAAe;EACf,aAAa,MAAM,GAAG,kBAAkB;;EAExC,eAAe,MAAM,GAAG;;;;;EAKxB;;EAEA;;EAEA,QAAQ;EACR,SAAS;EACT,SAAS;EACT;EACA;;EAEA,QAAQ,UAAU;;EAElB;;wBAOc,KAAK,KACnB,MACA,YACA,cACA,eACA,YACA,OACA,QACA,QACA,cACA,oBACA,OACA,kBACC,UAAU,qBAAE,IAAA;iBAuBE;EACf,OAAO;;EAEP,cAAc;;EAEd,UAAU;;EAEV,WAAW;;EAEX;EACA;EACA;;EAEA;EACA;EACA,QAAQ,UAAU;;;wBAIJ,UACd,OACA,aACA,SACA,UACA,UACA,UACA,SACA,YACA,oBACA,SACC,+BAAY,IAAA"}
|