@kanso-labs/react-native-kanso-ui 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +4 -1
  2. package/dist/autocomplete/index.js +39 -0
  3. package/dist/autocomplete/index.js.map +1 -0
  4. package/dist/badge/index.js +74 -0
  5. package/dist/badge/index.js.map +1 -0
  6. package/dist/badge/styles.js +51 -0
  7. package/dist/badge/styles.js.map +1 -0
  8. package/dist/button/index.d.ts +2 -1
  9. package/dist/button/index.js +35 -2
  10. package/dist/button/index.js.map +1 -1
  11. package/dist/button/slots.d.ts +2 -1
  12. package/dist/button/slots.js.map +1 -1
  13. package/dist/chip/index.js +2 -2
  14. package/dist/components/app-bar/index.d.ts +111 -0
  15. package/dist/components/app-bar/index.js +341 -0
  16. package/dist/components/app-bar/index.js.map +1 -0
  17. package/dist/components/autocomplete/index.d.ts +49 -0
  18. package/dist/components/autocomplete/index.js +87 -0
  19. package/dist/components/autocomplete/index.js.map +1 -0
  20. package/dist/components/button/index.d.ts +1 -1
  21. package/dist/components/button/index.js +197 -151
  22. package/dist/components/button/index.js.map +1 -1
  23. package/dist/components/card/index.js +2 -2
  24. package/dist/components/checkbox/index.js +106 -193
  25. package/dist/components/checkbox/index.js.map +1 -1
  26. package/dist/components/chip/index.js +1 -1
  27. package/dist/components/chip-group/index.js +3 -3
  28. package/dist/components/dialog/index.js +4 -3
  29. package/dist/components/dialog/index.js.map +1 -1
  30. package/dist/components/icon-button/index.d.ts +1 -1
  31. package/dist/components/icon-button/index.js +206 -160
  32. package/dist/components/icon-button/index.js.map +1 -1
  33. package/dist/components/link/index.js +2 -2
  34. package/dist/components/list/index.d.ts +216 -0
  35. package/dist/components/list/index.js +1118 -0
  36. package/dist/components/list/index.js.map +1 -0
  37. package/dist/components/list-detail/index.d.ts +56 -0
  38. package/dist/components/list-detail/index.js +169 -0
  39. package/dist/components/list-detail/index.js.map +1 -0
  40. package/dist/components/list-item/index.d.ts +63 -0
  41. package/dist/components/list-item/index.js +275 -0
  42. package/dist/components/list-item/index.js.map +1 -0
  43. package/dist/components/menu/index.d.ts +309 -0
  44. package/dist/components/menu/index.js +1283 -0
  45. package/dist/components/menu/index.js.map +1 -0
  46. package/dist/components/navigation-bar/index.d.ts +170 -0
  47. package/dist/components/navigation-bar/index.js +494 -0
  48. package/dist/components/navigation-bar/index.js.map +1 -0
  49. package/dist/components/number-field/index.js +3 -3
  50. package/dist/components/popover/index.d.ts +140 -0
  51. package/dist/components/popover/index.js +704 -0
  52. package/dist/components/popover/index.js.map +1 -0
  53. package/dist/components/progress-indicator/index.js +3 -3
  54. package/dist/components/radio-group/index.js +2 -2
  55. package/dist/components/search-field/index.d.ts +11 -3
  56. package/dist/components/search-field/index.js +66 -60
  57. package/dist/components/search-field/index.js.map +1 -1
  58. package/dist/components/segmented-button/index.js +4 -4
  59. package/dist/components/sheet/index.js +5 -4
  60. package/dist/components/sheet/index.js.map +1 -1
  61. package/dist/components/snackbar/index.js +4 -4
  62. package/dist/components/switch/index.js +3 -3
  63. package/dist/control/checkbox-box.js +137 -0
  64. package/dist/control/checkbox-box.js.map +1 -0
  65. package/dist/field/index.d.ts +1 -1
  66. package/dist/field/index.js +3 -3
  67. package/dist/form/index.d.ts +1 -1
  68. package/dist/glyphs/index.js +22 -3
  69. package/dist/glyphs/index.js.map +1 -1
  70. package/dist/hooks/useAppBarScroll.d.ts +56 -0
  71. package/dist/hooks/useAppBarScroll.js +87 -0
  72. package/dist/hooks/useAppBarScroll.js.map +1 -0
  73. package/dist/i18n/index.js +16 -1
  74. package/dist/i18n/index.js.map +1 -1
  75. package/dist/i18n/messages.js +272 -34
  76. package/dist/i18n/messages.js.map +1 -1
  77. package/dist/index.d.ts +12 -3
  78. package/dist/index.js +12 -3
  79. package/dist/indicator/index.d.ts +2 -2
  80. package/dist/indicator/index.js +1 -1
  81. package/dist/indicator/motion.js +1 -1
  82. package/dist/mark/index.js +1 -1
  83. package/dist/modal/index.d.ts +1 -1
  84. package/dist/modal/index.js +2 -9
  85. package/dist/modal/index.js.map +1 -1
  86. package/dist/navigation/index.d.ts +29 -0
  87. package/dist/navigation/index.js +405 -0
  88. package/dist/navigation/index.js.map +1 -0
  89. package/dist/navigation/styles.js +61 -0
  90. package/dist/navigation/styles.js.map +1 -0
  91. package/dist/overlay/anchored.d.ts +2 -0
  92. package/dist/overlay/anchored.js +182 -0
  93. package/dist/overlay/anchored.js.map +1 -0
  94. package/dist/overlay/host.d.ts +2 -0
  95. package/dist/overlay/index.d.ts +4 -0
  96. package/dist/overlay/panel.js +215 -0
  97. package/dist/overlay/panel.js.map +1 -0
  98. package/dist/overlay/placement.d.ts +8 -0
  99. package/dist/overlay/placement.js +87 -0
  100. package/dist/overlay/placement.js.map +1 -0
  101. package/dist/press/index.js +74 -68
  102. package/dist/press/index.js.map +1 -1
  103. package/dist/ref/index.js +15 -0
  104. package/dist/ref/index.js.map +1 -0
  105. package/dist/row/index.js +158 -0
  106. package/dist/row/index.js.map +1 -0
  107. package/dist/row/styles.js +51 -0
  108. package/dist/row/styles.js.map +1 -0
  109. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ReactNode","Ref","GestureResponderEvent","HostInstance","ModalProps","ViewProps","ViewStyle","AnimatedStyle","EdgeInsets","OverlayTriggerState","useCallback","useEffect","useMemo","useRef","useState","AccessibilityInfo","I18nManager","Modal","Platform","StyleSheet","useOverlayTriggerState","ButtonSlots","ResolvedTheme","AnimatedPressable","ButtonSlotContext","OverlayHost","withOpacity","useTheme","composeStyles","themedStyles","NO_INSETS","bottom","left","right","top","ORIENTATIONS","SCRIM_OPACITY","stylesOf","colors","create","scrim","backgroundColor","position","ModalOpenProps","defaultOpen","isOpen","onOpenChange","ModalTrigger","state","trigger","ModalWindowProps","children","isKeyboardDismissDisabled","labelledBy","onClose","onScrimPress","title","focusOf","OS","sendAccessibilityEvent","ignore","insetsOf","insets","rtl","isRTL","paddingBottom","paddingEnd","paddingStart","paddingTop","ModalWindow","t0","$","_c","styles","T0","t1","t2","undefined","t3","t4","t5","t6","t8","t9","T1","t10","T2","T3","t11","t12","t13","t14","t15","t16","t17","t18","t7","panelRoleOf","role","Pick","refsOf","own","node","T","other","current","registerOf","setParts","update","parts","Readonly","Record","Part","part","useModalState","outer","props","present","setPresent","close","slots","useReturnFocus","useModalTrigger","setTrigger","context","default","event","target","currentTarget","open","shown","gone","_c"],"sources":["../../src/modal/index.tsx"],"sourcesContent":["import type { ReactNode, Ref } from 'react'\nimport type {\n GestureResponderEvent,\n HostInstance,\n ModalProps,\n ViewProps,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle } from 'react-native-reanimated'\nimport type { EdgeInsets } from 'react-native-safe-area-context'\nimport type { OverlayTriggerState } from 'react-stately/useOverlayTriggerState'\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n AccessibilityInfo,\n I18nManager,\n Modal,\n Platform,\n StyleSheet,\n} from 'react-native'\nimport { useOverlayTriggerState } from 'react-stately/useOverlayTriggerState'\n\nimport type { ButtonSlots } from '../button/slots'\nimport type { ResolvedTheme } from '../theme/scope'\n\nimport { AnimatedPressable } from '../button'\nimport { ButtonSlotContext } from '../button/slots'\nimport { OverlayHost } from '../overlay'\nimport { withOpacity } from '../theme/color'\nimport { useTheme } from '../theme/scope'\nimport { composeStyles, themedStyles } from '../theme/styles'\n\n// The window a modal surface is drawn in, and what a dialog and a sheet share\n// around it: the trigger that opens it, the open state, the scrim, and where\n// focus goes as it shows and once it has gone. Internal: nothing here is\n// exported from the package.\n//\n// **It is a React Native `Modal`**, which keeps React context, so the surface\n// keeps the `ThemeScope` around it, and which is a window of its own on iOS\n// and Android, above the screen and its overlays. The window therefore hosts\n// overlays of its own, so a snackbar or a popover raised from inside it draws\n// above it rather than under it.\n\n// Outside a SafeAreaProvider the insets are unknown, and the window's own edge\n// is the best bound there is.\nconst NO_INSETS: EdgeInsets = { bottom: 0, left: 0, right: 0, top: 0 }\n\n// iOS presents a `Modal` in portrait alone unless told otherwise, which would\n// turn an app held sideways round as the surface opened.\nconst ORIENTATIONS: ModalProps['supportedOrientations'] = [\n 'portrait',\n 'portrait-upside-down',\n 'landscape',\n 'landscape-left',\n 'landscape-right',\n]\n\n// The scrim is the scrim role at 32%, the opacity Material Design gives a\n// modal's scrim and web mixes in.\nconst SCRIM_OPACITY = 0.32\n\nconst stylesOf = themedStyles(({ colors }: ResolvedTheme) =>\n StyleSheet.create({\n scrim: {\n backgroundColor: withOpacity(colors.scrim, SCRIM_OPACITY),\n bottom: 0,\n left: 0,\n position: 'absolute',\n right: 0,\n top: 0,\n },\n }),\n)\n\n/** Whether a modal surface is open, and who holds that state. */\ntype ModalOpenProps = {\n readonly defaultOpen?: boolean\n readonly isOpen?: boolean\n readonly onOpenChange?: (isOpen: boolean) => void\n}\n\n/**\n * What a surface's trigger part hands its content: the open state, and the\n * button that last opened it, for focus to return to.\n */\ntype ModalTrigger = {\n readonly state: OverlayTriggerState\n readonly trigger: HostInstance | null\n}\n\ntype ModalWindowProps = {\n readonly children?: ReactNode\n /** Whether Android's back gesture and Escape on web leave it open. */\n readonly isKeyboardDismissDisabled: boolean\n /** The headline's id, which names the window on web. */\n readonly labelledBy: string | undefined\n /** What the back gesture and Escape call. */\n readonly onClose: () => void\n /** What a press on the scrim calls, or nothing where it closes nothing. */\n readonly onScrimPress: (() => void) | undefined\n /** The scrim's motion. */\n readonly scrim: AnimatedStyle<ViewStyle>\n /** The headline, which a screen reader is sent to once the window shows. */\n readonly title: HostInstance | null\n}\n\n// Sends the screen reader to the headline once the window has shown. React\n// Native Web's `Modal` moves focus into itself.\nfunction focusOf(title: HostInstance | null) {\n return () => {\n if (title !== null && Platform.OS !== 'web') {\n AccessibilityInfo.sendAccessibilityEvent(title, 'focus')\n }\n }\n}\n\n// What the back gesture does on a surface it may not close: nothing, rather\n// than leaving the handler out, which Android warns about.\nfunction ignore() {}\n\n// The safe area as padding. The insets are physical edges, and React Native\n// swaps a left and a right style under a right-to-left layout, so they are\n// handed over as the start and end they are in the direction the layout runs.\nfunction insetsOf(insets: EdgeInsets): ViewStyle {\n const rtl = I18nManager.isRTL\n\n return {\n paddingBottom: insets.bottom,\n paddingEnd: rtl ? insets.left : insets.right,\n paddingStart: rtl ? insets.right : insets.left,\n paddingTop: insets.top,\n }\n}\n\n/**\n * The window a modal surface is drawn in: the `Modal`, the overlays it hosts,\n * and the scrim, with the surface itself as its children.\n */\nfunction ModalWindow({\n children,\n isKeyboardDismissDisabled,\n labelledBy,\n onClose,\n onScrimPress,\n scrim,\n title,\n}: ModalWindowProps) {\n const styles = stylesOf(useTheme())\n\n return (\n <Modal\n animationType=\"none\"\n aria-labelledby={Platform.OS === 'web' ? labelledBy : undefined}\n navigationBarTranslucent\n onRequestClose={isKeyboardDismissDisabled ? ignore : onClose}\n onShow={focusOf(title)}\n statusBarTranslucent\n supportedOrientations={ORIENTATIONS}\n transparent\n visible\n >\n {/* Nothing in the window takes the trigger's slot, the overlays it\n hosts included, so a button in a snackbar raised from the surface\n opens nothing; only the surface's buttons take the close slot. */}\n <ButtonSlotContext value={null}>\n <OverlayHost>\n {/* A screen reader and a keyboard skip the scrim: the first closes\n the surface with the back or escape gesture, the second with\n Escape. React Native Web's Pressable is a tab stop unless told\n otherwise, whatever `focusable` says. */}\n <AnimatedPressable\n accessible={false}\n aria-hidden\n focusable={false}\n onPress={onScrimPress}\n style={composeStyles<AnimatedStyle<ViewStyle>>(styles.scrim, scrim)}\n tabIndex={-1}\n />\n {children}\n </OverlayHost>\n </ButtonSlotContext>\n </Modal>\n )\n}\n\n// The surface's role and name on iOS and Android. On web React Native Web's\n// `Modal` is the dialog element, so the surface takes neither there.\nfunction panelRoleOf(\n role: 'alertdialog' | 'dialog',\n labelledBy: string | undefined,\n): Pick<ViewProps, 'aria-labelledby' | 'aria-modal' | 'role'> {\n if (Platform.OS === 'web') {\n return {}\n }\n\n return { 'aria-labelledby': labelledBy, 'aria-modal': true, role }\n}\n\n// Every ref a node is handed to, the part's own and the call site's.\nfunction refsOf<T>(own: (node: null | T) => void, other: Ref<T> | undefined) {\n return (node: null | T) => {\n own(node)\n if (typeof other === 'function') {\n other(node)\n } else if (other !== null && other !== undefined) {\n other.current = node\n }\n }\n}\n\n// Counts each part as it mounts and unmounts, so the parts around it know\n// which of them are there.\nfunction registerOf<Part extends string>(\n setParts: (\n update: (\n parts: Readonly<Record<Part, number>>,\n ) => Readonly<Record<Part, number>>,\n ) => void,\n) {\n return (part: Part) => {\n setParts((parts) => ({ ...parts, [part]: parts[part] + 1 }))\n\n return () => {\n setParts((parts) => ({ ...parts, [part]: parts[part] - 1 }))\n }\n }\n}\n\n/**\n * The open state a surface's content part reads: its trigger's, inside one,\n * and its own otherwise. `present` stays true from the moment it opens until\n * the call site's exit has run and set it false, and the close slot and the\n * scrim close it through `close`.\n */\nfunction useModalState(outer: ModalTrigger | null, props: ModalOpenProps) {\n const own = useOverlayTriggerState(props)\n const state = outer?.state ?? own\n const [present, setPresent] = useState(state.isOpen)\n const close = useCallback(() => {\n state.close()\n }, [state])\n const slots = useMemo<ButtonSlots>(() => ({ close }), [close])\n\n // Mounted the moment it opens, and kept until its exit has run.\n if (state.isOpen && !present) {\n setPresent(true)\n }\n\n useReturnFocus(present, outer)\n\n return { close, present, setPresent, slots, state }\n}\n\n/**\n * The open state a surface's trigger part holds, and the default slot a\n * button inside it fills: it records itself as the button focus returns to,\n * and opens the surface. React Native types the target as a bare view tag\n * too, which focus cannot be sent to, so such a press records nothing.\n */\nfunction useModalTrigger(props: ModalOpenProps) {\n const state = useOverlayTriggerState(props)\n const [trigger, setTrigger] = useState<HostInstance | null>(null)\n const context = useMemo<ModalTrigger>(\n () => ({ state, trigger }),\n [state, trigger],\n )\n const slots = useMemo<ButtonSlots>(\n () => ({\n default: (event: GestureResponderEvent) => {\n const target = event.currentTarget\n\n setTrigger(typeof target === 'number' ? null : target)\n state.open()\n },\n }),\n [state],\n )\n\n return { context, slots }\n}\n\n// Sends the screen reader back to the button that opened the surface once it\n// has gone. React Native Web's `Modal` restores focus itself.\nfunction useReturnFocus(present: boolean, outer: ModalTrigger | null) {\n const shown = useRef(present)\n\n useEffect(() => {\n const trigger = outer?.trigger ?? null\n const gone = shown.current && !present\n\n shown.current = present\n if (gone && trigger !== null && Platform.OS !== 'web') {\n AccessibilityInfo.sendAccessibilityEvent(trigger, 'focus')\n }\n }, [outer, present])\n}\n\nexport {\n insetsOf,\n ModalWindow,\n NO_INSETS,\n panelRoleOf,\n refsOf,\n registerOf,\n useModalState,\n useModalTrigger,\n}\nexport type { ModalOpenProps, ModalTrigger }\n"],"mappings":";;;;;;;;;;;;AA6CA,MAAM8B,YAAwB;CAAEC,QAAQ;CAAGC,MAAM;CAAGC,OAAO;CAAGC,KAAK;AAAE;AAIrE,MAAMC,eAAoD;CACxD;CACA;CACA;CACA;CACA;AAAiB;AAKnB,MAAMC,gBAAgB;AAEtB,MAAMC,WAAWR,cAAc,EAAES,aAC/BnB,WAAWoB,OAAO,EAChBC,OAAO;CACLC,iBAAiBf,YAAYY,OAAOE,OAAOJ,aAAa;CACxDL,QAAQ;CACRC,MAAM;CACNU,UAAU;CACVT,OAAO;CACPC,KAAK;AACP,EACF,CAAC,CACH;AAoCA,SAASuB,QAAQD,OAA4B;CAC3C,aAAa;EACX,IAAIA,UAAU,QAAQtC,SAASwC,OAAO,OACpC3C,kBAAkB4C,uBAAuBH,OAAO,OAAO;CAE3D;AACF;AAIA,SAASI,SAAS,CAAC;AAKnB,SAASC,SAASC,QAA+B;CAC/C,MAAMC,MAAM/C,YAAYgD;CAExB,OAAO;EACLC,eAAeH,OAAO/B;EACtBmC,YAAYH,MAAMD,OAAO9B,OAAO8B,OAAO7B;EACvCkC,cAAcJ,MAAMD,OAAO7B,QAAQ6B,OAAO9B;EAC1CoC,YAAYN,OAAO5B;CACrB;AACF;;;;;AAMA,SAAAmC,YAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAqB,MAAA,EAAArB,UAAAC,2BAAAC,YAAAC,SAAAC,cAAAf,OAAAgB,UAAAc;CASnB,MAAAG,SAAepC,SAASV,SAAS,CAAC;CAG/B,MAAA+C,KAAAzD;CACe,MAAA0D,KAAA;CACG,MAAAC,KAAA1D,SAAQwC,OAAQ,QAAhBL,aAAAwB,KAAAA;CACjB,MAAAC,KAAA;CACgB,MAAAC,KAAA3B,4BAAAQ,SAAAN;CAA4C,IAAA0B;CAAA,IAAAT,EAAA,OAAAf,OAAA;EACpDwB,KAAAvB,QAAQD,KAAK;EAACe,EAAA,KAAAf;EAAAe,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CACtB,MAAAU,KAAA;CACuB9C,MAAAA,KAAAA;CACvB,MAAA+C,KAAA;CACA,MAAAC,KAAA;CAKC,MAAAC,KAAA5D;CAAyB,MAAA6D,MAAA;CACvB,MAAAC,KAAA7D;CAKE,MAAA8D,KAAAhE;CACa,MAAAiE,MAAA;CACZ,MAAAC,MAAA;CACW,MAAAC,MAAA;CAEJ,MAAAC,MAAA/D,cAAwC6C,OAAMjC,OAAQA,KAAK;CAAC,IAAAoD;CAAA,IAAArB,EAAA,OAAAgB,MAAAhB,EAAA,OAAAhB,gBAAAgB,EAAA,OAAAoB,KAAA;EALrEC,MAAA,oBAAC,IAAD;GACc,YAAAJ;GACZ,eAAAC;GACW,WAAAC;GACFnC,SAAAA;GACF,OAAAoC;GACG,UAAA;EAAE,CAAA;EACZpB,EAAA,KAAAgB;EAAAhB,EAAA,KAAAhB;EAAAgB,EAAA,KAAAoB;EAAApB,EAAA,KAAAqB;CAAA,OAAAA,MAAArB,EAAA;CAAA,IAAAsB;CAAA,IAAAtB,EAAA,OAAAe,MAAAf,EAAA,OAAApB,YAAAoB,EAAA,OAAAqB,KAAA;EAZJC,MAAA,qBAAC,IAAD,EAAA,UAAA,CAKED,KAQCzC,QAbS,EAAA,CAAA;EAcEoB,EAAA,KAAAe;EAAAf,EAAA,KAAApB;EAAAoB,EAAA,KAAAqB;EAAArB,EAAA,KAAAsB;CAAA,OAAAA,MAAAtB,EAAA;CAAA,IAAAuB;CAAA,IAAAvB,EAAA,QAAAa,MAAAb,EAAA,QAAAsB,KAAA;EAfhBC,MAAA,oBAAC,IAAD;GAA0B,OAAAT;GACxBQ,UAAAA;EADgB,CAAA;EAgBEtB,EAAA,MAAAa;EAAAb,EAAA,MAAAsB;EAAAtB,EAAA,MAAAuB;CAAA,OAAAA,MAAAvB,EAAA;CAAA,IAAAwB;CAAA,IAAAxB,EAAA,QAAAG,MAAAH,EAAA,QAAAuB,OAAAvB,EAAA,QAAAK,MAAAL,EAAA,QAAAQ,MAAAR,EAAA,QAAAS,MAAAT,EAAA,QAAAyB,IAAA;EA9BtBD,MAAA,oBAAC,IAAD;GACgB,eAAApB;GACG,mBAAAC;GACjB,0BAAAE;GACgB,gBAAAC;GACR,QAAAC;GACR,sBAAAC;GACuB9C,uBAAAA;GACvB,aAAA+C;GACA,SAAAC;GAKAW,UAAAA;EAdI,CAAA;EA+BEvB,EAAA,MAAAG;EAAAH,EAAA,MAAAuB;EAAAvB,EAAA,MAAAK;EAAAL,EAAA,MAAAQ;EAAAR,EAAA,MAAAS;EAAAT,EAAA,MAAAyB;EAAAzB,EAAA,MAAAwB;CAAA,OAAAA,MAAAxB,EAAA;CAAA,OA/BRwB;AA+BQ;AAMZ,SAASE,YACPC,MACA7C,YAC4D;CAC5D,IAAInC,SAASwC,OAAO,OAClB,OAAO,CAAC;CAGV,OAAO;EAAE,mBAAmBL;EAAY,cAAc;EAAM6C;CAAK;AACnE;AAGA,SAASE,OAAUC,KAA+BG,OAA2B;CAC3E,QAAQF,SAAmB;EACzBD,IAAIC,IAAI;EACR,IAAI,OAAOE,UAAU,YACnBA,MAAMF,IAAI;OACL,IAAIE,UAAU,QAAQA,UAAU3B,KAAAA,GACrC2B,MAAMC,UAAUH;CAEpB;AACF;AAIA,SAASI,WACPC,UAKA;CACA,QAAQM,SAAe;EACrBN,UAAUE,WAAW;GAAE,GAAGA;IAAQI,OAAOJ,MAAMI,QAAQ;EAAE,EAAE;EAE3D,aAAa;GACXN,UAAUE,WAAW;IAAE,GAAGA;KAAQI,OAAOJ,MAAMI,QAAQ;GAAE,EAAE;EAC7D;CACF;AACF;;;;;;;AAQA,SAAAC,cAAAC,OAAAC,OAAA;CAAA,MAAA7C,IAAAC,EAAA,CAAA;CACE,MAAA6B,MAAYjF,uBAAuBgG,KAAK;CACxC,MAAApE,QAAcmE,OAAKnE,SAALqD;CACd,MAAA,CAAAgB,SAAAC,cAA8BxG,SAASkC,MAAKH,MAAO;CAAC,IAAAyB;CAAA,IAAAC,EAAA,OAAAvB,OAAA;EAC1BsB,WAAA;GACxBtB,MAAKuE,MAAO;EAAC;EACdhD,EAAA,KAAAvB;EAAAuB,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAFD,MAAAgD,QAAcjD;CAEH,IAAAK;CAAA,IAAAJ,EAAA,OAAAgD,OAAA;EAC+B5C,KAAA,EAAA4C,MAAQ;EAAChD,EAAA,KAAAgD;EAAAhD,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAAnD,MAAAiD,QAA0C7C;CAG1C,IAAI3B,MAAKH,UAAL,CAAiBwE,SACnBC,WAAW,IAAI;CAGjBG,eAAeJ,SAASF,KAAK;CAAC,IAAAvC;CAAA,IAAAL,EAAA,OAAAgD,SAAAhD,EAAA,OAAA8C,WAAA9C,EAAA,OAAAiD,SAAAjD,EAAA,OAAAvB,OAAA;EAEvB4B,KAAA;GAAA2C;GAAAF;GAAAC;GAAAE;GAAAxE;EAA2C;EAACuB,EAAA,KAAAgD;EAAAhD,EAAA,KAAA8C;EAAA9C,EAAA,KAAAiD;EAAAjD,EAAA,KAAAvB;EAAAuB,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAAA,OAA5CK;AAA4C;;;;;;;AASrD,SAAA8C,gBAAAN,OAAA;CAAA,MAAA7C,IAAAC,EAAA,CAAA;CACE,MAAAxB,QAAc5B,uBAAuBgG,KAAK;CAC1C,MAAA,CAAAnE,SAAA0E,cAA8B7G,SAA8B,IAAI;CAAC,IAAAwD;CAAA,IAAAC,EAAA,OAAAvB,SAAAuB,EAAA,OAAAtB,SAAA;EAExDqB,KAAA;GAAAtB;GAAAC;EAAiB;EAACsB,EAAA,KAAAvB;EAAAuB,EAAA,KAAAtB;EAAAsB,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAD3B,MAAAqD,UACStD;CAER,IAAAK;CAAA,IAAAJ,EAAA,OAAAvB,OAAA;EAEQ2B,KAAA,EAAAkD,UACIC,UAAA;GACP,MAAAC,SAAeD,MAAKE;GAEpBL,WAAW,OAAOI,WAAW,WAAlB,OAAAA,MAA0C;GACrD/E,MAAKiF,KAAM;EAAC,EAEhB;EAAC1D,EAAA,KAAAvB;EAAAuB,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CARH,MAAAiD,QACS7C;CASR,IAAAC;CAAA,IAAAL,EAAA,OAAAqD,WAAArD,EAAA,OAAAiD,OAAA;EAEM5C,KAAA;GAAAgD;GAAAJ;EAAiB;EAACjD,EAAA,KAAAqD;EAAArD,EAAA,KAAAiD;EAAAjD,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAAA,OAAlBK;AAAkB;AAK3B,SAAA6C,eAAAJ,SAAAF,OAAA;CAAA,MAAA5C,IAAAC,EAAA,CAAA;CACE,MAAA0D,QAAcrH,OAAOwG,OAAO;CAAC,IAAA/C;CAAA,IAAAC,EAAA,OAAA4C,OAAAlE,WAAAsB,EAAA,OAAA8C,SAAA;EAEnB/C,WAAA;GACR,MAAArB,UAAgBkE,OAAKlE,WAAL;GAChB,MAAAkF,OAAaD,MAAKzB,WAAL,CAAkBY;GAE/Ba,MAAKzB,UAAWY;GAChB,IAAIc,QAAQlF,YAAY,QAAQ/B,SAAQwC,OAAQ,OAC9C3C,kBAAiB4C,uBAAwBV,SAAS,OAAO;EAC1D;EACFsB,EAAA,KAAA4C,OAAAlE;EAAAsB,EAAA,KAAA8C;EAAA9C,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAI;CAAA,IAAAJ,EAAA,OAAA4C,SAAA5C,EAAA,OAAA8C,SAAA;EAAE1C,KAAA,CAACwC,OAAOE,OAAO;EAAC9C,EAAA,KAAA4C;EAAA5C,EAAA,KAAA8C;EAAA9C,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CARnB5D,UAAU2D,IAQPK,EAAgB;AAAC"}
