@apple-pie/slice-native 0.1.6 → 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.
- package/README.md +138 -261
- package/SliceNative.podspec +24 -0
- package/dist/cjs/components.js +4 -0
- package/dist/cjs/hooks.js +2 -0
- package/dist/cjs/index.js +9 -0
- package/dist/cjs/src/components/SliceBackgroundBlur/SliceBackgroundBlur.js +11 -0
- package/dist/cjs/src/components/SliceButton/SliceButton.js +50 -23
- package/dist/cjs/src/components/SliceLiquidGlassView/SliceLiquidGlassView.js +12 -0
- package/dist/cjs/src/components/SliceTextInput/SliceTextInput.js +39 -9
- package/dist/cjs/src/hooks/useDeviceCapabilities/useDeviceCapabilities.js +19 -0
- package/dist/cjs/src/utils/sizes/sizes.js +40 -0
- package/dist/cjs/utils.js +3 -0
- package/dist/esm/components.mjs +2 -0
- package/dist/esm/hooks.mjs +1 -0
- package/dist/esm/index.mjs +4 -0
- package/dist/esm/src/components/SliceBackgroundBlur/SliceBackgroundBlur.mjs +9 -0
- package/dist/esm/src/components/SliceButton/SliceButton.mjs +50 -23
- package/dist/esm/src/components/SliceLiquidGlassView/SliceLiquidGlassView.mjs +10 -0
- package/dist/esm/src/components/SliceTextInput/SliceTextInput.mjs +39 -9
- package/dist/esm/src/hooks/useDeviceCapabilities/useDeviceCapabilities.mjs +17 -0
- package/dist/esm/src/utils/sizes/sizes.mjs +37 -0
- package/dist/esm/utils.mjs +1 -0
- package/dist/react-native/native/src/components/SliceBackgroundBlur/SliceBackgroundBlur.js +6 -0
- package/dist/react-native/native/src/components/SliceBackgroundBlur/SliceBackgroundBlur.native.js +6 -0
- package/dist/react-native/native/src/components/SliceBackgroundBlur/_types.js +1 -0
- package/dist/react-native/native/src/components/SliceBackgroundBlur/index.js +1 -0
- package/dist/react-native/native/src/components/SliceButton/SliceButton.js +141 -0
- package/dist/react-native/native/src/components/SliceButton/_types.js +1 -0
- package/dist/react-native/native/src/components/SliceButton/index.js +1 -0
- package/dist/react-native/native/src/components/SliceIcon/SliceIcon.js +15 -0
- package/dist/react-native/native/src/components/SliceIcon/_types.js +1 -0
- package/dist/react-native/native/src/components/SliceIcon/iconRegistry.js +663 -0
- package/dist/react-native/native/src/components/SliceIcon/icons.js +140 -0
- package/dist/react-native/native/src/components/SliceIcon/index.js +2 -0
- package/dist/react-native/native/src/components/SliceLiquidGlassView/SliceLiquidGlassView.ios.js +6 -0
- package/dist/react-native/native/src/components/SliceLiquidGlassView/SliceLiquidGlassView.js +7 -0
- package/dist/react-native/native/src/components/SliceLiquidGlassView/_types.js +1 -0
- package/dist/react-native/native/src/components/SliceLiquidGlassView/index.js +1 -0
- package/dist/react-native/native/src/components/SliceText/SliceText.js +16 -0
- package/dist/react-native/native/src/components/SliceText/_types.js +1 -0
- package/dist/react-native/native/src/components/SliceText/index.js +1 -0
- package/dist/react-native/native/src/components/SliceTextInput/SliceTextInput.js +111 -0
- package/dist/react-native/native/src/components/SliceTextInput/_types.js +1 -0
- package/dist/react-native/native/src/components/SliceTextInput/index.js +1 -0
- package/dist/react-native/native/src/components/index.js +6 -0
- package/dist/react-native/native/src/hooks/index.js +2 -0
- package/dist/react-native/native/src/hooks/useCreateThemedStyles/index.js +1 -0
- package/dist/react-native/native/src/hooks/useCreateThemedStyles/useCreateThemedStyles.js +8 -0
- package/dist/react-native/native/src/hooks/useDeviceCapabilities/_types.js +1 -0
- package/dist/react-native/native/src/hooks/useDeviceCapabilities/index.js +1 -0
- package/dist/react-native/native/src/hooks/useDeviceCapabilities/useDeviceCapabilities.js +14 -0
- package/dist/react-native/native/src/hooks/useDeviceCapabilities/useDeviceCapabilities.native.js +23 -0
- package/dist/react-native/native/src/index.js +6 -0
- package/dist/react-native/native/src/providers/SliceThemeProvider.js +30 -0
- package/dist/react-native/native/src/providers/index.js +1 -0
- package/dist/react-native/native/src/specs/BackgroundBlurNativeComponent.ts +16 -0
- package/dist/react-native/native/src/specs/LiquidGlassNativeComponent.ts +18 -0
- package/dist/react-native/native/src/specs/NativeDeviceCapabilities.ts +13 -0
- package/dist/react-native/native/src/theme/index.js +69 -0
- package/dist/react-native/native/src/theme/motion.js +43 -0
- package/dist/react-native/native/src/types/index.js +1 -0
- package/dist/react-native/native/src/types/sharedTypes.js +1 -0
- package/dist/react-native/native/src/utils/index.js +2 -0
- package/dist/react-native/native/src/utils/sizes/index.js +1 -0
- package/dist/react-native/native/src/utils/sizes/sizes.js +35 -0
- package/dist/react-native/native/src/utils/typography/index.js +1 -0
- package/dist/react-native/native/src/utils/typography/typography.js +13 -0
- package/dist/react-native/src/theme/colors/colors.js +385 -0
- package/dist/react-native/src/theme/colors/types.js +1 -0
- package/dist/react-native/src/theme/corners/corners.js +10 -0
- package/dist/react-native/src/theme/corners/types.js +1 -0
- package/dist/react-native/src/theme/elevations/_types.js +1 -0
- package/dist/react-native/src/theme/elevations/elevations.js +13 -0
- package/dist/react-native/src/theme/motion/_types.js +1 -0
- package/dist/react-native/src/theme/motion/motion.js +11 -0
- package/dist/react-native/src/theme/spacing/_types.js +1 -0
- package/dist/react-native/src/theme/spacing/spacing.js +10 -0
- package/dist/react-native/src/theme/type/type.js +371 -0
- package/dist/react-native/src/theme/type/types.js +1 -0
- package/dist/types/native/src/components/SliceBackgroundBlur/SliceBackgroundBlur.d.ts +3 -0
- package/dist/types/native/src/components/SliceBackgroundBlur/SliceBackgroundBlur.native.d.ts +2 -0
- package/dist/types/native/src/components/SliceBackgroundBlur/_types.d.ts +24 -0
- package/dist/types/native/src/components/SliceBackgroundBlur/index.d.ts +2 -0
- package/dist/types/native/src/components/SliceButton/_types.d.ts +33 -2
- package/dist/types/native/src/components/SliceLiquidGlassView/SliceLiquidGlassView.d.ts +3 -0
- package/dist/types/native/src/components/SliceLiquidGlassView/SliceLiquidGlassView.ios.d.ts +2 -0
- package/dist/types/native/src/components/SliceLiquidGlassView/_types.d.ts +17 -0
- package/dist/types/native/src/components/SliceLiquidGlassView/index.d.ts +2 -0
- package/dist/types/native/src/components/SliceTextInput/_types.d.ts +23 -1
- package/dist/types/native/src/components/index.d.ts +4 -0
- package/dist/types/native/src/hooks/index.d.ts +2 -0
- package/dist/types/native/src/hooks/useDeviceCapabilities/_types.d.ts +17 -0
- package/dist/types/native/src/hooks/useDeviceCapabilities/index.d.ts +2 -0
- package/dist/types/native/src/hooks/useDeviceCapabilities/useDeviceCapabilities.d.ts +3 -0
- package/dist/types/native/src/hooks/useDeviceCapabilities/useDeviceCapabilities.native.d.ts +7 -0
- package/dist/types/native/src/index.d.ts +12 -0
- package/dist/types/native/src/specs/BackgroundBlurNativeComponent.d.ts +9 -0
- package/dist/types/native/src/specs/LiquidGlassNativeComponent.d.ts +9 -0
- package/dist/types/native/src/specs/NativeDeviceCapabilities.d.ts +11 -0
- package/dist/types/native/src/types/index.d.ts +1 -0
- package/dist/types/native/src/types/sharedTypes.d.ts +14 -0
- package/dist/types/native/src/utils/index.d.ts +1 -0
- package/dist/types/native/src/utils/sizes/index.d.ts +1 -0
- package/dist/types/native/src/utils/sizes/sizes.d.ts +7 -0
- package/package.json +30 -13
- package/platform/android/build.gradle +22 -0
- package/platform/android/src/main/AndroidManifest.xml +1 -0
- package/platform/android/src/main/java/com/slice/SliceBackgroundBlurManager.java +28 -0
- package/platform/android/src/main/java/com/slice/SliceBackgroundBlurView.java +98 -0
- package/platform/android/src/main/java/com/slice/SliceDeviceCapabilitiesModule.java +25 -0
- package/platform/android/src/main/java/com/slice/SlicePackage.java +25 -0
- package/platform/ios/BackgroundBlurSurface.swift +89 -0
- package/platform/ios/LiquidGlassSurface.swift +82 -0
- package/platform/ios/RCTBackgroundBlurView.h +3 -0
- package/platform/ios/RCTBackgroundBlurView.mm +42 -0
- package/platform/ios/RCTLiquidGlassView.h +8 -0
- package/platform/ios/RCTLiquidGlassView.mm +73 -0
- package/platform/ios/SliceDeviceCapabilities.h +4 -0
- package/platform/ios/SliceDeviceCapabilities.mm +35 -0
- package/react-native.config.js +1 -0
- package/src/specs/BackgroundBlurNativeComponent.ts +16 -0
- package/src/specs/LiquidGlassNativeComponent.ts +18 -0
- package/src/specs/NativeDeviceCapabilities.ts +13 -0
- package/dist/types/native/index.d.ts +0 -8
package/README.md
CHANGED
|
@@ -1,310 +1,187 @@
|
|
|
1
1
|
# @apple-pie/slice-native
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Includes native light/dark theme tokens and a theme provider.
|
|
5
|
-
It is built and published independently
|
|
6
|
-
of `@apple-pie/slice` and does not require that package at runtime.
|
|
3
|
+
**Alpha software — APIs, styling, and platform behavior may change between releases.**
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<SliceIcon
|
|
12
|
-
name={SliceIcons.ui.home}
|
|
13
|
-
size={24}
|
|
14
|
-
strokeColor="#334155"
|
|
15
|
-
accessibilityLabel="Go home"
|
|
16
|
-
onPress={() => navigation.navigate('Home')}
|
|
17
|
-
/>
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Supply native SVG props and
|
|
21
|
-
native `style` objects; use `onPress` instead of `onClick`. CSS classes, cursor
|
|
22
|
-
styling (`pointer`), and browser keyboard handlers are not part of this API.
|
|
23
|
-
Use an enclosing React Native `Pressable` when you need a larger touch target or
|
|
24
|
-
button feedback, and mark the icon `accessible={false}` when it is decorative.
|
|
25
|
-
|
|
26
|
-
Defaults are 20×20, stroke width 1.5, and black/white colors based on the system
|
|
27
|
-
color scheme. Pass `strokeColor` and `coverUp` explicitly to match an app theme.
|
|
28
|
-
`fillColor` retains the web API's meaning: **opacity from 0 to 1**, not a color.
|
|
29
|
-
`fill` enables that opacity (default 0.125 in light mode, 0.2 in dark mode).
|
|
30
|
-
`toggle` selects the on variant when available; unknown names render nothing.
|
|
31
|
-
`disabled` blocks press callbacks and halves the specified opacity.
|
|
32
|
-
|
|
33
|
-
The package requires React, React Native, and react-native-svg as peers. Install
|
|
34
|
-
the native SVG dependency in the consuming app using its normal native/Expo setup.
|
|
35
|
-
|
|
36
|
-
## Development
|
|
37
|
-
|
|
38
|
-
The package manifest and entry point live in `native/`. Icon components, types,
|
|
39
|
-
generated artwork, and tests live in `native/src/components/SliceIcon/`.
|
|
40
|
-
|
|
41
|
-
From this directory, run `npm run generate` after changing the web icon registry
|
|
42
|
-
or `SliceIcons` constants. Generated files contain native SVG components and have
|
|
43
|
-
no runtime imports from the web UIKit. Run `npm run typecheck` with the peer
|
|
44
|
-
dependencies installed and TypeScript available from the repository.
|
|
45
|
-
|
|
46
|
-
From the repository root:
|
|
47
|
-
|
|
48
|
-
```sh
|
|
49
|
-
npm install
|
|
50
|
-
npm install --prefix native
|
|
51
|
-
npm run lint --prefix native
|
|
52
|
-
npm test --prefix native
|
|
53
|
-
npm run build --prefix native
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
The build refreshes generated icons, checks types, and produces `dist/cjs/index.js`,
|
|
57
|
-
`dist/esm/index.mjs`, and declarations under `dist/types`. React, React Native, and
|
|
58
|
-
react-native-svg stay external peer dependencies. The web build is independent.
|
|
59
|
-
|
|
60
|
-
Native tests use their own `vitest.config.mts` and mocked native components. Install native
|
|
61
|
-
dependencies before running them. Root tests and coverage do not include the native package;
|
|
62
|
-
passing the native unit tests does not replace device rendering checks.
|
|
63
|
-
|
|
64
|
-
### Native coverage
|
|
5
|
+
A React Native UI kit with themed components, SVG icons, native blur, and Liquid Glass.
|
|
6
|
+
It shares Slice’s visual language with the web UIKit, but is packaged independently
|
|
7
|
+
and does not require `@apple-pie/slice` at runtime.
|
|
65
8
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
This runs only the native tests and measures runtime TypeScript in native components,
|
|
73
|
-
providers, theme modules, and the package entry point, including generated icon artwork.
|
|
74
|
-
Tests and type-only files are excluded. Shared web sources, build scripts, and dependencies
|
|
75
|
-
are outside this report. Files without tests are included in the coverage calculation.
|
|
76
|
-
|
|
77
|
-
Open `native/coverage/index.html` for the interactive report. The command also prints
|
|
78
|
-
a terminal summary and writes `native/coverage/lcov.info` and
|
|
79
|
-
`native/coverage/coverage-summary.json` for tooling. Reports are ignored by Git.
|
|
80
|
-
The coverage provider comes from the repository's existing `@vitest/coverage-v8`
|
|
81
|
-
development dependency; install both root and native dependencies as described above.
|
|
82
|
-
|
|
83
|
-
CI runs these checks independently in **Slice Native Lint, Build, Test** on Node 24.
|
|
84
|
-
It uses `npm run lint:ci --prefix native` to check formatting and types without writing
|
|
85
|
-
fixes, then runs native tests, builds, and inspects the package contents. Root dependencies
|
|
86
|
-
provide shared tooling such as Biome; native dependencies are installed separately.
|
|
87
|
-
|
|
88
|
-
Run `npm pack --dry-run` from `native/` to inspect the publishable files, or
|
|
89
|
-
`npm pack` to create a tarball. The `prepack` hook builds automatically. Build and
|
|
90
|
-
pack from this repository: generation uses the web artwork in `src/components/Icon`.
|
|
91
|
-
|
|
92
|
-
To build a local installable tarball without publishing to npm, run from the repository root:
|
|
93
|
-
|
|
94
|
-
```sh
|
|
95
|
-
npm run pack:tarball --prefix native
|
|
96
|
-
```
|
|
9
|
+
**Blur, gradient masking, Liquid Glass, and device capability detection are built
|
|
10
|
+
into this package and connected directly to native platform code.** No additional
|
|
11
|
+
blur, gradient, masking, or glass libraries are required—including `expo-blur`,
|
|
12
|
+
`expo-linear-gradient`, and `@react-native-masked-view/masked-view`.
|
|
97
13
|
|
|
98
|
-
|
|
99
|
-
The `pack/` directory is ignored by Git. Install the archive in another project:
|
|
14
|
+
## Installation
|
|
100
15
|
|
|
101
16
|
```sh
|
|
102
|
-
npm install
|
|
17
|
+
npm install @apple-pie/slice-native
|
|
103
18
|
```
|
|
104
19
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
## Theme tokens
|
|
111
|
-
|
|
112
|
-
### Buttons
|
|
20
|
+
Configure the package’s peer dependencies in your app: React 18/19, React Native
|
|
21
|
+
0.80+, `react-native-svg` 15, and Reanimated 4 with its compatible Worklets setup.
|
|
22
|
+
For Expo projects, use `npx expo install` for native peers to select compatible versions.
|
|
23
|
+
These general UI dependencies are separate from the built-in native visual effects.
|
|
113
24
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
Supply an `accessibilityLabel` for icon-only buttons; button icons are decorative.
|
|
119
|
-
|
|
120
|
-
```tsx
|
|
121
|
-
import { SliceButton, SliceThemeProvider } from '@apple-pie/slice-native';
|
|
122
|
-
|
|
123
|
-
<SliceThemeProvider>
|
|
124
|
-
<SliceButton icon="home" onPress={() => navigation.navigate('Home')}>
|
|
125
|
-
Go home
|
|
126
|
-
</SliceButton>
|
|
127
|
-
</SliceThemeProvider>
|
|
128
|
-
```
|
|
25
|
+
Native components require the New Architecture. iOS builds require Xcode 26+.
|
|
26
|
+
Install iOS pods and rebuild your app after installing or updating the package.
|
|
27
|
+
Expo apps need a development build; the custom native components are not available
|
|
28
|
+
in Expo Go. Restarting Metro alone does not register new native code.
|
|
129
29
|
|
|
130
|
-
|
|
30
|
+
## Quick start
|
|
131
31
|
|
|
132
32
|
```tsx
|
|
133
|
-
import {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
`preference` and `onPreferenceChange`; the app owns updating and persisting that
|
|
143
|
-
value. `useSliceContext` exposes `theme`, `mode`, `preference`, and the optional
|
|
144
|
-
`setPreference` callback. Both hooks require a surrounding `SliceThemeProvider`.
|
|
145
|
-
Use this exported provider and its hooks together so app and library components
|
|
146
|
-
share the same context.
|
|
147
|
-
|
|
148
|
-
```tsx
|
|
149
|
-
import { Text, View, useColorScheme } from 'react-native';
|
|
150
|
-
import { lightTheme, darkTheme } from '@apple-pie/slice-native/theme';
|
|
151
|
-
|
|
152
|
-
function Card() {
|
|
153
|
-
const theme = useColorScheme() === 'dark' ? darkTheme : lightTheme;
|
|
33
|
+
import { View } from 'react-native';
|
|
34
|
+
import {
|
|
35
|
+
SliceButton,
|
|
36
|
+
SliceIcons,
|
|
37
|
+
SliceTextInput,
|
|
38
|
+
SliceThemeProvider,
|
|
39
|
+
} from '@apple-pie/slice-native';
|
|
40
|
+
|
|
41
|
+
export default function App() {
|
|
154
42
|
return (
|
|
155
|
-
<
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
</Text>
|
|
164
|
-
</View>
|
|
43
|
+
<SliceThemeProvider>
|
|
44
|
+
<View style={{ padding: 24, gap: 16 }}>
|
|
45
|
+
<SliceTextInput accessibilityLabel="Search tasks" placeholder="Search…" />
|
|
46
|
+
<SliceButton icon={SliceIcons.ui.home} onPress={() => console.log('Home')}>
|
|
47
|
+
Go home
|
|
48
|
+
</SliceButton>
|
|
49
|
+
</View>
|
|
50
|
+
</SliceThemeProvider>
|
|
165
51
|
);
|
|
166
52
|
}
|
|
167
53
|
```
|
|
168
54
|
|
|
169
|
-
|
|
170
|
-
also available from the package root. `SliceTheme` aliases the native theme type.
|
|
171
|
-
The dedicated `/theme` entry has no runtime React Native, React, or SVG imports.
|
|
172
|
-
It also exports `coreColors`, `corners`, `spacing`, `elevations`, `type`, and `motion`.
|
|
55
|
+
## Components
|
|
173
56
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
57
|
+
| Component | Summary |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| `SliceButton` | Primary/secondary buttons, optional icons, disabled states, Reanimated transitions, and optional Liquid Glass backgrounds. |
|
|
60
|
+
| `SliceTextInput` | Themed native input with icons, optional focus control, focus callbacks, and opt-in clearing on blur. |
|
|
61
|
+
| `StyledText` | Theme-based typography presets with native text props. |
|
|
62
|
+
| `SliceIcon` / `SliceIcons` | Native SVG artwork and typed icon names shared with the web UIKit. Supports toggles, fills, sizing, and press handlers. |
|
|
63
|
+
| `SliceLiquidGlassView` | Native glass container with children, tint, interaction feedback, and rounded corners. |
|
|
64
|
+
| `SliceBackgroundBlur` | Background blur overlay with an optional directional fade on iOS. |
|
|
179
65
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
`
|
|
183
|
-
|
|
66
|
+
Buttons and inputs support `size` (`s`, `m`, `l`, or a number), `borderRadius`
|
|
67
|
+
(`pill`, `rectangular`, or a number), `borderWidth`, `borderColor`, and
|
|
68
|
+
`backgroundColor`. Sizes define minimum heights, allowing room for larger text.
|
|
69
|
+
Inputs forward `style` to the underlying text field. Buttons expose `animatedStyle`
|
|
70
|
+
for their wrapper.
|
|
184
71
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
values to Android's `elevation` property.
|
|
72
|
+
`SliceButton`, `SliceTextInput`, and `StyledText` use `SliceThemeProvider`. Give
|
|
73
|
+
inputs and icon-only buttons an accessible name. Icons inside these components
|
|
74
|
+
are decorative; standalone icons can use `accessibilityLabel` and `onPress`.
|
|
75
|
+
For `SliceIcon`, `fillColor` means fill opacity, not a color value.
|
|
190
76
|
|
|
191
|
-
|
|
192
|
-
JavaScript and declarations are included under `dist/`, including declarations for
|
|
193
|
-
shared source types. Changes to web tokens are picked up by the next native build.
|
|
77
|
+
### Built-in Liquid Glass and blur
|
|
194
78
|
|
|
195
|
-
|
|
79
|
+
| Effect | iOS | Android | Web |
|
|
80
|
+
| --- | --- | --- | --- |
|
|
81
|
+
| `SliceLiquidGlassView` | Native Liquid Glass on iOS 26+; system blur on older iOS. | Tinted color fallback. | Tinted color fallback. |
|
|
82
|
+
| `SliceBackgroundBlur` | Native backdrop blur; optional directional fade. | Uniform backdrop blur when the required API is present (SDK 37.2+) and hardware acceleration is available; otherwise a color fallback. | Color fallback. |
|
|
196
83
|
|
|
197
|
-
|
|
84
|
+
The implementations ship with the package: Swift/UIKit and Fabric on iOS, and Java
|
|
85
|
+
platform code on Android. Consumers do not need to install another effects library.
|
|
86
|
+
iOS respects Reduce Transparency and renders a fallback when it is enabled.
|
|
198
87
|
|
|
199
88
|
```tsx
|
|
200
|
-
import {
|
|
201
|
-
import { useCreateThemedStyles, type SliceNativeTheme } from '@apple-pie/slice-native';
|
|
202
|
-
|
|
203
|
-
const createStyles = (theme: SliceNativeTheme) => StyleSheet.create({
|
|
204
|
-
container: {
|
|
205
|
-
backgroundColor: theme.colors['core-surface-primary'],
|
|
206
|
-
padding: theme.spacing.m,
|
|
207
|
-
},
|
|
208
|
-
divider: { height: 1 }, // Styles do not have to use the theme.
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
function Card() {
|
|
212
|
-
const styles = useCreateThemedStyles(createStyles);
|
|
213
|
-
return <View style={styles.container} />;
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
The component must be inside `SliceThemeProvider`. Style keys and property types
|
|
218
|
-
are inferred from the factory return value. The hook recalculates when the theme
|
|
219
|
-
or factory changes; an inline factory works but is recreated every render. If
|
|
220
|
-
styles depend on component props, wrap the factory in `useCallback` with those
|
|
221
|
-
props in its dependency list. The hook accepts ordinary native style objects too;
|
|
222
|
-
calling `StyleSheet.create` inside the factory is optional.
|
|
223
|
-
|
|
224
|
-
## Typography utility
|
|
89
|
+
import { SliceBackgroundBlur, SliceLiquidGlassView } from '@apple-pie/slice-native';
|
|
225
90
|
|
|
226
|
-
|
|
91
|
+
// Place over background content; fills its parent by default.
|
|
92
|
+
<SliceBackgroundBlur blurIntensity={20} fadeStop={0.5} direction="down" />
|
|
227
93
|
|
|
228
|
-
|
|
229
|
-
|
|
94
|
+
<SliceLiquidGlassView cornerRadius={24} glassStyle="regular" style={{ padding: 20 }}>
|
|
95
|
+
{/* Foreground content */}
|
|
96
|
+
</SliceLiquidGlassView>
|
|
230
97
|
|
|
231
|
-
|
|
232
|
-
|
|
98
|
+
<SliceButton liquidGlassBackground={{ glassStyle: 'clear', fallbackColor: '#eeeeee' }}>
|
|
99
|
+
Continue
|
|
100
|
+
</SliceButton>
|
|
233
101
|
```
|
|
234
102
|
|
|
235
|
-
|
|
236
|
-
|
|
103
|
+
Blur defaults to intensity `12` and `fadeStop={0}`, which renders uniform blur
|
|
104
|
+
without a mask. A positive `fadeStop` (0–1) enables fading on iOS. Directions are
|
|
105
|
+
`down`, `up`, `left`, and `right`, from transparent toward full blur. Android
|
|
106
|
+
ignores fading props. This fades the visibility of a uniform blur rather than
|
|
107
|
+
varying the blur radius across the view.
|
|
108
|
+
|
|
109
|
+
Use `cornerRadius` to control a glass container’s shape. Supported glass buttons
|
|
110
|
+
keep their background transparent; unsupported devices use their solid background
|
|
111
|
+
or configured fallback. Both effect components accept `fallbackColor`. Avoid opaque
|
|
112
|
+
content over glass when you want the backdrop to remain visible. Android backdrop
|
|
113
|
+
blur samples the same window; separately composed surfaces such as video may differ.
|
|
237
114
|
|
|
238
|
-
##
|
|
115
|
+
## Hooks, provider, and theme
|
|
239
116
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
117
|
+
| Export | Purpose |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| `SliceThemeProvider` | Light/dark themes; follows the system by default. Use `preference="light"` or `"dark"` to override. |
|
|
120
|
+
| `useSliceTheme()` | Returns the active theme. |
|
|
121
|
+
| `useSliceContext()` | Returns the theme, mode, preference, and optional preference setter. |
|
|
122
|
+
| `useCreateThemedStyles(factory)` | Creates memoized styles from the active theme. Define the factory outside the component for stable reuse. |
|
|
123
|
+
| `useDeviceCapabilities()` | Reports native effect support, platform, OS/API version, and device information. Does not require the theme provider. |
|
|
243
124
|
|
|
244
125
|
```tsx
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
126
|
+
const {
|
|
127
|
+
supportsLiquidGlass,
|
|
128
|
+
supportsNativeBlur,
|
|
129
|
+
platform,
|
|
130
|
+
iosVersion,
|
|
131
|
+
androidSdkVersion,
|
|
132
|
+
deviceName,
|
|
133
|
+
deviceModel,
|
|
134
|
+
} = useDeviceCapabilities();
|
|
254
135
|
```
|
|
255
136
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
137
|
+
Capability flags describe API availability, not live accessibility settings or
|
|
138
|
+
per-view rendering conditions. They return `false` when the native module is absent.
|
|
139
|
+
`iosVersion` is a full version string; `androidSdkVersion` is an integer API level
|
|
140
|
+
without minor-release information. Use the support flags for effects decisions.
|
|
141
|
+
Unavailable fields are `null`. iOS device names may be generic; its model is a
|
|
142
|
+
hardware identifier such as `iPhone17,1`, not a marketing name. Android reports
|
|
143
|
+
the system model name/code.
|
|
260
144
|
|
|
261
|
-
`
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
on mount.
|
|
145
|
+
`lightTheme`, `darkTheme`, and `createTypography` are exported alongside theme types.
|
|
146
|
+
Themes include colors, spacing, corners, typography, shadows, stacking levels, and
|
|
147
|
+
motion. The `/theme` entry also exposes the underlying token groups. Typography
|
|
148
|
+
uses Funnel Sans by default; load it in your app or use `createTypography` with
|
|
149
|
+
your own loaded font. Fonts are not loaded by the package.
|
|
267
150
|
|
|
268
|
-
##
|
|
151
|
+
## Utilities and entry points
|
|
269
152
|
|
|
270
|
-
|
|
153
|
+
| Utility | Purpose |
|
|
154
|
+
| --- | --- |
|
|
155
|
+
| `sizeToNumber(size)` | Resolves size presets to points: `s` = 40, `m` = 48, `l` = 56. |
|
|
156
|
+
| `borderRadiusToNumber(radius)` | Resolves `pill` to 1000, `rectangular` to 4, and numeric radii to nonnegative points. |
|
|
157
|
+
| `lineHeightTextStyle(style, multiplier)` | Returns a new text style with an absolute line height. |
|
|
271
158
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
import { useCreateThemedStyles } from '@apple-pie/slice-native/hooks';
|
|
275
|
-
import { SliceThemeProvider } from '@apple-pie/slice-native/providers';
|
|
276
|
-
import { lineHeightTextStyle } from '@apple-pie/slice-native/utils';
|
|
277
|
-
import { lightTheme, darkTheme } from '@apple-pie/slice-native/theme';
|
|
278
|
-
```
|
|
159
|
+
Public types include `Size`, `BorderRadius`, `LiquidGlassBackground`,
|
|
160
|
+
`DeviceCapabilities`, component props, and theme/provider types.
|
|
279
161
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
CommonJS consumers should not assume the same elimination as ESM consumers.
|
|
285
|
-
The theme and utility entry points do not import React, SVG, or Reanimated at runtime.
|
|
162
|
+
Import from the package root or the dedicated `/components`, `/hooks`, `/providers`,
|
|
163
|
+
`/theme`, and `/utils` entry points. ESM, CommonJS, TypeScript declarations, and
|
|
164
|
+
Metro platform files are included. Theme tokens and utilities can be used independently
|
|
165
|
+
of the component runtime.
|
|
286
166
|
|
|
287
|
-
|
|
288
|
-
representative ESM consumer bundles. These checks verify that selecting only the
|
|
289
|
-
line-height utility removes other package code and that hooks do not pull in SVG
|
|
290
|
-
or Reanimated.
|
|
291
|
-
|
|
292
|
-
## Native Storybook (browser documentation)
|
|
167
|
+
## Development
|
|
293
168
|
|
|
294
|
-
From the repository root
|
|
169
|
+
From the repository root:
|
|
295
170
|
|
|
296
171
|
```sh
|
|
297
|
-
npm
|
|
298
|
-
npm
|
|
299
|
-
npm run
|
|
172
|
+
npm install
|
|
173
|
+
npm install --prefix native
|
|
174
|
+
npm run lint:ci --prefix native
|
|
175
|
+
npm run coverage --prefix native
|
|
176
|
+
npm run test:package --prefix native
|
|
177
|
+
npm run pack:tarball --prefix native
|
|
300
178
|
```
|
|
301
179
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
and Reanimated's web implementation render the actual components; these are not
|
|
307
|
-
native-platform screenshots. Browser stories supplement device testing.
|
|
180
|
+
Builds regenerate and automatically format native icons from the shared web artwork,
|
|
181
|
+
check types, and emit the package distributions. The tarball is written to
|
|
182
|
+
`native/pack/apple-pie-slice-native-<version>.tgz`; reinstall it and rebuild the
|
|
183
|
+
consuming native app when testing platform changes.
|
|
308
184
|
|
|
309
|
-
|
|
310
|
-
|
|
185
|
+
Browser documentation runs with `npm run storybook:native` from the repository root.
|
|
186
|
+
It previews web fallbacks; native effects need simulator/device checks. Native unit
|
|
187
|
+
coverage enforces a 95% overall threshold and does not measure Swift/Java rendering.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'SliceNative'
|
|
7
|
+
s.module_name = 'SliceNative'
|
|
8
|
+
s.version = package['version']
|
|
9
|
+
s.summary = package['description']
|
|
10
|
+
s.homepage = 'https://github.com/uris/slice'
|
|
11
|
+
s.license = package['license']
|
|
12
|
+
s.authors = package['author']
|
|
13
|
+
s.source = { :git => 'https://github.com/uris/slice.git', :tag => "native-v#{s.version}" }
|
|
14
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
15
|
+
s.swift_version = '5.0'
|
|
16
|
+
s.requires_arc = true
|
|
17
|
+
s.source_files = 'platform/ios/**/*.{h,m,mm,swift}'
|
|
18
|
+
# Keep C++ React headers out of the module imported by the Swift compiler.
|
|
19
|
+
s.private_header_files = 'platform/ios/RCT*View.h', 'platform/ios/SliceDeviceCapabilities.h'
|
|
20
|
+
s.frameworks = 'UIKit'
|
|
21
|
+
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
|
|
22
|
+
|
|
23
|
+
install_modules_dependencies(s)
|
|
24
|
+
end
|
package/dist/cjs/components.js
CHANGED
|
@@ -5,6 +5,8 @@ var icons = require('./src/components/SliceIcon/icons.js');
|
|
|
5
5
|
var SliceText = require('./src/components/SliceText/SliceText.js');
|
|
6
6
|
var SliceButton = require('./src/components/SliceButton/SliceButton.js');
|
|
7
7
|
var SliceTextInput = require('./src/components/SliceTextInput/SliceTextInput.js');
|
|
8
|
+
var SliceLiquidGlassView = require('./src/components/SliceLiquidGlassView/SliceLiquidGlassView.js');
|
|
9
|
+
var SliceBackgroundBlur = require('./src/components/SliceBackgroundBlur/SliceBackgroundBlur.js');
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
|
|
@@ -13,3 +15,5 @@ exports.SliceIcons = icons.SliceIcons;
|
|
|
13
15
|
exports.StyledText = SliceText.StyledText;
|
|
14
16
|
exports.SliceButton = SliceButton.SliceButton;
|
|
15
17
|
exports.SliceTextInput = SliceTextInput.SliceTextInput;
|
|
18
|
+
exports.SliceLiquidGlassView = SliceLiquidGlassView.SliceLiquidGlassView;
|
|
19
|
+
exports.SliceBackgroundBlur = SliceBackgroundBlur.SliceBackgroundBlur;
|
package/dist/cjs/hooks.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var useCreateThemedStyles = require('./src/hooks/useCreateThemedStyles/useCreateThemedStyles.js');
|
|
4
|
+
var useDeviceCapabilities = require('./src/hooks/useDeviceCapabilities/useDeviceCapabilities.js');
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
exports.useCreateThemedStyles = useCreateThemedStyles.useCreateThemedStyles;
|
|
9
|
+
exports.useDeviceCapabilities = useDeviceCapabilities.useDeviceCapabilities;
|
package/dist/cjs/index.js
CHANGED
|
@@ -5,10 +5,14 @@ var icons = require('./src/components/SliceIcon/icons.js');
|
|
|
5
5
|
var SliceText = require('./src/components/SliceText/SliceText.js');
|
|
6
6
|
var SliceButton = require('./src/components/SliceButton/SliceButton.js');
|
|
7
7
|
var SliceTextInput = require('./src/components/SliceTextInput/SliceTextInput.js');
|
|
8
|
+
var SliceLiquidGlassView = require('./src/components/SliceLiquidGlassView/SliceLiquidGlassView.js');
|
|
9
|
+
var SliceBackgroundBlur = require('./src/components/SliceBackgroundBlur/SliceBackgroundBlur.js');
|
|
8
10
|
var theme = require('./theme.js');
|
|
9
11
|
var SliceThemeProvider = require('./src/providers/SliceThemeProvider.js');
|
|
10
12
|
var useCreateThemedStyles = require('./src/hooks/useCreateThemedStyles/useCreateThemedStyles.js');
|
|
13
|
+
var useDeviceCapabilities = require('./src/hooks/useDeviceCapabilities/useDeviceCapabilities.js');
|
|
11
14
|
var typography = require('./src/utils/typography/typography.js');
|
|
15
|
+
var sizes = require('./src/utils/sizes/sizes.js');
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
|
|
@@ -17,6 +21,8 @@ exports.SliceIcons = icons.SliceIcons;
|
|
|
17
21
|
exports.StyledText = SliceText.StyledText;
|
|
18
22
|
exports.SliceButton = SliceButton.SliceButton;
|
|
19
23
|
exports.SliceTextInput = SliceTextInput.SliceTextInput;
|
|
24
|
+
exports.SliceLiquidGlassView = SliceLiquidGlassView.SliceLiquidGlassView;
|
|
25
|
+
exports.SliceBackgroundBlur = SliceBackgroundBlur.SliceBackgroundBlur;
|
|
20
26
|
exports.createTypography = theme.createTypography;
|
|
21
27
|
exports.darkTheme = theme.darkTheme;
|
|
22
28
|
exports.lightTheme = theme.lightTheme;
|
|
@@ -24,4 +30,7 @@ exports.SliceThemeProvider = SliceThemeProvider.SliceThemeProvider;
|
|
|
24
30
|
exports.useSliceContext = SliceThemeProvider.useSliceContext;
|
|
25
31
|
exports.useSliceTheme = SliceThemeProvider.useSliceTheme;
|
|
26
32
|
exports.useCreateThemedStyles = useCreateThemedStyles.useCreateThemedStyles;
|
|
33
|
+
exports.useDeviceCapabilities = useDeviceCapabilities.useDeviceCapabilities;
|
|
27
34
|
exports.lineHeightTextStyle = typography.lineHeightTextStyle;
|
|
35
|
+
exports.borderRadiusToNumber = sizes.borderRadiusToNumber;
|
|
36
|
+
exports.sizeToNumber = sizes.sizeToNumber;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var reactNative = require('react-native');
|
|
5
|
+
|
|
6
|
+
/** Web/other-platform fallback. Metro selects the native implementation on iOS/Android. */
|
|
7
|
+
function SliceBackgroundBlur({ style, fallbackColor = 'rgba(128, 128, 128, 0.18)', }) {
|
|
8
|
+
return jsxRuntime.jsx(reactNative.View, { pointerEvents: "none", style: [reactNative.StyleSheet.absoluteFill, style, { backgroundColor: fallbackColor }] });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
exports.SliceBackgroundBlur = SliceBackgroundBlur;
|