@apple-pie/slice-native 0.1.4 → 0.1.7

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 (178) hide show
  1. package/README.md +164 -97
  2. package/SliceNative.podspec +24 -0
  3. package/dist/cjs/components.js +19 -0
  4. package/dist/cjs/hooks.js +9 -0
  5. package/dist/cjs/index.js +27 -812
  6. package/dist/cjs/providers.js +9 -0
  7. package/dist/cjs/src/components/SliceBackgroundBlur/SliceBackgroundBlur.js +11 -0
  8. package/dist/cjs/src/components/SliceButton/SliceButton.js +146 -0
  9. package/dist/cjs/src/components/SliceIcon/SliceIcon.js +20 -0
  10. package/dist/cjs/src/components/SliceIcon/iconRegistry.js +668 -0
  11. package/dist/cjs/src/components/SliceIcon/icons.js +144 -0
  12. package/dist/cjs/src/components/SliceLiquidGlassView/SliceLiquidGlassView.js +12 -0
  13. package/dist/cjs/src/components/SliceText/SliceText.js +21 -0
  14. package/dist/cjs/src/components/SliceTextInput/SliceTextInput.js +117 -0
  15. package/dist/cjs/src/hooks/useCreateThemedStyles/useCreateThemedStyles.js +13 -0
  16. package/dist/cjs/src/hooks/useDeviceCapabilities/useDeviceCapabilities.js +19 -0
  17. package/dist/cjs/src/providers/SliceThemeProvider.js +37 -0
  18. package/dist/cjs/src/theme/colors/colors.js +253 -0
  19. package/dist/cjs/src/theme/corners/corners.js +14 -0
  20. package/dist/cjs/src/theme/elevations/elevations.js +17 -0
  21. package/dist/cjs/src/theme/motion/motion.js +15 -0
  22. package/dist/cjs/src/theme/motion.js +47 -0
  23. package/dist/cjs/src/theme/spacing/spacing.js +14 -0
  24. package/dist/cjs/src/theme/type/type.js +190 -0
  25. package/dist/cjs/src/utils/sizes/sizes.js +40 -0
  26. package/dist/cjs/src/utils/typography/typography.js +17 -0
  27. package/dist/cjs/theme.js +23 -538
  28. package/dist/cjs/utils.js +10 -0
  29. package/dist/esm/components.mjs +7 -0
  30. package/dist/esm/hooks.mjs +2 -0
  31. package/dist/esm/index.mjs +12 -813
  32. package/dist/esm/providers.mjs +1 -0
  33. package/dist/esm/src/components/SliceBackgroundBlur/SliceBackgroundBlur.mjs +9 -0
  34. package/dist/esm/src/components/SliceButton/SliceButton.mjs +144 -0
  35. package/dist/esm/src/components/SliceIcon/SliceIcon.mjs +18 -0
  36. package/dist/esm/src/components/SliceIcon/iconRegistry.mjs +666 -0
  37. package/dist/esm/src/components/SliceIcon/icons.mjs +142 -0
  38. package/dist/esm/src/components/SliceLiquidGlassView/SliceLiquidGlassView.mjs +10 -0
  39. package/dist/esm/src/components/SliceText/SliceText.mjs +19 -0
  40. package/dist/esm/src/components/SliceTextInput/SliceTextInput.mjs +115 -0
  41. package/dist/esm/src/hooks/useCreateThemedStyles/useCreateThemedStyles.mjs +11 -0
  42. package/dist/esm/src/hooks/useDeviceCapabilities/useDeviceCapabilities.mjs +17 -0
  43. package/dist/esm/src/providers/SliceThemeProvider.mjs +33 -0
  44. package/dist/esm/src/theme/colors/colors.mjs +249 -0
  45. package/dist/esm/src/theme/corners/corners.mjs +12 -0
  46. package/dist/esm/src/theme/elevations/elevations.mjs +15 -0
  47. package/dist/esm/src/theme/motion/motion.mjs +13 -0
  48. package/dist/esm/src/theme/motion.mjs +45 -0
  49. package/dist/esm/src/theme/spacing/spacing.mjs +12 -0
  50. package/dist/esm/src/theme/type/type.mjs +184 -0
  51. package/dist/esm/src/utils/sizes/sizes.mjs +37 -0
  52. package/dist/esm/src/utils/typography/typography.mjs +15 -0
  53. package/dist/esm/theme.mjs +7 -522
  54. package/dist/esm/utils.mjs +2 -0
  55. package/dist/react-native/native/src/components/SliceBackgroundBlur/SliceBackgroundBlur.js +6 -0
  56. package/dist/react-native/native/src/components/SliceBackgroundBlur/SliceBackgroundBlur.native.js +6 -0
  57. package/dist/react-native/native/src/components/SliceBackgroundBlur/_types.js +1 -0
  58. package/dist/react-native/native/src/components/SliceBackgroundBlur/index.js +1 -0
  59. package/dist/react-native/native/src/components/SliceButton/SliceButton.js +141 -0
  60. package/dist/react-native/native/src/components/SliceButton/_types.js +1 -0
  61. package/dist/react-native/native/src/components/SliceButton/index.js +1 -0
  62. package/dist/react-native/native/src/components/SliceIcon/SliceIcon.js +15 -0
  63. package/dist/react-native/native/src/components/SliceIcon/_types.js +1 -0
  64. package/dist/react-native/native/src/components/SliceIcon/iconRegistry.js +663 -0
  65. package/dist/react-native/native/src/components/SliceIcon/icons.js +140 -0
  66. package/dist/react-native/native/src/components/SliceIcon/index.js +2 -0
  67. package/dist/react-native/native/src/components/SliceLiquidGlassView/SliceLiquidGlassView.ios.js +6 -0
  68. package/dist/react-native/native/src/components/SliceLiquidGlassView/SliceLiquidGlassView.js +7 -0
  69. package/dist/react-native/native/src/components/SliceLiquidGlassView/_types.js +1 -0
  70. package/dist/react-native/native/src/components/SliceLiquidGlassView/index.js +1 -0
  71. package/dist/react-native/native/src/components/SliceText/SliceText.js +16 -0
  72. package/dist/react-native/native/src/components/SliceText/_types.js +1 -0
  73. package/dist/react-native/native/src/components/SliceText/index.js +1 -0
  74. package/dist/react-native/native/src/components/SliceTextInput/SliceTextInput.js +111 -0
  75. package/dist/react-native/native/src/components/SliceTextInput/_types.js +1 -0
  76. package/dist/react-native/native/src/components/SliceTextInput/index.js +1 -0
  77. package/dist/react-native/native/src/components/index.js +6 -0
  78. package/dist/react-native/native/src/hooks/index.js +2 -0
  79. package/dist/react-native/native/src/hooks/useCreateThemedStyles/index.js +1 -0
  80. package/dist/react-native/native/src/hooks/useCreateThemedStyles/useCreateThemedStyles.js +8 -0
  81. package/dist/react-native/native/src/hooks/useDeviceCapabilities/_types.js +1 -0
  82. package/dist/react-native/native/src/hooks/useDeviceCapabilities/index.js +1 -0
  83. package/dist/react-native/native/src/hooks/useDeviceCapabilities/useDeviceCapabilities.js +14 -0
  84. package/dist/react-native/native/src/hooks/useDeviceCapabilities/useDeviceCapabilities.native.js +23 -0
  85. package/dist/react-native/native/src/index.js +6 -0
  86. package/dist/react-native/native/src/providers/SliceThemeProvider.js +30 -0
  87. package/dist/react-native/native/src/providers/index.js +1 -0
  88. package/dist/react-native/native/src/specs/BackgroundBlurNativeComponent.ts +16 -0
  89. package/dist/react-native/native/src/specs/LiquidGlassNativeComponent.ts +18 -0
  90. package/dist/react-native/native/src/specs/NativeDeviceCapabilities.ts +13 -0
  91. package/dist/react-native/native/src/theme/index.js +69 -0
  92. package/dist/react-native/native/src/theme/motion.js +43 -0
  93. package/dist/react-native/native/src/types/index.js +1 -0
  94. package/dist/react-native/native/src/types/sharedTypes.js +1 -0
  95. package/dist/react-native/native/src/utils/index.js +2 -0
  96. package/dist/react-native/native/src/utils/sizes/index.js +1 -0
  97. package/dist/react-native/native/src/utils/sizes/sizes.js +35 -0
  98. package/dist/react-native/native/src/utils/typography/index.js +1 -0
  99. package/dist/react-native/native/src/utils/typography/typography.js +13 -0
  100. package/dist/react-native/src/theme/colors/colors.js +385 -0
  101. package/dist/react-native/src/theme/colors/types.js +1 -0
  102. package/dist/react-native/src/theme/corners/corners.js +10 -0
  103. package/dist/react-native/src/theme/corners/types.js +1 -0
  104. package/dist/react-native/src/theme/elevations/_types.js +1 -0
  105. package/dist/react-native/src/theme/elevations/elevations.js +13 -0
  106. package/dist/react-native/src/theme/motion/_types.js +1 -0
  107. package/dist/react-native/src/theme/motion/motion.js +11 -0
  108. package/dist/react-native/src/theme/spacing/_types.js +1 -0
  109. package/dist/react-native/src/theme/spacing/spacing.js +10 -0
  110. package/dist/react-native/src/theme/type/type.js +371 -0
  111. package/dist/react-native/src/theme/type/types.js +1 -0
  112. package/dist/types/native/src/components/SliceBackgroundBlur/SliceBackgroundBlur.d.ts +3 -0
  113. package/dist/types/native/src/components/SliceBackgroundBlur/SliceBackgroundBlur.native.d.ts +2 -0
  114. package/dist/types/native/src/components/SliceBackgroundBlur/_types.d.ts +24 -0
  115. package/dist/types/native/src/components/SliceBackgroundBlur/index.d.ts +2 -0
  116. package/dist/types/native/src/components/SliceButton/SliceButton.d.ts +5 -0
  117. package/dist/types/native/src/components/SliceButton/_types.d.ts +78 -0
  118. package/dist/types/native/src/components/SliceButton/index.d.ts +2 -0
  119. package/dist/types/native/src/components/SliceIcon/SliceIcon.d.ts +2 -0
  120. package/dist/types/native/{components/Icon → src/components/SliceIcon}/icons.d.ts +1 -0
  121. package/dist/types/native/src/components/SliceIcon/index.d.ts +3 -0
  122. package/dist/types/native/src/components/SliceLiquidGlassView/SliceLiquidGlassView.d.ts +3 -0
  123. package/dist/types/native/src/components/SliceLiquidGlassView/SliceLiquidGlassView.ios.d.ts +2 -0
  124. package/dist/types/native/src/components/SliceLiquidGlassView/_types.d.ts +17 -0
  125. package/dist/types/native/src/components/SliceLiquidGlassView/index.d.ts +2 -0
  126. package/dist/types/native/src/components/SliceText/SliceText.d.ts +5 -0
  127. package/dist/types/native/src/components/SliceText/_types.d.ts +17 -0
  128. package/dist/types/native/src/components/SliceText/index.d.ts +2 -0
  129. package/dist/types/native/src/components/SliceTextInput/SliceTextInput.d.ts +2 -0
  130. package/dist/types/native/src/components/SliceTextInput/_types.d.ts +58 -0
  131. package/dist/types/native/src/components/SliceTextInput/index.d.ts +2 -0
  132. package/dist/types/native/src/components/index.d.ts +12 -0
  133. package/dist/types/native/src/hooks/index.d.ts +3 -0
  134. package/dist/types/native/src/hooks/useCreateThemedStyles/index.d.ts +1 -0
  135. package/dist/types/native/src/hooks/useCreateThemedStyles/useCreateThemedStyles.d.ts +7 -0
  136. package/dist/types/native/src/hooks/useDeviceCapabilities/_types.d.ts +17 -0
  137. package/dist/types/native/src/hooks/useDeviceCapabilities/index.d.ts +2 -0
  138. package/dist/types/native/src/hooks/useDeviceCapabilities/useDeviceCapabilities.d.ts +3 -0
  139. package/dist/types/native/src/hooks/useDeviceCapabilities/useDeviceCapabilities.native.d.ts +7 -0
  140. package/dist/types/native/src/index.d.ts +12 -0
  141. package/dist/types/native/src/providers/SliceThemeProvider.d.ts +16 -0
  142. package/dist/types/native/src/providers/index.d.ts +2 -0
  143. package/dist/types/native/src/specs/BackgroundBlurNativeComponent.d.ts +9 -0
  144. package/dist/types/native/src/specs/LiquidGlassNativeComponent.d.ts +9 -0
  145. package/dist/types/native/src/specs/NativeDeviceCapabilities.d.ts +11 -0
  146. package/dist/types/native/{theme → src/theme}/index.d.ts +5 -5
  147. package/dist/types/native/src/types/index.d.ts +1 -0
  148. package/dist/types/native/src/types/sharedTypes.d.ts +14 -0
  149. package/dist/types/native/src/utils/index.d.ts +2 -0
  150. package/dist/types/native/src/utils/sizes/index.d.ts +1 -0
  151. package/dist/types/native/src/utils/sizes/sizes.d.ts +7 -0
  152. package/dist/types/native/src/utils/typography/index.d.ts +1 -0
  153. package/dist/types/native/src/utils/typography/typography.d.ts +7 -0
  154. package/package.json +57 -11
  155. package/platform/android/build.gradle +22 -0
  156. package/platform/android/src/main/AndroidManifest.xml +1 -0
  157. package/platform/android/src/main/java/com/slice/SliceBackgroundBlurManager.java +28 -0
  158. package/platform/android/src/main/java/com/slice/SliceBackgroundBlurView.java +98 -0
  159. package/platform/android/src/main/java/com/slice/SliceDeviceCapabilitiesModule.java +25 -0
  160. package/platform/android/src/main/java/com/slice/SlicePackage.java +25 -0
  161. package/platform/ios/BackgroundBlurSurface.swift +89 -0
  162. package/platform/ios/LiquidGlassSurface.swift +82 -0
  163. package/platform/ios/RCTBackgroundBlurView.h +3 -0
  164. package/platform/ios/RCTBackgroundBlurView.mm +42 -0
  165. package/platform/ios/RCTLiquidGlassView.h +8 -0
  166. package/platform/ios/RCTLiquidGlassView.mm +73 -0
  167. package/platform/ios/SliceDeviceCapabilities.h +4 -0
  168. package/platform/ios/SliceDeviceCapabilities.mm +35 -0
  169. package/react-native.config.js +1 -0
  170. package/src/specs/BackgroundBlurNativeComponent.ts +16 -0
  171. package/src/specs/LiquidGlassNativeComponent.ts +18 -0
  172. package/src/specs/NativeDeviceCapabilities.ts +13 -0
  173. package/dist/types/native/components/Icon/NativeIcon.d.ts +0 -2
  174. package/dist/types/native/components/Icon/index.d.ts +0 -3
  175. package/dist/types/native/index.d.ts +0 -4
  176. /package/dist/types/native/{components/Icon → src/components/SliceIcon}/_types.d.ts +0 -0
  177. /package/dist/types/native/{components/Icon → src/components/SliceIcon}/iconRegistry.d.ts +0 -0
  178. /package/dist/types/native/{theme → src/theme}/motion.d.ts +0 -0
