@agimon-ai/po-native-components 0.0.0-alpha.36 → 0.0.0-alpha.38
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/dist/components/CodeBlock.d.mts +3 -1
- package/dist/components/CodeBlock.d.mts.map +1 -1
- package/dist/components/CodeBlock.mjs +33 -16
- package/dist/components/CodeBlock.mjs.map +1 -1
- package/dist/components/DropdownMenu.d.mts.map +1 -1
- package/dist/components/DropdownMenu.mjs +10 -4
- package/dist/components/DropdownMenu.mjs.map +1 -1
- package/dist/components/HashlineLines.d.mts.map +1 -1
- package/dist/components/HashlineLines.mjs +13 -4
- package/dist/components/HashlineLines.mjs.map +1 -1
- package/dist/components/Input.mjs +2 -1
- package/dist/components/Input.mjs.map +1 -1
- package/dist/components/List.d.mts.map +1 -1
- package/dist/components/List.mjs +2 -0
- package/dist/components/List.mjs.map +1 -1
- package/dist/components/Markdown.d.mts +3 -1
- package/dist/components/Markdown.d.mts.map +1 -1
- package/dist/components/Markdown.mjs +160 -38
- package/dist/components/Markdown.mjs.map +1 -1
- package/dist/components/Sheet.d.mts +3 -1
- package/dist/components/Sheet.d.mts.map +1 -1
- package/dist/components/Sheet.mjs +10 -3
- package/dist/components/Sheet.mjs.map +1 -1
- package/dist/components/SheetFrame.mjs +5 -2
- package/dist/components/SheetFrame.mjs.map +1 -1
- package/dist/components/SheetList.d.mts +12 -0
- package/dist/components/SheetList.d.mts.map +1 -0
- package/dist/components/SheetList.mjs +33 -0
- package/dist/components/SheetList.mjs.map +1 -0
- package/dist/components/ShowMore.d.mts +10 -0
- package/dist/components/ShowMore.d.mts.map +1 -0
- package/dist/components/ShowMore.mjs +44 -0
- package/dist/components/ShowMore.mjs.map +1 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +3 -1
- package/dist/lib/markdown.mjs.map +1 -1
- package/dist/lib/reading.mjs +60 -0
- package/dist/lib/reading.mjs.map +1 -0
- package/dist/lib/useReadingPage.mjs +33 -0
- package/dist/lib/useReadingPage.mjs.map +1 -0
- package/package.json +12 -12
|
@@ -4,7 +4,9 @@ export interface CodeBlockProps {
|
|
|
4
4
|
text: string;
|
|
5
5
|
/** The fence's language word, such as `ts`; the web reads it from a `language-*` class. */
|
|
6
6
|
language?: string;
|
|
7
|
+
/** Initial reveal pages, useful for a reader restored to a known position. */
|
|
8
|
+
initialPage?: number;
|
|
7
9
|
}
|
|
8
|
-
export declare function CodeBlock({ text, language }: CodeBlockProps): import("react").JSX.Element;
|
|
10
|
+
export declare function CodeBlock({ text, language, initialPage }: CodeBlockProps): import("react").JSX.Element;
|
|
9
11
|
//#endregion
|
|
10
12
|
//# sourceMappingURL=CodeBlock.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlock.d.mts","names":[],"sources":["../../src/components/CodeBlock.tsx"],"mappings":";
|
|
1
|
+
{"version":3,"file":"CodeBlock.d.mts","names":[],"sources":["../../src/components/CodeBlock.tsx"],"mappings":";iBAiBiB;;EAEf;;EAEA;;EAEA;;wBAGc,YAAY,MAAM,UAAU,eAAmB,iCAAc,IAAA"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { fontOf } from "../lib/fonts.mjs";
|
|
2
|
+
import { codePrefix } from "../lib/reading.mjs";
|
|
3
|
+
import { useReadingPage } from "../lib/useReadingPage.mjs";
|
|
2
4
|
import { CopyButton } from "./CopyButton.mjs";
|
|
5
|
+
import { ShowMore } from "./ShowMore.mjs";
|
|
3
6
|
import { View } from "react-native-unistyles/components/native/View";
|
|
4
7
|
import { Text } from "react-native-unistyles/components/native/Text";
|
|
5
8
|
import { StyleSheet } from "react-native-unistyles";
|
|
@@ -7,26 +10,40 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
7
10
|
import { ScrollView } from "react-native-unistyles/components/native/ScrollView";
|
|
8
11
|
|
|
9
12
|
//#region src/components/CodeBlock.tsx
|
|
10
|
-
function CodeBlock({ text, language }) {
|
|
13
|
+
function CodeBlock({ text, language, initialPage = 1 }) {
|
|
14
|
+
const { page, reveal } = useReadingPage(text, initialPage);
|
|
15
|
+
const visible = codePrefix(text, page);
|
|
11
16
|
return /* @__PURE__ */ jsxs(View, {
|
|
12
|
-
style: styles.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
style: styles.root,
|
|
18
|
+
children: [/* @__PURE__ */ jsxs(View, {
|
|
19
|
+
style: styles.block,
|
|
20
|
+
accessibilityLabel: language === void 0 ? void 0 : `${language} code`,
|
|
21
|
+
children: [/* @__PURE__ */ jsx(ScrollView, {
|
|
22
|
+
horizontal: true,
|
|
23
|
+
showsHorizontalScrollIndicator: false,
|
|
24
|
+
contentContainerStyle: styles.scroll,
|
|
25
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
26
|
+
selectable: true,
|
|
27
|
+
style: styles.code,
|
|
28
|
+
children: visible
|
|
29
|
+
})
|
|
30
|
+
}), /* @__PURE__ */ jsx(CopyButton, {
|
|
31
|
+
text,
|
|
32
|
+
style: styles.copy
|
|
33
|
+
})]
|
|
34
|
+
}), visible.length < text.length ? /* @__PURE__ */ jsx(ShowMore, {
|
|
35
|
+
label: "Show more code",
|
|
36
|
+
summary: `${visible.length} of ${text.length} characters · ${visible.split("\n").length} of ${text.split("\n").length} lines`,
|
|
37
|
+
onPress: reveal
|
|
38
|
+
}) : null]
|
|
27
39
|
});
|
|
28
40
|
}
|
|
29
41
|
const styles = StyleSheet.create((theme) => ({
|
|
42
|
+
root: {
|
|
43
|
+
gap: theme.spacing(2),
|
|
44
|
+
minWidth: 0,
|
|
45
|
+
uni__dependencies: [0]
|
|
46
|
+
},
|
|
30
47
|
block: {
|
|
31
48
|
borderRadius: theme.borderRadius.DEFAULT,
|
|
32
49
|
borderWidth: 1,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlock.mjs","names":["StyleSheet","fontOf","CopyButton","CodeBlockProps","text","language","CodeBlock","styles","block","undefined","scroll","code","copy","create","theme","borderRadius","DEFAULT","borderWidth","borderColor","colors","border","backgroundColor","deep","
|
|
1
|
+
{"version":3,"file":"CodeBlock.mjs","names":["StyleSheet","fontOf","codePrefix","useReadingPage","CopyButton","ShowMore","CodeBlockProps","text","language","initialPage","CodeBlock","page","reveal","visible","styles","root","block","undefined","scroll","code","copy","length","split","create","theme","gap","spacing","minWidth","uni__dependencies","borderRadius","DEFAULT","borderWidth","borderColor","colors","border","backgroundColor","deep","padding","paddingRight","color","fontFamily","mono","fontSize","sm","lineHeight","lineHeightRelaxed","position","top","right"],"sources":["../../src/components/CodeBlock.tsx"],"sourcesContent":["import { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\nimport { codePrefix } from '../lib/reading';\nimport { useReadingPage } from '../lib/useReadingPage';\nimport { CopyButton } from './CopyButton';\nimport { ShowMore } from './ShowMore';\n\n/*\n * A fenced code block: the source in selectable mono type that scrolls\n * sideways rather than wrapping, and a copy button that says when it worked.\n *\n * ponytail: no syntax colouring and no mermaid diagrams yet; a mermaid fence\n * shows its source, which is still the whole content.\n */\n\nexport interface CodeBlockProps {\n /** The block's source, without the fence lines. */\n text: string;\n /** The fence's language word, such as `ts`; the web reads it from a `language-*` class. */\n language?: string;\n /** Initial reveal pages, useful for a reader restored to a known position. */\n initialPage?: number;\n}\n\nexport function CodeBlock({ text, language, initialPage = 1 }: CodeBlockProps) {\n const { page, reveal } = useReadingPage(text, initialPage);\n const visible = codePrefix(text, page);\n return (\n <View style={styles.root}>\n <View style={styles.block} accessibilityLabel={language === undefined ? undefined : `${language} code`}>\n <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.scroll}>\n <Text selectable style={styles.code}>\n {visible}\n </Text>\n </ScrollView>\n\n <CopyButton text={text} style={styles.copy} />\n </View>\n {visible.length < text.length ? (\n <ShowMore\n label=\"Show more code\"\n summary={`${visible.length} of ${text.length} characters · ${visible.split('\\n').length} of ${text.split('\\n').length} lines`}\n onPress={reveal}\n />\n ) : null}\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n root: { gap: theme.spacing(2), minWidth: 0 },\n block: {\n borderRadius: theme.borderRadius.DEFAULT,\n borderWidth: 1,\n borderColor: theme.colors.border,\n backgroundColor: theme.colors.deep,\n },\n // The right padding keeps the first line clear of the copy button.\n scroll: { padding: theme.spacing(2.5), paddingRight: theme.spacing(9) },\n code: {\n color: theme.colors.text,\n fontFamily: fontOf(theme.fontFamily.mono),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeightRelaxed.sm,\n },\n copy: { position: 'absolute', top: theme.spacing(1.5), right: theme.spacing(1.5) },\n}));\n"],"mappings":";;;;;;;;;;;;AA0BA,SAAgBU,UAAU,EAAEH,MAAMC,UAAUC,cAAc,KAAqB;CAC7E,MAAM,EAAEE,MAAMC,WAAWT,eAAeI,MAAME,WAAW;CACzD,MAAMI,UAAUX,WAAWK,MAAMI,IAAI;CACrC,OACE,qBAAC,MAAD;EAAM,OAAOG,OAAOC;YAApB,CACE,qBAAC,MAAD;GAAM,OAAOD,OAAOE;GAAO,oBAAoBR,aAAaS,SAAYA,SAAY,GAAGT,SAAQ;aAA/F,CACE,oBAAC,YAAD;IAAY;IAAW,gCAAgC;IAAO,uBAAuBM,OAAOI;cAC1F,oBAAC,MAAD;KAAM;KAAW,OAAOJ,OAAOK;eAC5BN;IACG;GACI,IAEZ,oBAAC,YAAD;IAAkBN;IAAM,OAAOO,OAAOM;GAAK,EACvC;MACLP,QAAQQ,SAASd,KAAKc,SACrB,oBAAC,UAAD;GACE,OAAM;GACN,SAAS,GAAGR,QAAQQ,OAAM,MAAOd,KAAKc,OAAM,gBAAiBR,QAAQS,MAAM,IAAI,CAAC,CAACD,OAAM,MAAOd,KAAKe,MAAM,IAAI,CAAC,CAACD,OAAM;GACrH,SAAST;EAAO,KAEhB,IACA;;AAEV;AAEA,MAAME,SAASd,WAAWuB,QAAQC,WAAW;CAC3CT,MAAM;EAAEU,KAAKD,MAAME,QAAQ,CAAC;EAAGC,UAAU;EAACC,mBAAA,CAAA,CAAA;CAAC;CAC3CZ,OAAO;EACLa,cAAcL,MAAMK,aAAaC;EACjCC,aAAa;EACbC,aAAaR,MAAMS,OAAOC;EAC1BC,iBAAiBX,MAAMS,OAAOG;EAAIR,mBAAA,CAAA,CAAA;CACpC;CAEAV,QAAQ;EAAEmB,SAASb,MAAME,QAAQ,GAAG;EAAGY,cAAcd,MAAME,QAAQ,CAAC;EAACE,mBAAA,CAAA,CAAA;CAAC;CACtET,MAAM;EACJoB,OAAOf,MAAMS,OAAO1B;EACpBiC,YAAYvC,OAAOuB,MAAMgB,WAAWC,IAAI;EACxCC,UAAUlB,MAAMkB,SAASC;EACzBC,YAAYpB,MAAMqB,kBAAkBF;EAAEf,mBAAA,CAAA,CAAA;CACxC;CACAR,MAAM;EAAE0B,UAAU;EAAYC,KAAKvB,MAAME,QAAQ,GAAG;EAAGsB,OAAOxB,MAAME,QAAQ,GAAG;EAACE,mBAAA,CAAA,CAAA;CAAC;AACnF,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMenu.d.mts","names":[],"sources":["../../src/components/DropdownMenu.tsx"],"mappings":";;;;iBAyCiB;;EAEf;EACA;EACA,gBAAgB;EAChB,WAAW;;wBAGG,eAAe,MAAM,aAAqB,cAAc,YAAY,oCAAiB,IAAA;;wBAMrF,sBAAsB,SAAS,uBAAuB,SAAS,8BAAW,IAAA;iBAczE;EACf,WAAW;;;wBAIG,sBAAsB,YAAY,2CAAwB,IAAA;
|
|
1
|
+
{"version":3,"file":"DropdownMenu.d.mts","names":[],"sources":["../../src/components/DropdownMenu.tsx"],"mappings":";;;;iBAyCiB;;EAEf;EACA;EACA,gBAAgB;EAChB,WAAW;;wBAGG,eAAe,MAAM,aAAqB,cAAc,YAAY,oCAAiB,IAAA;;wBAMrF,sBAAsB,SAAS,uBAAuB,SAAS,8BAAW,IAAA;iBAczE;EACf,WAAW;;;wBAIG,sBAAsB,YAAY,2CAAwB,IAAA;iBAazD,8BAA8B,KAAK;EAClD,WAAW;EACX,QAAQ,UAAU;;;wBAIJ,oBAAoB,aAAa,SAAS,wCAAqB,IAAA;YAInE;iBAEK;EACf,UAAU;;EAEV;EACA;;EAEA;;EAEA,WAAW;EACX,QAAQ,UAAU;;wBA8CJ,iBAAiB,OAAO,wCAAqB,IAAA;iBAI5C,sCAAsC,KAAK;EAC1D;EACA,mBAAmB;;;wBAIL,2BACd,SACA,iBACA,aACG,SACF,gDAA6B,IAAA;iBAef,oCAAoC;EACnD;EACA,iBAAiB;;;wBAIH,yBAAyB,OAAO,eAAe,aAAa,SAAS,8CAA2B,IAAA;iBAU/F,mCAAmC,KAAK;EACvD;;wBAGc,wBAAwB,OAAO,aAAa,SAAS,6CAA0B,IAAA;;wBAkB/E,oBAAoB,OAAO,aAAa,SAAS,4BAAS,IAAA;;wBAU1D,uBAAuB,UAAU,SAAS,4BAAS,IAAA;wBAInD,wBAAwB;EAAW,QAAQ,UAAU;oBAAY,IAAA"}
|
|
@@ -57,10 +57,16 @@ function DropdownMenuContent({ children }) {
|
|
|
57
57
|
return /* @__PURE__ */ jsx(SheetFrame, {
|
|
58
58
|
open,
|
|
59
59
|
onClose: () => setOpen(false),
|
|
60
|
-
children: /* @__PURE__ */ jsx(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
children: /* @__PURE__ */ jsx(MenuContext.Provider, {
|
|
61
|
+
value: {
|
|
62
|
+
open,
|
|
63
|
+
setOpen
|
|
64
|
+
},
|
|
65
|
+
children: /* @__PURE__ */ jsx(View, {
|
|
66
|
+
accessibilityRole: "menu",
|
|
67
|
+
style: styles.content,
|
|
68
|
+
children
|
|
69
|
+
})
|
|
64
70
|
})
|
|
65
71
|
});
|
|
66
72
|
}
|
|
@@ -1 +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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"}
|
|
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 <MenuContext.Provider value={{ open, setOpen }}>\n <View accessibilityRole=\"menu\" style={styles.content}>\n {children}\n </View>\n </MenuContext.Provider>\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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HashlineLines.d.mts","names":[],"sources":["../../src/components/HashlineLines.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"HashlineLines.d.mts","names":[],"sources":["../../src/components/HashlineLines.tsx"],"mappings":";;;iBA6BiB,2BAA2B,KAAK;EAC/C,gBAAgB;;EAEhB;;EAEA;;wBAwCc,gBAAgB,OAAO,QAAQ,MAAM,UAAU,SAAS,qCAAkB,IAAA"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { fontOf } from "../lib/fonts.mjs";
|
|
2
|
+
import { READING } from "../lib/reading.mjs";
|
|
3
|
+
import { useReadingPage } from "../lib/useReadingPage.mjs";
|
|
4
|
+
import { ShowMore } from "./ShowMore.mjs";
|
|
2
5
|
import { SyntaxLine } from "./SyntaxLine.mjs";
|
|
3
6
|
import { detectGrammar, hashlineGroups, hashlineGroupsKey, highlightToLines } from "@agimon-ai/po-web-components/text";
|
|
4
7
|
import { View } from "react-native-unistyles/components/native/View";
|
|
@@ -45,11 +48,13 @@ function useHashlineSpans(lines, path) {
|
|
|
45
48
|
return done?.key === key ? done.spans : NO_SPANS;
|
|
46
49
|
}
|
|
47
50
|
function HashlineLines({ lines, gutter, path, style, ...props }) {
|
|
48
|
-
const
|
|
49
|
-
|
|
51
|
+
const { page, reveal } = useReadingPage(`${path ?? ""}\n${lines.map((line) => JSON.stringify(line)).join("\n")}`);
|
|
52
|
+
const visible = useMemo(() => lines.slice(0, READING.hashlines * page), [lines, page]);
|
|
53
|
+
const spans = useHashlineSpans(visible, path);
|
|
54
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
50
55
|
style,
|
|
51
56
|
...props,
|
|
52
|
-
children:
|
|
57
|
+
children: [visible.map((line, index) => {
|
|
53
58
|
if (line.type === "file") return /* @__PURE__ */ jsx(Text, {
|
|
54
59
|
numberOfLines: 1,
|
|
55
60
|
style: [
|
|
@@ -89,7 +94,11 @@ function HashlineLines({ lines, gutter, path, style, ...props }) {
|
|
|
89
94
|
})
|
|
90
95
|
]
|
|
91
96
|
}, index);
|
|
92
|
-
})
|
|
97
|
+
}), visible.length < lines.length ? /* @__PURE__ */ jsx(ShowMore, {
|
|
98
|
+
label: "Show more lines",
|
|
99
|
+
summary: `${visible.length} of ${lines.length} lines`,
|
|
100
|
+
onPress: reveal
|
|
101
|
+
}) : null]
|
|
93
102
|
});
|
|
94
103
|
}
|
|
95
104
|
const styles = StyleSheet.create((theme) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HashlineLines.mjs","names":["detectGrammar","hashlineGroups","hashlineGroupsKey","highlightToLines","PresentedLine","SyntaxSpan","useEffect","useMemo","useState","ViewProps","StyleSheet","fontOf","SyntaxLine","HashlineLinesProps","Omit","lines","gutter","path","NO_SPANS","ReadonlyMap","Map","useHashlineSpans","groups","key","done","setDone","spans","live","controller","AbortController","next","work","map","group","grammar","text","undefined","highlighted","signal","offset","index","indices","entries","line","set","Promise","allSettled","then","size","abort","HashlineLines","style","props","type","styles","mono","faint","fileGap","dim","value","match","marker","row","String","padStart","get","content","hi","create","theme","flexDirection","gap","spacing","uni__dependencies","marginTop","fontFamily","fontSize","sm","lineHeight","lineHeightRelaxed","flex","minWidth","color","colors","blue"],"sources":["../../src/components/HashlineLines.tsx"],"sourcesContent":["import {\n detectGrammar,\n hashlineGroups,\n hashlineGroupsKey,\n highlightToLines,\n type PresentedLine,\n type SyntaxSpan,\n} from '@agimon-ai/po-web-components/text';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Text, View, type ViewProps } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\nimport { SyntaxLine } from './SyntaxLine';\n\n/*\n * The anchored body shared by hashline results, as the web's HashlineLines: a\n * file heading per group, a right-aligned line-number gutter, and a `>>`\n * marker on grep matches. Mono type makes a padded number the gutter, so the\n * column needs no measuring.\n *\n * The anchored lines are coloured with the web's grammars and palette when the\n * body names a file, or when `path` names one. Colour arrives late and never\n * blocks the text: an unhighlighted body is the same body without the colours.\n */\n\nexport interface HashlineLinesProps extends Omit<ViewProps, 'children'> {\n lines: readonly PresentedLine[];\n /** Width of the line-number column, in characters, from `hashlineBody`. */\n gutter: number;\n /** The file a body of bare anchored lines came from, for highlighting. */\n path?: string | undefined;\n}\n\nconst NO_SPANS: ReadonlyMap<number, readonly SyntaxSpan[]> = new Map();\n\n/** Spans per presented-line index, kept with the body they belong to, as the web's hook. */\nfunction useHashlineSpans(lines: readonly PresentedLine[], path: string | undefined) {\n const groups = useMemo(() => hashlineGroups(lines, path), [lines, path]);\n const key = hashlineGroupsKey(groups);\n const [done, setDone] = useState<{ key: string; spans: ReadonlyMap<number, readonly SyntaxSpan[]> }>();\n\n useEffect(() => {\n let live = true;\n const controller = new AbortController();\n const next = new Map<number, readonly SyntaxSpan[]>();\n const work = groups.map(async (group) => {\n const grammar = detectGrammar({ path: group.path, text: group.text });\n if (grammar === undefined) return;\n const highlighted = await highlightToLines(group.text, grammar, controller.signal);\n if (highlighted === undefined) return;\n for (const [offset, index] of group.indices.entries()) {\n const line = highlighted[offset];\n if (line !== undefined) next.set(index, line);\n }\n });\n // A grammar that fails to load leaves its run plain: colour is decoration.\n void Promise.allSettled(work).then(() => {\n if (live && next.size > 0) setDone({ key, spans: next });\n });\n return () => {\n live = false;\n controller.abort();\n };\n // The groups are rebuilt with the lines; their key is what actually changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [key]);\n\n return done?.key === key ? done.spans : NO_SPANS;\n}\n\nexport function HashlineLines({ lines, gutter, path, style, ...props }: HashlineLinesProps) {\n const spans = useHashlineSpans(
|
|
1
|
+
{"version":3,"file":"HashlineLines.mjs","names":["detectGrammar","hashlineGroups","hashlineGroupsKey","highlightToLines","PresentedLine","SyntaxSpan","useEffect","useMemo","useState","ViewProps","StyleSheet","fontOf","READING","useReadingPage","ShowMore","SyntaxLine","HashlineLinesProps","Omit","lines","gutter","path","NO_SPANS","ReadonlyMap","Map","useHashlineSpans","groups","key","done","setDone","spans","live","controller","AbortController","next","work","map","group","grammar","text","undefined","highlighted","signal","offset","index","indices","entries","line","set","Promise","allSettled","then","size","abort","HashlineLines","style","props","page","reveal","JSON","stringify","join","visible","slice","hashlines","type","styles","mono","faint","fileGap","dim","value","match","marker","row","String","padStart","get","content","hi","length","create","theme","flexDirection","gap","spacing","uni__dependencies","marginTop","fontFamily","fontSize","sm","lineHeight","lineHeightRelaxed","flex","minWidth","color","colors","blue"],"sources":["../../src/components/HashlineLines.tsx"],"sourcesContent":["import {\n detectGrammar,\n hashlineGroups,\n hashlineGroupsKey,\n highlightToLines,\n type PresentedLine,\n type SyntaxSpan,\n} from '@agimon-ai/po-web-components/text';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Text, View, type ViewProps } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\nimport { READING } from '../lib/reading';\nimport { useReadingPage } from '../lib/useReadingPage';\nimport { ShowMore } from './ShowMore';\nimport { SyntaxLine } from './SyntaxLine';\n\n/*\n * The anchored body shared by hashline results, as the web's HashlineLines: a\n * file heading per group, a right-aligned line-number gutter, and a `>>`\n * marker on grep matches. Mono type makes a padded number the gutter, so the\n * column needs no measuring.\n *\n * The anchored lines are coloured with the web's grammars and palette when the\n * body names a file, or when `path` names one. Colour arrives late and never\n * blocks the text: an unhighlighted body is the same body without the colours.\n */\n\nexport interface HashlineLinesProps extends Omit<ViewProps, 'children'> {\n lines: readonly PresentedLine[];\n /** Width of the line-number column, in characters, from `hashlineBody`. */\n gutter: number;\n /** The file a body of bare anchored lines came from, for highlighting. */\n path?: string | undefined;\n}\n\nconst NO_SPANS: ReadonlyMap<number, readonly SyntaxSpan[]> = new Map();\n\n/** Spans per presented-line index, kept with the body they belong to, as the web's hook. */\nfunction useHashlineSpans(lines: readonly PresentedLine[], path: string | undefined) {\n const groups = useMemo(() => hashlineGroups(lines, path), [lines, path]);\n const key = hashlineGroupsKey(groups);\n const [done, setDone] = useState<{ key: string; spans: ReadonlyMap<number, readonly SyntaxSpan[]> }>();\n\n useEffect(() => {\n let live = true;\n const controller = new AbortController();\n const next = new Map<number, readonly SyntaxSpan[]>();\n const work = groups.map(async (group) => {\n const grammar = detectGrammar({ path: group.path, text: group.text });\n if (grammar === undefined) return;\n const highlighted = await highlightToLines(group.text, grammar, controller.signal);\n if (highlighted === undefined) return;\n for (const [offset, index] of group.indices.entries()) {\n const line = highlighted[offset];\n if (line !== undefined) next.set(index, line);\n }\n });\n // A grammar that fails to load leaves its run plain: colour is decoration.\n void Promise.allSettled(work).then(() => {\n if (live && next.size > 0) setDone({ key, spans: next });\n });\n return () => {\n live = false;\n controller.abort();\n };\n // The groups are rebuilt with the lines; their key is what actually changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [key]);\n\n return done?.key === key ? done.spans : NO_SPANS;\n}\n\nexport function HashlineLines({ lines, gutter, path, style, ...props }: HashlineLinesProps) {\n // Whole anchored lines retain their exact content and line numbers, even above 640 characters.\n const { page, reveal } = useReadingPage(`${path ?? ''}\\n${lines.map((line) => JSON.stringify(line)).join('\\n')}`);\n const visible = useMemo(() => lines.slice(0, READING.hashlines * page), [lines, page]);\n const spans = useHashlineSpans(visible, path);\n return (\n <View style={style} {...props}>\n {visible.map((line, index) => {\n if (line.type === 'file') {\n return (\n <Text key={index} numberOfLines={1} style={[styles.mono, styles.faint, index > 0 && styles.fileGap]}>\n {line.path}\n </Text>\n );\n }\n if (line.type === 'plain') {\n return (\n <Text key={index} selectable style={[styles.mono, styles.dim]}>\n {line.text}\n </Text>\n );\n }\n const { value } = line;\n const match = value.marker === 'match';\n return (\n <View key={index} style={styles.row}>\n {value.marker !== undefined ? (\n <Text style={[styles.mono, match ? styles.marker : styles.faint]}>{match ? '>>' : ' '}</Text>\n ) : null}\n <Text style={[styles.mono, styles.faint]}>{String(value.line).padStart(gutter)}</Text>\n <SyntaxLine\n selectable\n spans={spans.get(index)}\n text={value.content}\n style={[styles.mono, styles.content, match ? styles.hi : styles.text]}\n />\n </View>\n );\n })}\n {visible.length < lines.length ? (\n <ShowMore label=\"Show more lines\" summary={`${visible.length} of ${lines.length} lines`} onPress={reveal} />\n ) : null}\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n row: { flexDirection: 'row', gap: theme.spacing(2) },\n fileGap: { marginTop: theme.spacing(1) },\n mono: {\n fontFamily: fontOf(theme.fontFamily.mono),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeightRelaxed.sm,\n },\n content: { flex: 1, minWidth: 0 },\n marker: { color: theme.colors.blue },\n faint: { color: theme.colors.faint },\n dim: { color: theme.colors.dim },\n text: { color: theme.colors.text },\n hi: { color: theme.colors.hi },\n}));\n"],"mappings":";;;;;;;;;;;;;AAqCA,MAAMqB,2BAAuD,IAAIE,IAAI;;AAGrE,SAASC,iBAAiBN,OAAiCE,MAA0B;CACnF,MAAMK,SAASlB,cAAcN,eAAeiB,OAAOE,IAAI,GAAG,CAACF,OAAOE,IAAI,CAAC;CACvE,MAAMM,MAAMxB,kBAAkBuB,MAAM;CACpC,MAAM,CAACE,MAAMC,WAAWpB,SAA6E;CAErGF,gBAAgB;EACd,IAAIwB,OAAO;EACX,MAAMC,aAAa,IAAIC,gBAAgB;EACvC,MAAMC,uBAAO,IAAIV,IAAmC;EACpD,MAAMW,OAAOT,OAAOU,IAAI,OAAOC,UAAU;GACvC,MAAMC,UAAUrC,cAAc;IAAEoB,MAAMgB,MAAMhB;IAAMkB,MAAMF,MAAME;GAAK,CAAC;GACpE,IAAID,YAAYE,QAAW;GAC3B,MAAMC,cAAc,MAAMrC,iBAAiBiC,MAAME,MAAMD,SAASN,WAAWU,MAAM;GACjF,IAAID,gBAAgBD,QAAW;GAC/B,KAAK,MAAM,CAACG,QAAQC,UAAUP,MAAMQ,QAAQC,QAAQ,GAAG;IACrD,MAAMC,OAAON,YAAYE;IACzB,IAAII,SAASP,QAAWN,KAAKc,IAAIJ,OAAOG,IAAI;GAC9C;EACF,CAAC;EAED,AAAKE,QAAQC,WAAWf,IAAI,CAAC,CAACgB,WAAW;GACvC,IAAIpB,QAAQG,KAAKkB,OAAO,GAAGvB,QAAQ;IAAEF;IAAKG,OAAOI;GAAK,CAAC;EACzD,CAAC;EACD,aAAa;GACXH,OAAO;GACPC,WAAWqB,MAAM;EACnB;CAGF,GAAG,CAAC1B,GAAG,CAAC;CAER,OAAOC,MAAMD,QAAQA,MAAMC,KAAKE,QAAQR;AAC1C;AAEA,SAAgBgC,cAAc,EAAEnC,OAAOC,QAAQC,MAAMkC,OAAO,GAAGC,SAA6B;CAE1F,MAAM,EAAEC,MAAMC,WAAW5C,eAAe,GAAGO,QAAQ,GAAE,IAAKF,MAAMiB,KAAKW,SAASY,KAAKC,UAAUb,IAAI,CAAC,CAAC,CAACc,KAAK,IAAI,GAAG;CAChH,MAAMC,UAAUtD,cAAcW,MAAM4C,MAAM,GAAGlD,QAAQmD,YAAYP,IAAI,GAAG,CAACtC,OAAOsC,IAAI,CAAC;CACrF,MAAM3B,QAAQL,iBAAiBqC,SAASzC,IAAI;CAC5C,OACE,qBAAC,MAAD;EAAakC;EAAO,GAAIC;YAAxB,CACGM,QAAQ1B,KAAKW,MAAMH,UAAU;GAC5B,IAAIG,KAAKkB,SAAS,QAChB,OACE,oBAAC,MAAD;IAAkB,eAAe;IAAG,OAAO;KAACC,OAAOC;KAAMD,OAAOE;KAAOxB,QAAQ,KAAKsB,OAAOG;IAAO;cAC/FtB,KAAK1B;GACF,GAFKuB,KAEL;GAGV,IAAIG,KAAKkB,SAAS,SAChB,OACE,oBAAC,MAAD;IAAkB;IAAW,OAAO,CAACC,OAAOC,MAAMD,OAAOI,GAAG;cACzDvB,KAAKR;GACF,GAFKK,KAEL;GAGV,MAAM,EAAE2B,UAAUxB;GAClB,MAAMyB,QAAQD,MAAME,WAAW;GAC/B,OACE,qBAAC,MAAD;IAAkB,OAAOP,OAAOQ;cAAhC;KACGH,MAAME,WAAWjC,SAChB,oBAAC,MAAD;MAAM,OAAO,CAAC0B,OAAOC,MAAMK,QAAQN,OAAOO,SAASP,OAAOE,KAAK;gBAAII,QAAQ,OAAO;KAAW,KAC3F;KACJ,oBAAC,MAAD;MAAM,OAAO,CAACN,OAAOC,MAAMD,OAAOE,KAAK;gBAAIO,OAAOJ,MAAMxB,IAAI,CAAC,CAAC6B,SAASxD,MAAM;KAAQ;KACrF,oBAAC,YAAD;MACE;MACA,OAAOU,MAAM+C,IAAIjC,KAAK;MACtB,MAAM2B,MAAMO;MACZ,OAAO;OAACZ,OAAOC;OAAMD,OAAOY;OAASN,QAAQN,OAAOa,KAAKb,OAAO3B;MAAI;KAAE;IAEpE;MAXKK,KAWL;EAEV,CAAC,GACAkB,QAAQkB,SAAS7D,MAAM6D,SACtB,oBAAC,UAAD;GAAU,OAAM;GAAkB,SAAS,GAAGlB,QAAQkB,OAAM,MAAO7D,MAAM6D,OAAM;GAAU,SAAStB;EAAO,KACvG,IACA;;AAEV;AAEA,MAAMQ,SAASvD,WAAWsE,QAAQC,WAAW;CAC3CR,KAAK;EAAES,eAAe;EAAOC,KAAKF,MAAMG,QAAQ,CAAC;EAACC,mBAAA,CAAA,CAAA;CAAC;CACnDjB,SAAS;EAAEkB,WAAWL,MAAMG,QAAQ,CAAC;EAACC,mBAAA,CAAA,CAAA;CAAC;CACvCnB,MAAM;EACJqB,YAAY5E,OAAOsE,MAAMM,WAAWrB,IAAI;EACxCsB,UAAUP,MAAMO,SAASC;EACzBC,YAAYT,MAAMU,kBAAkBF;EAAEJ,mBAAA,CAAA,CAAA;CACxC;CACAR,SAAS;EAAEe,MAAM;EAAGC,UAAU;CAAE;CAChCrB,QAAQ;EAAEsB,OAAOb,MAAMc,OAAOC;EAAIX,mBAAA,CAAA,CAAA;CAAC;CACnClB,OAAO;EAAE2B,OAAOb,MAAMc,OAAO5B;EAAKkB,mBAAA,CAAA,CAAA;CAAC;CACnChB,KAAK;EAAEyB,OAAOb,MAAMc,OAAO1B;EAAGgB,mBAAA,CAAA,CAAA;CAAC;CAC/B/C,MAAM;EAAEwD,OAAOb,MAAMc,OAAOzD;EAAI+C,mBAAA,CAAA,CAAA;CAAC;CACjCP,IAAI;EAAEgB,OAAOb,MAAMc,OAAOjB;EAAEO,mBAAA,CAAA,CAAA;CAAC;AAC/B,EAAE"}
|
|
@@ -17,7 +17,7 @@ const ThemedSheetTextInput = withUnistyles(BottomSheetTextInput);
|
|
|
17
17
|
* red edge when invalid. Inside a Sheet it becomes the sheet's own input.
|
|
18
18
|
*/
|
|
19
19
|
function Input({ variant = "default", size = "md", invalid = false, disabled = false, style, onFocus, onBlur, accessibilityState, ...props }) {
|
|
20
|
-
const { theme } = useUnistyles();
|
|
20
|
+
const { theme, rt } = useUnistyles();
|
|
21
21
|
const [focused, setFocused] = useState(false);
|
|
22
22
|
const Field = useInsideSheet() ? ThemedSheetTextInput : TextInput;
|
|
23
23
|
const _styles = styles;
|
|
@@ -28,6 +28,7 @@ function Input({ variant = "default", size = "md", invalid = false, disabled = f
|
|
|
28
28
|
});
|
|
29
29
|
return /* @__PURE__ */ jsx(Field, {
|
|
30
30
|
autoCorrect: false,
|
|
31
|
+
keyboardAppearance: rt.themeName === "dark" ? "dark" : "light",
|
|
31
32
|
spellCheck: false,
|
|
32
33
|
placeholderTextColor: theme.colors.faint,
|
|
33
34
|
selectionColor: theme.colors.green,
|
|
@@ -1 +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-po-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,
|
|
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","rt","focused","setFocused","Field","TextInput","_styles","styles","useVariants","undefined","themeName","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-po-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, rt } = 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 // iOS draws the keyboard light by default, a bright slab under a dark screen.\n keyboardAppearance={rt.themeName === 'dark' ? 'dark' : 'light'}\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,OAAOC,OAAOtB,aAAa;CACnC,MAAM,CAACuB,SAASC,cAAc3B,SAAS,KAAK;CAE5C,MAAM4B,QAAQtB,eAAe,IAAIK,uBAAuBkB;CACxD,MAAAC,UAAAC;CAAA;EAAA,MAAAA,SAAAD,QAAAE,YACmB;GAAElB,SAASA,YAAY,SAAS,SAASmB;GAAWlB;EAAK,CAAC;EAC7E,OACE,oBAAC,OAAD;GACE,aAAa;GAEb,oBAAoBU,GAAGS,cAAc,SAAS,SAAS;GACvD,YAAY;GACZ,sBAAsBV,MAAMW,OAAOC;GACnC,gBAAgBZ,MAAMW,OAAOE;GAC7B,aAAab,MAAMW,OAAOE;GAC1B,UAAU,CAACpB;GACX,oBAAoB;IAAE,GAAGK;IAAoBL;GAAS;GACtD,UAAUqB,UAAU;IAClBX,WAAW,IAAI;IACfP,UAAUkB,KAAK;GACjB;GACA,SAASA,UAAU;IACjBX,WAAW,KAAK;IAChBN,SAASiB,KAAK;GAChB;GACA,OAAO;IACLP,OAAOQ;IAGPb,WAAWZ,YAAY,aAAa,EAAE0B,aAAa1C,UAAU0B,MAAMW,OAAOE,OAAO5B,wBAAwB,EAAE;IAC3GO,WAAWe,OAAOf;IAClBC,YAAYc,OAAOd;IACnBE;GAAK;GAEP,GAAII;EAAM;CAEZ;AACJ;AAEA,MAAMQ,SAAS7B,WAAWuC,QAAQjB,WAAW;CAC3Ce,OAAO;EACLG,UAAU;EACVC,WAAW;EACXC,OAAOpB,MAAMW,OAAOU;EACpBC,YAAYzC,OAAOmB,MAAMsB,WAAWC,IAAI;EACxCC,UAAU;GACRlC,SAAS;IACPmC,SAAS;KACPC,cAAc1B,MAAM0B,aAAaC;KACjCC,aAAa;KACbZ,aAAahB,MAAMW,OAAOkB;KAC1BC,iBAAiB9B,MAAMW,OAAOoB;IAChC;;IAEAC,MAAM;KAAEJ,aAAa;KAAGE,iBAAiB;KAAeG,SAAS;IAAE;GACrE;GACA1C,MAAM;IACJ2C,IAAI;KACFC,mBAAmBnC,MAAMoC,QAAQ,GAAG;KACpCC,iBAAiBrC,MAAMoC,QAAQ,EAAG;KAClCE,UAAUtC,MAAMsC,SAASC;IAC3B;IACAA,IAAI;KACFJ,mBAAmBnC,MAAMoC,QAAQ,CAAC;KAClCC,iBAAiBrC,MAAMoC,QAAQ,CAAC;KAChCE,UAAUtC,MAAMsC,SAASC;IAC3B;IACAC,IAAI;KACFL,mBAAmBnC,MAAMoC,QAAQ,GAAG;KACpCC,iBAAiBrC,MAAMoC,QAAQ,GAAG;KAClCE,UAAUtC,MAAMsC,SAASG;IAC3B;IACAC,IAAI;KACFP,mBAAmBnC,MAAMoC,QAAQ,CAAC;KAClCC,iBAAiBrC,MAAMoC,QAAQ,GAAG;KAClCE,UAAUtC,MAAMsC,SAASG;IAC3B;GACF;EACF;EACAE,kBAAkB,CAAC;GAAErD,SAAS;GAAQiB,QAAQ;IAAE0B,SAAS;IAAGE,mBAAmB;IAAGE,iBAAiB;GAAE;EAAE,CAAC;EAACO,mBAAA,CAAA,GAAA,CAAA;CAC3G;CACApD,SAAS;EAAEwB,aAAahB,MAAMW,OAAO;EAAaS,OAAOpB,MAAMW,OAAOkC;EAAGD,mBAAA,CAAA,CAAA;CAAC;CAC1EnD,UAAU,EAAEqD,SAAS5D,iBAAiB;AACxC,EAAE"}
|
|
@@ -1 +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;
|
|
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;iBA2BE;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"}
|
package/dist/components/List.mjs
CHANGED
|
@@ -31,6 +31,8 @@ function List({ data, renderItem, keyExtractor, startAtBottom = false, separator
|
|
|
31
31
|
ListHeaderComponent: header === void 0 ? null : /* @__PURE__ */ jsx(Fragment, { children: header }),
|
|
32
32
|
ListFooterComponent: footer === void 0 ? null : /* @__PURE__ */ jsx(Fragment, { children: footer }),
|
|
33
33
|
onEndReached,
|
|
34
|
+
keyboardDismissMode: Platform.OS === "ios" ? "interactive" : "on-drag",
|
|
35
|
+
keyboardShouldPersistTaps: "handled",
|
|
34
36
|
contentInsetAdjustmentBehavior: "automatic",
|
|
35
37
|
contentContainerStyle: contentPadding === void 0 ? void 0 : { padding: contentPadding },
|
|
36
38
|
maintainVisibleContentPosition: startAtBottom ? {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"List.mjs","names":["FlashList","ReactElement","ReactNode","useCallback","Platform","StyleProp","ViewStyle","StyleSheet","ChevronRightIcon","fontOf","MIN_ROW_HEIGHT","DISABLED_OPACITY","PIN_THRESHOLD","ListProps","data","T","renderItem","item","index","keyExtractor","startAtBottom","separators","empty","header","footer","onEndReached","accessibilityLabel","style","contentPadding","Separator","styles","separator","List","renderRow","frame","undefined","padding","startRenderingFromBottom","autoscrollToBottomThreshold","ListRowProps","title","description","leading","trailing","selected","disabled","onPress","disclosure","ListRow","chevron","OS","content","text","titleSelected","row","pressed","create","theme","flex","minHeight","height","hairlineWidth","marginLeft","spacing","backgroundColor","colors","uni__dependencies","flexDirection","alignItems","gap","paddingHorizontal","paddingVertical","panel","opacity","minWidth","color","hi","fontFamily","sans","fontSize","base","lineHeight","fontWeight","medium","green","semibold","faint","sm"],"sources":["../../src/components/List.tsx"],"sourcesContent":["import { FlashList } from '@shopify/flash-list';\nimport { type ReactElement, type ReactNode, useCallback } from 'react';\nimport { Platform, Pressable, type StyleProp, Text, View, type ViewStyle } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { ChevronRightIcon } from '../icons/icons';\nimport { fontOf } from '../lib/fonts';\n\n/*\n * A virtualised list on FlashList: sessions, devices, a transcript. Rows\n * recycle, separators are hairlines, and a chat list can start at the bottom\n * and stay pinned there as rows arrive. The public props are this package's\n * own, so FlashList's types never reach a caller.\n */\n\nconst MIN_ROW_HEIGHT = 44;\nconst DISABLED_OPACITY = 0.4;\n/** How close to the bottom a reader must be for a new row to keep the list pinned, as a fraction of the visible height. */\nconst PIN_THRESHOLD = 0.1;\n\nexport interface ListProps<T> {\n data: readonly T[];\n renderItem: (item: T, index: number) => ReactElement | null;\n /** A stable key per row; FlashList recycles views by it. */\n keyExtractor: (item: T, index: number) => string;\n /**\n * A chat list: render from the bottom and keep the newest row in view as\n * rows arrive, while the reader is near the bottom.\n */\n startAtBottom?: boolean;\n /** Hairline separators between rows. On by default. */\n separators?: boolean;\n /** Shown when `data` is empty. */\n empty?: ReactNode;\n header?: ReactNode;\n footer?: ReactNode;\n onEndReached?: () => void;\n accessibilityLabel?: string;\n /** The list's frame; give it a height or a flex parent, since a virtualised list needs bounds. */\n style?: StyleProp<ViewStyle>;\n /** Padding around the rows. */\n contentPadding?: number;\n}\n\nfunction Separator() {\n return <View style={styles.separator} />;\n}\n\nexport function List<T>({\n data,\n renderItem,\n keyExtractor,\n startAtBottom = false,\n separators = true,\n empty,\n header,\n footer,\n onEndReached,\n accessibilityLabel,\n style,\n contentPadding,\n}: ListProps<T>) {\n const renderRow = useCallback(({ item, index }: { item: T; index: number }) => renderItem(item, index), [renderItem]);\n return (\n <View style={[styles.frame, style]} accessibilityLabel={accessibilityLabel}>\n <FlashList\n data={data}\n renderItem={renderRow}\n keyExtractor={keyExtractor}\n ItemSeparatorComponent={separators ? Separator : null}\n ListEmptyComponent={empty === undefined ? null : <>{empty}</>}\n ListHeaderComponent={header === undefined ? null : <>{header}</>}\n ListFooterComponent={footer === undefined ? null : <>{footer}</>}\n onEndReached={onEndReached}\n // Lets UIKit inset the rows under a translucent or large-title header instead of drawing beneath it.\n contentInsetAdjustmentBehavior=\"automatic\"\n contentContainerStyle={contentPadding === undefined ? undefined : { padding: contentPadding }}\n maintainVisibleContentPosition={\n startAtBottom ? { startRenderingFromBottom: true, autoscrollToBottomThreshold: PIN_THRESHOLD } : undefined\n }\n />\n </View>\n );\n}\n\nexport interface ListRowProps {\n title: ReactNode;\n /** A second, quieter line under the title. */\n description?: ReactNode;\n /** Before the text: a Dot, an icon. */\n leading?: ReactNode;\n /** After the text: a Badge, a ghost button, a count. */\n trailing?: ReactNode;\n /** Selected rows sit on a green tint. */\n selected?: boolean;\n disabled?: boolean;\n onPress?: () => void;\n /** The iOS disclosure chevron. Defaults to on for a pressable row on iOS, where rows that navigate wear one. */\n disclosure?: boolean;\n accessibilityLabel?: string;\n style?: StyleProp<ViewStyle>;\n}\n\n/** One list row: 44pt tall, optional leading and trailing slots, pressable when it navigates. */\nexport function ListRow({\n title,\n description,\n leading,\n trailing,\n selected = false,\n disabled = false,\n onPress,\n disclosure,\n accessibilityLabel,\n style,\n}: ListRowProps) {\n const chevron = disclosure ?? (onPress !== undefined && Platform.OS === 'ios');\n const content = (\n <>\n {leading}\n <View style={styles.text}>\n {typeof title === 'string' ? (\n <Text numberOfLines={1} style={[styles.title, selected && styles.titleSelected]}>\n {title}\n </Text>\n ) : (\n title\n )}\n {typeof description === 'string' ? (\n <Text numberOfLines={2} style={styles.description}>\n {description}\n </Text>\n ) : (\n description\n )}\n </View>\n {trailing}\n {chevron ? <ChevronRightIcon size={14} color=\"faint\" /> : null}\n </>\n );\n if (onPress === undefined) {\n return (\n <View\n accessibilityLabel={accessibilityLabel}\n accessibilityState={{ selected, disabled }}\n style={[styles.row, selected && styles.selected, disabled && styles.disabled, style]}\n >\n {content}\n </View>\n );\n }\n return (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel}\n accessibilityState={{ selected, disabled }}\n disabled={disabled}\n onPress={onPress}\n style={({ pressed }) => [\n styles.row,\n selected && styles.selected,\n pressed && styles.pressed,\n disabled && styles.disabled,\n style,\n ]}\n >\n {content}\n </Pressable>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n frame: { flex: 1, minHeight: 0 },\n separator: {\n height: StyleSheet.hairlineWidth,\n marginLeft: theme.spacing(4),\n backgroundColor: theme.colors['border-soft'],\n },\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(3),\n minHeight: MIN_ROW_HEIGHT,\n paddingHorizontal: theme.spacing(4),\n paddingVertical: theme.spacing(2),\n },\n selected: { backgroundColor: theme.colors['tint-green'] },\n pressed: { backgroundColor: theme.colors.panel },\n disabled: { opacity: DISABLED_OPACITY },\n text: { flex: 1, minWidth: 0, gap: theme.spacing(0.5) },\n title: {\n color: theme.colors.hi,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n fontWeight: theme.fontWeight.medium,\n },\n titleSelected: { color: theme.colors.green, fontWeight: theme.fontWeight.semibold },\n description: {\n color: theme.colors.faint,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n },\n}));\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"List.mjs","names":["FlashList","ReactElement","ReactNode","useCallback","Platform","StyleProp","ViewStyle","StyleSheet","ChevronRightIcon","fontOf","MIN_ROW_HEIGHT","DISABLED_OPACITY","PIN_THRESHOLD","ListProps","data","T","renderItem","item","index","keyExtractor","startAtBottom","separators","empty","header","footer","onEndReached","accessibilityLabel","style","contentPadding","Separator","styles","separator","List","renderRow","frame","undefined","OS","padding","startRenderingFromBottom","autoscrollToBottomThreshold","ListRowProps","title","description","leading","trailing","selected","disabled","onPress","disclosure","ListRow","chevron","content","text","titleSelected","row","pressed","create","theme","flex","minHeight","height","hairlineWidth","marginLeft","spacing","backgroundColor","colors","uni__dependencies","flexDirection","alignItems","gap","paddingHorizontal","paddingVertical","panel","opacity","minWidth","color","hi","fontFamily","sans","fontSize","base","lineHeight","fontWeight","medium","green","semibold","faint","sm"],"sources":["../../src/components/List.tsx"],"sourcesContent":["import { FlashList } from '@shopify/flash-list';\nimport { type ReactElement, type ReactNode, useCallback } from 'react';\nimport { Platform, Pressable, type StyleProp, Text, View, type ViewStyle } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { ChevronRightIcon } from '../icons/icons';\nimport { fontOf } from '../lib/fonts';\n\n/*\n * A virtualised list on FlashList: sessions, devices, a transcript. Rows\n * recycle, separators are hairlines, and a chat list can start at the bottom\n * and stay pinned there as rows arrive. The public props are this package's\n * own, so FlashList's types never reach a caller.\n */\n\nconst MIN_ROW_HEIGHT = 44;\nconst DISABLED_OPACITY = 0.4;\n/** How close to the bottom a reader must be for a new row to keep the list pinned, as a fraction of the visible height. */\nconst PIN_THRESHOLD = 0.1;\n\nexport interface ListProps<T> {\n data: readonly T[];\n renderItem: (item: T, index: number) => ReactElement | null;\n /** A stable key per row; FlashList recycles views by it. */\n keyExtractor: (item: T, index: number) => string;\n /**\n * A chat list: render from the bottom and keep the newest row in view as\n * rows arrive, while the reader is near the bottom.\n */\n startAtBottom?: boolean;\n /** Hairline separators between rows. On by default. */\n separators?: boolean;\n /** Shown when `data` is empty. */\n empty?: ReactNode;\n header?: ReactNode;\n footer?: ReactNode;\n onEndReached?: () => void;\n accessibilityLabel?: string;\n /** The list's frame; give it a height or a flex parent, since a virtualised list needs bounds. */\n style?: StyleProp<ViewStyle>;\n /** Padding around the rows. */\n contentPadding?: number;\n}\n\nfunction Separator() {\n return <View style={styles.separator} />;\n}\n\nexport function List<T>({\n data,\n renderItem,\n keyExtractor,\n startAtBottom = false,\n separators = true,\n empty,\n header,\n footer,\n onEndReached,\n accessibilityLabel,\n style,\n contentPadding,\n}: ListProps<T>) {\n const renderRow = useCallback(({ item, index }: { item: T; index: number }) => renderItem(item, index), [renderItem]);\n return (\n <View style={[styles.frame, style]} accessibilityLabel={accessibilityLabel}>\n <FlashList\n data={data}\n renderItem={renderRow}\n keyExtractor={keyExtractor}\n ItemSeparatorComponent={separators ? Separator : null}\n ListEmptyComponent={empty === undefined ? null : <>{empty}</>}\n ListHeaderComponent={header === undefined ? null : <>{header}</>}\n ListFooterComponent={footer === undefined ? null : <>{footer}</>}\n onEndReached={onEndReached}\n // Dragging the rows pulls the keyboard down with the finger, as in Messages; a tap on a row still lands.\n keyboardDismissMode={Platform.OS === 'ios' ? 'interactive' : 'on-drag'}\n keyboardShouldPersistTaps=\"handled\"\n // Lets UIKit inset the rows under a translucent or large-title header instead of drawing beneath it.\n contentInsetAdjustmentBehavior=\"automatic\"\n contentContainerStyle={contentPadding === undefined ? undefined : { padding: contentPadding }}\n maintainVisibleContentPosition={\n startAtBottom ? { startRenderingFromBottom: true, autoscrollToBottomThreshold: PIN_THRESHOLD } : undefined\n }\n />\n </View>\n );\n}\n\nexport interface ListRowProps {\n title: ReactNode;\n /** A second, quieter line under the title. */\n description?: ReactNode;\n /** Before the text: a Dot, an icon. */\n leading?: ReactNode;\n /** After the text: a Badge, a ghost button, a count. */\n trailing?: ReactNode;\n /** Selected rows sit on a green tint. */\n selected?: boolean;\n disabled?: boolean;\n onPress?: () => void;\n /** The iOS disclosure chevron. Defaults to on for a pressable row on iOS, where rows that navigate wear one. */\n disclosure?: boolean;\n accessibilityLabel?: string;\n style?: StyleProp<ViewStyle>;\n}\n\n/** One list row: 44pt tall, optional leading and trailing slots, pressable when it navigates. */\nexport function ListRow({\n title,\n description,\n leading,\n trailing,\n selected = false,\n disabled = false,\n onPress,\n disclosure,\n accessibilityLabel,\n style,\n}: ListRowProps) {\n const chevron = disclosure ?? (onPress !== undefined && Platform.OS === 'ios');\n const content = (\n <>\n {leading}\n <View style={styles.text}>\n {typeof title === 'string' ? (\n <Text numberOfLines={1} style={[styles.title, selected && styles.titleSelected]}>\n {title}\n </Text>\n ) : (\n title\n )}\n {typeof description === 'string' ? (\n <Text numberOfLines={2} style={styles.description}>\n {description}\n </Text>\n ) : (\n description\n )}\n </View>\n {trailing}\n {chevron ? <ChevronRightIcon size={14} color=\"faint\" /> : null}\n </>\n );\n if (onPress === undefined) {\n return (\n <View\n accessibilityLabel={accessibilityLabel}\n accessibilityState={{ selected, disabled }}\n style={[styles.row, selected && styles.selected, disabled && styles.disabled, style]}\n >\n {content}\n </View>\n );\n }\n return (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel}\n accessibilityState={{ selected, disabled }}\n disabled={disabled}\n onPress={onPress}\n style={({ pressed }) => [\n styles.row,\n selected && styles.selected,\n pressed && styles.pressed,\n disabled && styles.disabled,\n style,\n ]}\n >\n {content}\n </Pressable>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n frame: { flex: 1, minHeight: 0 },\n separator: {\n height: StyleSheet.hairlineWidth,\n marginLeft: theme.spacing(4),\n backgroundColor: theme.colors['border-soft'],\n },\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(3),\n minHeight: MIN_ROW_HEIGHT,\n paddingHorizontal: theme.spacing(4),\n paddingVertical: theme.spacing(2),\n },\n selected: { backgroundColor: theme.colors['tint-green'] },\n pressed: { backgroundColor: theme.colors.panel },\n disabled: { opacity: DISABLED_OPACITY },\n text: { flex: 1, minWidth: 0, gap: theme.spacing(0.5) },\n title: {\n color: theme.colors.hi,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n fontWeight: theme.fontWeight.medium,\n },\n titleSelected: { color: theme.colors.green, fontWeight: theme.fontWeight.semibold },\n description: {\n color: theme.colors.faint,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n },\n}));\n"],"mappings":"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"}
|
|
@@ -15,8 +15,10 @@ export interface MarkdownProps {
|
|
|
15
15
|
onFileLink?: FileLinkHandler;
|
|
16
16
|
/** Loads relative image paths; without it they show as unavailable. */
|
|
17
17
|
loadImage?: MarkdownImageLoader;
|
|
18
|
+
/** Initial reveal pages for a restored reading position. Defaults to one. */
|
|
19
|
+
initialPage?: number;
|
|
18
20
|
}
|
|
19
21
|
/** Markdown in Po's shared presentation, parsed by the package's own small parser. */
|
|
20
|
-
export declare const Markdown: import("react").MemoExoticComponent<({ text, onFileLink, loadImage }: MarkdownProps) => import("react").JSX.Element>;
|
|
22
|
+
export declare const Markdown: import("react").MemoExoticComponent<({ text, onFileLink, loadImage, initialPage }: MarkdownProps) => import("react").JSX.Element>;
|
|
21
23
|
//#endregion
|
|
22
24
|
//# sourceMappingURL=Markdown.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.d.mts","names":[],"sources":["../../src/components/Markdown.tsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"Markdown.d.mts","names":[],"sources":["../../src/components/Markdown.tsx"],"mappings":";;;;;;YAuBY,mBAAmB,cAAc;;YAQjC,uBAAuB,iBAAiB;EAAU;EAAa;;iBAmU1D;EACf;EACA,aAAa;;EAEb,YAAY;;EAEZ;;;qBAIW,0BAAQ,uBAAA,MAAA,YAAA,WAAA,eAA4E,kCAAa,IAAA"}
|