@yahoo/uds-mobile 2.21.2 → 2.22.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 (37) hide show
  1. package/README.md +2 -0
  2. package/dist/components/IconButton.cjs +24 -21
  3. package/dist/components/IconButton.js +25 -22
  4. package/dist/components/IconButton.js.map +1 -1
  5. package/dist/components/Switch.cjs +34 -12
  6. package/dist/components/Switch.d.cts.map +1 -1
  7. package/dist/components/Switch.d.ts.map +1 -1
  8. package/dist/components/Switch.js +36 -14
  9. package/dist/components/Switch.js.map +1 -1
  10. package/dist/components/UDSGestureProvider.cjs +4 -0
  11. package/dist/components/UDSGestureProvider.d.cts +3 -0
  12. package/dist/components/UDSGestureProvider.d.ts +3 -0
  13. package/dist/components/UDSGestureProvider.js +3 -0
  14. package/dist/components/UDSProvider.cjs +10 -5
  15. package/dist/components/UDSProvider.d.cts +15 -7
  16. package/dist/components/UDSProvider.d.cts.map +1 -1
  17. package/dist/components/UDSProvider.d.ts +15 -7
  18. package/dist/components/UDSProvider.d.ts.map +1 -1
  19. package/dist/components/UDSProvider.js +10 -6
  20. package/dist/components/UDSProvider.js.map +1 -1
  21. package/dist/components/internal/Overlay/OverlayPortal.js.map +1 -1
  22. package/dist/jest/mocks/styles.cjs +21 -9
  23. package/dist/jest/mocks/styles.d.cts.map +1 -1
  24. package/dist/jest/mocks/styles.d.ts.map +1 -1
  25. package/dist/jest/mocks/styles.js +21 -9
  26. package/dist/jest/mocks/styles.js.map +1 -1
  27. package/dist/jest/mocks/unistyles.cjs +16 -1
  28. package/dist/jest/mocks/unistyles.d.cts +56 -2
  29. package/dist/jest/mocks/unistyles.d.cts.map +1 -1
  30. package/dist/jest/mocks/unistyles.d.ts +56 -2
  31. package/dist/jest/mocks/unistyles.d.ts.map +1 -1
  32. package/dist/jest/mocks/unistyles.js +16 -1
  33. package/dist/jest/mocks/unistyles.js.map +1 -1
  34. package/dist/portal.cjs +1 -1
  35. package/dist/portal.js +1 -1
  36. package/dist/portal.js.map +1 -1
  37. package/package.json +11 -1
