@apple-pie/slice-native 0.1.4 → 0.1.6
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 +196 -6
- package/dist/cjs/components.js +15 -0
- package/dist/cjs/hooks.js +7 -0
- package/dist/cjs/index.js +18 -812
- package/dist/cjs/providers.js +9 -0
- package/dist/cjs/src/components/SliceButton/SliceButton.js +119 -0
- package/dist/cjs/src/components/SliceIcon/SliceIcon.js +20 -0
- package/dist/cjs/src/components/SliceIcon/iconRegistry.js +668 -0
- package/dist/cjs/src/components/SliceIcon/icons.js +144 -0
- package/dist/cjs/src/components/SliceText/SliceText.js +21 -0
- package/dist/cjs/src/components/SliceTextInput/SliceTextInput.js +87 -0
- package/dist/cjs/src/hooks/useCreateThemedStyles/useCreateThemedStyles.js +13 -0
- package/dist/cjs/src/providers/SliceThemeProvider.js +37 -0
- package/dist/cjs/src/theme/colors/colors.js +253 -0
- package/dist/cjs/src/theme/corners/corners.js +14 -0
- package/dist/cjs/src/theme/elevations/elevations.js +17 -0
- package/dist/cjs/src/theme/motion/motion.js +15 -0
- package/dist/cjs/src/theme/motion.js +47 -0
- package/dist/cjs/src/theme/spacing/spacing.js +14 -0
- package/dist/cjs/src/theme/type/type.js +190 -0
- package/dist/cjs/src/utils/typography/typography.js +17 -0
- package/dist/cjs/theme.js +23 -538
- package/dist/cjs/utils.js +7 -0
- package/dist/esm/components.mjs +5 -0
- package/dist/esm/hooks.mjs +1 -0
- package/dist/esm/index.mjs +8 -813
- package/dist/esm/providers.mjs +1 -0
- package/dist/esm/src/components/SliceButton/SliceButton.mjs +117 -0
- package/dist/esm/src/components/SliceIcon/SliceIcon.mjs +18 -0
- package/dist/esm/src/components/SliceIcon/iconRegistry.mjs +666 -0
- package/dist/esm/src/components/SliceIcon/icons.mjs +142 -0
- package/dist/esm/src/components/SliceText/SliceText.mjs +19 -0
- package/dist/esm/src/components/SliceTextInput/SliceTextInput.mjs +85 -0
- package/dist/esm/src/hooks/useCreateThemedStyles/useCreateThemedStyles.mjs +11 -0
- package/dist/esm/src/providers/SliceThemeProvider.mjs +33 -0
- package/dist/esm/src/theme/colors/colors.mjs +249 -0
- package/dist/esm/src/theme/corners/corners.mjs +12 -0
- package/dist/esm/src/theme/elevations/elevations.mjs +15 -0
- package/dist/esm/src/theme/motion/motion.mjs +13 -0
- package/dist/esm/src/theme/motion.mjs +45 -0
- package/dist/esm/src/theme/spacing/spacing.mjs +12 -0
- package/dist/esm/src/theme/type/type.mjs +184 -0
- package/dist/esm/src/utils/typography/typography.mjs +15 -0
- package/dist/esm/theme.mjs +7 -522
- package/dist/esm/utils.mjs +1 -0
- package/dist/types/native/index.d.ts +8 -4
- package/dist/types/native/src/components/SliceButton/SliceButton.d.ts +5 -0
- package/dist/types/native/src/components/SliceButton/_types.d.ts +47 -0
- package/dist/types/native/src/components/SliceButton/index.d.ts +2 -0
- package/dist/types/native/src/components/SliceIcon/SliceIcon.d.ts +2 -0
- package/dist/types/native/{components/Icon → src/components/SliceIcon}/icons.d.ts +1 -0
- package/dist/types/native/src/components/SliceIcon/index.d.ts +3 -0
- package/dist/types/native/src/components/SliceText/SliceText.d.ts +5 -0
- package/dist/types/native/src/components/SliceText/_types.d.ts +17 -0
- package/dist/types/native/src/components/SliceText/index.d.ts +2 -0
- package/dist/types/native/src/components/SliceTextInput/SliceTextInput.d.ts +2 -0
- package/dist/types/native/src/components/SliceTextInput/_types.d.ts +36 -0
- package/dist/types/native/src/components/SliceTextInput/index.d.ts +2 -0
- package/dist/types/native/src/components/index.d.ts +8 -0
- package/dist/types/native/src/hooks/index.d.ts +1 -0
- package/dist/types/native/src/hooks/useCreateThemedStyles/index.d.ts +1 -0
- package/dist/types/native/src/hooks/useCreateThemedStyles/useCreateThemedStyles.d.ts +7 -0
- package/dist/types/native/src/providers/SliceThemeProvider.d.ts +16 -0
- package/dist/types/native/src/providers/index.d.ts +2 -0
- package/dist/types/native/{theme → src/theme}/index.d.ts +5 -5
- package/dist/types/native/src/utils/index.d.ts +1 -0
- package/dist/types/native/src/utils/typography/index.d.ts +1 -0
- package/dist/types/native/src/utils/typography/typography.d.ts +7 -0
- package/package.json +32 -3
- package/dist/types/native/components/Icon/NativeIcon.d.ts +0 -2
- package/dist/types/native/components/Icon/index.d.ts +0 -3
- /package/dist/types/native/{components/Icon → src/components/SliceIcon}/_types.d.ts +0 -0
- /package/dist/types/native/{components/Icon → src/components/SliceIcon}/iconRegistry.d.ts +0 -0
- /package/dist/types/native/{theme → src/theme}/motion.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# @apple-pie/slice-native
|
|
2
2
|
|
|
3
3
|
Experimental React Native SVG icons, with the same names and artwork as the web UIKit.
|
|
4
|
-
Includes native light/dark theme tokens
|
|
5
|
-
|
|
4
|
+
Includes native light/dark theme tokens and a theme provider.
|
|
5
|
+
It is built and published independently
|
|
6
6
|
of `@apple-pie/slice` and does not require that package at runtime.
|
|
7
7
|
|
|
8
8
|
```tsx
|
|
9
|
-
import {
|
|
9
|
+
import { SliceIcon, SliceIcons } from '@apple-pie/slice-native';
|
|
10
10
|
|
|
11
|
-
<
|
|
11
|
+
<SliceIcon
|
|
12
12
|
name={SliceIcons.ui.home}
|
|
13
13
|
size={24}
|
|
14
14
|
strokeColor="#334155"
|
|
@@ -17,7 +17,7 @@ import { Icon, SliceIcons } from '@apple-pie/slice-native';
|
|
|
17
17
|
/>
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Supply native SVG props and
|
|
21
21
|
native `style` objects; use `onPress` instead of `onClick`. CSS classes, cursor
|
|
22
22
|
styling (`pointer`), and browser keyboard handlers are not part of this API.
|
|
23
23
|
Use an enclosing React Native `Pressable` when you need a larger touch target or
|
|
@@ -36,7 +36,7 @@ the native SVG dependency in the consuming app using its normal native/Expo setu
|
|
|
36
36
|
## Development
|
|
37
37
|
|
|
38
38
|
The package manifest and entry point live in `native/`. Icon components, types,
|
|
39
|
-
generated artwork, and tests live in `native/components/
|
|
39
|
+
generated artwork, and tests live in `native/src/components/SliceIcon/`.
|
|
40
40
|
|
|
41
41
|
From this directory, run `npm run generate` after changing the web icon registry
|
|
42
42
|
or `SliceIcons` constants. Generated files contain native SVG components and have
|
|
@@ -61,6 +61,25 @@ Native tests use their own `vitest.config.mts` and mocked native components. Ins
|
|
|
61
61
|
dependencies before running them. Root tests and coverage do not include the native package;
|
|
62
62
|
passing the native unit tests does not replace device rendering checks.
|
|
63
63
|
|
|
64
|
+
### Native coverage
|
|
65
|
+
|
|
66
|
+
From the repository root, run:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
npm run coverage --prefix native
|
|
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
|
+
|
|
64
83
|
CI runs these checks independently in **Slice Native Lint, Build, Test** on Node 24.
|
|
65
84
|
It uses `npm run lint:ci --prefix native` to check formatting and types without writing
|
|
66
85
|
fixes, then runs native tests, builds, and inspects the package contents. Root dependencies
|
|
@@ -70,8 +89,62 @@ Run `npm pack --dry-run` from `native/` to inspect the publishable files, or
|
|
|
70
89
|
`npm pack` to create a tarball. The `prepack` hook builds automatically. Build and
|
|
71
90
|
pack from this repository: generation uses the web artwork in `src/components/Icon`.
|
|
72
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
|
+
```
|
|
97
|
+
|
|
98
|
+
The archive is written to `native/pack/apple-pie-slice-native-<version>.tgz`.
|
|
99
|
+
The `pack/` directory is ignored by Git. Install the archive in another project:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
npm install /absolute/path/to/uikit/native/pack/apple-pie-slice-native-<version>.tgz
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Then import from `@apple-pie/slice-native` normally. The consuming app must have
|
|
106
|
+
compatible React, React Native, SVG, and Reanimated peer dependencies configured.
|
|
107
|
+
After library changes, regenerate the tarball and reinstall it in the consuming
|
|
108
|
+
project. Increment the native package version for each shared build to distinguish archives.
|
|
109
|
+
|
|
73
110
|
## Theme tokens
|
|
74
111
|
|
|
112
|
+
### Buttons
|
|
113
|
+
|
|
114
|
+
`SliceButton` uses the shared theme provider.
|
|
115
|
+
It supports `primary` and `secondary` variants, optional left/right icons, disabled
|
|
116
|
+
state, native Pressable props, and Reanimated layout/enter/exit animations.
|
|
117
|
+
Reanimated 4 and its compatible Worklets setup are required in the consuming app.
|
|
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
|
+
```
|
|
129
|
+
|
|
130
|
+
Wrap the app in `SliceThemeProvider` and read its theme with `useSliceTheme`:
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
import { SliceThemeProvider, useSliceTheme } from '@apple-pie/slice-native';
|
|
134
|
+
|
|
135
|
+
function App() {
|
|
136
|
+
return <SliceThemeProvider>{/* app content */}</SliceThemeProvider>;
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The provider follows the system appearance by default. Pass `preference="light"`
|
|
141
|
+
or `preference="dark"` to override it. For an app-controlled preference, pass
|
|
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
|
+
|
|
75
148
|
```tsx
|
|
76
149
|
import { Text, View, useColorScheme } from 'react-native';
|
|
77
150
|
import { lightTheme, darkTheme } from '@apple-pie/slice-native/theme';
|
|
@@ -118,3 +191,120 @@ values to Android's `elevation` property.
|
|
|
118
191
|
Build from the repository so shared source tokens are available. All generated
|
|
119
192
|
JavaScript and declarations are included under `dist/`, including declarations for
|
|
120
193
|
shared source types. Changes to web tokens are picked up by the next native build.
|
|
194
|
+
|
|
195
|
+
## Themed styles hook
|
|
196
|
+
|
|
197
|
+
Define the style factory outside the component so its identity stays stable:
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
import { StyleSheet, View } from 'react-native';
|
|
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
|
|
225
|
+
|
|
226
|
+
`lineHeightTextStyle` derives an absolute line height and returns a new style object:
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
import { lineHeightTextStyle } from '@apple-pie/slice-native';
|
|
230
|
+
|
|
231
|
+
const label = lineHeightTextStyle({ fontSize: 20, color: '#123456' }, 1.5);
|
|
232
|
+
// { fontSize: 20, color: '#123456', lineHeight: 30 }
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
The defaults are a 16 font size and a 1.2 multiplier. The multiplier must be a
|
|
236
|
+
finite number from 0 through 2. Existing line height is replaced; the input is unchanged.
|
|
237
|
+
|
|
238
|
+
## Text input
|
|
239
|
+
|
|
240
|
+
`SliceTextInput` and `SliceTextInputProps` are exported from the package root.
|
|
241
|
+
Use it within `SliceThemeProvider` and give each field an accessible name that
|
|
242
|
+
identifies its purpose, rather than relying on a placeholder alone:
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
<SliceTextInput
|
|
246
|
+
accessibilityLabel="Email address"
|
|
247
|
+
accessibilityHint="Used to send your receipt"
|
|
248
|
+
placeholder="you@example.com"
|
|
249
|
+
keyboardType="email-address"
|
|
250
|
+
autoCapitalize="none"
|
|
251
|
+
value={email}
|
|
252
|
+
onChangeText={setEmail}
|
|
253
|
+
/>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Native TextInput props and styles are forwarded. Icons are decorative and hidden
|
|
257
|
+
from accessibility focus. Font scaling remains enabled by default, and the field
|
|
258
|
+
uses a minimum height rather than a fixed height. Check large text and multiline
|
|
259
|
+
layouts on devices with VoiceOver/TalkBack enabled.
|
|
260
|
+
|
|
261
|
+
`focused` optionally requests native focus or blur; omit it for normal native
|
|
262
|
+
focus handling. `didFocus` reports focus changes alongside `onFocus`/`onBlur`.
|
|
263
|
+
Icons hide on actual focus unless `hideIconOnFocus={false}`. `blurClears` defaults
|
|
264
|
+
to false; when enabled, blur clears the native input and calls `onChangeText('')`
|
|
265
|
+
so controlled consumers can update their value. Initial values are never cleared
|
|
266
|
+
on mount.
|
|
267
|
+
|
|
268
|
+
## Package entry points and tree shaking
|
|
269
|
+
|
|
270
|
+
The base barrels under `native/src` are public package entry points:
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
import { SliceButton, SliceTextInput } from '@apple-pie/slice-native/components';
|
|
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
|
+
```
|
|
279
|
+
|
|
280
|
+
Root imports remain supported. Each entry provides ESM, CommonJS, and TypeScript
|
|
281
|
+
declarations. The build preserves individual modules and the package declares
|
|
282
|
+
`sideEffects: false` so compatible consuming bundlers can remove unused exports.
|
|
283
|
+
Actual tree shaking depends on the consuming app's bundler and configuration;
|
|
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.
|
|
286
|
+
|
|
287
|
+
Run `npm run test:package --prefix native` to build and verify export targets and
|
|
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)
|
|
293
|
+
|
|
294
|
+
From the repository root, after installing both root and native dependencies:
|
|
295
|
+
|
|
296
|
+
```sh
|
|
297
|
+
npm run storybook:native
|
|
298
|
+
npm run typecheck:storybook:native
|
|
299
|
+
npm run build-storybook:native
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
The development server uses port 6007. The static build goes to
|
|
303
|
+
`storybook-native-static/`, independently of the existing React Storybook.
|
|
304
|
+
Stories live in `native/stories/`; configuration lives in `.storybook-native/`.
|
|
305
|
+
The theme toolbar uses the native provider. React Native Web, SVG's web rendering,
|
|
306
|
+
and Reanimated's web implementation render the actual components; these are not
|
|
307
|
+
native-platform screenshots. Browser stories supplement device testing.
|
|
308
|
+
|
|
309
|
+
Deploy with `Dockerfile.react-native` and target `react-native-docs`, as described
|
|
310
|
+
in `deployment/README.md` at the repository root.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var SliceIcon = require('./src/components/SliceIcon/SliceIcon.js');
|
|
4
|
+
var icons = require('./src/components/SliceIcon/icons.js');
|
|
5
|
+
var SliceText = require('./src/components/SliceText/SliceText.js');
|
|
6
|
+
var SliceButton = require('./src/components/SliceButton/SliceButton.js');
|
|
7
|
+
var SliceTextInput = require('./src/components/SliceTextInput/SliceTextInput.js');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
exports.SliceIcon = SliceIcon.SliceIcon;
|
|
12
|
+
exports.SliceIcons = icons.SliceIcons;
|
|
13
|
+
exports.StyledText = SliceText.StyledText;
|
|
14
|
+
exports.SliceButton = SliceButton.SliceButton;
|
|
15
|
+
exports.SliceTextInput = SliceTextInput.SliceTextInput;
|