@@ -0,0 +1,7 @@
1
+ import type { ImageStyle, TextStyle, ViewStyle } from 'react-native';
2
+ import type { SliceNativeTheme } from '../../theme';
3
+ /** Resolve native styles using the current provider theme. Keep the factory stable
4
+ * (outside the component, or with useCallback) to reuse styles across renders. */
5
+ export declare function useCreateThemedStyles<T extends {
6
+ [K in keyof T]: ViewStyle | TextStyle | ImageStyle;
7
+ }>(styles: (theme: SliceNativeTheme) => T): T;
@@ -0,0 +1,17 @@
1
+ import type { Platform } from 'react-native';
2
+ export interface DeviceCapabilities {
3
+ /** Current React Native platform, including ios, android, and web. */
4
+ readonly platform: typeof Platform.OS;
5
+ /** Full iOS system version (e.g. '26.1.0'), or null on other platforms. */
6
+ readonly iosVersion: string | null;
7
+ /** Android API level (e.g. 37), or null on other platforms. */
8
+ readonly androidSdkVersion: number | null;
9
+ /** System-provided iOS name or Android model; null when unavailable. */
10
+ readonly deviceName: string | null;
11
+ /** iOS hardware identifier (e.g. 'iPhone17,1') or Android model; null when unavailable. */
12
+ readonly deviceModel: string | null;
13
+ /** Native Liquid Glass API availability (iOS 26+). */
14
+ readonly supportsLiquidGlass: boolean;
15
+ /** Native backdrop blur API availability, rather than content/window blur. */
16
+ readonly supportsNativeBlur: boolean;
17
+ }
@@ -0,0 +1,2 @@
1
+ export { useDeviceCapabilities } from './useDeviceCapabilities';
2
+ export type { DeviceCapabilities } from './_types';
@@ -0,0 +1,3 @@
1
+ import type { DeviceCapabilities } from './_types';
2
+ /** Unsupported-platform fallback. Metro selects the native hook on iOS/Android. */
3
+ export declare function useDeviceCapabilities(): DeviceCapabilities;
@@ -0,0 +1,7 @@
1
+ import type { DeviceCapabilities } from './_types';
2
+ /**
3
+ * Reports native API availability. Both values are false on unsupported platforms
4
+ * or when the package's native module is absent. Accessibility preferences and
5
+ * per-view hardware acceleration can still cause components to use their fallback.
6
+ */
7
+ export declare function useDeviceCapabilities(): DeviceCapabilities;
@@ -0,0 +1,12 @@
1
+ export { SliceIcon, SliceIcons, StyledText, SliceButton, SliceTextInput, SliceLiquidGlassView } from './components';
2
+ export type { IconProps, SliceIconProps, StyledTextProps, SliceButtonProps, SliceTextInputProps, SliceLiquidGlassViewProps, } from './components';
3
+ export { lightTheme, darkTheme, createTypography } from './theme';
4
+ export type { SliceNativeTheme, SliceTheme } from './theme';
5
+ export { SliceThemeProvider, useSliceTheme, useSliceContext } from './providers';
6
+ export type { ThemePreference, ThemeContextValue } from './providers';
7
+ export { useCreateThemedStyles, useDeviceCapabilities } from './hooks';
8
+ export type { DeviceCapabilities } from './hooks';
9
+ export { lineHeightTextStyle, sizeToNumber, borderRadiusToNumber } from './utils';
10
+ export { Size, BorderRadius, LiquidGlassBackground } from './types';
11
+ export { SliceBackgroundBlur } from './components/SliceBackgroundBlur';
12
+ export type { SliceBackgroundBlurProps } from './components/SliceBackgroundBlur';
@@ -0,0 +1,16 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type SliceNativeTheme } from '../theme';
3
+ export type ThemePreference = 'system' | 'light' | 'dark';
4
+ export type ThemeContextValue = {
5
+ theme: SliceNativeTheme;
6
+ mode: 'light' | 'dark';
7
+ preference: ThemePreference;
8
+ setPreference?: (preference: ThemePreference) => void;
9
+ };
10
+ export declare function SliceThemeProvider({ preference, onPreferenceChange, children, }: {
11
+ preference?: ThemePreference;
12
+ onPreferenceChange?: (preference: ThemePreference) => void;
13
+ children: ReactNode;
14
+ }): import("react").JSX.Element;
15
+ export declare function useSliceContext(): ThemeContextValue;
16
+ export declare function useSliceTheme(): SliceNativeTheme;
@@ -0,0 +1,2 @@
1
+ export { SliceThemeProvider, useSliceTheme, useSliceContext } from './SliceThemeProvider';
2
+ export type { ThemePreference, ThemeContextValue } from './SliceThemeProvider';
@@ -0,0 +1,9 @@
1
+ import { type CodegenTypes, type ColorValue, type HostComponent, type ViewProps } from 'react-native';
2
+ export interface NativeProps extends ViewProps {
3
+ blurIntensity?: CodegenTypes.WithDefault<CodegenTypes.Double, 12>;
4
+ fadeStop?: CodegenTypes.WithDefault<CodegenTypes.Double, 0>;
5
+ direction?: CodegenTypes.WithDefault<'down' | 'up' | 'left' | 'right', 'down'>;
6
+ fallbackColor?: ColorValue;
7
+ }
8
+ declare const _default: HostComponent<NativeProps>;
9
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import { type CodegenTypes, type ColorValue, type HostComponent, type ViewProps } from 'react-native';
2
+ export interface NativeProps extends ViewProps {
3
+ glassStyle?: CodegenTypes.WithDefault<'regular' | 'clear', 'regular'>;
4
+ glassTintColor?: ColorValue;
5
+ interactive?: CodegenTypes.WithDefault<boolean, false>;
6
+ cornerRadius?: CodegenTypes.WithDefault<CodegenTypes.Double, 24>;
7
+ }
8
+ declare const _default: HostComponent<NativeProps>;
9
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import type { TurboModule } from 'react-native';
2
+ export interface Spec extends TurboModule {
3
+ readonly getConstants: () => {
4
+ supportsLiquidGlass: boolean;
5
+ supportsNativeBlur: boolean;
6
+ deviceName: string;
7
+ deviceModel: string;
8
+ };
9
+ }
10
+ declare const _default: Spec | null | undefined;
11
+ export default _default;
@@ -1,9 +1,9 @@
1
1
  import type { TextStyle, ViewStyle } from 'react-native';
