@agimon-ai/po-native-components 0.0.0-alpha.79 → 0.0.0-alpha.80
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/Input.d.mts +3 -1
- package/dist/components/Input.d.mts.map +1 -1
- package/dist/components/Input.mjs.map +1 -1
- package/dist/components/LiveDuration.mjs +2 -2
- package/dist/components/LiveDuration.mjs.map +1 -1
- package/dist/components/Markdown.d.mts.map +1 -1
- package/dist/components/Markdown.mjs +2 -1
- 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 +2 -1
- package/dist/components/Sheet.mjs.map +1 -1
- package/dist/components/SheetFrame.mjs +7 -4
- package/dist/components/SheetFrame.mjs.map +1 -1
- package/package.json +4 -4
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { TextInputProps } from "react-native";
|
|
1
|
+
import { TextInput, TextInputProps } from "react-native";
|
|
2
|
+
import { ComponentRef, Ref } from "react";
|
|
2
3
|
//#region src/components/Input.d.ts
|
|
3
4
|
export type FieldVariant = 'default' | 'bare';
|
|
4
5
|
export type FieldSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
5
6
|
export interface InputProps extends Omit<TextInputProps, 'editable'> {
|
|
7
|
+
ref?: Ref<ComponentRef<typeof TextInput>>;
|
|
6
8
|
variant?: FieldVariant;
|
|
7
9
|
/** The same rungs Button names, so a field and the button beside it line up. */
|
|
8
10
|
size?: FieldSize;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.d.mts","names":[],"sources":["../../src/components/Input.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Input.d.mts","names":[],"sources":["../../src/components/Input.tsx"],"mappings":";;;YASY;YACA;iBAQK,mBAAmB,KAAK;EACvC,MAAM,IAAI,oBAAoB;EAC9B,UAAU;;EAEV,OAAO;;EAEP;EACA;;;;;;wBAOc,QACd,SACA,MACA,SACA,UACA,OACA,SACA,QACA,uBACG,SACF,6BAAU,IAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.mjs","names":["useInsideSheet","withAlpha","BottomSheetTextInput","useState","TextInputProps","StyleSheet","useUnistyles","withUnistyles","fontOf","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","
|
|
1
|
+
{"version":3,"file":"Input.mjs","names":["useInsideSheet","withAlpha","BottomSheetTextInput","useState","ComponentRef","Ref","TextInputProps","StyleSheet","useUnistyles","withUnistyles","fontOf","FieldVariant","FieldSize","FOCUS_EDGE_ALPHA_PERCENT","DISABLED_OPACITY","ThemedSheetTextInput","TextInput","InputProps","Omit","ref","variant","size","invalid","disabled","Input","style","onFocus","onBlur","accessibilityState","props","theme","rt","focused","setFocused","Field","_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 { useInsideSheet } from '@agimon-ai/po-native-components/shell';\nimport { withAlpha } from '@agimon-ai/po-web-components/nativeTheme';\nimport { BottomSheetTextInput } from '@gorhom/bottom-sheet';\nimport { useState, type ComponentRef, type Ref } from 'react';\nimport { TextInput, type TextInputProps } from 'react-native';\nimport { StyleSheet, useUnistyles, withUnistyles } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\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\n// Both fields expose the native input handle; the sheet's gesture-handler declaration names its component instead.\nconst ThemedSheetTextInput = withUnistyles(BottomSheetTextInput) as unknown as typeof TextInput;\nexport interface InputProps extends Omit<TextInputProps, 'editable'> {\n ref?: Ref<ComponentRef<typeof TextInput>>;\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,MAAMa,2BAA2B;AACjC,MAAMC,mBAAmB;AAGzB,MAAMC,uBAAuBN,cAAcP,oBAAoB;;;;;AAe/D,SAAgBsB,MAAM,EACpBJ,UAAU,WACVC,OAAO,MACPC,UAAU,OACVC,WAAW,OACXE,OACAC,SACAC,QACAC,oBACA,GAAGC,SACU;CACb,MAAM,EAAEC,OAAOC,OAAOvB,aAAa;CACnC,MAAM,CAACwB,SAASC,cAAc9B,SAAS,KAAK;CAE5C,MAAM+B,QAAQlC,eAAe,IAAIe,uBAAuBC;CACxD,MAAAmB,UAAAC;CAAA;EAAA,MAAAA,SAAAD,QAAAE,YACmB;GAAEjB,SAASA,YAAY,SAAS,SAASkB;GAAWjB;EAAK,CAAC;EAC7E,OACE,oBAAC,OAAD;GACE,aAAa;GAEb,oBAAoBU,GAAGQ,cAAc,SAAS,SAAS;GACvD,YAAY;GACZ,sBAAsBT,MAAMU,OAAOC;GACnC,gBAAgBX,MAAMU,OAAOE;GAC7B,aAAaZ,MAAMU,OAAOE;GAC1B,UAAU,CAACnB;GACX,oBAAoB;IAAE,GAAGK;IAAoBL;GAAS;GACtD,UAAUoB,UAAU;IAClBV,WAAW,IAAI;IACfP,UAAUiB,KAAK;GACjB;GACA,SAASA,UAAU;IACjBV,WAAW,KAAK;IAChBN,SAASgB,KAAK;GAChB;GACA,OAAO;IACLP,OAAOQ;IAGPZ,WAAWZ,YAAY,aAAa,EAAEyB,aAAa5C,UAAU6B,MAAMU,OAAOE,OAAO7B,wBAAwB,EAAE;IAC3GS,WAAWc,OAAOd;IAClBC,YAAYa,OAAOb;IACnBE;GAAK;GAEP,GAAII;EAAM;CAEZ;AACJ;AAEA,MAAMO,SAAS7B,WAAWuC,QAAQhB,WAAW;CAC3Cc,OAAO;EACLG,UAAU;EACVC,WAAW;EACXC,OAAOnB,MAAMU,OAAOU;EACpBC,YAAYzC,OAAOoB,MAAMqB,WAAWC,IAAI;EACxCC,UAAU;GACRjC,SAAS;IACPkC,SAAS;KACPC,cAAczB,MAAMyB,aAAaC;KACjCC,aAAa;KACbZ,aAAaf,MAAMU,OAAOkB;KAC1BC,iBAAiB7B,MAAMU,OAAOoB;IAChC;;IAEAC,MAAM;KAAEJ,aAAa;KAAGE,iBAAiB;KAAeG,SAAS;IAAE;GACrE;GACAzC,MAAM;IACJ0C,IAAI;KACFC,mBAAmBlC,MAAMmC,QAAQ,GAAG;KACpCC,iBAAiBpC,MAAMmC,QAAQ,EAAG;KAClCE,UAAUrC,MAAMqC,SAASC;IAC3B;IACAA,IAAI;KACFJ,mBAAmBlC,MAAMmC,QAAQ,CAAC;KAClCC,iBAAiBpC,MAAMmC,QAAQ,CAAC;KAChCE,UAAUrC,MAAMqC,SAASC;IAC3B;IACAC,IAAI;KACFL,mBAAmBlC,MAAMmC,QAAQ,GAAG;KACpCC,iBAAiBpC,MAAMmC,QAAQ,GAAG;KAClCE,UAAUrC,MAAMqC,SAASG;IAC3B;IACAC,IAAI;KACFP,mBAAmBlC,MAAMmC,QAAQ,CAAC;KAClCC,iBAAiBpC,MAAMmC,QAAQ,GAAG;KAClCE,UAAUrC,MAAMqC,SAASG;IAC3B;GACF;EACF;EACAE,kBAAkB,CAAC;GAAEpD,SAAS;GAAQgB,QAAQ;IAAE0B,SAAS;IAAGE,mBAAmB;IAAGE,iBAAiB;GAAE;EAAE,CAAC;EAACO,mBAAA,CAAA,GAAA,CAAA;CAC3G;CACAnD,SAAS;EAAEuB,aAAaf,MAAMU,OAAO;EAAaS,OAAOnB,MAAMU,OAAOkC;EAAGD,mBAAA,CAAA,CAAA;CAAC;CAC1ElD,UAAU,EAAEoD,SAAS7D,iBAAiB;AACxC,EAAE"}
|
|
@@ -3,11 +3,11 @@ import { StyleSheet } from "react-native-unistyles";
|
|
|
3
3
|
import { AppState } from "react-native";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
|
-
import { TextInput } from "react-native-unistyles/components/native/TextInput";
|
|
6
|
+
import { TextInput as TextInput$1 } from "react-native-unistyles/components/native/TextInput";
|
|
7
7
|
import Animated, { useAnimatedProps, useSharedValue } from "react-native-reanimated";
|
|
8
8
|
|
|
9
9
|
//#region src/components/LiveDuration.tsx
|
|
10
|
-
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
|
|
10
|
+
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput$1);
|
|
11
11
|
/**
|
|
12
12
|
* "running · 12m" that ages by itself, or any `clock` format. Each change writes a shared value the UI thread
|
|
13
13
|
* draws, so a list of running work re-renders nothing to keep its clocks current. It sleeps while the app is in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LiveDuration.mjs","names":["clockRefreshMs","clockText","useEffect","useState","AppState","StyleProp","TextInputProps","TextStyle","Animated","useAnimatedProps","useSharedValue","StyleSheet","AnimatedTextInput","createAnimatedComponent","TextInput","LiveDurationReading","text","nextMs","LiveDurationProps","style","label","since","clock","now","LiveDuration","read","initial","Date","timer","ReturnType","setTimeout","tick","clearTimeout","undefined","currentState","reading","value","Math","max","subscription","addEventListener","remove","animatedProps","styles","create","padding","margin"],"sources":["../../src/components/LiveDuration.tsx"],"sourcesContent":["import { clockRefreshMs, clockText } from '@agimon-ai/po-web-components/text';\nimport { useEffect, useState } from 'react';\nimport { AppState, type StyleProp, TextInput, type TextInputProps, type TextStyle } from 'react-native';\nimport Animated, { useAnimatedProps, useSharedValue } from 'react-native-reanimated';\nimport { StyleSheet } from 'react-native-unistyles';\n\nconst AnimatedTextInput = Animated.createAnimatedComponent(TextInput);\n\n/** What a custom clock shows at `now`, and how long until it changes; no `nextMs` freezes it. */\nexport interface LiveDurationReading {\n text: string;\n nextMs?: number;\n}\n\nexport type LiveDurationProps = {\n style?: StyleProp<TextStyle>;\n} & (\n | {\n /** The copy before the elapsed time, such as \"running\". */\n label: string;\n /** Epoch milliseconds the clock counts from. */\n since: number;\n clock?: undefined;\n }\n | {\n /** A custom format; keep it stable (useCallback), since a new function restarts the clock. */\n clock: (now: number) => LiveDurationReading;\n label?: undefined;\n since?: undefined;\n }\n);\n\n/**\n * \"running · 12m\" that ages by itself, or any `clock` format. Each change writes a shared value the UI thread\n * draws, so a list of running work re-renders nothing to keep its clocks current. It sleeps while the app is in\n * the background and catches up on return. Read-only and not focusable: it sits inside a row whose own label\n * speaks for it.\n */\nexport function LiveDuration({ label, since, clock, style }: LiveDurationProps) {\n const read = (now: number): LiveDurationReading =>\n clock ? clock(now) : { text: clockText({ label, since }, now), nextMs: clockRefreshMs(since, now) };\n // The first paint's text; the effect below keeps it current from then on.\n const [initial] = useState(() => read(Date.now()).text);\n const text = useSharedValue(initial);\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = (): void => {\n clearTimeout(timer);\n timer = undefined;\n if (AppState.currentState !== 'active') return;\n const reading = read(Date.now());\n text.value = reading.text;\n if (reading.nextMs !== undefined) timer = setTimeout(tick, Math.max(1, reading.nextMs));\n };\n const subscription = AppState.addEventListener('change', tick);\n tick();\n return () => {\n clearTimeout(timer);\n subscription.remove();\n };\n // read is rebuilt each render from exactly these inputs.\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [label, since, clock, text]);\n const animatedProps = useAnimatedProps(() => ({ text: text.value }) as TextInputProps);\n return (\n <AnimatedTextInput\n editable={false}\n focusable={false}\n pointerEvents=\"none\"\n underlineColorAndroid=\"transparent\"\n defaultValue={initial}\n animatedProps={animatedProps}\n style={[styles.text, style]}\n />\n );\n}\n\nconst styles = StyleSheet.create({\n // A TextInput pads itself on Android; a status line sits flush like the Text beside it.\n text: { padding: 0, margin: 0 },\n});\n"],"mappings":";;;;;;;;;AAMA,MAAMY,oBAAoBJ,SAASK,wBAAwBC,
|
|
1
|
+
{"version":3,"file":"LiveDuration.mjs","names":["clockRefreshMs","clockText","useEffect","useState","AppState","StyleProp","TextInputProps","TextStyle","Animated","useAnimatedProps","useSharedValue","StyleSheet","AnimatedTextInput","createAnimatedComponent","TextInput","LiveDurationReading","text","nextMs","LiveDurationProps","style","label","since","clock","now","LiveDuration","read","initial","Date","timer","ReturnType","setTimeout","tick","clearTimeout","undefined","currentState","reading","value","Math","max","subscription","addEventListener","remove","animatedProps","styles","create","padding","margin","TextInput"],"sources":["../../src/components/LiveDuration.tsx"],"sourcesContent":["import { clockRefreshMs, clockText } from '@agimon-ai/po-web-components/text';\nimport { useEffect, useState } from 'react';\nimport { AppState, type StyleProp, TextInput, type TextInputProps, type TextStyle } from 'react-native';\nimport Animated, { useAnimatedProps, useSharedValue } from 'react-native-reanimated';\nimport { StyleSheet } from 'react-native-unistyles';\n\nconst AnimatedTextInput = Animated.createAnimatedComponent(TextInput);\n\n/** What a custom clock shows at `now`, and how long until it changes; no `nextMs` freezes it. */\nexport interface LiveDurationReading {\n text: string;\n nextMs?: number;\n}\n\nexport type LiveDurationProps = {\n style?: StyleProp<TextStyle>;\n} & (\n | {\n /** The copy before the elapsed time, such as \"running\". */\n label: string;\n /** Epoch milliseconds the clock counts from. */\n since: number;\n clock?: undefined;\n }\n | {\n /** A custom format; keep it stable (useCallback), since a new function restarts the clock. */\n clock: (now: number) => LiveDurationReading;\n label?: undefined;\n since?: undefined;\n }\n);\n\n/**\n * \"running · 12m\" that ages by itself, or any `clock` format. Each change writes a shared value the UI thread\n * draws, so a list of running work re-renders nothing to keep its clocks current. It sleeps while the app is in\n * the background and catches up on return. Read-only and not focusable: it sits inside a row whose own label\n * speaks for it.\n */\nexport function LiveDuration({ label, since, clock, style }: LiveDurationProps) {\n const read = (now: number): LiveDurationReading =>\n clock ? clock(now) : { text: clockText({ label, since }, now), nextMs: clockRefreshMs(since, now) };\n // The first paint's text; the effect below keeps it current from then on.\n const [initial] = useState(() => read(Date.now()).text);\n const text = useSharedValue(initial);\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = (): void => {\n clearTimeout(timer);\n timer = undefined;\n if (AppState.currentState !== 'active') return;\n const reading = read(Date.now());\n text.value = reading.text;\n if (reading.nextMs !== undefined) timer = setTimeout(tick, Math.max(1, reading.nextMs));\n };\n const subscription = AppState.addEventListener('change', tick);\n tick();\n return () => {\n clearTimeout(timer);\n subscription.remove();\n };\n // read is rebuilt each render from exactly these inputs.\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [label, since, clock, text]);\n const animatedProps = useAnimatedProps(() => ({ text: text.value }) as TextInputProps);\n return (\n <AnimatedTextInput\n editable={false}\n focusable={false}\n pointerEvents=\"none\"\n underlineColorAndroid=\"transparent\"\n defaultValue={initial}\n animatedProps={animatedProps}\n style={[styles.text, style]}\n />\n );\n}\n\nconst styles = StyleSheet.create({\n // A TextInput pads itself on Android; a status line sits flush like the Text beside it.\n text: { padding: 0, margin: 0 },\n});\n"],"mappings":";;;;;;;;;AAMA,MAAMY,oBAAoBJ,SAASK,wBAAwBC,WAAS;;;;;;;AAgCpE,SAAgBU,aAAa,EAAEJ,OAAOC,OAAOC,OAAOH,SAA4B;CAC9E,MAAMM,QAAQF,QACZD,QAAQA,MAAMC,GAAG,IAAI;EAAEP,MAAMf,UAAU;GAAEmB;GAAOC;EAAM,GAAGE,GAAG;EAAGN,QAAQjB,eAAeqB,OAAOE,GAAG;CAAE;CAEpG,MAAM,CAACG,WAAWvB,eAAesB,KAAKE,KAAKJ,IAAI,CAAC,CAAC,CAACP,IAAI;CACtD,MAAMA,OAAON,eAAegB,OAAO;CACnCxB,gBAAgB;EACd,IAAI0B;EACJ,MAAMG,aAAmB;GACvBC,aAAaJ,KAAK;GAClBA,QAAQK;GACR,IAAI7B,SAAS8B,iBAAiB,UAAU;GACxC,MAAMC,UAAUV,KAAKE,KAAKJ,IAAI,CAAC;GAC/BP,KAAKoB,QAAQD,QAAQnB;GACrB,IAAImB,QAAQlB,WAAWgB,QAAWL,QAAQE,WAAWC,MAAMM,KAAKC,IAAI,GAAGH,QAAQlB,MAAM,CAAC;EACxF;EACA,MAAMsB,eAAenC,SAASoC,iBAAiB,UAAUT,IAAI;EAC7DA,KAAK;EACL,aAAa;GACXC,aAAaJ,KAAK;GAClBW,aAAaE,OAAO;EACtB;CAGF,GAAG;EAACrB;EAAOC;EAAOC;EAAON;CAAI,CAAC;CAC9B,MAAM0B,gBAAgBjC,wBAAwB,EAAEO,MAAMA,KAAKoB,MAAM,EAAoB;CACrF,OACE,oBAAC,mBAAD;EACE,UAAU;EACV,WAAW;EACX,eAAc;EACd,uBAAsB;EACtB,cAAcV;EACCgB;EACf,OAAO,CAACC,OAAO3B,MAAMG,KAAK;CAAE;AAGlC;AAEA,MAAMwB,SAAShC,WAAWiC,OAAO,EAE/B5B,MAAM;CAAE6B,SAAS;CAAGC,QAAQ;AAAE,EAChC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.d.mts","names":[],"sources":["../../src/components/Markdown.tsx"],"mappings":";;;;;;YAuBY,mBAAmB,cAAc;;YAQjC,uBAAuB,iBAAiB;EAAU;EAAa;;
|
|
1
|
+
{"version":3,"file":"Markdown.d.mts","names":[],"sources":["../../src/components/Markdown.tsx"],"mappings":";;;;;;YAuBY,mBAAmB,cAAc;;YAQjC,uBAAuB,iBAAiB;EAAU;EAAa;;iBAuU1D;EACf;EACA,aAAa;;EAEb,YAAY;;EAEZ;;;qBAIW,0BAAQ,uBAAA,MAAA,YAAA,WAAA,eAA4E,kCAAa,IAAA"}
|
|
@@ -63,7 +63,8 @@ function InlineLink({ href, children }) {
|
|
|
63
63
|
/** One image: a file path through the host's loader, or a web or data address as written. */
|
|
64
64
|
function MarkdownImage({ src, alt }) {
|
|
65
65
|
const loader = useContext(ImageContext);
|
|
66
|
-
const
|
|
66
|
+
const source = src.startsWith("@artifact:") ? src.slice(1) : src;
|
|
67
|
+
const path = URL_OR_ANCHOR.test(source) && !source.startsWith("artifact:") ? void 0 : decoded(source.split(/[?#]/u, 1)[0]) ?? "";
|
|
67
68
|
const [loaded, setLoaded] = useState();
|
|
68
69
|
const [ratio, setRatio] = useState(PLACEHOLDER_RATIO);
|
|
69
70
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.mjs","names":["createContext","memo","ReactNode","useContext","useEffect","useMemo","useState","Linking","StyleSheet","fontOf","MarkdownBlock","MarkdownHeadingLevel","MarkdownInline","parseMarkdown","READING","inlineLength","inlinePrefix","useReadingPage","CodeBlock","ShowMore","FileLinkHandler","text","explicit","InitialPageContext","FileLinkContext","undefined","MarkdownImageLoader","path","Promise","url","dispose","ImageContext","URL_OR_ANCHOR","DIRECT_IMAGE","PLACEHOLDER_RATIO","decoded","href","decodeURIComponent","InlineCode","originalText","onFileLink","open","includes","styles","code","fileLink","InlineLink","children","isFile","test","openURL","catch","link","MarkdownImage","src","alt","loader","split","loaded","setLoaded","failed","ratio","setRatio","active","asset","Awaited","ReturnType","resolve","then","Error","result","current","uri","waiting","prose","imageState","nativeEvent","fit","width","height","size","source","Image","getSize","image","aspectRatio","renderInline","nodes","map","node","index","type","strong","em","MarkdownTable","header","rows","initialPage","rowPage","setRows","columnPage","setColumns","cellPage","setCells","visibleRows","slice","visibleHeader","columns","limit","cell","clipped","row","length","some","root","table","column","headCell","meta","actions","page","Blocks","blocks","quoted","setPage","visible","parts","block","value","BoundedBlock","props","first","characters","total","shown","items","reduce","sum","item","remaining","next","push","more","Block","heading","level","firstHeading","run","flush","list","marker","ordered","start","itemText","language","rule","quote","MarkdownProps","loadImage","Markdown","generation","HEADING_STEP","const","HEADING_SPACE","HEADING_INK","create","theme","color","colors","dim","fontFamily","sans","fontSize","sm","lineHeight","uni__dependencies","flexDirection","flexWrap","minWidth","gap","spacing","base","marginTop","letterSpacing","fontWeight","semibold","hi","fontStyle","backgroundColor","deep","green","mono","textDecorationLine","blue","paddingLeft","flexShrink","borderLeftWidth","borderLeftColor","border","borderTopWidth","borderColor","paddingHorizontal","paddingVertical","borderRightWidth","borderBottomWidth","maxHeight","borderRadius","md","borderWidth"],"sources":["../../src/components/Markdown.tsx"],"sourcesContent":["import { createContext, memo, type ReactNode, useContext, useEffect, useMemo, useState } from 'react';\nimport { Image, Linking, ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\nimport { type MarkdownBlock, type MarkdownHeadingLevel, type MarkdownInline, parseMarkdown } from '../lib/markdown';\nimport { READING, inlineLength, inlinePrefix } from '../lib/reading';\nimport { useReadingPage } from '../lib/useReadingPage';\nimport { CodeBlock } from './CodeBlock';\nimport { ShowMore } from './ShowMore';\n\n/*\n * Markdown in the web component's element styles, from the package's own\n * parser: headings, paragraphs, lists, code spans and fences, bold, italic,\n * links, images, blockquotes and tables. Web links open with Linking; a file\n * path goes to the host. Raw HTML blocks are left out, as on the web.\n */\n\n/**\n * What a piece of inline code or a relative link opens, when the host knows.\n * Returning undefined leaves it as plain code or an ordinary link. The same\n * contract as the web Markdown's handler.\n */\nexport type FileLinkHandler = (text: string, explicit?: boolean) => (() => void) | undefined;\n\n/** Passed by context so the inline renderers stay module functions. */\nconst InitialPageContext = createContext(1);\n\nconst FileLinkContext = createContext<FileLinkHandler | undefined>(undefined);\n\n/** Loads a relative image path from the host; the same contract as the web Markdown's `loadImage`. */\nexport type MarkdownImageLoader = (path: string) => Promise<{ url: string; dispose(): void }>;\n\nconst ImageContext = createContext<MarkdownImageLoader | undefined>(undefined);\n\nconst URL_OR_ANCHOR = /^(?:[a-z][a-z\\d+.-]*:|\\/\\/|#|\\?)/i;\n/** Sources an Image may load as written; any other scheme stays its alt text. */\nconst DIRECT_IMAGE = /^(?:https?:|data:image\\/)/i;\n/** Until the image reports its size, it holds a landscape box rather than collapsing. */\nconst PLACEHOLDER_RATIO = 16 / 9;\n\nfunction decoded(href: string): string | undefined {\n try {\n return decodeURIComponent(href);\n } catch {\n return undefined;\n }\n}\n\nfunction InlineCode({ text, originalText = text }: { text: string; originalText?: string }) {\n const onFileLink = useContext(FileLinkContext);\n const open = originalText.includes('\\n') ? undefined : onFileLink?.(originalText);\n if (open !== undefined) {\n return (\n <Text\n accessibilityRole=\"link\"\n accessibilityHint={`open ${originalText}`}\n onPress={open}\n style={[styles.code, styles.fileLink]}\n >\n {text}\n </Text>\n );\n }\n return <Text style={styles.code}>{text}</Text>;\n}\n\nfunction InlineLink({ href, children }: { href: string; children: ReactNode }) {\n const onFileLink = useContext(FileLinkContext);\n const path = decoded(href);\n const isFile = path !== undefined && path !== '' && !URL_OR_ANCHOR.test(path);\n const open = isFile ? onFileLink?.(path, true) : undefined;\n return (\n <Text\n accessibilityRole=\"link\"\n onPress={() => {\n if (open !== undefined) open();\n else if (!isFile) Linking.openURL(href).catch(() => undefined);\n }}\n style={styles.link}\n >\n {children}\n </Text>\n );\n}\n\n/** One image: a file path through the host's loader, or a web or data address as written. */\nfunction MarkdownImage({ src, alt }: { src: string; alt: string }) {\n const loader = useContext(ImageContext);\n // An invalid encoded filename is shown as unavailable, never fetched.\n const path = URL_OR_ANCHOR.test(src) ? undefined : (decoded(src.split(/[?#]/u, 1)[0]!) ?? '');\n const [loaded, setLoaded] = useState<{ path: string; url?: string; failed?: boolean }>();\n const [ratio, setRatio] = useState(PLACEHOLDER_RATIO);\n useEffect(() => {\n if (loader === undefined || path === undefined) return;\n let active = true;\n let asset: Awaited<ReturnType<MarkdownImageLoader>> | undefined;\n void Promise.resolve()\n .then(() => {\n if (path === '') throw new Error('Invalid image path.');\n return loader(path);\n })\n .then((result) => {\n if (!active) return result.dispose();\n asset = result;\n setLoaded({ path, url: result.url });\n })\n .catch(() => {\n // The failure is shown in place, as the web image does.\n if (active) setLoaded({ path, failed: true });\n });\n return () => {\n active = false;\n asset?.dispose();\n };\n }, [path, loader]);\n const current = loaded?.path === path ? loaded : undefined;\n const uri = path === undefined ? (DIRECT_IMAGE.test(src) ? src : undefined) : current?.url;\n if (uri === undefined || current?.failed) {\n const waiting = path !== undefined && loader !== undefined && current === undefined;\n return (\n <Text style={[styles.prose, styles.imageState]} accessibilityRole={waiting ? 'text' : 'alert'}>\n {alt || path || 'Image'} ({waiting ? 'loading\\u2026' : 'unavailable'})\n </Text>\n );\n }\n return (\n <Image\n source={{ uri }}\n accessibilityLabel={alt || 'Image'}\n accessibilityIgnoresInvertColors\n resizeMode=\"contain\"\n onLoad={({ nativeEvent }) => {\n const fit = (width: number, height: number) => {\n if (width > 0 && height > 0) setRatio(width / height);\n };\n // iOS and Android report the size with the event; react-native-web does not, so it asks.\n const size = (nativeEvent as { source?: { width: number; height: number } } | undefined)?.source;\n if (size !== undefined) fit(size.width, size.height);\n else Image.getSize(uri, fit, () => undefined);\n }}\n onError={() => setLoaded({ path: path ?? src, failed: true })}\n style={[styles.image, { aspectRatio: ratio }]}\n />\n );\n}\nfunction renderInline(nodes: readonly MarkdownInline[]): ReactNode[] {\n return nodes.map((node, index) => {\n switch (node.type) {\n case 'text':\n return node.text;\n case 'code':\n return <InlineCode key={index} text={node.text} originalText={node.originalText} />;\n case 'strong':\n return (\n <Text key={index} style={styles.strong}>\n {renderInline(node.children)}\n </Text>\n );\n case 'em':\n return (\n <Text key={index} style={styles.em}>\n {renderInline(node.children)}\n </Text>\n );\n case 'link':\n return (\n <InlineLink key={index} href={node.href}>\n {renderInline(node.children)}\n </InlineLink>\n );\n case 'image':\n // Inside a heading or list item an image keeps to its alt text; paragraphs draw it.\n return node.alt;\n }\n });\n}\n\n/**\n * A table read column by column: every cell keeps to one line inside the sideways scroll, so each\n * column takes its widest cell and the rows line up without a table layout.\n */\nfunction MarkdownTable({ header, rows }: { header: MarkdownInline[][]; rows: MarkdownInline[][][] }) {\n const initialPage = useContext(InitialPageContext);\n const [rowPage, setRows] = useState(initialPage);\n const [columnPage, setColumns] = useState(initialPage);\n const [cellPage, setCells] = useState(initialPage);\n const visibleRows = rows.slice(0, READING.rows * rowPage);\n const visibleHeader = header.slice(0, READING.columns * columnPage);\n const limit = READING.cell * cellPage;\n const clipped = [visibleHeader, ...visibleRows.map((row) => row.slice(0, visibleHeader.length))].some((row) =>\n row.some((cell) => inlineLength(cell) > limit),\n );\n return (\n <View style={styles.root}>\n <ScrollView horizontal showsHorizontalScrollIndicator={false}>\n <View style={styles.table}>\n {visibleHeader.map((cell, column) => (\n <View key={column}>\n <Text style={[styles.prose, styles.cell, styles.headCell]}>\n {renderInline(inlinePrefix(cell, limit))}\n {inlineLength(cell) > limit ? '…' : ''}\n </Text>\n {visibleRows.map((row, index) => (\n <Text key={index} style={[styles.prose, styles.cell]}>\n {renderInline(inlinePrefix(row[column] ?? [], limit))}\n {inlineLength(row[column] ?? []) > limit ? '…' : ''}\n </Text>\n ))}\n </View>\n ))}\n </View>\n </ScrollView>\n <Text style={styles.meta}>\n {visibleRows.length} of {rows.length} rows · {visibleHeader.length} of {header.length} columns\n {clipped ? ` · Cells: first ${limit} characters` : ''}\n </Text>\n <View style={styles.actions}>\n {visibleRows.length < rows.length ? (\n <ShowMore label=\"Show more rows\" onPress={() => setRows((page) => page + 1)} />\n ) : null}\n {visibleHeader.length < header.length ? (\n <ShowMore label=\"Show more columns\" onPress={() => setColumns((page) => page + 1)} />\n ) : null}\n {clipped ? <ShowMore label=\"Show more cell text\" onPress={() => setCells((page) => page + 1)} /> : null}\n </View>\n </View>\n );\n}\n\nfunction Blocks({ blocks, quoted = false }: { blocks: MarkdownBlock[]; quoted?: boolean }) {\n const initialPage = useContext(InitialPageContext);\n const [page, setPage] = useState(initialPage);\n const visible = blocks.slice(0, READING.parts * page);\n return (\n <>\n {visible.map((block, index) => (\n <BoundedBlock key={index} block={block} first={index === 0} quoted={quoted} />\n ))}\n {visible.length < blocks.length ? (\n <ShowMore\n label=\"Show more\"\n summary={`${visible.length} of ${blocks.length} parts`}\n onPress={() => setPage((value) => value + 1)}\n />\n ) : null}\n </>\n );\n}\n\nfunction BoundedBlock({ block, ...props }: { block: MarkdownBlock; first: boolean; quoted?: boolean }) {\n const initialPage = useContext(InitialPageContext);\n const [page, setPage] = useState(initialPage);\n const limit = READING.characters * page;\n let visible = block;\n let total = 0;\n let shown = 0;\n if (block.type === 'heading' || block.type === 'paragraph') {\n total = inlineLength(block.children);\n const children = inlinePrefix(block.children, limit);\n shown = inlineLength(children);\n visible = { ...block, children };\n } else if (block.type === 'list') {\n total = block.items.reduce((sum, item) => sum + inlineLength(item), 0);\n let remaining = limit;\n const items = [];\n for (const item of block.items.slice(0, READING.parts * page)) {\n if (remaining <= 0) break;\n const next = inlinePrefix(item, remaining);\n items.push(next);\n remaining -= inlineLength(next);\n }\n shown = limit - remaining;\n visible = { ...block, items };\n }\n const more =\n shown < total || (block.type === 'list' && visible.type === 'list' && visible.items.length < block.items.length);\n return (\n <View style={styles.root}>\n <Block block={visible} {...props} />\n {more ? (\n <ShowMore\n label=\"Show more text\"\n summary={`${shown} of ${total} characters`}\n onPress={() => setPage((value) => value + 1)}\n />\n ) : null}\n </View>\n );\n}\n\nfunction Block({ block, first, quoted = false }: { block: MarkdownBlock; first: boolean; quoted?: boolean }) {\n const initialPage = useContext(InitialPageContext);\n const prose = [styles.prose, quoted && styles.quoted];\n switch (block.type) {\n case 'heading':\n return (\n <Text\n accessibilityRole=\"header\"\n style={[...prose, styles.heading(block.level), first && styles.firstHeading, quoted && styles.quoted]}\n >\n {renderInline(block.children)}\n </Text>\n );\n case 'paragraph': {\n // An image breaks the paragraph's text into runs, since an Image cannot sit inside Text.\n const parts: ReactNode[] = [];\n let run: MarkdownInline[] = [];\n const flush = () => {\n if (run.length > 0)\n parts.push(\n <Text key={parts.length} style={prose}>\n {renderInline(run)}\n </Text>,\n );\n run = [];\n };\n for (const node of block.children) {\n if (node.type !== 'image') {\n run.push(node);\n continue;\n }\n flush();\n parts.push(<MarkdownImage key={parts.length} src={node.src} alt={node.alt} />);\n }\n flush();\n return parts.length === 1 ? parts[0] : <View style={styles.root}>{parts}</View>;\n }\n case 'list':\n return (\n <View accessibilityRole=\"list\" style={styles.list}>\n {block.items.map((item, index) => (\n <View key={index} style={styles.item}>\n <Text style={[...prose, styles.marker]}>{block.ordered ? `${block.start + index}.` : '\\u2022'}</Text>\n <Text style={[...prose, styles.itemText]}>{renderInline(item)}</Text>\n </View>\n ))}\n </View>\n );\n case 'code':\n return <CodeBlock text={block.text} language={block.language} initialPage={initialPage} />;\n case 'rule':\n return <View accessible={false} style={styles.rule} />;\n case 'quote':\n return (\n <View style={[styles.root, styles.quote]}>\n <Blocks blocks={block.children} quoted />\n </View>\n );\n case 'table':\n return <MarkdownTable header={block.header} rows={block.rows} />;\n }\n}\n\nexport interface MarkdownProps {\n text: string;\n onFileLink?: FileLinkHandler;\n /** Loads relative image paths; without it they show as unavailable. */\n loadImage?: MarkdownImageLoader;\n /** Initial reveal pages for a restored reading position. Defaults to one. */\n initialPage?: number;\n}\n\n/** Markdown in Po's shared presentation, parsed by the package's own small parser. */\nexport const Markdown = memo(function Markdown({ text, onFileLink, loadImage, initialPage = 1 }: MarkdownProps) {\n const blocks = useMemo(() => parseMarkdown(text), [text]);\n const { generation } = useReadingPage(text);\n return (\n <InitialPageContext.Provider value={initialPage}>\n <FileLinkContext.Provider value={onFileLink}>\n <ImageContext.Provider value={loadImage}>\n <View style={styles.root}>\n <Blocks key={generation} blocks={blocks} />\n </View>\n </ImageContext.Provider>\n </FileLinkContext.Provider>\n </InitialPageContext.Provider>\n );\n});\n\n/**\n * Headings step up from the prose and never shrink below it; h4 to h6 keep\n * the prose size and lean on weight, fading from `hi` to `dim`.\n */\nconst HEADING_STEP = { 1: '2xl', 2: 'xl', 3: 'lg', 4: 'base', 5: 'base', 6: 'base' } as const;\nconst HEADING_SPACE = { 1: 2, 2: 2, 3: 1, 4: 0, 5: 0, 6: 0 } as const;\nconst HEADING_INK = { 1: 'hi', 2: 'hi', 3: 'hi', 4: 'hi', 5: 'text', 6: 'dim' } as const;\n\nconst styles = StyleSheet.create((theme) => ({\n meta: {\n color: theme.colors.dim,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n },\n actions: { flexDirection: 'row', flexWrap: 'wrap' },\n root: { minWidth: 0, gap: theme.spacing(2) },\n prose: {\n color: theme.colors.text,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n },\n heading: (level: MarkdownHeadingLevel) => ({\n marginTop: theme.spacing(HEADING_SPACE[level]),\n fontSize: theme.fontSize[HEADING_STEP[level]],\n lineHeight: theme.lineHeight[HEADING_STEP[level]],\n letterSpacing: theme.letterSpacing[HEADING_STEP[level]],\n fontWeight: theme.fontWeight.semibold,\n color: theme.colors[HEADING_INK[level]],\n }),\n firstHeading: { marginTop: 0 },\n strong: { fontWeight: theme.fontWeight.semibold, color: theme.colors.hi },\n em: { fontStyle: 'italic' },\n code: {\n backgroundColor: theme.colors.deep,\n color: theme.colors.green,\n fontFamily: fontOf(theme.fontFamily.mono),\n },\n fileLink: { textDecorationLine: 'underline' },\n link: { color: theme.colors.blue, textDecorationLine: 'underline' },\n list: { gap: theme.spacing(0.5) },\n item: { flexDirection: 'row', gap: theme.spacing(2), paddingLeft: theme.spacing(1) },\n marker: { minWidth: theme.spacing(3), color: theme.colors.dim },\n itemText: { flexShrink: 1 },\n rule: { height: 1, backgroundColor: theme.colors['border-soft'] },\n // The web blockquote: a rule at the left and quieter text.\n quote: { borderLeftWidth: 2, borderLeftColor: theme.colors.border, paddingLeft: theme.spacing(3) },\n quoted: { color: theme.colors.dim },\n // The web table: bordered cells, the header on the deep surface.\n table: {\n flexDirection: 'row',\n borderTopWidth: 1,\n borderLeftWidth: 1,\n borderColor: theme.colors.border,\n },\n cell: {\n paddingHorizontal: theme.spacing(2),\n paddingVertical: theme.spacing(1),\n borderRightWidth: 1,\n borderBottomWidth: 1,\n borderColor: theme.colors.border,\n },\n headCell: { backgroundColor: theme.colors.deep, fontWeight: theme.fontWeight.semibold, color: theme.colors.hi },\n // The web image's frame: at most 480 tall, a soft border and rounded corners.\n image: {\n width: '100%',\n maxHeight: 480,\n borderRadius: theme.borderRadius.md,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n imageState: { color: theme.colors.dim },\n}));\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Markdown.mjs","names":["createContext","memo","ReactNode","useContext","useEffect","useMemo","useState","Linking","StyleSheet","fontOf","MarkdownBlock","MarkdownHeadingLevel","MarkdownInline","parseMarkdown","READING","inlineLength","inlinePrefix","useReadingPage","CodeBlock","ShowMore","FileLinkHandler","text","explicit","InitialPageContext","FileLinkContext","undefined","MarkdownImageLoader","path","Promise","url","dispose","ImageContext","URL_OR_ANCHOR","DIRECT_IMAGE","PLACEHOLDER_RATIO","decoded","href","decodeURIComponent","InlineCode","originalText","onFileLink","open","includes","styles","code","fileLink","InlineLink","children","isFile","test","openURL","catch","link","MarkdownImage","src","alt","loader","source","startsWith","slice","split","loaded","setLoaded","failed","ratio","setRatio","active","asset","Awaited","ReturnType","resolve","then","Error","result","current","uri","waiting","prose","imageState","nativeEvent","fit","width","height","size","Image","getSize","image","aspectRatio","renderInline","nodes","map","node","index","type","strong","em","MarkdownTable","header","rows","initialPage","rowPage","setRows","columnPage","setColumns","cellPage","setCells","visibleRows","visibleHeader","columns","limit","cell","clipped","row","length","some","root","table","column","headCell","meta","actions","page","Blocks","blocks","quoted","setPage","visible","parts","block","value","BoundedBlock","props","first","characters","total","shown","items","reduce","sum","item","remaining","next","push","more","Block","heading","level","firstHeading","run","flush","list","marker","ordered","start","itemText","language","rule","quote","MarkdownProps","loadImage","Markdown","generation","HEADING_STEP","const","HEADING_SPACE","HEADING_INK","create","theme","color","colors","dim","fontFamily","sans","fontSize","sm","lineHeight","uni__dependencies","flexDirection","flexWrap","minWidth","gap","spacing","base","marginTop","letterSpacing","fontWeight","semibold","hi","fontStyle","backgroundColor","deep","green","mono","textDecorationLine","blue","paddingLeft","flexShrink","borderLeftWidth","borderLeftColor","border","borderTopWidth","borderColor","paddingHorizontal","paddingVertical","borderRightWidth","borderBottomWidth","maxHeight","borderRadius","md","borderWidth"],"sources":["../../src/components/Markdown.tsx"],"sourcesContent":["import { createContext, memo, type ReactNode, useContext, useEffect, useMemo, useState } from 'react';\nimport { Image, Linking, ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\nimport { type MarkdownBlock, type MarkdownHeadingLevel, type MarkdownInline, parseMarkdown } from '../lib/markdown';\nimport { READING, inlineLength, inlinePrefix } from '../lib/reading';\nimport { useReadingPage } from '../lib/useReadingPage';\nimport { CodeBlock } from './CodeBlock';\nimport { ShowMore } from './ShowMore';\n\n/*\n * Markdown in the web component's element styles, from the package's own\n * parser: headings, paragraphs, lists, code spans and fences, bold, italic,\n * links, images, blockquotes and tables. Web links open with Linking; a file\n * path goes to the host. Raw HTML blocks are left out, as on the web.\n */\n\n/**\n * What a piece of inline code or a relative link opens, when the host knows.\n * Returning undefined leaves it as plain code or an ordinary link. The same\n * contract as the web Markdown's handler.\n */\nexport type FileLinkHandler = (text: string, explicit?: boolean) => (() => void) | undefined;\n\n/** Passed by context so the inline renderers stay module functions. */\nconst InitialPageContext = createContext(1);\n\nconst FileLinkContext = createContext<FileLinkHandler | undefined>(undefined);\n\n/** Loads a relative image path from the host; the same contract as the web Markdown's `loadImage`. */\nexport type MarkdownImageLoader = (path: string) => Promise<{ url: string; dispose(): void }>;\n\nconst ImageContext = createContext<MarkdownImageLoader | undefined>(undefined);\n\nconst URL_OR_ANCHOR = /^(?:[a-z][a-z\\d+.-]*:|\\/\\/|#|\\?)/i;\n/** Sources an Image may load as written; any other scheme stays its alt text. */\nconst DIRECT_IMAGE = /^(?:https?:|data:image\\/)/i;\n/** Until the image reports its size, it holds a landscape box rather than collapsing. */\nconst PLACEHOLDER_RATIO = 16 / 9;\n\nfunction decoded(href: string): string | undefined {\n try {\n return decodeURIComponent(href);\n } catch {\n return undefined;\n }\n}\n\nfunction InlineCode({ text, originalText = text }: { text: string; originalText?: string }) {\n const onFileLink = useContext(FileLinkContext);\n const open = originalText.includes('\\n') ? undefined : onFileLink?.(originalText);\n if (open !== undefined) {\n return (\n <Text\n accessibilityRole=\"link\"\n accessibilityHint={`open ${originalText}`}\n onPress={open}\n style={[styles.code, styles.fileLink]}\n >\n {text}\n </Text>\n );\n }\n return <Text style={styles.code}>{text}</Text>;\n}\n\nfunction InlineLink({ href, children }: { href: string; children: ReactNode }) {\n const onFileLink = useContext(FileLinkContext);\n const path = decoded(href);\n const isFile = path !== undefined && path !== '' && !URL_OR_ANCHOR.test(path);\n const open = isFile ? onFileLink?.(path, true) : undefined;\n return (\n <Text\n accessibilityRole=\"link\"\n onPress={() => {\n if (open !== undefined) open();\n else if (!isFile) Linking.openURL(href).catch(() => undefined);\n }}\n style={styles.link}\n >\n {children}\n </Text>\n );\n}\n\n/** One image: a file path through the host's loader, or a web or data address as written. */\nfunction MarkdownImage({ src, alt }: { src: string; alt: string }) {\n const loader = useContext(ImageContext);\n // An invalid encoded filename is shown as unavailable, never fetched.\n const source = src.startsWith('@artifact:') ? src.slice(1) : src;\n const path =\n URL_OR_ANCHOR.test(source) && !source.startsWith('artifact:')\n ? undefined\n : (decoded(source.split(/[?#]/u, 1)[0]!) ?? '');\n const [loaded, setLoaded] = useState<{ path: string; url?: string; failed?: boolean }>();\n const [ratio, setRatio] = useState(PLACEHOLDER_RATIO);\n useEffect(() => {\n if (loader === undefined || path === undefined) return;\n let active = true;\n let asset: Awaited<ReturnType<MarkdownImageLoader>> | undefined;\n void Promise.resolve()\n .then(() => {\n if (path === '') throw new Error('Invalid image path.');\n return loader(path);\n })\n .then((result) => {\n if (!active) return result.dispose();\n asset = result;\n setLoaded({ path, url: result.url });\n })\n .catch(() => {\n // The failure is shown in place, as the web image does.\n if (active) setLoaded({ path, failed: true });\n });\n return () => {\n active = false;\n asset?.dispose();\n };\n }, [path, loader]);\n const current = loaded?.path === path ? loaded : undefined;\n const uri = path === undefined ? (DIRECT_IMAGE.test(src) ? src : undefined) : current?.url;\n if (uri === undefined || current?.failed) {\n const waiting = path !== undefined && loader !== undefined && current === undefined;\n return (\n <Text style={[styles.prose, styles.imageState]} accessibilityRole={waiting ? 'text' : 'alert'}>\n {alt || path || 'Image'} ({waiting ? 'loading\\u2026' : 'unavailable'})\n </Text>\n );\n }\n return (\n <Image\n source={{ uri }}\n accessibilityLabel={alt || 'Image'}\n accessibilityIgnoresInvertColors\n resizeMode=\"contain\"\n onLoad={({ nativeEvent }) => {\n const fit = (width: number, height: number) => {\n if (width > 0 && height > 0) setRatio(width / height);\n };\n // iOS and Android report the size with the event; react-native-web does not, so it asks.\n const size = (nativeEvent as { source?: { width: number; height: number } } | undefined)?.source;\n if (size !== undefined) fit(size.width, size.height);\n else Image.getSize(uri, fit, () => undefined);\n }}\n onError={() => setLoaded({ path: path ?? src, failed: true })}\n style={[styles.image, { aspectRatio: ratio }]}\n />\n );\n}\nfunction renderInline(nodes: readonly MarkdownInline[]): ReactNode[] {\n return nodes.map((node, index) => {\n switch (node.type) {\n case 'text':\n return node.text;\n case 'code':\n return <InlineCode key={index} text={node.text} originalText={node.originalText} />;\n case 'strong':\n return (\n <Text key={index} style={styles.strong}>\n {renderInline(node.children)}\n </Text>\n );\n case 'em':\n return (\n <Text key={index} style={styles.em}>\n {renderInline(node.children)}\n </Text>\n );\n case 'link':\n return (\n <InlineLink key={index} href={node.href}>\n {renderInline(node.children)}\n </InlineLink>\n );\n case 'image':\n // Inside a heading or list item an image keeps to its alt text; paragraphs draw it.\n return node.alt;\n }\n });\n}\n\n/**\n * A table read column by column: every cell keeps to one line inside the sideways scroll, so each\n * column takes its widest cell and the rows line up without a table layout.\n */\nfunction MarkdownTable({ header, rows }: { header: MarkdownInline[][]; rows: MarkdownInline[][][] }) {\n const initialPage = useContext(InitialPageContext);\n const [rowPage, setRows] = useState(initialPage);\n const [columnPage, setColumns] = useState(initialPage);\n const [cellPage, setCells] = useState(initialPage);\n const visibleRows = rows.slice(0, READING.rows * rowPage);\n const visibleHeader = header.slice(0, READING.columns * columnPage);\n const limit = READING.cell * cellPage;\n const clipped = [visibleHeader, ...visibleRows.map((row) => row.slice(0, visibleHeader.length))].some((row) =>\n row.some((cell) => inlineLength(cell) > limit),\n );\n return (\n <View style={styles.root}>\n <ScrollView horizontal showsHorizontalScrollIndicator={false}>\n <View style={styles.table}>\n {visibleHeader.map((cell, column) => (\n <View key={column}>\n <Text style={[styles.prose, styles.cell, styles.headCell]}>\n {renderInline(inlinePrefix(cell, limit))}\n {inlineLength(cell) > limit ? '…' : ''}\n </Text>\n {visibleRows.map((row, index) => (\n <Text key={index} style={[styles.prose, styles.cell]}>\n {renderInline(inlinePrefix(row[column] ?? [], limit))}\n {inlineLength(row[column] ?? []) > limit ? '…' : ''}\n </Text>\n ))}\n </View>\n ))}\n </View>\n </ScrollView>\n <Text style={styles.meta}>\n {visibleRows.length} of {rows.length} rows · {visibleHeader.length} of {header.length} columns\n {clipped ? ` · Cells: first ${limit} characters` : ''}\n </Text>\n <View style={styles.actions}>\n {visibleRows.length < rows.length ? (\n <ShowMore label=\"Show more rows\" onPress={() => setRows((page) => page + 1)} />\n ) : null}\n {visibleHeader.length < header.length ? (\n <ShowMore label=\"Show more columns\" onPress={() => setColumns((page) => page + 1)} />\n ) : null}\n {clipped ? <ShowMore label=\"Show more cell text\" onPress={() => setCells((page) => page + 1)} /> : null}\n </View>\n </View>\n );\n}\n\nfunction Blocks({ blocks, quoted = false }: { blocks: MarkdownBlock[]; quoted?: boolean }) {\n const initialPage = useContext(InitialPageContext);\n const [page, setPage] = useState(initialPage);\n const visible = blocks.slice(0, READING.parts * page);\n return (\n <>\n {visible.map((block, index) => (\n <BoundedBlock key={index} block={block} first={index === 0} quoted={quoted} />\n ))}\n {visible.length < blocks.length ? (\n <ShowMore\n label=\"Show more\"\n summary={`${visible.length} of ${blocks.length} parts`}\n onPress={() => setPage((value) => value + 1)}\n />\n ) : null}\n </>\n );\n}\n\nfunction BoundedBlock({ block, ...props }: { block: MarkdownBlock; first: boolean; quoted?: boolean }) {\n const initialPage = useContext(InitialPageContext);\n const [page, setPage] = useState(initialPage);\n const limit = READING.characters * page;\n let visible = block;\n let total = 0;\n let shown = 0;\n if (block.type === 'heading' || block.type === 'paragraph') {\n total = inlineLength(block.children);\n const children = inlinePrefix(block.children, limit);\n shown = inlineLength(children);\n visible = { ...block, children };\n } else if (block.type === 'list') {\n total = block.items.reduce((sum, item) => sum + inlineLength(item), 0);\n let remaining = limit;\n const items = [];\n for (const item of block.items.slice(0, READING.parts * page)) {\n if (remaining <= 0) break;\n const next = inlinePrefix(item, remaining);\n items.push(next);\n remaining -= inlineLength(next);\n }\n shown = limit - remaining;\n visible = { ...block, items };\n }\n const more =\n shown < total || (block.type === 'list' && visible.type === 'list' && visible.items.length < block.items.length);\n return (\n <View style={styles.root}>\n <Block block={visible} {...props} />\n {more ? (\n <ShowMore\n label=\"Show more text\"\n summary={`${shown} of ${total} characters`}\n onPress={() => setPage((value) => value + 1)}\n />\n ) : null}\n </View>\n );\n}\n\nfunction Block({ block, first, quoted = false }: { block: MarkdownBlock; first: boolean; quoted?: boolean }) {\n const initialPage = useContext(InitialPageContext);\n const prose = [styles.prose, quoted && styles.quoted];\n switch (block.type) {\n case 'heading':\n return (\n <Text\n accessibilityRole=\"header\"\n style={[...prose, styles.heading(block.level), first && styles.firstHeading, quoted && styles.quoted]}\n >\n {renderInline(block.children)}\n </Text>\n );\n case 'paragraph': {\n // An image breaks the paragraph's text into runs, since an Image cannot sit inside Text.\n const parts: ReactNode[] = [];\n let run: MarkdownInline[] = [];\n const flush = () => {\n if (run.length > 0)\n parts.push(\n <Text key={parts.length} style={prose}>\n {renderInline(run)}\n </Text>,\n );\n run = [];\n };\n for (const node of block.children) {\n if (node.type !== 'image') {\n run.push(node);\n continue;\n }\n flush();\n parts.push(<MarkdownImage key={parts.length} src={node.src} alt={node.alt} />);\n }\n flush();\n return parts.length === 1 ? parts[0] : <View style={styles.root}>{parts}</View>;\n }\n case 'list':\n return (\n <View accessibilityRole=\"list\" style={styles.list}>\n {block.items.map((item, index) => (\n <View key={index} style={styles.item}>\n <Text style={[...prose, styles.marker]}>{block.ordered ? `${block.start + index}.` : '\\u2022'}</Text>\n <Text style={[...prose, styles.itemText]}>{renderInline(item)}</Text>\n </View>\n ))}\n </View>\n );\n case 'code':\n return <CodeBlock text={block.text} language={block.language} initialPage={initialPage} />;\n case 'rule':\n return <View accessible={false} style={styles.rule} />;\n case 'quote':\n return (\n <View style={[styles.root, styles.quote]}>\n <Blocks blocks={block.children} quoted />\n </View>\n );\n case 'table':\n return <MarkdownTable header={block.header} rows={block.rows} />;\n }\n}\n\nexport interface MarkdownProps {\n text: string;\n onFileLink?: FileLinkHandler;\n /** Loads relative image paths; without it they show as unavailable. */\n loadImage?: MarkdownImageLoader;\n /** Initial reveal pages for a restored reading position. Defaults to one. */\n initialPage?: number;\n}\n\n/** Markdown in Po's shared presentation, parsed by the package's own small parser. */\nexport const Markdown = memo(function Markdown({ text, onFileLink, loadImage, initialPage = 1 }: MarkdownProps) {\n const blocks = useMemo(() => parseMarkdown(text), [text]);\n const { generation } = useReadingPage(text);\n return (\n <InitialPageContext.Provider value={initialPage}>\n <FileLinkContext.Provider value={onFileLink}>\n <ImageContext.Provider value={loadImage}>\n <View style={styles.root}>\n <Blocks key={generation} blocks={blocks} />\n </View>\n </ImageContext.Provider>\n </FileLinkContext.Provider>\n </InitialPageContext.Provider>\n );\n});\n\n/**\n * Headings step up from the prose and never shrink below it; h4 to h6 keep\n * the prose size and lean on weight, fading from `hi` to `dim`.\n */\nconst HEADING_STEP = { 1: '2xl', 2: 'xl', 3: 'lg', 4: 'base', 5: 'base', 6: 'base' } as const;\nconst HEADING_SPACE = { 1: 2, 2: 2, 3: 1, 4: 0, 5: 0, 6: 0 } as const;\nconst HEADING_INK = { 1: 'hi', 2: 'hi', 3: 'hi', 4: 'hi', 5: 'text', 6: 'dim' } as const;\n\nconst styles = StyleSheet.create((theme) => ({\n meta: {\n color: theme.colors.dim,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n },\n actions: { flexDirection: 'row', flexWrap: 'wrap' },\n root: { minWidth: 0, gap: theme.spacing(2) },\n prose: {\n color: theme.colors.text,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n },\n heading: (level: MarkdownHeadingLevel) => ({\n marginTop: theme.spacing(HEADING_SPACE[level]),\n fontSize: theme.fontSize[HEADING_STEP[level]],\n lineHeight: theme.lineHeight[HEADING_STEP[level]],\n letterSpacing: theme.letterSpacing[HEADING_STEP[level]],\n fontWeight: theme.fontWeight.semibold,\n color: theme.colors[HEADING_INK[level]],\n }),\n firstHeading: { marginTop: 0 },\n strong: { fontWeight: theme.fontWeight.semibold, color: theme.colors.hi },\n em: { fontStyle: 'italic' },\n code: {\n backgroundColor: theme.colors.deep,\n color: theme.colors.green,\n fontFamily: fontOf(theme.fontFamily.mono),\n },\n fileLink: { textDecorationLine: 'underline' },\n link: { color: theme.colors.blue, textDecorationLine: 'underline' },\n list: { gap: theme.spacing(0.5) },\n item: { flexDirection: 'row', gap: theme.spacing(2), paddingLeft: theme.spacing(1) },\n marker: { minWidth: theme.spacing(3), color: theme.colors.dim },\n itemText: { flexShrink: 1 },\n rule: { height: 1, backgroundColor: theme.colors['border-soft'] },\n // The web blockquote: a rule at the left and quieter text.\n quote: { borderLeftWidth: 2, borderLeftColor: theme.colors.border, paddingLeft: theme.spacing(3) },\n quoted: { color: theme.colors.dim },\n // The web table: bordered cells, the header on the deep surface.\n table: {\n flexDirection: 'row',\n borderTopWidth: 1,\n borderLeftWidth: 1,\n borderColor: theme.colors.border,\n },\n cell: {\n paddingHorizontal: theme.spacing(2),\n paddingVertical: theme.spacing(1),\n borderRightWidth: 1,\n borderBottomWidth: 1,\n borderColor: theme.colors.border,\n },\n headCell: { backgroundColor: theme.colors.deep, fontWeight: theme.fontWeight.semibold, color: theme.colors.hi },\n // The web image's frame: at most 480 tall, a soft border and rounded corners.\n image: {\n width: '100%',\n maxHeight: 480,\n borderRadius: theme.borderRadius.md,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n imageState: { color: theme.colors.dim },\n}));\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,MAAMuB,qBAAqBvB,cAAc,CAAC;AAE1C,MAAMwB,kBAAkBxB,cAA2CyB,MAAS;AAK5E,MAAMM,eAAe/B,cAA+CyB,MAAS;AAE7E,MAAMO,gBAAgB;;AAEtB,MAAMC,eAAe;;AAErB,MAAMC,oBAAoB,KAAK;AAE/B,SAASC,QAAQC,MAAkC;CACjD,IAAI;EACF,OAAOC,mBAAmBD,IAAI;CAChC,QAAQ;EACN;CACF;AACF;AAEA,SAASE,WAAW,EAAEjB,MAAMkB,eAAelB,QAAiD;CAC1F,MAAMmB,aAAarC,WAAWqB,eAAe;CAC7C,MAAMiB,OAAOF,aAAaG,SAAS,IAAI,IAAIjB,SAAYe,aAAaD,YAAY;CAChF,IAAIE,SAAShB,QACX,OACE,oBAAC,MAAD;EACE,mBAAkB;EAClB,mBAAmB,QAAQc;EAC3B,SAASE;EACT,OAAO,CAACE,OAAOC,MAAMD,OAAOE,QAAQ;YAEnCxB;CACG;CAGV,OAAO,oBAAC,MAAD;EAAM,OAAOsB,OAAOC;YAAOvB;CAAW;AAC/C;AAEA,SAASyB,WAAW,EAAEV,MAAMW,YAAmD;CAC7E,MAAMP,aAAarC,WAAWqB,eAAe;CAC7C,MAAMG,OAAOQ,QAAQC,IAAI;CACzB,MAAMY,SAASrB,SAASF,UAAaE,SAAS,MAAM,CAACK,cAAciB,KAAKtB,IAAI;CAC5E,MAAMc,OAAOO,SAASR,aAAab,MAAM,IAAI,IAAIF;CACjD,OACE,oBAAC,MAAD;EACE,mBAAkB;EAClB,eAAe;GACb,IAAIgB,SAAShB,QAAWgB,KAAK;QACxB,IAAI,CAACO,QAAQzC,QAAQ2C,QAAQd,IAAI,CAAC,CAACe,YAAY1B,MAAS;EAC/D;EACA,OAAOkB,OAAOS;EAEbL;CACG;AAEV;;AAGA,SAASM,cAAc,EAAEC,KAAKC,OAAqC;CACjE,MAAMC,SAASrD,WAAW4B,YAAY;CAEtC,MAAM0B,SAASH,IAAII,WAAW,YAAY,IAAIJ,IAAIK,MAAM,CAAC,IAAIL;CAC7D,MAAM3B,OACJK,cAAciB,KAAKQ,MAAM,KAAK,CAACA,OAAOC,WAAW,WAAW,IACxDjC,SACCU,QAAQsB,OAAOG,MAAM,SAAS,CAAC,CAAC,CAAC,EAAG,KAAK;CAChD,MAAM,CAACC,QAAQC,aAAaxD,SAA2D;CACvF,MAAM,CAAC0D,OAAOC,YAAY3D,SAAS4B,iBAAiB;CACpD9B,gBAAgB;EACd,IAAIoD,WAAW/B,UAAaE,SAASF,QAAW;EAChD,IAAIyC,SAAS;EACb,IAAIC;EACJ,AAAKvC,QAAQ0C,QAAQ,CAAC,CACnBC,WAAW;GACV,IAAI5C,SAAS,IAAI,MAAM,IAAI6C,MAAM,qBAAqB;GACtD,OAAOhB,OAAO7B,IAAI;EACpB,CAAC,CAAC,CACD4C,MAAME,WAAW;GAChB,IAAI,CAACP,QAAQ,OAAOO,OAAO3C,QAAQ;GACnCqC,QAAQM;GACRX,UAAU;IAAEnC;IAAME,KAAK4C,OAAO5C;GAAI,CAAC;EACrC,CAAC,CAAC,CACDsB,YAAY;GAEX,IAAIe,QAAQJ,UAAU;IAAEnC;IAAMoC,QAAQ;GAAK,CAAC;EAC9C,CAAC;EACH,aAAa;GACXG,SAAS;GACTC,OAAOrC,QAAQ;EACjB;CACF,GAAG,CAACH,MAAM6B,MAAM,CAAC;CACjB,MAAMkB,UAAUb,QAAQlC,SAASA,OAAOkC,SAASpC;CACjD,MAAMkD,MAAMhD,SAASF,SAAaQ,aAAagB,KAAKK,GAAG,IAAIA,MAAM7B,SAAaiD,SAAS7C;CACvF,IAAI8C,QAAQlD,UAAaiD,SAASX,QAAQ;EACxC,MAAMa,UAAUjD,SAASF,UAAa+B,WAAW/B,UAAaiD,YAAYjD;EAC1E,OACE,qBAAC,MAAD;GAAM,OAAO,CAACkB,OAAOkC,OAAOlC,OAAOmC,UAAU;GAAG,mBAAmBF,UAAU,SAAS;aAAtF;IACGrB,OAAO5B,QAAQ;IAAQ;IAAGiD,UAAU,aAAkB;IAAc;GACjE;;CAEV;CACA,OACE,oBAAC,OAAD;EACE,QAAQ,EAAED,IAAI;EACd,oBAAoBpB,OAAO;EAC3B;EACA,YAAW;EACX,SAAS,EAAEwB,kBAAkB;GAC3B,MAAMC,OAAOC,OAAeC,WAAmB;IAC7C,IAAID,QAAQ,KAAKC,SAAS,GAAGjB,SAASgB,QAAQC,MAAM;GACtD;GAEA,MAAMC,OAAQJ,aAA4EtB;GAC1F,IAAI0B,SAAS1D,QAAWuD,IAAIG,KAAKF,OAAOE,KAAKD,MAAM;QAC9CE,MAAMC,QAAQV,KAAKK,WAAWvD,MAAS;EAC9C;EACA,eAAeqC,UAAU;GAAEnC,MAAMA,QAAQ2B;GAAKS,QAAQ;EAAK,CAAC;EAC5D,OAAO,CAACpB,OAAO2C,OAAO,EAAEC,aAAavB,MAAM,CAAC;CAAE;AAGpD;AACA,SAASwB,aAAaC,OAA+C;CACnE,OAAOA,MAAMC,KAAKC,MAAMC,UAAU;EAChC,QAAQD,KAAKE,MAAb;GACE,KAAK,QACH,OAAOF,KAAKtE;GACd,KAAK,QACH,OAAO,oBAAC,YAAD;IAAwB,MAAMsE,KAAKtE;IAAM,cAAcsE,KAAKpD;GAAa,GAAxDqD,KAAwD;GAClF,KAAK,UACH,OACE,oBAAC,MAAD;IAAkB,OAAOjD,OAAOmD;cAC7BN,aAAaG,KAAK5C,QAAQ;GACvB,GAFK6C,KAEL;GAEV,KAAK,MACH,OACE,oBAAC,MAAD;IAAkB,OAAOjD,OAAOoD;cAC7BP,aAAaG,KAAK5C,QAAQ;GACvB,GAFK6C,KAEL;GAEV,KAAK,QACH,OACE,oBAAC,YAAD;IAAwB,MAAMD,KAAKvD;cAChCoD,aAAaG,KAAK5C,QAAQ;GACjB,GAFK6C,KAEL;GAEhB,KAAK,SAEH,OAAOD,KAAKpC;EAChB;CACF,CAAC;AACH;;;;;AAMA,SAASyC,cAAc,EAAEC,QAAQC,QAAoE;CACnG,MAAMC,cAAchG,WAAWoB,kBAAkB;CACjD,MAAM,CAAC6E,SAASC,WAAW/F,SAAS6F,WAAW;CAC/C,MAAM,CAACG,YAAYC,cAAcjG,SAAS6F,WAAW;CACrD,MAAM,CAACK,UAAUC,YAAYnG,SAAS6F,WAAW;CACjD,MAAMO,cAAcR,KAAKvC,MAAM,GAAG7C,QAAQoF,OAAOE,OAAO;CACxD,MAAMO,gBAAgBV,OAAOtC,MAAM,GAAG7C,QAAQ8F,UAAUN,UAAU;CAClE,MAAMO,QAAQ/F,QAAQgG,OAAON;CAC7B,MAAMO,UAAU,CAACJ,eAAe,GAAGD,YAAYhB,KAAKsB,QAAQA,IAAIrD,MAAM,GAAGgD,cAAcM,MAAM,CAAC,CAAC,CAAC,CAACC,MAAMF,QACrGA,IAAIE,MAAMJ,SAAS/F,aAAa+F,IAAI,IAAID,KAAK,CAC/C;CACA,OACE,qBAAC,MAAD;EAAM,OAAOlE,OAAOwE;YAApB;GACE,oBAAC,YAAD;IAAY;IAAW,gCAAgC;cACrD,oBAAC,MAAD;KAAM,OAAOxE,OAAOyE;eACjBT,cAAcjB,KAAKoB,MAAMO,WACxB,qBAAC,MAAD,aACE,qBAAC,MAAD;MAAM,OAAO;OAAC1E,OAAOkC;OAAOlC,OAAOmE;OAAMnE,OAAO2E;MAAQ;gBAAxD,CACG9B,aAAaxE,aAAa8F,MAAMD,KAAK,CAAC,GACtC9F,aAAa+F,IAAI,IAAID,QAAQ,MAAM,EAChC;SACLH,YAAYhB,KAAKsB,KAAKpB,UACrB,qBAAC,MAAD;MAAkB,OAAO,CAACjD,OAAOkC,OAAOlC,OAAOmE,IAAI;gBAAnD,CACGtB,aAAaxE,aAAagG,IAAIK,WAAW,CAAA,GAAIR,KAAK,CAAC,GACnD9F,aAAaiG,IAAIK,WAAW,CAAA,CAAE,IAAIR,QAAQ,MAAM,EAC7C;QAHKjB,KAGL,CACP,CACG,KAXKyB,MAWL,CACP;IACG;GACI;GACZ,qBAAC,MAAD;IAAM,OAAO1E,OAAO4E;cAApB;KACGb,YAAYO;KAAO;KAAKf,KAAKe;KAAO;KAASN,cAAcM;KAAO;KAAKhB,OAAOgB;KAAO;KACrFF,UAAU,mBAAmBF,MAAK,eAAgB;IAC/C;;GACN,qBAAC,MAAD;IAAM,OAAOlE,OAAO6E;cAApB;KACGd,YAAYO,SAASf,KAAKe,SACzB,oBAAC,UAAD;MAAU,OAAM;MAAiB,eAAeZ,SAASoB,SAASA,OAAO,CAAC;KAAE,KAC1E;KACHd,cAAcM,SAAShB,OAAOgB,SAC7B,oBAAC,UAAD;MAAU,OAAM;MAAoB,eAAeV,YAAYkB,SAASA,OAAO,CAAC;KAAE,KAChF;KACHV,UAAU,oBAAC,UAAD;MAAU,OAAM;MAAsB,eAAeN,UAAUgB,SAASA,OAAO,CAAC;KAAE,KAAM;IAC/F;;EACF;;AAEV;AAEA,SAASC,OAAO,EAAEC,QAAQC,SAAS,SAAwD;CACzF,MAAMzB,cAAchG,WAAWoB,kBAAkB;CACjD,MAAM,CAACkG,MAAMI,WAAWvH,SAAS6F,WAAW;CAC5C,MAAM2B,UAAUH,OAAOhE,MAAM,GAAG7C,QAAQiH,QAAQN,IAAI;CACpD,OACE,4CACGK,QAAQpC,KAAKsC,OAAOpC,UACnB,oBAAC,cAAD;EAAiCoC;EAAO,OAAOpC,UAAU;EAAWgC;CAAO,GAAxDhC,KAAwD,CAC5E,GACAkC,QAAQb,SAASU,OAAOV,SACvB,oBAAC,UAAD;EACE,OAAM;EACN,SAAS,GAAGa,QAAQb,OAAM,MAAOU,OAAOV,OAAM;EAC9C,eAAeY,SAASI,UAAUA,QAAQ,CAAC;CAAE,KAE7C,IACN;AAEJ;AAEA,SAASC,aAAa,EAAEF,OAAO,GAAGG,SAAqE;CACrG,MAAMhC,cAAchG,WAAWoB,kBAAkB;CACjD,MAAM,CAACkG,MAAMI,WAAWvH,SAAS6F,WAAW;CAC5C,MAAMU,QAAQ/F,QAAQuH,aAAaZ;CACnC,IAAIK,UAAUE;CACd,IAAIM,QAAQ;CACZ,IAAIC,QAAQ;CACZ,IAAIP,MAAMnC,SAAS,aAAamC,MAAMnC,SAAS,aAAa;EAC1DyC,QAAQvH,aAAaiH,MAAMjF,QAAQ;EACnC,MAAMA,WAAW/B,aAAagH,MAAMjF,UAAU8D,KAAK;EACnD0B,QAAQxH,aAAagC,QAAQ;EAC7B+E,UAAU;GAAE,GAAGE;GAAOjF;EAAS;CACjC,OAAO,IAAIiF,MAAMnC,SAAS,QAAQ;EAChCyC,QAAQN,MAAMQ,MAAMC,QAAQC,KAAKC,SAASD,MAAM3H,aAAa4H,IAAI,GAAG,CAAC;EACrE,IAAIC,YAAY/B;EAChB,MAAM2B,QAAQ,CAAA;EACd,KAAK,MAAMG,QAAQX,MAAMQ,MAAM7E,MAAM,GAAG7C,QAAQiH,QAAQN,IAAI,GAAG;GAC7D,IAAImB,aAAa,GAAG;GACpB,MAAMC,OAAO7H,aAAa2H,MAAMC,SAAS;GACzCJ,MAAMM,KAAKD,IAAI;GACfD,aAAa7H,aAAa8H,IAAI;EAChC;EACAN,QAAQ1B,QAAQ+B;EAChBd,UAAU;GAAE,GAAGE;GAAOQ;EAAM;CAC9B;CACA,MAAMO,OACJR,QAAQD,SAAUN,MAAMnC,SAAS,UAAUiC,QAAQjC,SAAS,UAAUiC,QAAQU,MAAMvB,SAASe,MAAMQ,MAAMvB;CAC3G,OACE,qBAAC,MAAD;EAAM,OAAOtE,OAAOwE;YAApB,CACE,oBAAC,OAAD;GAAO,OAAOW;GAAS,GAAIK;EAAM,IAChCY,OACC,oBAAC,UAAD;GACE,OAAM;GACN,SAAS,GAAGR,MAAK,MAAOD,MAAK;GAC7B,eAAeT,SAASI,UAAUA,QAAQ,CAAC;EAAE,KAE7C,IACA;;AAEV;AAEA,SAASe,MAAM,EAAEhB,OAAOI,OAAOR,SAAS,SAAqE;CAC3G,MAAMzB,cAAchG,WAAWoB,kBAAkB;CACjD,MAAMsD,QAAQ,CAAClC,OAAOkC,OAAO+C,UAAUjF,OAAOiF,MAAM;CACpD,QAAQI,MAAMnC,MAAd;EACE,KAAK,WACH,OACE,oBAAC,MAAD;GACE,mBAAkB;GAClB,OAAO;IAAC,GAAGhB;IAAOlC,OAAOsG,QAAQjB,MAAMkB,KAAK;IAAGd,SAASzF,OAAOwG;IAAcvB,UAAUjF,OAAOiF;GAAM;aAEnGpC,aAAawC,MAAMjF,QAAQ;EACxB;EAEV,KAAK,aAAa;GAEhB,MAAMgF,QAAqB,CAAA;GAC3B,IAAIqB,MAAwB,CAAA;GAC5B,MAAMC,cAAc;IAClB,IAAID,IAAInC,SAAS,GACfc,MAAMe,KACJ,oBAAC,MAAD;KAAyB,OAAOjE;eAC7BW,aAAa4D,GAAG;IACb,GAFKrB,MAAMd,MAEX,CACR;IACFmC,MAAM,CAAA;GACR;GACA,KAAK,MAAMzD,QAAQqC,MAAMjF,UAAU;IACjC,IAAI4C,KAAKE,SAAS,SAAS;KACzBuD,IAAIN,KAAKnD,IAAI;KACb;IACF;IACA0D,MAAM;IACNtB,MAAMe,KAAK,oBAAC,eAAD;KAAkC,KAAKnD,KAAKrC;KAAK,KAAKqC,KAAKpC;IAAI,GAA3CwE,MAAMd,MAAqC,CAAG;GAC/E;GACAoC,MAAM;GACN,OAAOtB,MAAMd,WAAW,IAAIc,MAAM,KAAK,oBAAC,MAAD;IAAM,OAAOpF,OAAOwE;cAAOY;GAAY;EAChF;EACA,KAAK,QACH,OACE,oBAAC,MAAD;GAAM,mBAAkB;GAAO,OAAOpF,OAAO2G;aAC1CtB,MAAMQ,MAAM9C,KAAKiD,MAAM/C,UACtB,qBAAC,MAAD;IAAkB,OAAOjD,OAAOgG;cAAhC,CACE,oBAAC,MAAD;KAAM,OAAO,CAAC,GAAG9D,OAAOlC,OAAO4G,MAAM;eAAIvB,MAAMwB,UAAU,GAAGxB,MAAMyB,QAAQ7D,MAAK,KAAM;IAAe,IACpG,oBAAC,MAAD;KAAM,OAAO,CAAC,GAAGf,OAAOlC,OAAO+G,QAAQ;eAAIlE,aAAamD,IAAI;IAAQ,EAChE;MAHK/C,KAGL,CACP;EACG;EAEV,KAAK,QACH,OAAO,oBAAC,WAAD;GAAW,MAAMoC,MAAM3G;GAAM,UAAU2G,MAAM2B;GAAuBxD;EAAY;EACzF,KAAK,QACH,OAAO,oBAAC,MAAD;GAAM,YAAY;GAAO,OAAOxD,OAAOiH;EAAK;EACrD,KAAK,SACH,OACE,oBAAC,MAAD;GAAM,OAAO,CAACjH,OAAOwE,MAAMxE,OAAOkH,KAAK;aACrC,oBAAC,QAAD;IAAQ,QAAQ7B,MAAMjF;IAAU;GAAM;EAClC;EAEV,KAAK,SACH,OAAO,oBAAC,eAAD;GAAe,QAAQiF,MAAM/B;GAAQ,MAAM+B,MAAM9B;EAAK;CACjE;AACF;;AAYA,MAAa8D,WAAW/J,KAAK,SAAS+J,SAAS,EAAE3I,MAAMmB,YAAYuH,WAAW5D,cAAc,KAAoB;CAC9G,MAAMwB,SAAStH,cAAcQ,cAAcQ,IAAI,GAAG,CAACA,IAAI,CAAC;CACxD,MAAM,EAAE4I,eAAehJ,eAAeI,IAAI;CAC1C,OACE,oBAAC,mBAAmB,UAApB;EAA6B,OAAO8E;YAClC,oBAAC,gBAAgB,UAAjB;GAA0B,OAAO3D;aAC/B,oBAAC,aAAa,UAAd;IAAuB,OAAOuH;cAC5B,oBAAC,MAAD;KAAM,OAAOpH,OAAOwE;eAClB,oBAAC,QAAD,EAAiCQ,OAAO,GAA3BsC,UAA2B;IACpC;GACe;EACC;CACC;AAEjC,CAAC;;;;;AAMD,MAAMC,eAAe;CAAE,GAAG;CAAO,GAAG;CAAM,GAAG;CAAM,GAAG;CAAQ,GAAG;CAAQ,GAAG;AAAO;AACnF,MAAME,gBAAgB;CAAE,GAAG;CAAG,GAAG;CAAG,GAAG;CAAG,GAAG;CAAG,GAAG;CAAG,GAAG;AAAE;AAC3D,MAAMC,cAAc;CAAE,GAAG;CAAM,GAAG;CAAM,GAAG;CAAM,GAAG;CAAM,GAAG;CAAQ,GAAG;AAAM;AAE9E,MAAM1H,SAASnC,WAAW8J,QAAQC,WAAW;CAC3ChD,MAAM;EACJiD,OAAOD,MAAME,OAAOC;EACpBC,YAAYlK,OAAO8J,MAAMI,WAAWC,IAAI;EACxCC,UAAUN,MAAMM,SAASC;EACzBC,YAAYR,MAAMQ,WAAWD;EAAEE,mBAAA,CAAA,CAAA;CACjC;CACAxD,SAAS;EAAEyD,eAAe;EAAOC,UAAU;CAAO;CAClD/D,MAAM;EAAEgE,UAAU;EAAGC,KAAKb,MAAMc,QAAQ,CAAC;EAACL,mBAAA,CAAA,CAAA;CAAC;CAC3CnG,OAAO;EACL2F,OAAOD,MAAME,OAAOpJ;EACpBsJ,YAAYlK,OAAO8J,MAAMI,WAAWC,IAAI;EACxCC,UAAUN,MAAMM,SAASS;EACzBP,YAAYR,MAAMQ,WAAWO;EAAIN,mBAAA,CAAA,CAAA;CACnC;CACA/B,UAAUC,WAAiC;EACzCqC,WAAWhB,MAAMc,QAAQjB,cAAclB,MAAM;EAC7C2B,UAAUN,MAAMM,SAASX,aAAahB;EACtC6B,YAAYR,MAAMQ,WAAWb,aAAahB;EAC1CsC,eAAejB,MAAMiB,cAActB,aAAahB;EAChDuC,YAAYlB,MAAMkB,WAAWC;EAC7BlB,OAAOD,MAAME,OAAOJ,YAAYnB;EAAO8B,mBAAA,CAAA,CAAA;CACzC;CACA7B,cAAc,EAAEoC,WAAW,EAAE;CAC7BzF,QAAQ;EAAE2F,YAAYlB,MAAMkB,WAAWC;EAAUlB,OAAOD,MAAME,OAAOkB;EAAEX,mBAAA,CAAA,CAAA;CAAC;CACxEjF,IAAI,EAAE6F,WAAW,SAAS;CAC1BhJ,MAAM;EACJiJ,iBAAiBtB,MAAME,OAAOqB;EAC9BtB,OAAOD,MAAME,OAAOsB;EACpBpB,YAAYlK,OAAO8J,MAAMI,WAAWqB,IAAI;EAAChB,mBAAA,CAAA,CAAA;CAC3C;CACAnI,UAAU,EAAEoJ,oBAAoB,YAAY;CAC5C7I,MAAM;EAAEoH,OAAOD,MAAME,OAAOyB;EAAMD,oBAAoB;EAAWjB,mBAAA,CAAA,CAAA;CAAC;CAClE1B,MAAM;EAAE8B,KAAKb,MAAMc,QAAQ,EAAG;EAACL,mBAAA,CAAA,CAAA;CAAC;CAChCrC,MAAM;EAAEsC,eAAe;EAAOG,KAAKb,MAAMc,QAAQ,CAAC;EAAGc,aAAa5B,MAAMc,QAAQ,CAAC;EAACL,mBAAA,CAAA,CAAA;CAAC;CACnFzB,QAAQ;EAAE4B,UAAUZ,MAAMc,QAAQ,CAAC;EAAGb,OAAOD,MAAME,OAAOC;EAAGM,mBAAA,CAAA,CAAA;CAAC;CAC9DtB,UAAU,EAAE0C,YAAY,EAAE;CAC1BxC,MAAM;EAAE1E,QAAQ;EAAG2G,iBAAiBtB,MAAME,OAAO;EAAcO,mBAAA,CAAA,CAAA;CAAC;CAEhEnB,OAAO;EAAEwC,iBAAiB;EAAGC,iBAAiB/B,MAAME,OAAO8B;EAAQJ,aAAa5B,MAAMc,QAAQ,CAAC;EAACL,mBAAA,CAAA,CAAA;CAAC;CACjGpD,QAAQ;EAAE4C,OAAOD,MAAME,OAAOC;EAAGM,mBAAA,CAAA,CAAA;CAAC;CAElC5D,OAAO;EACL6D,eAAe;EACfuB,gBAAgB;EAChBH,iBAAiB;EACjBI,aAAalC,MAAME,OAAO8B;EAAMvB,mBAAA,CAAA,CAAA;CAClC;CACAlE,MAAM;EACJ4F,mBAAmBnC,MAAMc,QAAQ,CAAC;EAClCsB,iBAAiBpC,MAAMc,QAAQ,CAAC;EAChCuB,kBAAkB;EAClBC,mBAAmB;EACnBJ,aAAalC,MAAME,OAAO8B;EAAMvB,mBAAA,CAAA,CAAA;CAClC;CACA1D,UAAU;EAAEuE,iBAAiBtB,MAAME,OAAOqB;EAAML,YAAYlB,MAAMkB,WAAWC;EAAUlB,OAAOD,MAAME,OAAOkB;EAAEX,mBAAA,CAAA,CAAA;CAAC;CAE9G1F,OAAO;EACLL,OAAO;EACP6H,WAAW;EACXC,cAAcxC,MAAMwC,aAAaC;EACjCC,aAAa;EACbR,aAAalC,MAAME,OAAO8B;EAAMvB,mBAAA,CAAA,CAAA;CAClC;CACAlG,YAAY;EAAE0F,OAAOD,MAAME,OAAOC;EAAGM,mBAAA,CAAA,CAAA;CAAC;AACxC,EAAE"}
|
|
@@ -22,9 +22,11 @@ export interface SheetContentProps {
|
|
|
22
22
|
scrollable?: boolean;
|
|
23
23
|
/** The sheet holds unsaved work: a prompt arriving in the conversation leaves it open with a note. */
|
|
24
24
|
keep?: boolean;
|
|
25
|
+
/** Runs after the native modal is dismissed, including a caller-initiated close. */
|
|
26
|
+
onDismiss?: () => void;
|
|
25
27
|
}
|
|
26
28
|
/** The sheet surface. Fields inside it switch to the sheet's own input so the keyboard lifts the sheet. */
|
|
27
|
-
export declare function SheetContent({ children, scrollable, footer, keep }: SheetContentProps): import("react").JSX.Element;
|
|
29
|
+
export declare function SheetContent({ children, scrollable, footer, keep, onDismiss }: SheetContentProps): import("react").JSX.Element;
|
|
28
30
|
export interface SheetPartProps extends Omit<ViewProps, 'children' | 'style'> {
|
|
29
31
|
children?: ReactNode;
|
|
30
32
|
style?: StyleProp<ViewStyle>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sheet.d.mts","names":[],"sources":["../../src/components/Sheet.tsx"],"mappings":";;;;iBAwBiB;;EAEf;EACA;EACA,gBAAgB;EAChB,WAAW;;wBAGG,QAAQ,MAAM,aAAqB,cAAc,YAAY,6BAAU,IAAA;;wBAMvE,eAAe,YAAY,SAAS,8BAAW,IAAA;;wBAc/C,aAAa,YAAY,SAAS,8BAAW,IAAA;iBAa5C;EACf,WAAW;;EAEX,SAAS;;EAET;;EAEA;;;wBAIc,eAAe,UAAU,YAAmB,QAAQ,
|
|
1
|
+
{"version":3,"file":"Sheet.d.mts","names":[],"sources":["../../src/components/Sheet.tsx"],"mappings":";;;;iBAwBiB;;EAEf;EACA;EACA,gBAAgB;EAChB,WAAW;;wBAGG,QAAQ,MAAM,aAAqB,cAAc,YAAY,6BAAU,IAAA;;wBAMvE,eAAe,YAAY,SAAS,8BAAW,IAAA;;wBAc/C,aAAa,YAAY,SAAS,8BAAW,IAAA;iBAa5C;EACf,WAAW;;EAEX,SAAS;;EAET;;EAEA;;EAEA;;;wBAIc,eAAe,UAAU,YAAmB,QAAQ,MAAM,aAAa,oCAAiB,IAAA;iBAkBvF,uBAAuB,KAAK;EAC3C,WAAW;EACX,QAAQ,UAAU;;iBAGH,yBAAyB;;EAExC;;EAEA;;wBAGc,cAAc,aAAoB,YAAsB,OAAO,aAAa,SAAS,mCAAgB,IAAA;wBAoBrG,aAAa,UAAU,SAAS,4BAAS,IAAA;wBAIzC,mBAAmB,UAAU,SAAS,4BAAS,IAAA;;wBAK/C,YAAY,OAAO,aAAa,SAAS,iCAAc,IAAA;wBAQvD,cAAc,OAAO,aAAa,SAAS,iCAAc,IAAA"}
|
|
@@ -48,13 +48,14 @@ function SheetClose({ onPress, ...props }) {
|
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
/** The sheet surface. Fields inside it switch to the sheet's own input so the keyboard lifts the sheet. */
|
|
51
|
-
function SheetContent({ children, scrollable = true, footer, keep }) {
|
|
51
|
+
function SheetContent({ children, scrollable = true, footer, keep, onDismiss }) {
|
|
52
52
|
const { open, setOpen } = useContext(SheetContext);
|
|
53
53
|
return /* @__PURE__ */ jsx(SheetFrame, {
|
|
54
54
|
open,
|
|
55
55
|
onClose: () => setOpen(false),
|
|
56
56
|
scrollable,
|
|
57
57
|
keep,
|
|
58
|
+
onDismiss,
|
|
58
59
|
...footer === void 0 ? {} : { footer: /* @__PURE__ */ jsx(SheetContext.Provider, {
|
|
59
60
|
value: {
|
|
60
61
|
open,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sheet.mjs","names":["createContext","ReactNode","useContext","StyleProp","TextProps","ViewProps","ViewStyle","StyleSheet","CloseIcon","fontOf","useControllable","wrapText","Button","ButtonProps","SheetFrame","SheetState","open","setOpen","SheetContext","undefined","SheetProps","defaultOpen","onOpenChange","children","Sheet","current","SheetTrigger","onPress","props","event","SheetClose","SheetContentProps","footer","scrollable","keep","SheetContent","SheetPartProps","Omit","style","SheetHeaderProps","dismissible","closeLabel","SheetHeader","styles","header","close","SheetTitle","title","SheetDescription","description","SheetBody","body","SheetFooter","hint","create","theme","flexDirection","alignItems","gap","spacing","minWidth","height","borderBottomWidth","borderBottomColor","colors","border","paddingHorizontal","uni__dependencies","marginLeft","flexShrink","color","hi","fontFamily","sans","fontSize","lg","lineHeight","fontWeight","semibold","dim","sm","lineHeightRelaxed","paddingVertical","flexWrap","justifyContent","minHeight","borderTopWidth","borderTopColor","backgroundColor","deep","faint"],"sources":["../../src/components/Sheet.tsx"],"sourcesContent":["import { createContext, type ReactNode, useContext } from 'react';\nimport { type StyleProp, Text, type TextProps, View, type ViewProps, type ViewStyle } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { CloseIcon } from '../icons/icons';\nimport { fontOf } from '../lib/fonts';\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 Sheet as a bottom sheet: the native shape for a detail view or a\n * short form over what the reader was looking at. `side` and `width` are\n * dropped; a phone sheet rises from the bottom edge and takes the width.\n */\n\ninterface SheetState {\n open: boolean;\n setOpen: (open: boolean) => void;\n}\n\nexport const SheetContext = createContext<SheetState>({ open: false, setOpen: () => undefined });\n\nexport interface SheetProps {\n /** Controlled mode; pair with onOpenChange. Omit it and the sheet keeps its own state. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: ReactNode;\n}\n\nexport function Sheet({ open, defaultOpen = false, onOpenChange, children }: SheetProps) {\n const [current, setOpen] = useControllable(open, defaultOpen, onOpenChange);\n return <SheetContext.Provider value={{ open: current, setOpen }}>{children}</SheetContext.Provider>;\n}\n\n/** A Button that opens the enclosing sheet. */\nexport function SheetTrigger({ onPress, ...props }: ButtonProps) {\n const { setOpen } = useContext(SheetContext);\n return (\n <Button\n onPress={(event) => {\n onPress?.(event);\n setOpen(true);\n }}\n {...props}\n />\n );\n}\n\n/** A Button that closes the enclosing sheet. */\nexport function SheetClose({ onPress, ...props }: ButtonProps) {\n const { setOpen } = useContext(SheetContext);\n return (\n <Button\n onPress={(event) => {\n onPress?.(event);\n setOpen(false);\n }}\n {...props}\n />\n );\n}\n\nexport interface SheetContentProps {\n children?: ReactNode;\n /** Pinned actions outside the scrolling body. The footer carries the bottom safe area. */\n footer?: ReactNode;\n /** False when an embedded SheetList owns vertical scrolling. */\n scrollable?: boolean;\n /** The sheet holds unsaved work: a prompt arriving in the conversation leaves it open with a note. */\n keep?: boolean;\n}\n\n/** The sheet surface. Fields inside it switch to the sheet's own input so the keyboard lifts the sheet. */\nexport function SheetContent({ children, scrollable = true, footer, keep }: SheetContentProps) {\n const { open, setOpen } = useContext(SheetContext);\n return (\n <SheetFrame\n open={open}\n onClose={() => setOpen(false)}\n scrollable={scrollable}\n keep={keep}\n {...(footer === undefined\n ? {}\n : { footer: <SheetContext.Provider value={{ open, setOpen }}>{footer}</SheetContext.Provider> })}\n >\n <SheetContext.Provider value={{ open, setOpen }}>{children}</SheetContext.Provider>\n </SheetFrame>\n );\n}\n\nexport interface SheetPartProps extends Omit<ViewProps, 'children' | 'style'> {\n children?: ReactNode;\n style?: StyleProp<ViewStyle>;\n}\n\nexport interface SheetHeaderProps extends SheetPartProps {\n /** Show the close control at the right of the strip. On by default: a sheet is dismissed, not answered. */\n dismissible?: boolean;\n /** What the close control announces. */\n closeLabel?: string;\n}\n\nexport function SheetHeader({ dismissible = true, closeLabel = 'close', style, children, ...props }: SheetHeaderProps) {\n const { setOpen } = useContext(SheetContext);\n return (\n <View style={[styles.header, style]} {...props}>\n {children}\n {dismissible ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n accessibilityLabel={closeLabel}\n onPress={() => setOpen(false)}\n style={styles.close}\n >\n <CloseIcon size={12} color=\"faint\" />\n </Button>\n ) : null}\n </View>\n );\n}\n\nexport function SheetTitle({ style, ...props }: TextProps) {\n return <Text accessibilityRole=\"header\" numberOfLines={1} style={[styles.title, style]} {...props} />;\n}\n\nexport function SheetDescription({ style, ...props }: TextProps) {\n return <Text style={[styles.description, style]} {...props} />;\n}\n\n/** The scrolling middle; the sheet itself scrolls, so this only spaces its children. */\nexport function SheetBody({ style, children, ...props }: SheetPartProps) {\n return (\n <View style={[styles.body, style]} {...props}>\n {wrapText(children, styles.description)}\n </View>\n );\n}\n\nexport function SheetFooter({ style, children, ...props }: SheetPartProps) {\n return (\n <View style={[styles.footer, style]} {...props}>\n {wrapText(children, styles.hint)}\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n header: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(2.5),\n minWidth: 0,\n height: theme.spacing(11),\n borderBottomWidth: 1,\n borderBottomColor: theme.colors.border,\n paddingHorizontal: theme.spacing(4),\n },\n close: { marginLeft: 'auto' },\n title: {\n flexShrink: 1,\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 },\n description: {\n color: theme.colors.dim,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeightRelaxed.sm,\n },\n body: {\n gap: theme.spacing(3),\n paddingHorizontal: theme.spacing(4),\n paddingVertical: theme.spacing(3),\n },\n footer: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: theme.spacing(2),\n minHeight: 34,\n borderTopWidth: 1,\n borderTopColor: theme.colors['border-soft'],\n backgroundColor: theme.colors.deep,\n paddingHorizontal: theme.spacing(4),\n paddingVertical: theme.spacing(1.5),\n },\n hint: {\n color: theme.colors.faint,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize['2xs'],\n lineHeight: theme.lineHeight['2xs'],\n },\n}));\n"],"mappings":";;;;;;;;;;;;;AAsBA,MAAakB,eAAelB,cAA0B;CAAEgB,MAAM;CAAOC,eAAeE;AAAU,CAAC;AAU/F,SAAgBK,MAAM,EAAER,MAAMK,cAAc,OAAOC,cAAcC,YAAwB;CACvF,MAAM,CAACE,SAASR,WAAWP,gBAAgBM,MAAMK,aAAaC,YAAY;CAC1E,OAAO,oBAAC,aAAa,UAAd;EAAuB,OAAO;GAAEN,MAAMS;GAASR;EAAQ;EAAIM;CAAgC;AACpG;;AAGA,SAAgBG,aAAa,EAAEC,SAAS,GAAGC,SAAsB;CAC/D,MAAM,EAAEX,YAAYf,WAAWgB,YAAY;CAC3C,OACE,oBAAC,QAAD;EACE,UAAUW,UAAU;GAClBF,UAAUE,KAAK;GACfZ,QAAQ,IAAI;EACd;EACA,GAAIW;CAAM;AAGhB;;AAGA,SAAgBE,WAAW,EAAEH,SAAS,GAAGC,SAAsB;CAC7D,MAAM,EAAEX,YAAYf,WAAWgB,YAAY;CAC3C,OACE,oBAAC,QAAD;EACE,UAAUW,UAAU;GAClBF,UAAUE,KAAK;GACfZ,QAAQ,KAAK;EACf;EACA,GAAIW;CAAM;AAGhB;;AAaA,SAAgBO,aAAa,EAAEZ,UAAUU,aAAa,MAAMD,QAAQE,QAA2B;CAC7F,MAAM,EAAElB,MAAMC,YAAYf,WAAWgB,YAAY;CACjD,OACE,oBAAC,YAAD;EACQF;EACN,eAAeC,QAAQ,KAAK;EAChBgB;EACNC;EACN,GAAKF,WAAWb,SACZ,CAAC,IACD,EAAEa,QAAQ,oBAAC,aAAa,UAAd;GAAuB,OAAO;IAAEhB;IAAMC;GAAQ;aAAIe;EAA8B,GAAE;YAEhG,oBAAC,aAAa,UAAd;GAAuB,OAAO;IAAEhB;IAAMC;GAAQ;GAAIM;EAAgC;CACxE;AAEhB;AAcA,SAAgBmB,YAAY,EAAEF,cAAc,MAAMC,aAAa,SAASH,OAAOf,UAAU,GAAGK,SAA2B;CACrH,MAAM,EAAEX,YAAYf,WAAWgB,YAAY;CAC3C,OACE,qBAAC,MAAD;EAAM,OAAO,CAACyB,OAAOC,QAAQN,KAAK;EAAG,GAAIV;YAAzC,CACGL,UACAiB,cACC,oBAAC,QAAD;GACE,SAAQ;GACR,MAAK;GACL,oBAAoBC;GACpB,eAAexB,QAAQ,KAAK;GAC5B,OAAO0B,OAAOE;aAEd,oBAAC,WAAD;IAAW,MAAM;IAAI,OAAM;GAAO;EAC5B,KACN,IACA;;AAEV;AAEA,SAAgBC,WAAW,EAAER,OAAO,GAAGV,SAAoB;CACzD,OAAO,oBAAC,MAAD;EAAM,mBAAkB;EAAS,eAAe;EAAG,OAAO,CAACe,OAAOI,OAAOT,KAAK;EAAG,GAAIV;CAAM;AACpG;AAEA,SAAgBoB,iBAAiB,EAAEV,OAAO,GAAGV,SAAoB;CAC/D,OAAO,oBAAC,MAAD;EAAM,OAAO,CAACe,OAAOM,aAAaX,KAAK;EAAG,GAAIV;CAAM;AAC7D;;AAGA,SAAgBsB,UAAU,EAAEZ,OAAOf,UAAU,GAAGK,SAAyB;CACvE,OACE,oBAAC,MAAD;EAAM,OAAO,CAACe,OAAOQ,MAAMb,KAAK;EAAG,GAAIV;YACpCjB,SAASY,UAAUoB,OAAOM,WAAW;CAClC;AAEV;AAEA,SAAgBG,YAAY,EAAEd,OAAOf,UAAU,GAAGK,SAAyB;CACzE,OACE,oBAAC,MAAD;EAAM,OAAO,CAACe,OAAOX,QAAQM,KAAK;EAAG,GAAIV;YACtCjB,SAASY,UAAUoB,OAAOU,IAAI;CAC3B;AAEV;AAEA,MAAMV,SAASpC,WAAW+C,QAAQC,WAAW;CAC3CX,QAAQ;EACNY,eAAe;EACfC,YAAY;EACZC,KAAKH,MAAMI,QAAQ,GAAG;EACtBC,UAAU;EACVC,QAAQN,MAAMI,QAAQ,EAAE;EACxBG,mBAAmB;EACnBC,mBAAmBR,MAAMS,OAAOC;EAChCC,mBAAmBX,MAAMI,QAAQ,CAAC;EAACQ,mBAAA,CAAA,CAAA;CACrC;CACAtB,OAAO,EAAEuB,YAAY,OAAO;CAC5BrB,OAAO;EACLsB,YAAY;EACZC,OAAOf,MAAMS,OAAOO;EACpBC,YAAY/D,OAAO8C,MAAMiB,WAAWC,IAAI;EACxCC,UAAUnB,MAAMmB,SAASC;EACzBC,YAAYrB,MAAMqB,WAAWD;EAC7BE,YAAYtB,MAAMsB,WAAWC;EAAQX,mBAAA,CAAA,CAAA;CACvC;CACAlB,aAAa;EACXqB,OAAOf,MAAMS,OAAOe;EACpBP,YAAY/D,OAAO8C,MAAMiB,WAAWC,IAAI;EACxCC,UAAUnB,MAAMmB,SAASM;EACzBJ,YAAYrB,MAAM0B,kBAAkBD;EAAEb,mBAAA,CAAA,CAAA;CACxC;CACAhB,MAAM;EACJO,KAAKH,MAAMI,QAAQ,CAAC;EACpBO,mBAAmBX,MAAMI,QAAQ,CAAC;EAClCuB,iBAAiB3B,MAAMI,QAAQ,CAAC;EAACQ,mBAAA,CAAA,CAAA;CACnC;CACAnC,QAAQ;EACNwB,eAAe;EACf2B,UAAU;EACV1B,YAAY;EACZ2B,gBAAgB;EAChB1B,KAAKH,MAAMI,QAAQ,CAAC;EACpB0B,WAAW;EACXC,gBAAgB;EAChBC,gBAAgBhC,MAAMS,OAAO;EAC7BwB,iBAAiBjC,MAAMS,OAAOyB;EAC9BvB,mBAAmBX,MAAMI,QAAQ,CAAC;EAClCuB,iBAAiB3B,MAAMI,QAAQ,GAAG;EAACQ,mBAAA,CAAA,CAAA;CACrC;CACAd,MAAM;EACJiB,OAAOf,MAAMS,OAAO0B;EACpBlB,YAAY/D,OAAO8C,MAAMiB,WAAWC,IAAI;EACxCC,UAAUnB,MAAMmB,SAAS;EACzBE,YAAYrB,MAAMqB,WAAW;EAAMT,mBAAA,CAAA,CAAA;CACrC;AACF,EAAE"}
|
|
1
|
+
{"version":3,"file":"Sheet.mjs","names":["createContext","ReactNode","useContext","StyleProp","TextProps","ViewProps","ViewStyle","StyleSheet","CloseIcon","fontOf","useControllable","wrapText","Button","ButtonProps","SheetFrame","SheetState","open","setOpen","SheetContext","undefined","SheetProps","defaultOpen","onOpenChange","children","Sheet","current","SheetTrigger","onPress","props","event","SheetClose","SheetContentProps","footer","scrollable","keep","onDismiss","SheetContent","SheetPartProps","Omit","style","SheetHeaderProps","dismissible","closeLabel","SheetHeader","styles","header","close","SheetTitle","title","SheetDescription","description","SheetBody","body","SheetFooter","hint","create","theme","flexDirection","alignItems","gap","spacing","minWidth","height","borderBottomWidth","borderBottomColor","colors","border","paddingHorizontal","uni__dependencies","marginLeft","flexShrink","color","hi","fontFamily","sans","fontSize","lg","lineHeight","fontWeight","semibold","dim","sm","lineHeightRelaxed","paddingVertical","flexWrap","justifyContent","minHeight","borderTopWidth","borderTopColor","backgroundColor","deep","faint"],"sources":["../../src/components/Sheet.tsx"],"sourcesContent":["import { createContext, type ReactNode, useContext } from 'react';\nimport { type StyleProp, Text, type TextProps, View, type ViewProps, type ViewStyle } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { CloseIcon } from '../icons/icons';\nimport { fontOf } from '../lib/fonts';\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 Sheet as a bottom sheet: the native shape for a detail view or a\n * short form over what the reader was looking at. `side` and `width` are\n * dropped; a phone sheet rises from the bottom edge and takes the width.\n */\n\ninterface SheetState {\n open: boolean;\n setOpen: (open: boolean) => void;\n}\n\nexport const SheetContext = createContext<SheetState>({ open: false, setOpen: () => undefined });\n\nexport interface SheetProps {\n /** Controlled mode; pair with onOpenChange. Omit it and the sheet keeps its own state. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: ReactNode;\n}\n\nexport function Sheet({ open, defaultOpen = false, onOpenChange, children }: SheetProps) {\n const [current, setOpen] = useControllable(open, defaultOpen, onOpenChange);\n return <SheetContext.Provider value={{ open: current, setOpen }}>{children}</SheetContext.Provider>;\n}\n\n/** A Button that opens the enclosing sheet. */\nexport function SheetTrigger({ onPress, ...props }: ButtonProps) {\n const { setOpen } = useContext(SheetContext);\n return (\n <Button\n onPress={(event) => {\n onPress?.(event);\n setOpen(true);\n }}\n {...props}\n />\n );\n}\n\n/** A Button that closes the enclosing sheet. */\nexport function SheetClose({ onPress, ...props }: ButtonProps) {\n const { setOpen } = useContext(SheetContext);\n return (\n <Button\n onPress={(event) => {\n onPress?.(event);\n setOpen(false);\n }}\n {...props}\n />\n );\n}\n\nexport interface SheetContentProps {\n children?: ReactNode;\n /** Pinned actions outside the scrolling body. The footer carries the bottom safe area. */\n footer?: ReactNode;\n /** False when an embedded SheetList owns vertical scrolling. */\n scrollable?: boolean;\n /** The sheet holds unsaved work: a prompt arriving in the conversation leaves it open with a note. */\n keep?: boolean;\n /** Runs after the native modal is dismissed, including a caller-initiated close. */\n onDismiss?: () => void;\n}\n\n/** The sheet surface. Fields inside it switch to the sheet's own input so the keyboard lifts the sheet. */\nexport function SheetContent({ children, scrollable = true, footer, keep, onDismiss }: SheetContentProps) {\n const { open, setOpen } = useContext(SheetContext);\n return (\n <SheetFrame\n open={open}\n onClose={() => setOpen(false)}\n scrollable={scrollable}\n keep={keep}\n onDismiss={onDismiss}\n {...(footer === undefined\n ? {}\n : { footer: <SheetContext.Provider value={{ open, setOpen }}>{footer}</SheetContext.Provider> })}\n >\n <SheetContext.Provider value={{ open, setOpen }}>{children}</SheetContext.Provider>\n </SheetFrame>\n );\n}\n\nexport interface SheetPartProps extends Omit<ViewProps, 'children' | 'style'> {\n children?: ReactNode;\n style?: StyleProp<ViewStyle>;\n}\n\nexport interface SheetHeaderProps extends SheetPartProps {\n /** Show the close control at the right of the strip. On by default: a sheet is dismissed, not answered. */\n dismissible?: boolean;\n /** What the close control announces. */\n closeLabel?: string;\n}\n\nexport function SheetHeader({ dismissible = true, closeLabel = 'close', style, children, ...props }: SheetHeaderProps) {\n const { setOpen } = useContext(SheetContext);\n return (\n <View style={[styles.header, style]} {...props}>\n {children}\n {dismissible ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n accessibilityLabel={closeLabel}\n onPress={() => setOpen(false)}\n style={styles.close}\n >\n <CloseIcon size={12} color=\"faint\" />\n </Button>\n ) : null}\n </View>\n );\n}\n\nexport function SheetTitle({ style, ...props }: TextProps) {\n return <Text accessibilityRole=\"header\" numberOfLines={1} style={[styles.title, style]} {...props} />;\n}\n\nexport function SheetDescription({ style, ...props }: TextProps) {\n return <Text style={[styles.description, style]} {...props} />;\n}\n\n/** The scrolling middle; the sheet itself scrolls, so this only spaces its children. */\nexport function SheetBody({ style, children, ...props }: SheetPartProps) {\n return (\n <View style={[styles.body, style]} {...props}>\n {wrapText(children, styles.description)}\n </View>\n );\n}\n\nexport function SheetFooter({ style, children, ...props }: SheetPartProps) {\n return (\n <View style={[styles.footer, style]} {...props}>\n {wrapText(children, styles.hint)}\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n header: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: theme.spacing(2.5),\n minWidth: 0,\n height: theme.spacing(11),\n borderBottomWidth: 1,\n borderBottomColor: theme.colors.border,\n paddingHorizontal: theme.spacing(4),\n },\n close: { marginLeft: 'auto' },\n title: {\n flexShrink: 1,\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 },\n description: {\n color: theme.colors.dim,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeightRelaxed.sm,\n },\n body: {\n gap: theme.spacing(3),\n paddingHorizontal: theme.spacing(4),\n paddingVertical: theme.spacing(3),\n },\n footer: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: theme.spacing(2),\n minHeight: 34,\n borderTopWidth: 1,\n borderTopColor: theme.colors['border-soft'],\n backgroundColor: theme.colors.deep,\n paddingHorizontal: theme.spacing(4),\n paddingVertical: theme.spacing(1.5),\n },\n hint: {\n color: theme.colors.faint,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize['2xs'],\n lineHeight: theme.lineHeight['2xs'],\n },\n}));\n"],"mappings":";;;;;;;;;;;;;AAsBA,MAAakB,eAAelB,cAA0B;CAAEgB,MAAM;CAAOC,eAAeE;AAAU,CAAC;AAU/F,SAAgBK,MAAM,EAAER,MAAMK,cAAc,OAAOC,cAAcC,YAAwB;CACvF,MAAM,CAACE,SAASR,WAAWP,gBAAgBM,MAAMK,aAAaC,YAAY;CAC1E,OAAO,oBAAC,aAAa,UAAd;EAAuB,OAAO;GAAEN,MAAMS;GAASR;EAAQ;EAAIM;CAAgC;AACpG;;AAGA,SAAgBG,aAAa,EAAEC,SAAS,GAAGC,SAAsB;CAC/D,MAAM,EAAEX,YAAYf,WAAWgB,YAAY;CAC3C,OACE,oBAAC,QAAD;EACE,UAAUW,UAAU;GAClBF,UAAUE,KAAK;GACfZ,QAAQ,IAAI;EACd;EACA,GAAIW;CAAM;AAGhB;;AAGA,SAAgBE,WAAW,EAAEH,SAAS,GAAGC,SAAsB;CAC7D,MAAM,EAAEX,YAAYf,WAAWgB,YAAY;CAC3C,OACE,oBAAC,QAAD;EACE,UAAUW,UAAU;GAClBF,UAAUE,KAAK;GACfZ,QAAQ,KAAK;EACf;EACA,GAAIW;CAAM;AAGhB;;AAeA,SAAgBQ,aAAa,EAAEb,UAAUU,aAAa,MAAMD,QAAQE,MAAMC,aAAgC;CACxG,MAAM,EAAEnB,MAAMC,YAAYf,WAAWgB,YAAY;CACjD,OACE,oBAAC,YAAD;EACQF;EACN,eAAeC,QAAQ,KAAK;EAChBgB;EACNC;EACKC;EACX,GAAKH,WAAWb,SACZ,CAAC,IACD,EAAEa,QAAQ,oBAAC,aAAa,UAAd;GAAuB,OAAO;IAAEhB;IAAMC;GAAQ;aAAIe;EAA8B,GAAE;YAEhG,oBAAC,aAAa,UAAd;GAAuB,OAAO;IAAEhB;IAAMC;GAAQ;GAAIM;EAAgC;CACxE;AAEhB;AAcA,SAAgBoB,YAAY,EAAEF,cAAc,MAAMC,aAAa,SAASH,OAAOhB,UAAU,GAAGK,SAA2B;CACrH,MAAM,EAAEX,YAAYf,WAAWgB,YAAY;CAC3C,OACE,qBAAC,MAAD;EAAM,OAAO,CAAC0B,OAAOC,QAAQN,KAAK;EAAG,GAAIX;YAAzC,CACGL,UACAkB,cACC,oBAAC,QAAD;GACE,SAAQ;GACR,MAAK;GACL,oBAAoBC;GACpB,eAAezB,QAAQ,KAAK;GAC5B,OAAO2B,OAAOE;aAEd,oBAAC,WAAD;IAAW,MAAM;IAAI,OAAM;GAAO;EAC5B,KACN,IACA;;AAEV;AAEA,SAAgBC,WAAW,EAAER,OAAO,GAAGX,SAAoB;CACzD,OAAO,oBAAC,MAAD;EAAM,mBAAkB;EAAS,eAAe;EAAG,OAAO,CAACgB,OAAOI,OAAOT,KAAK;EAAG,GAAIX;CAAM;AACpG;AAEA,SAAgBqB,iBAAiB,EAAEV,OAAO,GAAGX,SAAoB;CAC/D,OAAO,oBAAC,MAAD;EAAM,OAAO,CAACgB,OAAOM,aAAaX,KAAK;EAAG,GAAIX;CAAM;AAC7D;;AAGA,SAAgBuB,UAAU,EAAEZ,OAAOhB,UAAU,GAAGK,SAAyB;CACvE,OACE,oBAAC,MAAD;EAAM,OAAO,CAACgB,OAAOQ,MAAMb,KAAK;EAAG,GAAIX;YACpCjB,SAASY,UAAUqB,OAAOM,WAAW;CAClC;AAEV;AAEA,SAAgBG,YAAY,EAAEd,OAAOhB,UAAU,GAAGK,SAAyB;CACzE,OACE,oBAAC,MAAD;EAAM,OAAO,CAACgB,OAAOZ,QAAQO,KAAK;EAAG,GAAIX;YACtCjB,SAASY,UAAUqB,OAAOU,IAAI;CAC3B;AAEV;AAEA,MAAMV,SAASrC,WAAWgD,QAAQC,WAAW;CAC3CX,QAAQ;EACNY,eAAe;EACfC,YAAY;EACZC,KAAKH,MAAMI,QAAQ,GAAG;EACtBC,UAAU;EACVC,QAAQN,MAAMI,QAAQ,EAAE;EACxBG,mBAAmB;EACnBC,mBAAmBR,MAAMS,OAAOC;EAChCC,mBAAmBX,MAAMI,QAAQ,CAAC;EAACQ,mBAAA,CAAA,CAAA;CACrC;CACAtB,OAAO,EAAEuB,YAAY,OAAO;CAC5BrB,OAAO;EACLsB,YAAY;EACZC,OAAOf,MAAMS,OAAOO;EACpBC,YAAYhE,OAAO+C,MAAMiB,WAAWC,IAAI;EACxCC,UAAUnB,MAAMmB,SAASC;EACzBC,YAAYrB,MAAMqB,WAAWD;EAC7BE,YAAYtB,MAAMsB,WAAWC;EAAQX,mBAAA,CAAA,CAAA;CACvC;CACAlB,aAAa;EACXqB,OAAOf,MAAMS,OAAOe;EACpBP,YAAYhE,OAAO+C,MAAMiB,WAAWC,IAAI;EACxCC,UAAUnB,MAAMmB,SAASM;EACzBJ,YAAYrB,MAAM0B,kBAAkBD;EAAEb,mBAAA,CAAA,CAAA;CACxC;CACAhB,MAAM;EACJO,KAAKH,MAAMI,QAAQ,CAAC;EACpBO,mBAAmBX,MAAMI,QAAQ,CAAC;EAClCuB,iBAAiB3B,MAAMI,QAAQ,CAAC;EAACQ,mBAAA,CAAA,CAAA;CACnC;CACApC,QAAQ;EACNyB,eAAe;EACf2B,UAAU;EACV1B,YAAY;EACZ2B,gBAAgB;EAChB1B,KAAKH,MAAMI,QAAQ,CAAC;EACpB0B,WAAW;EACXC,gBAAgB;EAChBC,gBAAgBhC,MAAMS,OAAO;EAC7BwB,iBAAiBjC,MAAMS,OAAOyB;EAC9BvB,mBAAmBX,MAAMI,QAAQ,CAAC;EAClCuB,iBAAiB3B,MAAMI,QAAQ,GAAG;EAACQ,mBAAA,CAAA,CAAA;CACrC;CACAd,MAAM;EACJiB,OAAOf,MAAMS,OAAO0B;EACpBlB,YAAYhE,OAAO+C,MAAMiB,WAAWC,IAAI;EACxCC,UAAUnB,MAAMmB,SAAS;EACzBE,YAAYrB,MAAMqB,WAAW;EAAMT,mBAAA,CAAA,CAAA;CACrC;AACF,EAAE"}
|
|
@@ -19,7 +19,7 @@ const BACKDROP_ALPHA_PERCENT = 70;
|
|
|
19
19
|
* back, clear of the safe area and lifted by the keyboard. Private: the public
|
|
20
20
|
* parts keep bottom-sheet types out of the package API.
|
|
21
21
|
*/
|
|
22
|
-
function SheetFrame({ open, onClose, children, scrollable = true, footer, keep = false }) {
|
|
22
|
+
function SheetFrame({ open, onClose, onDismiss, children, scrollable = true, footer, keep = false }) {
|
|
23
23
|
const { theme } = useUnistyles();
|
|
24
24
|
const insets = useContext(SafeAreaInsetsContext);
|
|
25
25
|
const sheet = useRef(null);
|
|
@@ -29,11 +29,13 @@ function SheetFrame({ open, onClose, children, scrollable = true, footer, keep =
|
|
|
29
29
|
const [note, setNote] = useState();
|
|
30
30
|
const latest = useRef({
|
|
31
31
|
keep,
|
|
32
|
-
onClose
|
|
32
|
+
onClose,
|
|
33
|
+
onDismiss
|
|
33
34
|
});
|
|
34
35
|
latest.current = {
|
|
35
36
|
keep,
|
|
36
|
-
onClose
|
|
37
|
+
onClose,
|
|
38
|
+
onDismiss
|
|
37
39
|
};
|
|
38
40
|
const entry = useRef({
|
|
39
41
|
keep: () => latest.current.keep,
|
|
@@ -111,7 +113,8 @@ function SheetFrame({ open, onClose, children, scrollable = true, footer, keep =
|
|
|
111
113
|
handleIndicatorStyle: { backgroundColor: theme.colors.border },
|
|
112
114
|
onDismiss: () => {
|
|
113
115
|
presented.current = false;
|
|
114
|
-
if (openRef.current) onClose();
|
|
116
|
+
if (openRef.current) latest.current.onClose();
|
|
117
|
+
latest.current.onDismiss?.();
|
|
115
118
|
},
|
|
116
119
|
children: scrollable ? /* @__PURE__ */ jsxs(BottomSheetScrollView, {
|
|
117
120
|
keyboardShouldPersistTaps: "handled",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SheetFrame.mjs","names":["InsideSheetContext","OpenSheet","registerSheet","unregisterSheet","withAlpha","BottomSheetBackdrop","BottomSheetBackdropProps","BottomSheetModal","BottomSheetFooter","BottomSheetFooterProps","BottomSheetScrollView","ReactNode","useCallback","useContext","useEffect","useRef","useState","BackHandler","Keyboard","SafeAreaInsetsContext","StyleSheet","useUnistyles","fontOf","BACKDROP_ALPHA_PERCENT","SheetFrameProps","open","onClose","children","footer","scrollable","keep","sheetsYielded","yieldSheets","SheetFrame","theme","insets","sheet","openRef","presented","footerHeight","setFooterHeight","note","setNote","latest","current","entry","close","dismiss","present","undefined","subscription","addEventListener","remove","backdropColor","colors","deep","renderBackdrop","props","style","backgroundColor","renderFooter","event","nativeEvent","layout","height","paddingBottom","bottom","rail","top","footerComponent","borderRadius","lg","border","styles","content","SheetNote","create","flexGrow","marginHorizontal","spacing","marginBottom","color","magenta","fontFamily","sans","fontSize","sm","lineHeight","uni__dependencies"],"sources":["../../src/components/SheetFrame.tsx"],"sourcesContent":["import {\n InsideSheetContext,\n type OpenSheet,\n registerSheet,\n unregisterSheet,\n} from '@agimon-ai/po-native-components/shell';\nimport { withAlpha } from '@agimon-ai/po-web-components/nativeTheme';\nimport {\n BottomSheetBackdrop,\n type BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetFooter,\n type BottomSheetFooterProps,\n BottomSheetScrollView,\n} from '@gorhom/bottom-sheet';\nimport { type ReactNode, useCallback, useContext, useEffect, useRef, useState } from 'react';\nimport { BackHandler, Keyboard, Text, View } from 'react-native';\nimport { SafeAreaInsetsContext } from 'react-native-safe-area-context';\nimport { StyleSheet, useUnistyles } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\n\n/** `bg-po-deep/70`, the overlay every web sheet and dialog draws. */\nconst BACKDROP_ALPHA_PERCENT = 70;\n\nexport interface SheetFrameProps {\n open: boolean;\n /** The sheet asked to close: a drag down, a backdrop tap or Android back. */\n onClose: () => void;\n children?: ReactNode;\n footer?: ReactNode;\n /** False when the content supplies its own Gorhom virtualized scroll owner. */\n scrollable?: boolean;\n /** The sheet holds work not yet saved, so a prompt arriving leaves it open with a note instead of closing it. */\n keep?: boolean;\n}\n\nexport { sheetsYielded, yieldSheets } from '@agimon-ai/po-native-components/shell';\n\n/**\n * The bottom sheet both Sheet and DropdownMenu sit in: a drag handle, sized\n * to its content, closed by dragging down, tapping the backdrop or Android\n * back, clear of the safe area and lifted by the keyboard. Private: the public\n * parts keep bottom-sheet types out of the package API.\n */\nexport function SheetFrame({ open, onClose, children, scrollable = true, footer, keep = false }: SheetFrameProps) {\n const { theme } = useUnistyles();\n const insets = useContext(SafeAreaInsetsContext);\n const sheet = useRef<BottomSheetModal>(null);\n const openRef = useRef(open);\n const presented = useRef(false);\n const [footerHeight, setFooterHeight] = useState(0);\n const [note, setNote] = useState<string>();\n const latest = useRef({ keep, onClose });\n latest.current = { keep, onClose };\n const entry = useRef<OpenSheet>({\n keep: () => latest.current.keep,\n close: () => latest.current.onClose(),\n setNote,\n });\n\n useEffect(() => {\n openRef.current = open;\n if (open) {\n presented.current = true;\n registerSheet(entry.current);\n // The keyboard of the field behind would cover the sheet; a field inside it focuses after this.\n Keyboard.dismiss();\n sheet.current?.present();\n } else {\n unregisterSheet(entry.current);\n setNote(undefined);\n if (presented.current) {\n // Only a presented sheet is dismissed. Dismissing one that never opened leaves bottom-sheet's\n // modal stuck in its dismissing status, and the next present() then never draws.\n presented.current = false;\n sheet.current?.dismiss();\n }\n }\n }, [open]);\n\n useEffect(\n () => () => {\n unregisterSheet(entry.current);\n },\n [],\n );\n\n useEffect(() => {\n if (!open) return undefined;\n const subscription = BackHandler.addEventListener('hardwareBackPress', () => {\n onClose();\n return true;\n });\n return () => subscription.remove();\n }, [open, onClose]);\n\n const backdropColor = withAlpha(theme.colors.deep, BACKDROP_ALPHA_PERCENT);\n const renderBackdrop = useCallback(\n (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n opacity={1}\n pressBehavior=\"close\"\n style={[props.style, { backgroundColor: backdropColor }]}\n />\n ),\n [backdropColor],\n );\n\n const renderFooter = useCallback(\n (props: BottomSheetFooterProps) => (\n <BottomSheetFooter {...props}>\n <View\n onLayout={(event) => setFooterHeight(event.nativeEvent.layout.height)}\n style={{ paddingBottom: insets?.bottom ?? 0, backgroundColor: theme.colors.rail }}\n >\n <InsideSheetContext.Provider value>{footer}</InsideSheetContext.Provider>\n </View>\n </BottomSheetFooter>\n ),\n [footer, insets?.bottom, theme.colors.rail],\n );\n\n return (\n <BottomSheetModal\n ref={sheet}\n stackBehavior=\"push\"\n enablePanDownToClose\n topInset={insets?.top ?? 0}\n keyboardBehavior=\"interactive\"\n keyboardBlurBehavior=\"restore\"\n android_keyboardInputMode=\"adjustResize\"\n backdropComponent={renderBackdrop}\n {...(footer === undefined ? {} : { footerComponent: renderFooter })}\n backgroundStyle={{ backgroundColor: theme.colors.rail, borderRadius: theme.borderRadius.lg }}\n handleIndicatorStyle={{ backgroundColor: theme.colors.border }}\n // A sheet the caller closed is already shut; only a close the sheet started is reported.\n onDismiss={() => {\n // Already shut, so the close the parent answers with must not dismiss it a second time.\n presented.current = false;\n if (openRef.current) onClose();\n }}\n >\n {scrollable ? (\n <BottomSheetScrollView\n keyboardShouldPersistTaps=\"handled\"\n contentContainerStyle={[\n styles.content,\n { paddingBottom: footer === undefined ? (insets?.bottom ?? 0) : footerHeight },\n ]}\n >\n {note ? <SheetNote note={note} /> : null}\n <InsideSheetContext.Provider value>{children}</InsideSheetContext.Provider>\n </BottomSheetScrollView>\n ) : (\n <>\n {note ? <SheetNote note={note} /> : null}\n <InsideSheetContext.Provider value>{children}</InsideSheetContext.Provider>\n </>\n )}\n </BottomSheetModal>\n );\n}\n\n/** A gentle rose line: the person is asked something below, never told to hurry. */\nfunction SheetNote({ note }: { note: string }) {\n return (\n <Text style={styles.note} accessibilityRole=\"alert\">\n {note}\n </Text>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n content: { flexGrow: 1 },\n note: {\n marginHorizontal: theme.spacing(4),\n marginBottom: theme.spacing(2),\n color: theme.colors.magenta,\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":"SheetFrame.mjs","names":["InsideSheetContext","OpenSheet","registerSheet","unregisterSheet","withAlpha","BottomSheetBackdrop","BottomSheetBackdropProps","BottomSheetModal","BottomSheetFooter","BottomSheetFooterProps","BottomSheetScrollView","ReactNode","useCallback","useContext","useEffect","useRef","useState","BackHandler","Keyboard","SafeAreaInsetsContext","StyleSheet","useUnistyles","fontOf","BACKDROP_ALPHA_PERCENT","SheetFrameProps","open","onClose","onDismiss","children","footer","scrollable","keep","sheetsYielded","yieldSheets","SheetFrame","theme","insets","sheet","openRef","presented","footerHeight","setFooterHeight","note","setNote","latest","current","entry","close","dismiss","present","undefined","subscription","addEventListener","remove","backdropColor","colors","deep","renderBackdrop","props","style","backgroundColor","renderFooter","event","nativeEvent","layout","height","paddingBottom","bottom","rail","top","footerComponent","borderRadius","lg","border","styles","content","SheetNote","create","flexGrow","marginHorizontal","spacing","marginBottom","color","magenta","fontFamily","sans","fontSize","sm","lineHeight","uni__dependencies"],"sources":["../../src/components/SheetFrame.tsx"],"sourcesContent":["import {\n InsideSheetContext,\n type OpenSheet,\n registerSheet,\n unregisterSheet,\n} from '@agimon-ai/po-native-components/shell';\nimport { withAlpha } from '@agimon-ai/po-web-components/nativeTheme';\nimport {\n BottomSheetBackdrop,\n type BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetFooter,\n type BottomSheetFooterProps,\n BottomSheetScrollView,\n} from '@gorhom/bottom-sheet';\nimport { type ReactNode, useCallback, useContext, useEffect, useRef, useState } from 'react';\nimport { BackHandler, Keyboard, Text, View } from 'react-native';\nimport { SafeAreaInsetsContext } from 'react-native-safe-area-context';\nimport { StyleSheet, useUnistyles } from 'react-native-unistyles';\n\nimport { fontOf } from '../lib/fonts';\n\n/** `bg-po-deep/70`, the overlay every web sheet and dialog draws. */\nconst BACKDROP_ALPHA_PERCENT = 70;\n\nexport interface SheetFrameProps {\n open: boolean;\n /** The sheet asked to close: a drag down, a backdrop tap or Android back. */\n onClose: () => void;\n onDismiss?: () => void;\n children?: ReactNode;\n footer?: ReactNode;\n /** False when the content supplies its own Gorhom virtualized scroll owner. */\n scrollable?: boolean;\n /** The sheet holds work not yet saved, so a prompt arriving leaves it open with a note instead of closing it. */\n keep?: boolean;\n}\n\nexport { sheetsYielded, yieldSheets } from '@agimon-ai/po-native-components/shell';\n\n/**\n * The bottom sheet both Sheet and DropdownMenu sit in: a drag handle, sized\n * to its content, closed by dragging down, tapping the backdrop or Android\n * back, clear of the safe area and lifted by the keyboard. Private: the public\n * parts keep bottom-sheet types out of the package API.\n */\nexport function SheetFrame({\n open,\n onClose,\n onDismiss,\n children,\n scrollable = true,\n footer,\n keep = false,\n}: SheetFrameProps) {\n const { theme } = useUnistyles();\n const insets = useContext(SafeAreaInsetsContext);\n const sheet = useRef<BottomSheetModal>(null);\n const openRef = useRef(open);\n const presented = useRef(false);\n const [footerHeight, setFooterHeight] = useState(0);\n const [note, setNote] = useState<string>();\n const latest = useRef({ keep, onClose, onDismiss });\n latest.current = { keep, onClose, onDismiss };\n const entry = useRef<OpenSheet>({\n keep: () => latest.current.keep,\n close: () => latest.current.onClose(),\n setNote,\n });\n\n useEffect(() => {\n openRef.current = open;\n if (open) {\n presented.current = true;\n registerSheet(entry.current);\n // The keyboard of the field behind would cover the sheet; a field inside it focuses after this.\n Keyboard.dismiss();\n sheet.current?.present();\n } else {\n unregisterSheet(entry.current);\n setNote(undefined);\n if (presented.current) {\n // Only a presented sheet is dismissed. Dismissing one that never opened leaves bottom-sheet's\n // modal stuck in its dismissing status, and the next present() then never draws.\n presented.current = false;\n sheet.current?.dismiss();\n }\n }\n }, [open]);\n\n useEffect(\n () => () => {\n unregisterSheet(entry.current);\n },\n [],\n );\n\n useEffect(() => {\n if (!open) return undefined;\n const subscription = BackHandler.addEventListener('hardwareBackPress', () => {\n onClose();\n return true;\n });\n return () => subscription.remove();\n }, [open, onClose]);\n\n const backdropColor = withAlpha(theme.colors.deep, BACKDROP_ALPHA_PERCENT);\n const renderBackdrop = useCallback(\n (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n opacity={1}\n pressBehavior=\"close\"\n style={[props.style, { backgroundColor: backdropColor }]}\n />\n ),\n [backdropColor],\n );\n\n const renderFooter = useCallback(\n (props: BottomSheetFooterProps) => (\n <BottomSheetFooter {...props}>\n <View\n onLayout={(event) => setFooterHeight(event.nativeEvent.layout.height)}\n style={{ paddingBottom: insets?.bottom ?? 0, backgroundColor: theme.colors.rail }}\n >\n <InsideSheetContext.Provider value>{footer}</InsideSheetContext.Provider>\n </View>\n </BottomSheetFooter>\n ),\n [footer, insets?.bottom, theme.colors.rail],\n );\n\n return (\n <BottomSheetModal\n ref={sheet}\n stackBehavior=\"push\"\n enablePanDownToClose\n topInset={insets?.top ?? 0}\n keyboardBehavior=\"interactive\"\n keyboardBlurBehavior=\"restore\"\n android_keyboardInputMode=\"adjustResize\"\n backdropComponent={renderBackdrop}\n {...(footer === undefined ? {} : { footerComponent: renderFooter })}\n backgroundStyle={{ backgroundColor: theme.colors.rail, borderRadius: theme.borderRadius.lg }}\n handleIndicatorStyle={{ backgroundColor: theme.colors.border }}\n // A sheet the caller closed is already shut; only a close the sheet started is reported.\n onDismiss={() => {\n // Already shut, so the close the parent answers with must not dismiss it a second time.\n presented.current = false;\n if (openRef.current) latest.current.onClose();\n latest.current.onDismiss?.();\n }}\n >\n {scrollable ? (\n <BottomSheetScrollView\n keyboardShouldPersistTaps=\"handled\"\n contentContainerStyle={[\n styles.content,\n { paddingBottom: footer === undefined ? (insets?.bottom ?? 0) : footerHeight },\n ]}\n >\n {note ? <SheetNote note={note} /> : null}\n <InsideSheetContext.Provider value>{children}</InsideSheetContext.Provider>\n </BottomSheetScrollView>\n ) : (\n <>\n {note ? <SheetNote note={note} /> : null}\n <InsideSheetContext.Provider value>{children}</InsideSheetContext.Provider>\n </>\n )}\n </BottomSheetModal>\n );\n}\n\n/** A gentle rose line: the person is asked something below, never told to hurry. */\nfunction SheetNote({ note }: { note: string }) {\n return (\n <Text style={styles.note} accessibilityRole=\"alert\">\n {note}\n </Text>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n content: { flexGrow: 1 },\n note: {\n marginHorizontal: theme.spacing(4),\n marginBottom: theme.spacing(2),\n color: theme.colors.magenta,\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n },\n}));\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/po-native-components",
|
|
3
|
-
"version": "0.0.0-alpha.
|
|
3
|
+
"version": "0.0.0-alpha.80",
|
|
4
4
|
"description": "Shared React Native components for Po and its native plugins: the web component library's look and API on native parts, tuned to the Po palette.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -49,11 +49,11 @@
|
|
|
49
49
|
"access": "public"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@agimon-ai/po-web-components": "0.0.0-alpha.
|
|
52
|
+
"@agimon-ai/po-web-components": "0.0.0-alpha.80"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@agimon-ai/po-build": "0.0.0-alpha.
|
|
56
|
-
"@agimon-ai/vibe-lint-plugin-po-web": "0.0.0-alpha.
|
|
55
|
+
"@agimon-ai/po-build": "0.0.0-alpha.80",
|
|
56
|
+
"@agimon-ai/vibe-lint-plugin-po-web": "0.0.0-alpha.80",
|
|
57
57
|
"@babel/core": "7.29.7",
|
|
58
58
|
"@expo/vector-icons": "15.1.1",
|
|
59
59
|
"@fontsource-variable/ibm-plex-sans": "5.3.0",
|