1
+ {"version":3,"file":"index.js","names":["ReactNode","GestureResponderEvent","HostInstance","ModalProps","ViewProps","ViewStyle","AnimatedStyle","EdgeInsets","OverlayTriggerState","useCallback","useEffect","useMemo","useRef","useState","AccessibilityInfo","I18nManager","Modal","Platform","StyleSheet","useOverlayTriggerState","ButtonSlots","ResolvedTheme","AnimatedPressable","ButtonSlotContext","OverlayHost","withOpacity","useTheme","composeStyles","themedStyles","NO_INSETS","bottom","left","right","top","ORIENTATIONS","SCRIM_OPACITY","stylesOf","colors","create","scrim","backgroundColor","position","ModalOpenProps","defaultOpen","isOpen","onOpenChange","ModalTrigger","state","trigger","ModalWindowProps","children","isKeyboardDismissDisabled","labelledBy","onClose","onScrimPress","title","focusOf","OS","sendAccessibilityEvent","ignore","insetsOf","insets","rtl","isRTL","paddingBottom","paddingEnd","paddingStart","paddingTop","ModalWindow","t0","$","_c","styles","T0","t1","t2","undefined","t3","t4","t5","t6","t8","t9","T1","t10","T2","T3","t11","t12","t13","t14","t15","t16","t17","t18","t7","panelRoleOf","role","Pick","registerOf","setParts","update","parts","Readonly","Record","Part","part","useModalState","outer","props","own","present","setPresent","close","slots","useReturnFocus","useModalTrigger","setTrigger","context","default","event","target","currentTarget","open","shown","gone","current","_c"],"sources":["../../src/modal/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport type {\n GestureResponderEvent,\n HostInstance,\n ModalProps,\n ViewProps,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle } from 'react-native-reanimated'\nimport type { EdgeInsets } from 'react-native-safe-area-context'\nimport type { OverlayTriggerState } from 'react-stately/useOverlayTriggerState'\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n AccessibilityInfo,\n I18nManager,\n Modal,\n Platform,\n StyleSheet,\n} from 'react-native'\nimport { useOverlayTriggerState } from 'react-stately/useOverlayTriggerState'\n\nimport type { ButtonSlots } from '../button/slots'\nimport type { ResolvedTheme } from '../theme/scope'\n\nimport { AnimatedPressable } from '../button'\nimport { ButtonSlotContext } from '../button/slots'\nimport { OverlayHost } from '../overlay'\nimport { withOpacity } from '../theme/color'\nimport { useTheme } from '../theme/scope'\nimport { composeStyles, themedStyles } from '../theme/styles'\n\n// The window a modal surface is drawn in, and what a dialog and a sheet share\n// around it: the trigger that opens it, the open state, the scrim, and where\n// focus goes as it shows and once it has gone. Internal: nothing here is\n// exported from the package.\n//\n// **It is a React Native `Modal`**, which keeps React context, so the surface\n// keeps the `ThemeScope` around it, and which is a window of its own on iOS\n// and Android, above the screen and its overlays. The window therefore hosts\n// overlays of its own, so a snackbar or a popover raised from inside it draws\n// above it rather than under it.\n\n// Outside a SafeAreaProvider the insets are unknown, and the window's own edge\n// is the best bound there is.\nconst NO_INSETS: EdgeInsets = { bottom: 0, left: 0, right: 0, top: 0 }\n\n// iOS presents a `Modal` in portrait alone unless told otherwise, which would\n// turn an app held sideways round as the surface opened.\nconst ORIENTATIONS: ModalProps['supportedOrientations'] = [\n 'portrait',\n 'portrait-upside-down',\n 'landscape',\n 'landscape-left',\n 'landscape-right',\n]\n\n// The scrim is the scrim role at 32%, the opacity Material Design gives a\n// modal's scrim and web mixes in.\nconst SCRIM_OPACITY = 0.32\n\nconst stylesOf = themedStyles(({ colors }: ResolvedTheme) =>\n StyleSheet.create({\n scrim: {\n backgroundColor: withOpacity(colors.scrim, SCRIM_OPACITY),\n bottom: 0,\n left: 0,\n position: 'absolute',\n right: 0,\n top: 0,\n },\n }),\n)\n\n/** Whether a modal surface is open, and who holds that state. */\ntype ModalOpenProps = {\n readonly defaultOpen?: boolean\n readonly isOpen?: boolean\n readonly onOpenChange?: (isOpen: boolean) => void\n}\n\n/**\n * What a surface's trigger part hands its content: the open state, and the\n * button that last opened it, for focus to return to.\n */\ntype ModalTrigger = {\n readonly state: OverlayTriggerState\n readonly trigger: HostInstance | null\n}\n\ntype ModalWindowProps = {\n readonly children?: ReactNode\n /** Whether Android's back gesture and Escape on web leave it open. */\n readonly isKeyboardDismissDisabled: boolean\n /** The headline's id, which names the window on web. */\n readonly labelledBy: string | undefined\n /** What the back gesture and Escape call. */\n readonly onClose: () => void\n /** What a press on the scrim calls, or nothing where it closes nothing. */\n readonly onScrimPress: (() => void) | undefined\n /** The scrim's motion. */\n readonly scrim: AnimatedStyle<ViewStyle>\n /** The headline, which a screen reader is sent to once the window shows. */\n readonly title: HostInstance | null\n}\n\n// Sends the screen reader to the headline once the window has shown. React\n// Native Web's `Modal` moves focus into itself.\nfunction focusOf(title: HostInstance | null) {\n return () => {\n if (title !== null && Platform.OS !== 'web') {\n AccessibilityInfo.sendAccessibilityEvent(title, 'focus')\n }\n }\n}\n\n// What the back gesture does on a surface it may not close: nothing, rather\n// than leaving the handler out, which Android warns about.\nfunction ignore() {}\n\n// The safe area as padding. The insets are physical edges, and React Native\n// swaps a left and a right style under a right-to-left layout, so they are\n// handed over as the start and end they are in the direction the layout runs.\nfunction insetsOf(insets: EdgeInsets): ViewStyle {\n const rtl = I18nManager.isRTL\n\n return {\n paddingBottom: insets.bottom,\n paddingEnd: rtl ? insets.left : insets.right,\n paddingStart: rtl ? insets.right : insets.left,\n paddingTop: insets.top,\n }\n}\n\n/**\n * The window a modal surface is drawn in: the `Modal`, the overlays it hosts,\n * and the scrim, with the surface itself as its children.\n */\nfunction ModalWindow({\n children,\n isKeyboardDismissDisabled,\n labelledBy,\n onClose,\n onScrimPress,\n scrim,\n title,\n}: ModalWindowProps) {\n const styles = stylesOf(useTheme())\n\n return (\n <Modal\n animationType=\"none\"\n aria-labelledby={Platform.OS === 'web' ? labelledBy : undefined}\n navigationBarTranslucent\n onRequestClose={isKeyboardDismissDisabled ? ignore : onClose}\n onShow={focusOf(title)}\n statusBarTranslucent\n supportedOrientations={ORIENTATIONS}\n transparent\n visible\n >\n {/* Nothing in the window takes the trigger's slot, the overlays it\n hosts included, so a button in a snackbar raised from the surface\n opens nothing; only the surface's buttons take the close slot. */}\n <ButtonSlotContext value={null}>\n <OverlayHost>\n {/* A screen reader and a keyboard skip the scrim: the first closes\n the surface with the back or escape gesture, the second with\n Escape. React Native Web's Pressable is a tab stop unless told\n otherwise, whatever `focusable` says. */}\n <AnimatedPressable\n accessible={false}\n aria-hidden\n focusable={false}\n onPress={onScrimPress}\n style={composeStyles<AnimatedStyle<ViewStyle>>(styles.scrim, scrim)}\n tabIndex={-1}\n />\n {children}\n </OverlayHost>\n </ButtonSlotContext>\n </Modal>\n )\n}\n\n// The surface's role and name on iOS and Android. On web React Native Web's\n// `Modal` is the dialog element, so the surface takes neither there.\nfunction panelRoleOf(\n role: 'alertdialog' | 'dialog',\n labelledBy: string | undefined,\n): Pick<ViewProps, 'aria-labelledby' | 'aria-modal' | 'role'> {\n if (Platform.OS === 'web') {\n return {}\n }\n\n return { 'aria-labelledby': labelledBy, 'aria-modal': true, role }\n}\n\n// Counts each part as it mounts and unmounts, so the parts around it know\n// which of them are there.\nfunction registerOf<Part extends string>(\n setParts: (\n update: (\n parts: Readonly<Record<Part, number>>,\n ) => Readonly<Record<Part, number>>,\n ) => void,\n) {\n return (part: Part) => {\n setParts((parts) => ({ ...parts, [part]: parts[part] + 1 }))\n\n return () => {\n setParts((parts) => ({ ...parts, [part]: parts[part] - 1 }))\n }\n }\n}\n\n/**\n * The open state a surface's content part reads: its trigger's, inside one,\n * and its own otherwise. `present` stays true from the moment it opens until\n * the call site's exit has run and set it false, and the close slot and the\n * scrim close it through `close`.\n */\nfunction useModalState(outer: ModalTrigger | null, props: ModalOpenProps) {\n const own = useOverlayTriggerState(props)\n const state = outer?.state ?? own\n const [present, setPresent] = useState(state.isOpen)\n const close = useCallback(() => {\n state.close()\n }, [state])\n const slots = useMemo<ButtonSlots>(() => ({ close }), [close])\n\n // Mounted the moment it opens, and kept until its exit has run.\n if (state.isOpen && !present) {\n setPresent(true)\n }\n\n useReturnFocus(present, outer)\n\n return { close, present, setPresent, slots, state }\n}\n\n/**\n * The open state a surface's trigger part holds, and the default slot a\n * button inside it fills: it records itself as the button focus returns to,\n * and opens the surface. React Native types the target as a bare view tag\n * too, which focus cannot be sent to, so such a press records nothing.\n */\nfunction useModalTrigger(props: ModalOpenProps) {\n const state = useOverlayTriggerState(props)\n const [trigger, setTrigger] = useState<HostInstance | null>(null)\n const context = useMemo<ModalTrigger>(\n () => ({ state, trigger }),\n [state, trigger],\n )\n const slots = useMemo<ButtonSlots>(\n () => ({\n default: (event: GestureResponderEvent) => {\n const target = event.currentTarget\n\n setTrigger(typeof target === 'number' ? null : target)\n state.open()\n },\n }),\n [state],\n )\n\n return { context, slots }\n}\n\n// Sends the screen reader back to the button that opened the surface once it\n// has gone. React Native Web's `Modal` restores focus itself.\nfunction useReturnFocus(present: boolean, outer: ModalTrigger | null) {\n const shown = useRef(present)\n\n useEffect(() => {\n const trigger = outer?.trigger ?? null\n const gone = shown.current && !present\n\n shown.current = present\n if (gone && trigger !== null && Platform.OS !== 'web') {\n AccessibilityInfo.sendAccessibilityEvent(trigger, 'focus')\n }\n }, [outer, present])\n}\n\nexport {\n insetsOf,\n ModalWindow,\n NO_INSETS,\n panelRoleOf,\n registerOf,\n useModalState,\n useModalTrigger,\n}\nexport type { ModalOpenProps, ModalTrigger }\n"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { PressableProps, StyleProp, View, ViewStyle } from "react-native";
2
+ import { ComponentRef, ReactNode, Ref } from "react";
3
+ //#region src/navigation/index.d.ts
4
+ type NavigationDestinationProps = Omit<PressableProps, 'children' | 'disabled' | 'style'> & {
5
+ /**
6
+ * A badge on the icon: `true` for the badges page's small dot, a number
7
+ * for the large badge holding it. The badge is hidden from a screen
8
+ * reader, so say what it says in the destination's `aria-label` too:
9
+ * "First item, 3 new".
10
+ */
11
+ readonly badge?: boolean | number | undefined;
12
+ /** The destination's name, drawn as its label. */
13
+ readonly children?: ReactNode;
14
+ /**
15
+ * The destination's icon, at the page's 24dp, which the destination hands
16
+ * its colour and size through `useIconStyle()`.
17
+ */
18
+ readonly icon?: ReactNode;
19
+ /**
20
+ * Draws the destination disabled, and it takes no press.
21
+ * @default false
22
+ */
23
+ readonly isDisabled?: boolean;
24
+ readonly ref?: Ref<ComponentRef<typeof View>>;
25
+ readonly style?: StyleProp<ViewStyle>;
26
+ };
27
+ //#endregion
28
+ export type { NavigationDestinationProps };
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,405 @@
1
+ import { IconStyleContext } from "../glyphs/icon-style.js";
2
+ import { useTheme } from "../theme/scope.js";
3
+ import { composeStyles } from "../theme/styles.js";
4
+ import { hitSlop, usePressFeedback } from "../press/index.js";
5
+ import { useTypeRole } from "../typography/roles.js";
6
+ import { withOpacity } from "../theme/color.js";
7
+ import { Badge } from "../badge/index.js";
8
+ import { INDICATOR, styles, stylesOf } from "./styles.js";
9
+ import { c } from "react/compiler-runtime";
10
+ import { Pressable, Text, View } from "react-native";
11
+ import Animated, { Easing, useAnimatedStyle, useReducedMotion, useSharedValue, withTiming } from "react-native-reanimated";
12
+ import { createContext, use, useEffect } from "react";
13
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
14
+ //#region src/navigation/index.tsx
15
+ const GROWN_FROM = .4;
16
+ const FADE_SHARE = .2;
17
+ const ICON_SIZE = 24;
18
+ const NavigationContext = createContext({
19
+ form: "vertical",
20
+ measuring: false
21
+ });
22
+ /**
23
+ * The active indicator's fill, which grows from its centre while its
24
+ * destination is current and shrinks back once it is not.
25
+ */
26
+ function ActiveIndicator(t0) {
27
+ const $ = c(12);
28
+ const { selected } = t0;
29
+ const theme = useTheme();
30
+ const { colors, motion } = theme;
31
+ const reduceMotion = useReducedMotion();
32
+ const progress = useSharedValue(selected ? 1 : 0);
33
+ let t1;
34
+ let t2;
35
+ if ($[0] !== motion || $[1] !== progress || $[2] !== reduceMotion || $[3] !== selected) {
36
+ t1 = () => {
37
+ const target = selected ? 1 : 0;
38
+ progress.set(reduceMotion ? target : withTiming(target, {
39
+ duration: motion.durationLong2,
40
+ easing: Easing.bezier(...motion.easingEmphasized)
41
+ }));
42
+ };
43
+ t2 = [
44
+ motion,
45
+ progress,
46
+ reduceMotion,
47
+ selected
48
+ ];
49
+ $[0] = motion;
50
+ $[1] = progress;
51
+ $[2] = reduceMotion;
52
+ $[3] = selected;
53
+ $[4] = t1;
54
+ $[5] = t2;
55
+ } else {
56
+ t1 = $[4];
57
+ t2 = $[5];
58
+ }
59
+ useEffect(t1, t2);
60
+ const motionStyle = useAnimatedStyle(() => {
61
+ "worklet";
62
+ const grown = progress.get();
63
+ return {
64
+ opacity: Math.min(1, grown / FADE_SHARE),
65
+ transform: [{ scaleX: GROWN_FROM + .6 * grown }]
66
+ };
67
+ });
68
+ let t3;
69
+ if ($[6] !== colors.secondaryContainer || $[7] !== motionStyle || $[8] !== theme) {
70
+ t3 = composeStyles(styles.fill, stylesOf(theme).pill, { backgroundColor: colors.secondaryContainer }, motionStyle);
71
+ $[6] = colors.secondaryContainer;
72
+ $[7] = motionStyle;
73
+ $[8] = theme;
74
+ $[9] = t3;
75
+ } else t3 = $[9];
76
+ let t4;
77
+ if ($[10] !== t3) {
78
+ t4 = /* @__PURE__ */ jsx(Animated.View, { style: t3 });
79
+ $[10] = t3;
80
+ $[11] = t4;
81
+ } else t4 = $[11];
82
+ return t4;
83
+ }
84
+ /**
85
+ * What a destination draws over its indicator: the icon and its badge, and
86
+ * in a horizontal destination the label before them in the tree, which the
87
+ * pill's reversed row draws after them.
88
+ */
89
+ function DestinationContent(t0) {
90
+ const $ = c(20);
91
+ const { badge, form, icon, isDisabled, label, selected } = t0;
92
+ const theme = useTheme();
93
+ const horizontal = form === "horizontal";
94
+ let t1;
95
+ if ($[0] !== form || $[1] !== horizontal || $[2] !== isDisabled || $[3] !== label || $[4] !== selected) {
96
+ t1 = horizontal ? /* @__PURE__ */ jsx(Label, {
97
+ form,
98
+ isDisabled,
99
+ selected,
100
+ children: label
101
+ }) : null;
102
+ $[0] = form;
103
+ $[1] = horizontal;
104
+ $[2] = isDisabled;
105
+ $[3] = label;
106
+ $[4] = selected;
107
+ $[5] = t1;
108
+ } else t1 = $[5];
109
+ let t2;
110
+ if ($[6] !== isDisabled || $[7] !== selected || $[8] !== theme) {
111
+ t2 = iconStyleOf(iconColorOf(theme, isDisabled, selected));
112
+ $[6] = isDisabled;
113
+ $[7] = selected;
114
+ $[8] = theme;
115
+ $[9] = t2;
116
+ } else t2 = $[9];
117
+ let t3;
118
+ if ($[10] !== badge || $[11] !== horizontal || $[12] !== icon) {
119
+ t3 = badge === void 0 || badge === false ? icon : /* @__PURE__ */ jsx(Badge, {
120
+ count: badge === true ? void 0 : badge,
121
+ inFlow: horizontal,
122
+ children: icon
123
+ });
124
+ $[10] = badge;
125
+ $[11] = horizontal;
126
+ $[12] = icon;
127
+ $[13] = t3;
128
+ } else t3 = $[13];
129
+ let t4;
130
+ if ($[14] !== t2 || $[15] !== t3) {
131
+ t4 = /* @__PURE__ */ jsx(View, {
132
+ style: styles.icon,
133
+ children: /* @__PURE__ */ jsx(IconStyleContext, {
134
+ value: t2,
135
+ children: t3
136
+ })
137
+ });
138
+ $[14] = t2;
139
+ $[15] = t3;
140
+ $[16] = t4;
141
+ } else t4 = $[16];
142
+ let t5;
143
+ if ($[17] !== t1 || $[18] !== t4) {
144
+ t5 = /* @__PURE__ */ jsxs(Fragment$1, { children: [t1, t4] });
145
+ $[17] = t1;
146
+ $[18] = t4;
147
+ $[19] = t5;
148
+ } else t5 = $[19];
149
+ return t5;
150
+ }
151
+ /** The colour a destination draws its icon in. */
152
+ function iconColorOf({ colors, stateLayerOpacity }, isDisabled, selected) {
153
+ if (isDisabled) return withOpacity(colors.onSurface, stateLayerOpacity.disabledContent);
154
+ return selected ? colors.onSecondaryContainer : colors.onSurfaceVariant;
155
+ }
156
+ function iconStyleOf(color) {
157
+ return {
158
+ color,
159
+ size: ICON_SIZE
160
+ };
161
+ }
162
+ /** A destination's label, on one line, in label medium. */
163
+ function Label(t0) {
164
+ const $ = c(9);
165
+ const { children, form, isDisabled, selected } = t0;
166
+ const theme = useTheme();
167
+ const role = useTypeRole("labelMedium");
168
+ let t1;
169
+ if ($[0] !== form || $[1] !== isDisabled || $[2] !== role || $[3] !== selected || $[4] !== theme) {
170
+ t1 = composeStyles(role, styles.label, { color: labelColorOf(theme, form, isDisabled, selected) });
171
+ $[0] = form;
172
+ $[1] = isDisabled;
173
+ $[2] = role;
174
+ $[3] = selected;
175
+ $[4] = theme;
176
+ $[5] = t1;
177
+ } else t1 = $[5];
178
+ let t2;
179
+ if ($[6] !== children || $[7] !== t1) {
180
+ t2 = /* @__PURE__ */ jsx(Text, {
181
+ numberOfLines: 1,
182
+ style: t1,
183
+ children
184
+ });
185
+ $[6] = children;
186
+ $[7] = t1;
187
+ $[8] = t2;
188
+ } else t2 = $[8];
189
+ return t2;
190
+ }
191
+ /** The colour a destination draws its label in, which its form decides. */
192
+ function labelColorOf(theme, form, isDisabled, selected) {
193
+ return selected && !isDisabled && form === "vertical" ? theme.colors.secondary : iconColorOf(theme, isDisabled, selected);
194
+ }
195
+ function nameOf(children) {
196
+ return typeof children === "string" ? children : void 0;
197
+ }
198
+ /**
199
+ * One destination, in the form the bar around it asks for: an icon and a
200
+ * label, and the active indicator behind the icon while it is current. A
201
+ * `tab` reporting whether it is selected.
202
+ */
203
+ function NavigationDestination(t0) {
204
+ const $ = c(54);
205
+ let ariaLabel;
206
+ let badge;
207
+ let children;
208
+ let icon;
209
+ let onBlur;
210
+ let onFocus;
211
+ let onHoverIn;
212
+ let onHoverOut;
213
+ let onPressIn;
214
+ let onPressOut;
215
+ let props;
216
+ let selected;
217
+ let style;
218
+ let t1;
219
+ if ($[0] !== t0) {
220
+ ({"aria-label": ariaLabel, badge, children, icon, isDisabled: t1, onBlur, onFocus, onHoverIn, onHoverOut, onPressIn, onPressOut, selected, style, ...props} = t0);
221
+ $[0] = t0;
222
+ $[1] = ariaLabel;
223
+ $[2] = badge;
224
+ $[3] = children;
225
+ $[4] = icon;
226
+ $[5] = onBlur;
227
+ $[6] = onFocus;
228
+ $[7] = onHoverIn;
229
+ $[8] = onHoverOut;
230
+ $[9] = onPressIn;
231
+ $[10] = onPressOut;
232
+ $[11] = props;
233
+ $[12] = selected;
234
+ $[13] = style;
235
+ $[14] = t1;
236
+ } else {
237
+ ariaLabel = $[1];
238
+ badge = $[2];
239
+ children = $[3];
240
+ icon = $[4];
241
+ onBlur = $[5];
242
+ onFocus = $[6];
243
+ onHoverIn = $[7];
244
+ onHoverOut = $[8];
245
+ onPressIn = $[9];
246
+ onPressOut = $[10];
247
+ props = $[11];
248
+ selected = $[12];
249
+ style = $[13];
250
+ t1 = $[14];
251
+ }
252
+ const isDisabled = t1 === void 0 ? false : t1;
253
+ const theme = useTheme();
254
+ const { form, measuring } = use(NavigationContext);
255
+ const own = stylesOf(theme);
256
+ const horizontal = form === "horizontal";
257
+ const feedback = usePressFeedback({
258
+ area: horizontal ? void 0 : INDICATOR,
259
+ color: theme.colors.onSecondaryContainer,
260
+ corners: own.pill,
261
+ disabled: isDisabled,
262
+ onBlur,
263
+ onFocus,
264
+ onHoverIn,
265
+ onHoverOut,
266
+ onPressIn,
267
+ onPressOut
268
+ });
269
+ let t2;
270
+ if ($[15] !== badge || $[16] !== children || $[17] !== form || $[18] !== icon || $[19] !== isDisabled || $[20] !== selected) {
271
+ t2 = /* @__PURE__ */ jsx(DestinationContent, {
272
+ badge,
273
+ form,
274
+ icon,
275
+ isDisabled,
276
+ label: children,
277
+ selected
278
+ });
279
+ $[15] = badge;
280
+ $[16] = children;
281
+ $[17] = form;
282
+ $[18] = icon;
283
+ $[19] = isDisabled;
284
+ $[20] = selected;
285
+ $[21] = t2;
286
+ } else t2 = $[21];
287
+ const content = t2;
288
+ if (measuring) return /* @__PURE__ */ jsx(View, {
289
+ style: own.horizontal,
290
+ children: content
291
+ });
292
+ if (horizontal) {
293
+ let t3;
294
+ if ($[22] !== ariaLabel || $[23] !== children) {
295
+ t3 = ariaLabel ?? nameOf(children);
296
+ $[22] = ariaLabel;
297
+ $[23] = children;
298
+ $[24] = t3;
299
+ } else t3 = $[24];
300
+ let t4;
301
+ if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
302
+ t4 = hitSlop(40);
303
+ $[25] = t4;
304
+ } else t4 = $[25];
305
+ let t5;
306
+ if ($[26] !== selected) {
307
+ t5 = /* @__PURE__ */ jsx(ActiveIndicator, { selected });
308
+ $[26] = selected;
309
+ $[27] = t5;
310
+ } else t5 = $[27];
311
+ return /* @__PURE__ */ jsxs(Pressable, {
312
+ "aria-label": t3,
313
+ "aria-selected": selected,
314
+ hitSlop: t4,
315
+ role: "tab",
316
+ ...props,
317
+ ...feedback.handlers,
318
+ disabled: isDisabled,
319
+ style: composeStyles(own.horizontal, feedback.ring, style),
320
+ children: [
321
+ t5,
322
+ feedback.layer,
323
+ content
324
+ ]
325
+ });
326
+ }
327
+ const T0 = Pressable;
328
+ let t3;
329
+ if ($[28] !== ariaLabel || $[29] !== children) {
330
+ t3 = ariaLabel ?? nameOf(children);
331
+ $[28] = ariaLabel;
332
+ $[29] = children;
333
+ $[30] = t3;
334
+ } else t3 = $[30];
335
+ const t4 = "tab";
336
+ const t5 = feedback.handlers;
337
+ const t6 = composeStyles(own.vertical, style);
338
+ let t7;
339
+ if ($[31] !== children || $[32] !== form || $[33] !== isDisabled || $[34] !== selected) {
340
+ t7 = /* @__PURE__ */ jsx(Label, {
341
+ form,
342
+ isDisabled,
343
+ selected,
344
+ children
345
+ });
346
+ $[31] = children;
347
+ $[32] = form;
348
+ $[33] = isDisabled;
349
+ $[34] = selected;
350
+ $[35] = t7;
351
+ } else t7 = $[35];
352
+ const T1 = View;
353
+ const t8 = composeStyles(own.indicator, feedback.ring);
354
+ let t9;
355
+ if ($[36] !== selected) {
356
+ t9 = /* @__PURE__ */ jsx(ActiveIndicator, { selected });
357
+ $[36] = selected;
358
+ $[37] = t9;
359
+ } else t9 = $[37];
360
+ let t10;
361
+ if ($[38] !== T1 || $[39] !== content || $[40] !== feedback.layer || $[41] !== t8 || $[42] !== t9) {
362
+ t10 = /* @__PURE__ */ jsxs(T1, {
363
+ style: t8,
364
+ children: [
365
+ t9,
366
+ feedback.layer,
367
+ content
368
+ ]
369
+ });
370
+ $[38] = T1;
371
+ $[39] = content;
372
+ $[40] = feedback.layer;
373
+ $[41] = t8;
374
+ $[42] = t9;
375
+ $[43] = t10;
376
+ } else t10 = $[43];
377
+ let t11;
378
+ if ($[44] !== T0 || $[45] !== feedback.handlers || $[46] !== isDisabled || $[47] !== props || $[48] !== selected || $[49] !== t10 || $[50] !== t3 || $[51] !== t6 || $[52] !== t7) {
379
+ t11 = /* @__PURE__ */ jsxs(T0, {
380
+ "aria-label": t3,
381
+ "aria-selected": selected,
382
+ role: t4,
383
+ ...props,
384
+ ...t5,
385
+ disabled: isDisabled,
386
+ style: t6,
387
+ children: [t7, t10]
388
+ });
389
+ $[44] = T0;
390
+ $[45] = feedback.handlers;
391
+ $[46] = isDisabled;
392
+ $[47] = props;
393
+ $[48] = selected;
394
+ $[49] = t10;
395
+ $[50] = t3;
396
+ $[51] = t6;
397
+ $[52] = t7;
398
+ $[53] = t11;
399
+ } else t11 = $[53];
400
+ return t11;
401
+ }
402
+ //#endregion
403
+ export { NavigationContext, NavigationDestination, iconColorOf, labelColorOf };
404
+
405
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","ColorValue","PressableProps","StyleProp","TextStyle","ViewStyle","AnimatedStyle","createContext","use","useEffect","Text","NativeText","Pressable","View","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","IconStyle","ResolvedTheme","Badge","IconStyleContext","hitSlop","usePressFeedback","withOpacity","useTheme","composeStyles","useTypeRole","INDICATOR","PILL_HEIGHT","styles","stylesOf","NavigationContextValue","form","NavigationForm","measuring","selectedRoute","NavigationDestinationProps","Omit","badge","children","icon","isDisabled","ref","style","GROWN_FROM","FADE_SHARE","ICON_SIZE","NavigationContext","ActiveIndicator","t0","$","_c","selected","theme","colors","motion","reduceMotion","progress","t1","t2","target","set","duration","durationLong2","easing","bezier","easingEmphasized","motionStyle","grown","get","opacity","Math","min","transform","scaleX","t3","secondaryContainer","fill","pill","backgroundColor","t4","DestinationContent","label","horizontal","iconStyleOf","iconColorOf","undefined","t5","stateLayerOpacity","onSurface","disabledContent","onSecondaryContainer","onSurfaceVariant","color","size","Label","role","labelColorOf","secondary","nameOf","NavigationDestination","ariaLabel","onBlur","onFocus","onHoverIn","onHoverOut","onPressIn","onPressOut","props","own","feedback","area","corners","disabled","content","Symbol","for","handlers","ring","layer","T0","t6","vertical","t7","T1","t8","indicator","t9","t10","t11","_c","NativeText"],"sources":["../../src/navigation/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type {\n ColorValue,\n PressableProps,\n StyleProp,\n TextStyle,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle } from 'react-native-reanimated'\n\nimport { createContext, use, useEffect } from 'react'\nimport { Text as NativeText, Pressable, View } from 'react-native'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\n\nimport type { IconStyle } from '../glyphs/icon-style'\nimport type { ResolvedTheme } from '../theme/scope'\n\nimport { Badge } from '../badge'\nimport { IconStyleContext } from '../glyphs/icon-style'\nimport { hitSlop, usePressFeedback } from '../press'\nimport { withOpacity } from '../theme/color'\nimport { useTheme } from '../theme/scope'\nimport { composeStyles } from '../theme/styles'\nimport { useTypeRole } from '../typography/roles'\nimport { INDICATOR, PILL_HEIGHT, styles, stylesOf } from './styles'\n\n// The destination NavigationBar draws, in the two forms its page gives it,\n// as kanso-ui's src/navigation draws it. Apart from the bar, so the forms it\n// shares with a rail cannot drift.\n//\n// A vertical destination puts its icon in the page's 56dp by 32dp active\n// indicator with the label 4dp under it, in label medium. A horizontal one is\n// a 40dp pill holding the icon and the label side by side, 16dp in at either\n// end with 4dp between the two, in label medium too. Which one a destination\n// draws is the bar's to say, through the context it hands them.\n//\n// The current destination's indicator is the secondary container, with its\n// icon in on secondary container and, under the indicator, its label in\n// secondary; every other is on surface variant. A label set inside the pill,\n// as a horizontal destination sets it, takes on secondary container instead,\n// as on web: secondary over secondary container is not a pair a scheme is\n// held to, and on secondary container is.\n//\n// **The indicator grows** when its destination becomes current, and shrinks\n// back when another does: from 40% of its width to the whole of it from its\n// centre over `durationLong2` on the emphasized curve, fading in over the\n// first fifth of that, as Material's Android components draw it. Web draws it\n// at once. Under reduced motion it does here too.\n//\n// The state layer, the ripple and the focus ring are src/press's, in on\n// secondary container, drawn on the pill: the indicator in a vertical\n// destination, which its ripple grows from the centre of wherever it is\n// pressed, and the whole destination in a horizontal one. A horizontal pill's\n// press reaches 4dp above and below it, to the 48dp target; a vertical\n// destination is the bar's full height already. A disabled one draws its icon\n// and label on surface at the disabled content opacity, with no layer.\n//\n// A destination is a `tab`, reporting whether it is the selected one, and is\n// named by its label, or by `aria-label` where that is given: the badge on\n// its icon is hidden from a screen reader, so what it says belongs there.\n//\n// **The label comes first in the tree and is drawn after the icon**, through\n// a reversed column or row, so the text inside a destination starts with its\n// name. A badge's count is text, hidden from a screen reader but still\n// written inside the destination under React Native Web, and first in the\n// tree it put the count ahead of the name: a destination named \"Second item,\n// 3 new\" read \"3 Second item\", which is not what a speech-input user would\n// say, and is what axe's label-in-name check fails. src/badge sets the count\n// apart from the label with a space for the same reason.\n\n/** What a bar hands each of its destinations. */\ntype NavigationContextValue = {\n readonly form: NavigationForm\n /**\n * Whether the destinations are being drawn off screen to measure the\n * horizontal form, which draws each one's content and nothing else.\n */\n readonly measuring: boolean\n /** The route of the current destination, matched against an `href`. */\n readonly selectedRoute?: string | undefined\n}\n\ntype NavigationDestinationProps = Omit<\n PressableProps,\n 'children' | 'disabled' | 'style'\n> & {\n /**\n * A badge on the icon: `true` for the badges page's small dot, a number\n * for the large badge holding it. The badge is hidden from a screen\n * reader, so say what it says in the destination's `aria-label` too:\n * \"First item, 3 new\".\n */\n readonly badge?: boolean | number | undefined\n /** The destination's name, drawn as its label. */\n readonly children?: ReactNode\n /**\n * The destination's icon, at the page's 24dp, which the destination hands\n * its colour and size through `useIconStyle()`.\n */\n readonly icon?: ReactNode\n /**\n * Draws the destination disabled, and it takes no press.\n * @default false\n */\n readonly isDisabled?: boolean\n readonly ref?: Ref<ComponentRef<typeof View>>\n readonly style?: StyleProp<ViewStyle>\n}\n\n/**\n * Which of the page's two forms a destination draws: the label under the\n * icon, or beside it.\n */\ntype NavigationForm = 'horizontal' | 'vertical'\n\n// The indicator's width when it starts to grow, as a share of its whole\n// width, and the share of the move it fades in over.\nconst GROWN_FROM = 0.4\nconst FADE_SHARE = 0.2\n\nconst ICON_SIZE = 24\n\nconst NavigationContext = createContext<NavigationContextValue>({\n form: 'vertical',\n measuring: false,\n})\n\n/**\n * The active indicator's fill, which grows from its centre while its\n * destination is current and shrinks back once it is not.\n */\nfunction ActiveIndicator({ selected }: { readonly selected: boolean }) {\n const theme = useTheme()\n const { colors, motion } = theme\n const reduceMotion = useReducedMotion()\n const progress = useSharedValue(selected ? 1 : 0)\n\n useEffect(() => {\n const target = selected ? 1 : 0\n\n progress.set(\n reduceMotion\n ? target\n : withTiming(target, {\n duration: motion.durationLong2,\n easing: Easing.bezier(...motion.easingEmphasized),\n }),\n )\n }, [motion, progress, reduceMotion, selected])\n\n const motionStyle = useAnimatedStyle(() => {\n 'worklet'\n const grown = progress.get()\n\n return {\n opacity: Math.min(1, grown / FADE_SHARE),\n transform: [{ scaleX: GROWN_FROM + (1 - GROWN_FROM) * grown }],\n }\n })\n\n return (\n <Animated.View\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.fill,\n stylesOf(theme).pill,\n { backgroundColor: colors.secondaryContainer },\n motionStyle,\n )}\n />\n )\n}\n\n/**\n * What a destination draws over its indicator: the icon and its badge, and\n * in a horizontal destination the label before them in the tree, which the\n * pill's reversed row draws after them.\n */\nfunction DestinationContent({\n badge,\n form,\n icon,\n isDisabled,\n label,\n selected,\n}: {\n readonly badge: boolean | number | undefined\n readonly form: NavigationForm\n readonly icon: ReactNode\n readonly isDisabled: boolean\n readonly label: ReactNode\n readonly selected: boolean\n}) {\n const theme = useTheme()\n const horizontal = form === 'horizontal'\n\n return (\n <>\n {horizontal ? (\n <Label form={form} isDisabled={isDisabled} selected={selected}>\n {label}\n </Label>\n ) : null}\n <View style={styles.icon}>\n <IconStyleContext\n value={iconStyleOf(iconColorOf(theme, isDisabled, selected))}\n >\n {badge === undefined || badge === false ? (\n icon\n ) : (\n <Badge\n count={badge === true ? undefined : badge}\n inFlow={horizontal}\n >\n {icon}\n </Badge>\n )}\n </IconStyleContext>\n </View>\n </>\n )\n}\n\n/** The colour a destination draws its icon in. */\nfunction iconColorOf(\n { colors, stateLayerOpacity }: ResolvedTheme,\n isDisabled: boolean,\n selected: boolean,\n): string {\n if (isDisabled) {\n return withOpacity(colors.onSurface, stateLayerOpacity.disabledContent)\n }\n return selected ? colors.onSecondaryContainer : colors.onSurfaceVariant\n}\n\n// Built by a call rather than written inline at the prop, which is what\n// react-perf's jsx-no-new-object-as-prop is after; the React Compiler\n// memoises the result on its inputs.\nfunction iconStyleOf(color: ColorValue): IconStyle {\n return { color, size: ICON_SIZE }\n}\n\n/** A destination's label, on one line, in label medium. */\nfunction Label({\n children,\n form,\n isDisabled,\n selected,\n}: {\n readonly children: ReactNode\n readonly form: NavigationForm\n readonly isDisabled: boolean\n readonly selected: boolean\n}) {\n const theme = useTheme()\n const role = useTypeRole('labelMedium')\n\n return (\n <NativeText\n numberOfLines={1}\n style={composeStyles<TextStyle>(role, styles.label, {\n color: labelColorOf(theme, form, isDisabled, selected),\n })}\n >\n {children}\n </NativeText>\n )\n}\n\n/** The colour a destination draws its label in, which its form decides. */\nfunction labelColorOf(\n theme: ResolvedTheme,\n form: NavigationForm,\n isDisabled: boolean,\n selected: boolean,\n): string {\n return selected && !isDisabled && form === 'vertical'\n ? theme.colors.secondary\n : iconColorOf(theme, isDisabled, selected)\n}\n\n// A label that is a string names its destination; anything else leaves the\n// name to `aria-label`.\nfunction nameOf(children: ReactNode): string | undefined {\n return typeof children === 'string' ? children : undefined\n}\n\n/**\n * One destination, in the form the bar around it asks for: an icon and a\n * label, and the active indicator behind the icon while it is current. A\n * `tab` reporting whether it is selected.\n */\nfunction NavigationDestination({\n 'aria-label': ariaLabel,\n badge,\n children,\n icon,\n isDisabled = false,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onPressIn,\n onPressOut,\n selected,\n style,\n ...props\n}: NavigationDestinationProps & { readonly selected: boolean }) {\n const theme = useTheme()\n const { form, measuring } = use(NavigationContext)\n const own = stylesOf(theme)\n const horizontal = form === 'horizontal'\n const feedback = usePressFeedback({\n area: horizontal ? undefined : INDICATOR,\n color: theme.colors.onSecondaryContainer,\n corners: own.pill,\n disabled: isDisabled,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onPressIn,\n onPressOut,\n })\n const content = (\n <DestinationContent\n badge={badge}\n form={form}\n icon={icon}\n isDisabled={isDisabled}\n label={children}\n selected={selected}\n />\n )\n\n if (measuring) {\n return <View style={own.horizontal}>{content}</View>\n }\n\n if (horizontal) {\n return (\n <Pressable\n aria-label={ariaLabel ?? nameOf(children)}\n aria-selected={selected}\n hitSlop={hitSlop(PILL_HEIGHT)}\n role=\"tab\"\n {...props}\n {...feedback.handlers}\n disabled={isDisabled}\n style={composeStyles<ViewStyle>(own.horizontal, feedback.ring, style)}\n >\n <ActiveIndicator selected={selected} />\n {feedback.layer}\n {content}\n </Pressable>\n )\n }\n\n return (\n <Pressable\n aria-label={ariaLabel ?? nameOf(children)}\n aria-selected={selected}\n role=\"tab\"\n {...props}\n {...feedback.handlers}\n disabled={isDisabled}\n style={composeStyles<ViewStyle>(own.vertical, style)}\n >\n <Label form={form} isDisabled={isDisabled} selected={selected}>\n {children}\n </Label>\n <View style={composeStyles<ViewStyle>(own.indicator, feedback.ring)}>\n <ActiveIndicator selected={selected} />\n {feedback.layer}\n {content}\n </View>\n </Pressable>\n )\n}\n\nexport type {\n NavigationContextValue,\n NavigationDestinationProps,\n NavigationForm,\n}\n\nexport { iconColorOf, labelColorOf, NavigationContext, NavigationDestination }\n"],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { themedStyles } from "../theme/styles.js";
2
+ import { StyleSheet } from "react-native";
3
+ //#region src/navigation/styles.ts
4
+ const INDICATOR = {
5
+ height: 32,
6
+ width: 56
7
+ };
8
+ const VERTICAL_PADDING = 6;
9
+ const styles = StyleSheet.create({
10
+ fill: {
11
+ bottom: 0,
12
+ end: 0,
13
+ position: "absolute",
14
+ start: 0,
15
+ top: 0
16
+ },
17
+ icon: {
18
+ alignItems: "center",
19
+ flexShrink: 0,
20
+ justifyContent: "center"
21
+ },
22
+ label: {
23
+ flexShrink: 1,
24
+ maxWidth: "100%"
25
+ }
26
+ });
27
+ const stylesOf = themedStyles(({ radii, spacing }) => StyleSheet.create({
28
+ horizontal: {
29
+ alignItems: "center",
30
+ borderRadius: radii.pill,
31
+ flexDirection: "row-reverse",
32
+ flexShrink: 0,
33
+ gap: spacing.xs,
34
+ justifyContent: "center",
35
+ minHeight: 40,
36
+ paddingHorizontal: spacing.lg
37
+ },
38
+ indicator: {
39
+ alignItems: "center",
40
+ borderRadius: radii.pill,
41
+ flexShrink: 0,
42
+ height: INDICATOR.height,
43
+ justifyContent: "center",
44
+ width: INDICATOR.width
45
+ },
46
+ pill: { borderRadius: radii.pill },
47
+ vertical: {
48
+ alignItems: "center",
49
+ flexBasis: 0,
50
+ flexDirection: "column-reverse",
51
+ flexGrow: 1,
52
+ gap: spacing.xs,
53
+ justifyContent: "center",
54
+ minWidth: 0,
55
+ paddingVertical: VERTICAL_PADDING
56
+ }
57
+ }));
58
+ //#endregion
59
+ export { INDICATOR, styles, stylesOf };
60
+
61
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","names":["StyleSheet","themedStyles","INDICATOR","height","width","const","PILL_HEIGHT","VERTICAL_PADDING","styles","create","fill","bottom","end","position","start","top","icon","alignItems","flexShrink","justifyContent","label","maxWidth","stylesOf","radii","spacing","horizontal","borderRadius","pill","flexDirection","gap","xs","minHeight","paddingHorizontal","lg","indicator","vertical","flexBasis","flexGrow","minWidth","paddingVertical"],"sources":["../../src/navigation/styles.ts"],"sourcesContent":["import { StyleSheet } from 'react-native'\n\nimport { themedStyles } from '../theme/styles'\n\n// The page's active indicator in a vertical destination: 56dp by 32dp, the\n// icon centred in it.\nconst INDICATOR = { height: 32, width: 56 } as const\n\n// A horizontal destination's pill, the page's 40dp, which its press reaches\n// past to the 48dp target.\nconst PILL_HEIGHT = 40\n\n// A vertical destination's padding above the indicator and below the label,\n// which puts the two in the bar's 64dp: 6, 32, 4 and 16, then 6.\nconst VERTICAL_PADDING = 6\n\nconst styles = StyleSheet.create({\n // The active indicator's fill, behind the icon in a vertical destination\n // and behind the whole pill in a horizontal one.\n fill: {\n bottom: 0,\n end: 0,\n position: 'absolute',\n start: 0,\n top: 0,\n },\n // An icon, and the badge on it, never squeezed by a long label.\n icon: {\n alignItems: 'center',\n flexShrink: 0,\n justifyContent: 'center',\n },\n // The label never wraps: a destination's name is a word or two, and one\n // broken over two lines would push its neighbours apart. Cut short with an\n // ellipsis where the destination is narrower than it.\n label: {\n flexShrink: 1,\n maxWidth: '100%',\n },\n})\n\nconst stylesOf = themedStyles(({ radii, spacing }) =>\n StyleSheet.create({\n // A horizontal destination: the pill, holding the icon and the label side\n // by side, 16dp in at either end and 4dp between the two, as wide as what\n // it holds. Reversed, since the label comes first in the tree.\n horizontal: {\n alignItems: 'center',\n borderRadius: radii.pill,\n flexDirection: 'row-reverse',\n flexShrink: 0,\n gap: spacing.xs,\n justifyContent: 'center',\n minHeight: PILL_HEIGHT,\n paddingHorizontal: spacing.lg,\n },\n // The active indicator of a vertical destination, which draws the layers\n // and the ring as well as the fill.\n indicator: {\n alignItems: 'center',\n borderRadius: radii.pill,\n flexShrink: 0,\n height: INDICATOR.height,\n justifyContent: 'center',\n width: INDICATOR.width,\n },\n // The fill's corners, the pill's.\n pill: {\n borderRadius: radii.pill,\n },\n // A vertical destination: the indicator with the label 4dp under it,\n // sharing the bar's width with the others. Its press is the whole of\n // that share, so it needs no reach of its own. Reversed, since the label\n // comes first in the tree.\n vertical: {\n alignItems: 'center',\n flexBasis: 0,\n flexDirection: 'column-reverse',\n flexGrow: 1,\n gap: spacing.xs,\n justifyContent: 'center',\n minWidth: 0,\n paddingVertical: VERTICAL_PADDING,\n },\n }),\n)\n\nexport { INDICATOR, PILL_HEIGHT, styles, stylesOf }\n"],"mappings":";;;AAMA,MAAME,YAAY;CAAEC,QAAQ;CAAIC,OAAO;AAAG;AAQ1C,MAAMG,mBAAmB;AAEzB,MAAMC,SAASR,WAAWS,OAAO;CAG/BC,MAAM;EACJC,QAAQ;EACRC,KAAK;EACLC,UAAU;EACVC,OAAO;EACPC,KAAK;CACP;CAEAC,MAAM;EACJC,YAAY;EACZC,YAAY;EACZC,gBAAgB;CAClB;CAIAC,OAAO;EACLF,YAAY;EACZG,UAAU;CACZ;AACF,CAAC;AAED,MAAMC,WAAWrB,cAAc,EAAEsB,OAAOC,cACtCxB,WAAWS,OAAO;CAIhBgB,YAAY;EACVR,YAAY;EACZS,cAAcH,MAAMI;EACpBC,eAAe;EACfV,YAAY;EACZW,KAAKL,QAAQM;EACbX,gBAAgB;EAChBY,WAAAA;EACAC,mBAAmBR,QAAQS;CAC7B;CAGAC,WAAW;EACTjB,YAAY;EACZS,cAAcH,MAAMI;EACpBT,YAAY;EACZf,QAAQD,UAAUC;EAClBgB,gBAAgB;EAChBf,OAAOF,UAAUE;CACnB;CAEAuB,MAAM,EACJD,cAAcH,MAAMI,KACtB;CAKAQ,UAAU;EACRlB,YAAY;EACZmB,WAAW;EACXR,eAAe;EACfS,UAAU;EACVR,KAAKL,QAAQM;EACbX,gBAAgB;EAChBmB,UAAU;EACVC,iBAAiBhC;CACnB;AACF,CAAC,CACH"}
@@ -0,0 +1,2 @@
1
+ import { HostInstance, LayoutChangeEvent, ViewStyle } from "react-native";
2
+ import { RefObject } from "react";