2
- import { light, coreColors as webCore } from '../../src/theme/colors/colors';
3
- import { corners } from '../../src/theme/corners/corners';
4
- import { elevations } from '../../src/theme/elevations/elevations';
5
- import { spacing } from '../../src/theme/spacing/spacing';
6
- import { type as webType } from '../../src/theme/type/type';
2
+ import { light, coreColors as webCore } from '../../../src/theme/colors/colors';
3
+ import { corners } from '../../../src/theme/corners/corners';
4
+ import { elevations } from '../../../src/theme/elevations/elevations';
5
+ import { spacing } from '../../../src/theme/spacing/spacing';
6
+ import { type as webType } from '../../../src/theme/type/type';
7
7
  export { corners, spacing, elevations };
8
8
  export type NativeTypography = Record<keyof typeof webType, TextStyle>;
9
9
  type ShadowKey = 'surface-shadow-soft' | 'surface-shadow-strong';
@@ -0,0 +1 @@
1
+ export type { BorderRadius, LiquidGlassBackground, Size } from './sharedTypes';
@@ -0,0 +1,14 @@
1
+ import type { SliceLiquidGlassViewProps } from '../components';
2
+ /**
3
+ * Size type exposed in components
4
+ */
5
+ export type Size = 's' | 'm' | 'l' | number;
6
+ /**
7
+ * Used for props in components that implement an optional liquid glass background
8
+ * Other props of the liquid glass components are inferred by the parent component
9
+ */
10
+ export type LiquidGlassBackground = Omit<SliceLiquidGlassViewProps, 'cornerRadius' | 'removeClippedSubviews' | 'interactive'>;
11
+ /**
12
+ * Border radius exposed for components that apply it
13
+ */
14
+ export type BorderRadius = 'pill' | 'rectangular' | number;
@@ -0,0 +1,2 @@
1
+ export { lineHeightTextStyle } from './typography';
2
+ export { sizeToNumber, borderRadiusToNumber } from './sizes';
@@ -0,0 +1 @@
1
+ export { sizeToNumber, borderRadiusToNumber } from './sizes';
@@ -0,0 +1,7 @@
1
+ import type { BorderRadius, Size } from '../../types/sharedTypes';
2
+ /**
3
+ * Internal utility converting size props to an absolute number
4
+ */
5
+ export declare function sizeToNumber(size?: Size): number;
6
+ /** Resolve radius presets; invalid or negative values produce square corners. */
7
+ export declare function borderRadiusToNumber(borderRadius?: BorderRadius): number;
@@ -0,0 +1 @@
1
+ export { lineHeightTextStyle } from './typography';
@@ -0,0 +1,7 @@
1
+ import type { TextStyle } from 'react-native';
2
+ /**
3
+ * Simple utility to take text style and returns a defined line height factor
4
+ * Since there is no relative/percent in native, looks for the fontsize and
5
+ * derives an absolute line height from the font size
6
+ */
7
+ export declare function lineHeightTextStyle(styles: TextStyle, lineHeightFactor?: number): TextStyle;
package/package.json CHANGED
@@ -1,38 +1,66 @@
1
1
  {
2
2
  "name": "@apple-pie/slice-native",
3
- "version": "0.1.4",
4
- "description": "React Native icons and design tokens for Slice",
3
+ "version": "0.1.7",
4
+ "description": "React Native components, icons and design tokens for Slice",
5
5
  "author": "Uris Dacosta",
6
6
  "license": "ISC",
7
7
  "type": "commonjs",
8
8
  "main": "./dist/cjs/index.js",
9
9
  "module": "./dist/esm/index.mjs",
10
- "react-native": "./dist/esm/index.mjs",
11
- "types": "./dist/types/native/index.d.ts",
10
+ "react-native": "./dist/react-native/native/src/index.js",
11
+ "types": "./dist/types/native/src/index.d.ts",
12
12
  "exports": {
13
13
  ".": {
14
- "types": "./dist/types/native/index.d.ts",
15
- "react-native": "./dist/esm/index.mjs",
14
+ "types": "./dist/types/native/src/index.d.ts",
15
+ "react-native": "./dist/react-native/native/src/index.js",
16
16
  "import": "./dist/esm/index.mjs",
17
17
  "require": "./dist/cjs/index.js"
18
18
  },
19
19
  "./package.json": "./package.json",
20
20
  "./theme": {
21
- "types": "./dist/types/native/theme/index.d.ts",
22
- "react-native": "./dist/esm/theme.mjs",
21
+ "types": "./dist/types/native/src/theme/index.d.ts",
22
+ "react-native": "./dist/react-native/native/src/theme/index.js",
23
23
  "import": "./dist/esm/theme.mjs",
24
24
  "require": "./dist/cjs/theme.js"
25
+ },
26
+ "./components": {
27
+ "types": "./dist/types/native/src/components/index.d.ts",
28
+ "react-native": "./dist/react-native/native/src/components/index.js",
29
+ "import": "./dist/esm/components.mjs",
30
+ "require": "./dist/cjs/components.js"
31
+ },
32
+ "./hooks": {
33
+ "types": "./dist/types/native/src/hooks/index.d.ts",
34
+ "react-native": "./dist/react-native/native/src/hooks/index.js",
35
+ "import": "./dist/esm/hooks.mjs",
36
+ "require": "./dist/cjs/hooks.js"
37
+ },
38
+ "./providers": {
39
+ "types": "./dist/types/native/src/providers/index.d.ts",
40
+ "react-native": "./dist/react-native/native/src/providers/index.js",
41
+ "import": "./dist/esm/providers.mjs",
42
+ "require": "./dist/cjs/providers.js"
43
+ },
44
+ "./utils": {
45
+ "types": "./dist/types/native/src/utils/index.d.ts",
46
+ "react-native": "./dist/react-native/native/src/utils/index.js",
47
+ "import": "./dist/esm/utils.mjs",
48
+ "require": "./dist/cjs/utils.js"
25
49
  }
26
50
  },
27
- "files": ["dist"],
51
+ "files": ["dist", "platform", "src/specs", "SliceNative.podspec", "react-native.config.js"],
28
52
  "sideEffects": false,
29
53
  "scripts": {
30
54
  "test": "vitest run --config vitest.config.mts",
55
+ "test:package": "npm run build && node scripts/check-package.mjs",
56
+ "coverage": "vitest run --config vitest.config.mts --coverage",
31
57
  "lint": "biome format --write . && biome check . && npm run typecheck",
32
58
  "lint:ci": "biome ci . && npm run typecheck",
33
59
  "build": "npm run generate && node scripts/build.mjs",
60
+ "pack:tarball": "node scripts/pack.mjs",
61
+ "pack": "node scripts/pack.mjs",
34
62
  "prepack": "npm run build",
35
- "generate": "node scripts/generate-icons.mjs",
63
+ "generate": "node scripts/generate-icons.mjs && biome format --write src/components/SliceIcon/iconRegistry.tsx src/components/SliceIcon/icons.ts",
36
64
  "typecheck": "tsc --noEmit -p tsconfig.json"
37
65
  },
38
66
  "publishConfig": {
@@ -47,6 +75,24 @@
47
75
  "peerDependencies": {
48
76
  "react": "^18.0.0 || ^19.0.0",
49
77
  "react-native": ">=0.80.0 <1.0.0",
50
- "react-native-svg": "^15.0.0"
78
+ "react-native-svg": "^15.0.0",
79
+ "react-native-reanimated": "^4.0.0"
80
+ },
81
+ "codegenConfig": {
82
+ "name": "SliceNativeSpec",
83
+ "type": "all",
84
+ "jsSrcsDir": "src/specs",
85
+ "ios": {
86
+ "componentProvider": {
87
+ "SliceLiquidGlassView": "RCTLiquidGlassView",
88
+ "SliceBackgroundBlur": "RCTBackgroundBlurView"
89
+ },
90
+ "modulesProvider": {
91
+ "SliceDeviceCapabilities": "SliceDeviceCapabilities"
92
+ }
93
+ },
94
+ "android": {
95
+ "javaPackageName": "com.slice"
96
+ }
51
97
  }
52
98
  }
@@ -0,0 +1,22 @@
1
+ buildscript {
2
+ repositories { google(); mavenCentral() }
3
+ dependencies { classpath 'com.android.tools.build:gradle:8.7.3' }
4
+ }
5
+ apply plugin: 'com.android.library'
6
+ apply plugin: 'com.facebook.react'
7
+
8
+ react {
9
+ jsRootDir = file('../../src')
10
+ libraryName = 'SliceNativeSpec'
11
+ codegenJavaPackageName = 'com.slice'
12
+ }
13
+ android {
14
+ namespace 'com.slice'
15
+ compileSdkVersion rootProject.ext.has('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
16
+ defaultConfig {
17
+ minSdkVersion 24
18
+ targetSdkVersion rootProject.ext.has('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
19
+ }
20
+ }
21
+ repositories { google(); mavenCentral() }
22
+ dependencies { implementation 'com.facebook.react:react-android' }
@@ -0,0 +1 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" />
@@ -0,0 +1,28 @@
1
+ package com.slice;
2
+
3
+ import androidx.annotation.Nullable;
4
+ import com.facebook.react.uimanager.SimpleViewManager;
5
+ import com.facebook.react.uimanager.ThemedReactContext;
6
+ import com.facebook.react.uimanager.ViewManagerDelegate;
7
+ import com.facebook.react.uimanager.annotations.ReactProp;
8
+ import com.facebook.react.viewmanagers.SliceBackgroundBlurManagerDelegate;
9
+ import com.facebook.react.viewmanagers.SliceBackgroundBlurManagerInterface;
10
+
11
+ public final class SliceBackgroundBlurManager extends SimpleViewManager<SliceBackgroundBlurView>
12
+ implements SliceBackgroundBlurManagerInterface<SliceBackgroundBlurView> {
13
+ private final ViewManagerDelegate<SliceBackgroundBlurView> delegate = new SliceBackgroundBlurManagerDelegate<>(this);
14
+ @Override protected ViewManagerDelegate<SliceBackgroundBlurView> getDelegate() { return delegate; }
15
+ @Override public String getName() { return "SliceBackgroundBlur"; }
16
+ @Override protected SliceBackgroundBlurView createViewInstance(ThemedReactContext context) {
17
+ return new SliceBackgroundBlurView(context);
18
+ }
19
+ @Override @ReactProp(name = "blurIntensity", defaultDouble = 12)
20
+ public void setBlurIntensity(SliceBackgroundBlurView view, double value) { view.setIntensity(value); }
21
+ @Override @ReactProp(name = "fallbackColor", customType = "Color")
22
+ public void setFallbackColor(SliceBackgroundBlurView view, @Nullable Integer value) { view.setFallbackColor(value); }
23
+ // Directional fading is intentionally iOS-only.
24
+ @Override @ReactProp(name = "fadeStop", defaultDouble = 0)
25
+ public void setFadeStop(SliceBackgroundBlurView view, double value) {}
26
+ @Override @ReactProp(name = "direction")
27
+ public void setDirection(SliceBackgroundBlurView view, @Nullable String value) {}
28
+ }
@@ -0,0 +1,98 @@
1
+ package com.slice;
2
+
3
+ import android.content.Context;
4
+ import android.graphics.Canvas;
5
+ import android.graphics.Color;
6
+ import android.graphics.RenderEffect;
7
+ import android.graphics.RenderNode;
8
+ import android.graphics.Shader;
9
+ import android.os.Build;
10
+ import android.view.View;
11
+ import java.lang.reflect.Method;
12
+
13
+ /** Uniform, same-window backdrop blur. Older platforms draw only the fallback. */
14
+ public final class SliceBackgroundBlurView extends View {
15
+ private double intensity = 12;
16
+ private int fallbackColor = Color.argb(46, 128, 128, 128);
17
+ private BackdropRenderer renderer;
18
+
19
+ public SliceBackgroundBlurView(Context context) {
20
+ super(context);
21
+ setWillNotDraw(false);
22
+ // Resolve a public API at runtime to avoid requiring SDK 37.2 to build consumers.
23
+ // SDK_INT alone cannot distinguish Android's minor API releases.
24
+ if (supportsNativeBlur()) {
25
+ try {
26
+ renderer = new BackdropRenderer();
27
+ } catch (ReflectiveOperationException | LinkageError ignored) {
28
+ renderer = null;
29
+ }
30
+ }
31
+ }
32
+
33
+ static boolean supportsNativeBlur() {
34
+ if (Build.VERSION.SDK_INT < 37) return false;
35
+ try {
36
+ RenderNode.class.getMethod("setBackdropRenderEffect", RenderEffect.class);
37
+ return true;
38
+ } catch (ReflectiveOperationException | RuntimeException | LinkageError ignored) {
39
+ return false;
40
+ }
41
+ }
42
+
43
+ public void setIntensity(double value) {
44
+ intensity = Double.isFinite(value) ? Math.max(0, Math.min(100, value)) : 12;
45
+ invalidate();
46
+ }
47
+
48
+ public void setFallbackColor(Integer value) {
49
+ fallbackColor = value == null ? Color.argb(46, 128, 128, 128) : value;
50
+ invalidate();
51
+ }
52
+
53
+ @Override protected void onDraw(Canvas canvas) {
54
+ super.onDraw(canvas);
55
+ if (intensity == 0) return;
56
+ if (renderer != null && canvas.isHardwareAccelerated() && isHardwareAccelerated()) {
57
+ try {
58
+ float radius = (float) intensity * getResources().getDisplayMetrics().density;
59
+ renderer.draw(canvas, getWidth(), getHeight(), radius);
60
+ return;
61
+ } catch (ReflectiveOperationException | RuntimeException | LinkageError ignored) {
62
+ renderer = null;
63
+ }
64
+ }
65
+ canvas.drawColor(fallbackColor);
66
+ }
67
+
68
+ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
69
+ super.onSizeChanged(w, h, oldw, oldh);
70
+ if (renderer != null) renderer.node.discardDisplayList();
71
+ }
72
+
73
+ @Override protected void onDetachedFromWindow() {
74
+ if (renderer != null) renderer.node.discardDisplayList();
75
+ super.onDetachedFromWindow();
76
+ }
77
+
78
+ // Keep newer graphics classes out of the View's fields on older Android releases.
79
+ private static final class BackdropRenderer {
80
+ final RenderNode node = new RenderNode("SliceBackgroundBlur");
81
+ final Method setBackdropEffect;
82
+
83
+ BackdropRenderer() throws ReflectiveOperationException {
84
+ setBackdropEffect = RenderNode.class.getMethod("setBackdropRenderEffect", RenderEffect.class);
85
+ node.setClipToBounds(true);
86
+ }
87
+
88
+ void draw(Canvas canvas, int width, int height, float radius) throws ReflectiveOperationException {
89
+ setBackdropEffect.invoke(node, RenderEffect.createBlurEffect(radius, radius, Shader.TileMode.CLAMP));
90
+ node.setPosition(0, 0, width, height);
91
+ if (!node.hasDisplayList()) {
92
+ node.beginRecording(width, height);
93
+ node.endRecording();
94
+ }
95
+ canvas.drawRenderNode(node);
96
+ }
97
+ }
98
+ }
@@ -0,0 +1,25 @@
1
+ package com.slice;
2
+
3
+ import android.os.Build;
4
+ import com.facebook.react.bridge.ReactApplicationContext;
5
+ import com.facebook.react.module.annotations.ReactModule;
6
+ import java.util.HashMap;
7
+ import java.util.Map;
8
+
9
+ @ReactModule(name = SliceDeviceCapabilitiesModule.NAME)
10
+ public final class SliceDeviceCapabilitiesModule extends NativeDeviceCapabilitiesSpec {
11
+ public static final String NAME = "SliceDeviceCapabilities";
12
+
13
+ public SliceDeviceCapabilitiesModule(ReactApplicationContext context) { super(context); }
14
+
15
+ @Override public String getName() { return NAME; }
16
+
17
+ @Override protected Map<String, Object> getTypedExportedConstants() {
18
+ Map<String, Object> result = new HashMap<>();
19
+ result.put("supportsLiquidGlass", false);
20
+ result.put("supportsNativeBlur", SliceBackgroundBlurView.supportsNativeBlur());
21
+ result.put("deviceName", Build.MODEL);
22
+ result.put("deviceModel", Build.MODEL);
23
+ return result;
24
+ }
25
+ }
@@ -0,0 +1,25 @@
1
+ package com.slice;
2
+
3
+ import androidx.annotation.Nullable;
4
+ import com.facebook.react.BaseReactPackage;
5
+ import com.facebook.react.bridge.NativeModule;
6
+ import com.facebook.react.bridge.ReactApplicationContext;
7
+ import com.facebook.react.module.model.ReactModuleInfo;
8
+ import com.facebook.react.module.model.ReactModuleInfoProvider;
9
+ import com.facebook.react.uimanager.ViewManager;
10
+ import java.util.Collections;
11
+ import java.util.List;
12
+
13
+ public final class SlicePackage extends BaseReactPackage {
14
+ @Override @Nullable public NativeModule getModule(String name, ReactApplicationContext context) {
15
+ return SliceDeviceCapabilitiesModule.NAME.equals(name) ? new SliceDeviceCapabilitiesModule(context) : null;
16
+ }
17
+ @Override public ReactModuleInfoProvider getReactModuleInfoProvider() {
18
+ return () -> Collections.singletonMap(SliceDeviceCapabilitiesModule.NAME, new ReactModuleInfo(
19
+ SliceDeviceCapabilitiesModule.NAME, SliceDeviceCapabilitiesModule.NAME,
20
+ false, false, false, true));
21
+ }
22
+ @Override public List<ViewManager> createViewManagers(ReactApplicationContext context) {
23
+ return Collections.singletonList(new SliceBackgroundBlurManager());
24
+ }
25
+ }
@@ -0,0 +1,89 @@
1
+ import UIKit
2
+
3
+ @objc(SliceBackgroundBlurSurface)
4
+ public final class BackgroundBlurSurface: UIView {
5
+ private let effectView = UIVisualEffectView(effect: nil)
6
+ private var animator: UIViewPropertyAnimator?
7
+ private var intensity: Double = 12
8
+ private var fadeStop: Double = 0
9
+ private var direction = "down"
10
+ private var fallbackColor: UIColor = .secondarySystemBackground
11
+ private var observer: NSObjectProtocol?
12
+
13
+ public override init(frame: CGRect) {
14
+ super.init(frame: frame)
15
+ isUserInteractionEnabled = false
16
+ addSubview(effectView)
17
+ observer = NotificationCenter.default.addObserver(
18
+ forName: UIAccessibility.reduceTransparencyStatusDidChangeNotification,
19
+ object: nil, queue: .main
20
+ ) { [weak self] _ in
21
+ MainActor.assumeIsolated { self?.updateEffect() }
22
+ }
23
+ }
24
+
25
+ public required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
26
+
27
+ deinit {
28
+ animator?.stopAnimation(true)
29
+ if let observer { NotificationCenter.default.removeObserver(observer) }
30
+ }
31
+
32
+ @objc public func configure(intensity: Double, fadeStop: Double, direction: String, fallbackColor: UIColor?) {
33
+ self.intensity = intensity.isFinite ? min(100, max(0, intensity)) : 12
34
+ self.fadeStop = fadeStop.isFinite ? min(1, max(0, fadeStop)) : 0
35
+ self.direction = direction
36
+ self.fallbackColor = fallbackColor ?? .secondarySystemBackground
37
+ updateEffect()
38
+ setNeedsLayout()
39
+ }
40
+
41
+ public override func didMoveToWindow() {
42
+ super.didMoveToWindow()
43
+ updateEffect()
44
+ }
45
+
46
+ private func updateEffect() {
47
+ setNeedsLayout()
48
+ animator?.stopAnimation(true)
49
+ animator = nil
50
+ effectView.effect = nil
51
+ effectView.backgroundColor = .clear
52
+ if UIAccessibility.isReduceTransparencyEnabled {
53
+ effectView.backgroundColor = fallbackColor
54
+ } else if intensity > 0, window != nil {
55
+ let animator = UIViewPropertyAnimator(duration: 1, curve: .linear) { [weak self] in
56
+ self?.effectView.effect = UIBlurEffect(style: .regular)
57
+ }
58
+ animator.pausesOnCompletion = true
59
+ animator.startAnimation()
60
+ animator.pauseAnimation()
61
+ animator.fractionComplete = CGFloat(intensity / 100)
62
+ self.animator = animator
63
+ }
64
+ }
65
+
66
+ public override func layoutSubviews() {
67
+ super.layoutSubviews()
68
+ effectView.frame = bounds
69
+ guard fadeStop > 0, !UIAccessibility.isReduceTransparencyEnabled else {
70
+ effectView.mask = nil
71
+ return
72
+ }
73
+ // Mask the effect view directly, never its parent. Reassign after resizing
74
+ // so UIKit refreshes its internal copies of the mask.
75
+ let mask = UIView(frame: effectView.bounds)
76
+ let gradient = CAGradientLayer()
77
+ gradient.frame = mask.bounds
78
+ gradient.colors = [UIColor.clear.cgColor, UIColor.black.cgColor, UIColor.black.cgColor]
79
+ gradient.locations = [0, NSNumber(value: fadeStop), 1]
80
+ switch direction {
81
+ case "up": gradient.startPoint = CGPoint(x: 0.5, y: 1); gradient.endPoint = CGPoint(x: 0.5, y: 0)
82
+ case "left": gradient.startPoint = CGPoint(x: 1, y: 0.5); gradient.endPoint = CGPoint(x: 0, y: 0.5)
83
+ case "right": gradient.startPoint = CGPoint(x: 0, y: 0.5); gradient.endPoint = CGPoint(x: 1, y: 0.5)
84
+ default: gradient.startPoint = CGPoint(x: 0.5, y: 0); gradient.endPoint = CGPoint(x: 0.5, y: 1)
85
+ }
86
+ mask.layer.addSublayer(gradient)
87
+ effectView.mask = mask
88
+ }
89
+ }