@@ -1 +1 @@
1
- {"version":3,"file":"unistyles.js","names":[],"sources":["../../../src/jest/mocks/unistyles.ts"],"sourcesContent":["/**\n * Jest mock for react-native-unistyles.\n *\n * Provides minimal implementations of:\n * - useUnistyles() hook\n * - StyleSheet.create() / StyleSheet.configure()\n * - UnistylesRuntime\n */\n\n/// <reference types=\"jest\" />\n\nconst mockTheme = {\n colors: {\n text: {\n primary: '#000000',\n secondary: '#666666',\n tertiary: '#999999',\n muted: '#CCCCCC',\n onColor: '#FFFFFF',\n brand: '#6001D2',\n alert: '#D93025',\n positive: '#188038',\n warning: '#F29900',\n info: '#1A73E8',\n },\n background: {\n primary: '#FFFFFF',\n secondary: '#F5F5F5',\n accent: '#E8E0F0',\n brand: '#6001D2',\n 'brand-secondary': '#F3E8FF',\n alert: '#D93025',\n 'alert-secondary': '#FDECEA',\n positive: '#188038',\n 'positive-secondary': '#E6F4EA',\n warning: '#F29900',\n 'warning-secondary': '#FEF7E0',\n info: '#1A73E8',\n 'info-secondary': '#E8F0FE',\n 'elevation-0': '#FFFFFF',\n 'elevation-1': '#FFFFFF',\n 'elevation-2': '#FFFFFF',\n 'elevation-3': '#FFFFFF',\n 'elevation-4': '#FFFFFF',\n 'elevation-5': '#FFFFFF',\n },\n border: {\n primary: '#E0E0E0',\n secondary: '#CCCCCC',\n },\n },\n spacing: {\n '0': 0,\n '1': 4,\n '2': 8,\n '3': 12,\n '4': 16,\n '5': 20,\n '6': 24,\n '8': 32,\n '10': 40,\n '12': 48,\n },\n borderRadius: {\n none: 0,\n xs: 2,\n sm: 4,\n md: 8,\n lg: 12,\n xl: 16,\n full: 9999,\n },\n components: {},\n};\n\nconst mockRuntime = {\n themeName: 'light' as 'light' | 'dark',\n colorScheme: 'light' as 'light' | 'dark',\n setTheme: jest.fn(),\n setColorScheme: jest.fn(),\n screen: {\n width: 375,\n height: 812,\n },\n insets: {\n top: 44,\n bottom: 34,\n left: 0,\n right: 0,\n },\n statusBar: {\n height: 44,\n },\n navigationBar: {\n height: 0,\n },\n};\n\nconst useUnistyles = jest.fn(() => ({\n theme: mockTheme,\n rt: mockRuntime,\n}));\n\nconst useInitialTheme = jest.fn();\n\n// StyleSheet mock that handles both static and dynamic styles\nconst createStyleSheet = (styleCreator: unknown) => {\n // If it's a function (dynamic styles), call it with mock theme\n if (typeof styleCreator === 'function') {\n const styles = styleCreator(mockTheme, mockRuntime);\n // Add useVariants as a no-op for each style object\n if (styles && typeof styles === 'object') {\n const result = { ...styles };\n for (const key of Object.keys(result)) {\n const styleObj = result[key];\n if (styleObj && typeof styleObj === 'object') {\n (styleObj as Record<string, unknown>).useVariants = jest.fn();\n }\n }\n return result;\n }\n return styles;\n }\n // Static styles, return as-is\n return styleCreator;\n};\n\nconst StyleSheet = {\n create: createStyleSheet,\n configure: jest.fn(),\n};\n\nconst UnistylesRuntime = mockRuntime;\n\n// react-native-unistyles/reanimated exports\n// These are used for animated theme values in components like Button, Switch, Link, IconButton\n\nconst useAnimatedTheme = jest.fn(() => ({\n value: mockTheme,\n}));\n\nconst useAnimatedVariantColor = jest.fn((_path: string, fallback?: string) => ({\n value: fallback ?? '#000000',\n}));\n\n// All exports at the end of the file\nexport {\n StyleSheet,\n UnistylesRuntime,\n useAnimatedTheme,\n useAnimatedVariantColor,\n useInitialTheme,\n useUnistyles,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAWA,MAAM,YAAY;CAChB,QAAQ;EACN,MAAM;GACJ,SAAS;GACT,WAAW;GACX,UAAU;GACV,OAAO;GACP,SAAS;GACT,OAAO;GACP,OAAO;GACP,UAAU;GACV,SAAS;GACT,MAAM;GACP;EACD,YAAY;GACV,SAAS;GACT,WAAW;GACX,QAAQ;GACR,OAAO;GACP,mBAAmB;GACnB,OAAO;GACP,mBAAmB;GACnB,UAAU;GACV,sBAAsB;GACtB,SAAS;GACT,qBAAqB;GACrB,MAAM;GACN,kBAAkB;GAClB,eAAe;GACf,eAAe;GACf,eAAe;GACf,eAAe;GACf,eAAe;GACf,eAAe;GAChB;EACD,QAAQ;GACN,SAAS;GACT,WAAW;GACZ;EACF;CACD,SAAS;EACP,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,MAAM;EACN,MAAM;EACP;CACD,cAAc;EACZ,MAAM;EACN,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,MAAM;EACP;CACD,YAAY,EAAE;CACf;AAED,MAAM,cAAc;CAClB,WAAW;CACX,aAAa;CACb,UAAU,KAAK,IAAI;CACnB,gBAAgB,KAAK,IAAI;CACzB,QAAQ;EACN,OAAO;EACP,QAAQ;EACT;CACD,QAAQ;EACN,KAAK;EACL,QAAQ;EACR,MAAM;EACN,OAAO;EACR;CACD,WAAW,EACT,QAAQ,IACT;CACD,eAAe,EACb,QAAQ,GACT;CACF;AAED,MAAM,eAAe,KAAK,UAAU;CAClC,OAAO;CACP,IAAI;CACL,EAAE;AAEH,MAAM,kBAAkB,KAAK,IAAI;AAGjC,MAAM,oBAAoB,iBAA0B;CAElD,IAAI,OAAO,iBAAiB,YAAY;EACtC,MAAM,SAAS,aAAa,WAAW,YAAY;EAEnD,IAAI,UAAU,OAAO,WAAW,UAAU;GACxC,MAAM,SAAS,EAAE,GAAG,QAAQ;GAC5B,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;IACrC,MAAM,WAAW,OAAO;IACxB,IAAI,YAAY,OAAO,aAAa,UAClC,SAAsC,cAAc,KAAK,IAAI;;GAGjE,OAAO;;EAET,OAAO;;CAGT,OAAO;;AAGT,MAAM,aAAa;CACjB,QAAQ;CACR,WAAW,KAAK,IAAI;CACrB;AAED,MAAM,mBAAmB;AAKzB,MAAM,mBAAmB,KAAK,UAAU,EACtC,OAAO,WACR,EAAE;AAEH,MAAM,0BAA0B,KAAK,IAAI,OAAe,cAAuB,EAC7E,OAAO,YAAY,WACpB,EAAE"}
1
+ {"version":3,"file":"unistyles.js","names":[],"sources":["../../../src/jest/mocks/unistyles.ts"],"sourcesContent":["/**\n * Jest mock for react-native-unistyles.\n *\n * Provides minimal implementations of:\n * - useUnistyles() hook\n * - StyleSheet.create() / StyleSheet.configure()\n * - UnistylesRuntime\n */\n\n/// <reference types=\"jest\" />\n\nconst mockTheme = {\n colors: {\n text: {\n primary: '#000000',\n secondary: '#666666',\n tertiary: '#999999',\n muted: '#CCCCCC',\n onColor: '#FFFFFF',\n brand: '#6001D2',\n alert: '#D93025',\n positive: '#188038',\n warning: '#F29900',\n info: '#1A73E8',\n },\n background: {\n primary: '#FFFFFF',\n secondary: '#F5F5F5',\n accent: '#E8E0F0',\n brand: '#6001D2',\n 'brand-secondary': '#F3E8FF',\n alert: '#D93025',\n 'alert-secondary': '#FDECEA',\n positive: '#188038',\n 'positive-secondary': '#E6F4EA',\n warning: '#F29900',\n 'warning-secondary': '#FEF7E0',\n info: '#1A73E8',\n 'info-secondary': '#E8F0FE',\n 'elevation-0': '#FFFFFF',\n 'elevation-1': '#FFFFFF',\n 'elevation-2': '#FFFFFF',\n 'elevation-3': '#FFFFFF',\n 'elevation-4': '#FFFFFF',\n 'elevation-5': '#FFFFFF',\n },\n border: {\n primary: '#E0E0E0',\n secondary: '#CCCCCC',\n },\n },\n spacing: {\n '0': 0,\n '1': 4,\n '2': 8,\n '3': 12,\n '4': 16,\n '5': 20,\n '6': 24,\n '8': 32,\n '10': 40,\n '12': 48,\n },\n borderRadius: {\n none: 0,\n xs: 2,\n sm: 4,\n md: 8,\n lg: 12,\n xl: 16,\n full: 9999,\n },\n components: {\n 'switch/variant/default/active/off/handle/rest': {\n backgroundColor: '#ffffff',\n },\n 'switch/variant/default/active/off/handleIcon/rest': {\n color: '#666666',\n },\n 'switch/variant/default/active/off/rootText/rest': {\n color: '#6001D2',\n },\n 'switch/variant/default/active/off/switch/rest': {\n backgroundColor: '#188038',\n borderColor: '#188038',\n },\n 'switch/variant/default/active/on/handle/rest': {\n backgroundColor: '#ffffff',\n },\n 'switch/variant/default/active/on/handleIcon/rest': {\n color: '#6001D2',\n },\n 'switch/variant/default/active/on/rootText/rest': {\n color: '#D93025',\n },\n 'switch/variant/default/active/on/switch/rest': {\n backgroundColor: '#D93025',\n borderColor: '#D93025',\n },\n },\n};\n\nconst mockRuntime = {\n themeName: 'light' as 'light' | 'dark',\n colorScheme: 'light' as 'light' | 'dark',\n setTheme: jest.fn(),\n setColorScheme: jest.fn(),\n screen: {\n width: 375,\n height: 812,\n },\n insets: {\n top: 44,\n bottom: 34,\n left: 0,\n right: 0,\n },\n statusBar: {\n height: 44,\n },\n navigationBar: {\n height: 0,\n },\n};\n\nconst useUnistyles = jest.fn(() => ({\n theme: mockTheme,\n rt: mockRuntime,\n}));\n\nconst useInitialTheme = jest.fn();\n\n// StyleSheet mock that handles both static and dynamic styles\nconst createStyleSheet = (styleCreator: unknown) => {\n // If it's a function (dynamic styles), call it with mock theme\n if (typeof styleCreator === 'function') {\n const styles = styleCreator(mockTheme, mockRuntime);\n // Add useVariants as a no-op for each style object\n if (styles && typeof styles === 'object') {\n const result = { ...styles };\n for (const key of Object.keys(result)) {\n const styleObj = result[key];\n if (styleObj && typeof styleObj === 'object') {\n (styleObj as Record<string, unknown>).useVariants = jest.fn();\n }\n }\n return result;\n }\n return styles;\n }\n // Static styles, return as-is\n return styleCreator;\n};\n\nconst StyleSheet = {\n create: createStyleSheet,\n configure: jest.fn(),\n};\n\nconst UnistylesRuntime = mockRuntime;\n\n// react-native-unistyles/reanimated exports\n// These are used for animated theme values in components like Button, Switch, Link, IconButton\n\nconst useAnimatedTheme = jest.fn(() => ({\n value: mockTheme,\n}));\n\nconst useAnimatedVariantColor = jest.fn((_path: string, fallback?: string) => ({\n value: fallback ?? '#000000',\n}));\n\n// All exports at the end of the file\nexport {\n StyleSheet,\n UnistylesRuntime,\n useAnimatedTheme,\n useAnimatedVariantColor,\n useInitialTheme,\n useUnistyles,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAWA,MAAM,YAAY;CAChB,QAAQ;EACN,MAAM;GACJ,SAAS;GACT,WAAW;GACX,UAAU;GACV,OAAO;GACP,SAAS;GACT,OAAO;GACP,OAAO;GACP,UAAU;GACV,SAAS;GACT,MAAM;GACP;EACD,YAAY;GACV,SAAS;GACT,WAAW;GACX,QAAQ;GACR,OAAO;GACP,mBAAmB;GACnB,OAAO;GACP,mBAAmB;GACnB,UAAU;GACV,sBAAsB;GACtB,SAAS;GACT,qBAAqB;GACrB,MAAM;GACN,kBAAkB;GAClB,eAAe;GACf,eAAe;GACf,eAAe;GACf,eAAe;GACf,eAAe;GACf,eAAe;GAChB;EACD,QAAQ;GACN,SAAS;GACT,WAAW;GACZ;EACF;CACD,SAAS;EACP,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,MAAM;EACN,MAAM;EACP;CACD,cAAc;EACZ,MAAM;EACN,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,MAAM;EACP;CACD,YAAY;EACV,iDAAiD,EAC/C,iBAAiB,WAClB;EACD,qDAAqD,EACnD,OAAO,WACR;EACD,mDAAmD,EACjD,OAAO,WACR;EACD,iDAAiD;GAC/C,iBAAiB;GACjB,aAAa;GACd;EACD,gDAAgD,EAC9C,iBAAiB,WAClB;EACD,oDAAoD,EAClD,OAAO,WACR;EACD,kDAAkD,EAChD,OAAO,WACR;EACD,gDAAgD;GAC9C,iBAAiB;GACjB,aAAa;GACd;EACF;CACF;AAED,MAAM,cAAc;CAClB,WAAW;CACX,aAAa;CACb,UAAU,KAAK,IAAI;CACnB,gBAAgB,KAAK,IAAI;CACzB,QAAQ;EACN,OAAO;EACP,QAAQ;EACT;CACD,QAAQ;EACN,KAAK;EACL,QAAQ;EACR,MAAM;EACN,OAAO;EACR;CACD,WAAW,EACT,QAAQ,IACT;CACD,eAAe,EACb,QAAQ,GACT;CACF;AAED,MAAM,eAAe,KAAK,UAAU;CAClC,OAAO;CACP,IAAI;CACL,EAAE;AAEH,MAAM,kBAAkB,KAAK,IAAI;AAGjC,MAAM,oBAAoB,iBAA0B;CAElD,IAAI,OAAO,iBAAiB,YAAY;EACtC,MAAM,SAAS,aAAa,WAAW,YAAY;EAEnD,IAAI,UAAU,OAAO,WAAW,UAAU;GACxC,MAAM,SAAS,EAAE,GAAG,QAAQ;GAC5B,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;IACrC,MAAM,WAAW,OAAO;IACxB,IAAI,YAAY,OAAO,aAAa,UAClC,SAAsC,cAAc,KAAK,IAAI;;GAGjE,OAAO;;EAET,OAAO;;CAGT,OAAO;;AAGT,MAAM,aAAa;CACjB,QAAQ;CACR,WAAW,KAAK,IAAI;CACrB;AAED,MAAM,mBAAmB;AAKzB,MAAM,mBAAmB,KAAK,UAAU,EACtC,OAAO,WACR,EAAE;AAEH,MAAM,0BAA0B,KAAK,IAAI,OAAe,cAAuB,EAC7E,OAAO,YAAY,WACpB,EAAE"}
package/dist/portal.cjs CHANGED
@@ -23,7 +23,7 @@ function portalReducer(state, action) {
23
23
  const PortalContext = (0, react.createContext)(null);
24
24
  function usePortalContext() {
25
25
  const ctx = (0, react.useContext)(PortalContext);
26
- if (!ctx) throw new Error("Portal must be used within a UDSProvider.");
26
+ if (!ctx) throw new Error("Portal must be used within a UDSGestureProvider.");
27
27
  return ctx;
28
28
  }
29
29
  const PortalHost = (0, react.memo)(function PortalHost({ state }) {
package/dist/portal.js CHANGED
@@ -21,7 +21,7 @@ function portalReducer(state, action) {
21
21
  const PortalContext = createContext(null);
22
22
  function usePortalContext() {
23
23
  const ctx = useContext(PortalContext);
24
- if (!ctx) throw new Error("Portal must be used within a UDSProvider.");
24
+ if (!ctx) throw new Error("Portal must be used within a UDSGestureProvider.");
25
25
  return ctx;
26
26
  }
27
27
  const PortalHost = memo(function PortalHost({ state }) {
@@ -1 +1 @@
1
- {"version":3,"file":"portal.js","names":[],"sources":["../src/portal.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useReducer,\n} from 'react';\nimport { StyleSheet, View } from 'react-native';\n\n// ---------------------------------------------------------------------------\n// State\n// ---------------------------------------------------------------------------\n\ntype PortalState = Map<string, ReactNode>;\n\ntype PortalAction =\n | { type: 'register'; id: string; node: ReactNode }\n | { type: 'unregister'; id: string };\n\nfunction portalReducer(state: PortalState, action: PortalAction): PortalState {\n switch (action.type) {\n case 'register': {\n const next = new Map(state);\n next.set(action.id, action.node);\n return next;\n }\n case 'unregister': {\n if (!state.has(action.id)) {\n return state;\n }\n const next = new Map(state);\n next.delete(action.id);\n return next;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\ninterface PortalContextValue {\n register: (id: string, node: ReactNode) => void;\n unregister: (id: string) => void;\n}\n\nconst PortalContext = createContext<PortalContextValue | null>(null);\n\nfunction usePortalContext(): PortalContextValue {\n const ctx = useContext(PortalContext);\n if (!ctx) {\n throw new Error('Portal must be used within a UDSProvider.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// PortalHost — renders registered portals. Place after children for z-order.\n// ---------------------------------------------------------------------------\n\nconst PortalHost = memo(function PortalHost({ state }: { state: PortalState }) {\n if (state.size === 0) {\n return null;\n }\n\n const nodes: ReactNode[] = [];\n state.forEach((node, id) => {\n nodes.push(\n <View key={id} style={styles.overlay} pointerEvents=\"box-none\">\n {node}\n </View>,\n );\n });\n return nodes;\n});\n\n// ---------------------------------------------------------------------------\n// Portal — registers children with the host. Renders nothing itself.\n// ---------------------------------------------------------------------------\n\nfunction Portal({ children }: { children: ReactNode }) {\n const id = useId();\n const { register, unregister } = usePortalContext();\n\n useEffect(() => {\n register(id, children);\n }, [id, children, register]);\n\n useEffect(() => {\n return () => unregister(id);\n }, [id, unregister]);\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// PortalProvider — sets up the portal context and host.\n// ---------------------------------------------------------------------------\n\nfunction PortalProvider({ children }: { children: ReactNode }) {\n const [state, dispatch] = useReducer(portalReducer, new Map() as PortalState);\n\n const register = useCallback(\n (id: string, node: ReactNode) => dispatch({ type: 'register', id, node }),\n [],\n );\n const unregister = useCallback((id: string) => dispatch({ type: 'unregister', id }), []);\n\n const contextValue = useMemo(() => ({ register, unregister }), [register, unregister]);\n\n return (\n <PortalContext.Provider value={contextValue}>\n {children}\n <PortalHost state={state} />\n </PortalContext.Provider>\n );\n}\n\nconst styles = StyleSheet.create({\n overlay: {\n ...StyleSheet.absoluteFill,\n },\n});\n\nexport { Portal, PortalProvider, usePortalContext };\nexport type { PortalContextValue };\n"],"mappings":";;;;;AAuBA,SAAS,cAAc,OAAoB,QAAmC;CAC5E,QAAQ,OAAO,MAAf;EACE,KAAK,YAAY;GACf,MAAM,OAAO,IAAI,IAAI,MAAM;GAC3B,KAAK,IAAI,OAAO,IAAI,OAAO,KAAK;GAChC,OAAO;;EAET,KAAK,cAAc;GACjB,IAAI,CAAC,MAAM,IAAI,OAAO,GAAG,EACvB,OAAO;GAET,MAAM,OAAO,IAAI,IAAI,MAAM;GAC3B,KAAK,OAAO,OAAO,GAAG;GACtB,OAAO;;;;AAcb,MAAM,gBAAgB,cAAyC,KAAK;AAEpE,SAAS,mBAAuC;CAC9C,MAAM,MAAM,WAAW,cAAc;CACrC,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,4CAA4C;CAE9D,OAAO;;AAOT,MAAM,aAAa,KAAK,SAAS,WAAW,EAAE,SAAiC;CAC7E,IAAI,MAAM,SAAS,GACjB,OAAO;CAGT,MAAM,QAAqB,EAAE;CAC7B,MAAM,SAAS,MAAM,OAAO;EAC1B,MAAM,KACJ,oBAAC,MAAD;GAAe,OAAO,OAAO;GAAS,eAAc;aACjD;GACI,EAFI,GAEJ,CACR;GACD;CACF,OAAO;EACP;AAMF,SAAS,OAAO,EAAE,YAAqC;CACrD,MAAM,KAAK,OAAO;CAClB,MAAM,EAAE,UAAU,eAAe,kBAAkB;CAEnD,gBAAgB;EACd,SAAS,IAAI,SAAS;IACrB;EAAC;EAAI;EAAU;EAAS,CAAC;CAE5B,gBAAgB;EACd,aAAa,WAAW,GAAG;IAC1B,CAAC,IAAI,WAAW,CAAC;CAEpB,OAAO;;AAOT,SAAS,eAAe,EAAE,YAAqC;CAC7D,MAAM,CAAC,OAAO,YAAY,WAAW,+BAAe,IAAI,KAAK,CAAgB;CAE7E,MAAM,WAAW,aACd,IAAY,SAAoB,SAAS;EAAE,MAAM;EAAY;EAAI;EAAM,CAAC,EACzE,EAAE,CACH;CACD,MAAM,aAAa,aAAa,OAAe,SAAS;EAAE,MAAM;EAAc;EAAI,CAAC,EAAE,EAAE,CAAC;CAExF,MAAM,eAAe,eAAe;EAAE;EAAU;EAAY,GAAG,CAAC,UAAU,WAAW,CAAC;CAEtF,OACE,qBAAC,cAAc,UAAf;EAAwB,OAAO;YAA/B,CACG,UACD,oBAAC,YAAD,EAAmB,OAAS,CAAA,CACL;;;AAI7B,MAAM,SAAS,WAAW,OAAO,EAC/B,SAAS,EACP,GAAG,WAAW,cACf,EACF,CAAC"}
1
+ {"version":3,"file":"portal.js","names":[],"sources":["../src/portal.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useReducer,\n} from 'react';\nimport { StyleSheet, View } from 'react-native';\n\n// ---------------------------------------------------------------------------\n// State\n// ---------------------------------------------------------------------------\n\ntype PortalState = Map<string, ReactNode>;\n\ntype PortalAction =\n | { type: 'register'; id: string; node: ReactNode }\n | { type: 'unregister'; id: string };\n\nfunction portalReducer(state: PortalState, action: PortalAction): PortalState {\n switch (action.type) {\n case 'register': {\n const next = new Map(state);\n next.set(action.id, action.node);\n return next;\n }\n case 'unregister': {\n if (!state.has(action.id)) {\n return state;\n }\n const next = new Map(state);\n next.delete(action.id);\n return next;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\ninterface PortalContextValue {\n register: (id: string, node: ReactNode) => void;\n unregister: (id: string) => void;\n}\n\nconst PortalContext = createContext<PortalContextValue | null>(null);\n\nfunction usePortalContext(): PortalContextValue {\n const ctx = useContext(PortalContext);\n if (!ctx) {\n throw new Error('Portal must be used within a UDSGestureProvider.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// PortalHost — renders registered portals. Place after children for z-order.\n// ---------------------------------------------------------------------------\n\nconst PortalHost = memo(function PortalHost({ state }: { state: PortalState }) {\n if (state.size === 0) {\n return null;\n }\n\n const nodes: ReactNode[] = [];\n state.forEach((node, id) => {\n nodes.push(\n <View key={id} style={styles.overlay} pointerEvents=\"box-none\">\n {node}\n </View>,\n );\n });\n return nodes;\n});\n\n// ---------------------------------------------------------------------------\n// Portal — registers children with the host. Renders nothing itself.\n// ---------------------------------------------------------------------------\n\nfunction Portal({ children }: { children: ReactNode }) {\n const id = useId();\n const { register, unregister } = usePortalContext();\n\n useEffect(() => {\n register(id, children);\n }, [id, children, register]);\n\n useEffect(() => {\n return () => unregister(id);\n }, [id, unregister]);\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// PortalProvider — sets up the portal context and host.\n// ---------------------------------------------------------------------------\n\nfunction PortalProvider({ children }: { children: ReactNode }) {\n const [state, dispatch] = useReducer(portalReducer, new Map() as PortalState);\n\n const register = useCallback(\n (id: string, node: ReactNode) => dispatch({ type: 'register', id, node }),\n [],\n );\n const unregister = useCallback((id: string) => dispatch({ type: 'unregister', id }), []);\n\n const contextValue = useMemo(() => ({ register, unregister }), [register, unregister]);\n\n return (\n <PortalContext.Provider value={contextValue}>\n {children}\n <PortalHost state={state} />\n </PortalContext.Provider>\n );\n}\n\nconst styles = StyleSheet.create({\n overlay: {\n ...StyleSheet.absoluteFill,\n },\n});\n\nexport { Portal, PortalProvider, usePortalContext };\nexport type { PortalContextValue };\n"],"mappings":";;;;;AAuBA,SAAS,cAAc,OAAoB,QAAmC;CAC5E,QAAQ,OAAO,MAAf;EACE,KAAK,YAAY;GACf,MAAM,OAAO,IAAI,IAAI,MAAM;GAC3B,KAAK,IAAI,OAAO,IAAI,OAAO,KAAK;GAChC,OAAO;;EAET,KAAK,cAAc;GACjB,IAAI,CAAC,MAAM,IAAI,OAAO,GAAG,EACvB,OAAO;GAET,MAAM,OAAO,IAAI,IAAI,MAAM;GAC3B,KAAK,OAAO,OAAO,GAAG;GACtB,OAAO;;;;AAcb,MAAM,gBAAgB,cAAyC,KAAK;AAEpE,SAAS,mBAAuC;CAC9C,MAAM,MAAM,WAAW,cAAc;CACrC,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,mDAAmD;CAErE,OAAO;;AAOT,MAAM,aAAa,KAAK,SAAS,WAAW,EAAE,SAAiC;CAC7E,IAAI,MAAM,SAAS,GACjB,OAAO;CAGT,MAAM,QAAqB,EAAE;CAC7B,MAAM,SAAS,MAAM,OAAO;EAC1B,MAAM,KACJ,oBAAC,MAAD;GAAe,OAAO,OAAO;GAAS,eAAc;aACjD;GACI,EAFI,GAEJ,CACR;GACD;CACF,OAAO;EACP;AAMF,SAAS,OAAO,EAAE,YAAqC;CACrD,MAAM,KAAK,OAAO;CAClB,MAAM,EAAE,UAAU,eAAe,kBAAkB;CAEnD,gBAAgB;EACd,SAAS,IAAI,SAAS;IACrB;EAAC;EAAI;EAAU;EAAS,CAAC;CAE5B,gBAAgB;EACd,aAAa,WAAW,GAAG;IAC1B,CAAC,IAAI,WAAW,CAAC;CAEpB,OAAO;;AAOT,SAAS,eAAe,EAAE,YAAqC;CAC7D,MAAM,CAAC,OAAO,YAAY,WAAW,+BAAe,IAAI,KAAK,CAAgB;CAE7E,MAAM,WAAW,aACd,IAAY,SAAoB,SAAS;EAAE,MAAM;EAAY;EAAI;EAAM,CAAC,EACzE,EAAE,CACH;CACD,MAAM,aAAa,aAAa,OAAe,SAAS;EAAE,MAAM;EAAc;EAAI,CAAC,EAAE,EAAE,CAAC;CAExF,MAAM,eAAe,eAAe;EAAE;EAAU;EAAY,GAAG,CAAC,UAAU,WAAW,CAAC;CAEtF,OACE,qBAAC,cAAc,UAAf;EAAwB,OAAO;YAA/B,CACG,UACD,oBAAC,YAAD,EAAmB,OAAS,CAAA,CACL;;;AAI7B,MAAM,SAAS,WAAW,OAAO,EAC/B,SAAS,EACP,GAAG,WAAW,cACf,EACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yahoo/uds-mobile",
3
- "version": "2.21.2",
3
+ "version": "2.22.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "uds-mobile": "./cli/uds-mobile.js"
@@ -330,6 +330,16 @@
330
330
  "default": "./dist/components/UDSProvider.cjs"
331
331
  }
332
332
  },
333
+ "./UDSGestureProvider": {
334
+ "import": {
335
+ "types": "./dist/components/UDSGestureProvider.d.ts",
336
+ "default": "./dist/components/UDSGestureProvider.js"
337
+ },
338
+ "require": {
339
+ "types": "./dist/components/UDSGestureProvider.d.cts",
340
+ "default": "./dist/components/UDSGestureProvider.cjs"
341
+ }
342
+ },
333
343
  "./VStack": {
334
344
  "import": {
335
345
  "types": "./dist/components/VStack.d.ts",