@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.
Files changed (74) hide show
  1. package/README.md +196 -6
  2. package/dist/cjs/components.js +15 -0
  3. package/dist/cjs/hooks.js +7 -0
  4. package/dist/cjs/index.js +18 -812
  5. package/dist/cjs/providers.js +9 -0
  6. package/dist/cjs/src/components/SliceButton/SliceButton.js +119 -0
  7. package/dist/cjs/src/components/SliceIcon/SliceIcon.js +20 -0
  8. package/dist/cjs/src/components/SliceIcon/iconRegistry.js +668 -0
  9. package/dist/cjs/src/components/SliceIcon/icons.js +144 -0
  10. package/dist/cjs/src/components/SliceText/SliceText.js +21 -0
  11. package/dist/cjs/src/components/SliceTextInput/SliceTextInput.js +87 -0
  12. package/dist/cjs/src/hooks/useCreateThemedStyles/useCreateThemedStyles.js +13 -0
  13. package/dist/cjs/src/providers/SliceThemeProvider.js +37 -0
  14. package/dist/cjs/src/theme/colors/colors.js +253 -0
  15. package/dist/cjs/src/theme/corners/corners.js +14 -0
  16. package/dist/cjs/src/theme/elevations/elevations.js +17 -0
  17. package/dist/cjs/src/theme/motion/motion.js +15 -0
  18. package/dist/cjs/src/theme/motion.js +47 -0
  19. package/dist/cjs/src/theme/spacing/spacing.js +14 -0
  20. package/dist/cjs/src/theme/type/type.js +190 -0
  21. package/dist/cjs/src/utils/typography/typography.js +17 -0
  22. package/dist/cjs/theme.js +23 -538
  23. package/dist/cjs/utils.js +7 -0
  24. package/dist/esm/components.mjs +5 -0
  25. package/dist/esm/hooks.mjs +1 -0
  26. package/dist/esm/index.mjs +8 -813
  27. package/dist/esm/providers.mjs +1 -0
  28. package/dist/esm/src/components/SliceButton/SliceButton.mjs +117 -0
  29. package/dist/esm/src/components/SliceIcon/SliceIcon.mjs +18 -0
  30. package/dist/esm/src/components/SliceIcon/iconRegistry.mjs +666 -0
  31. package/dist/esm/src/components/SliceIcon/icons.mjs +142 -0
  32. package/dist/esm/src/components/SliceText/SliceText.mjs +19 -0
  33. package/dist/esm/src/components/SliceTextInput/SliceTextInput.mjs +85 -0
  34. package/dist/esm/src/hooks/useCreateThemedStyles/useCreateThemedStyles.mjs +11 -0
  35. package/dist/esm/src/providers/SliceThemeProvider.mjs +33 -0
  36. package/dist/esm/src/theme/colors/colors.mjs +249 -0
  37. package/dist/esm/src/theme/corners/corners.mjs +12 -0
  38. package/dist/esm/src/theme/elevations/elevations.mjs +15 -0
  39. package/dist/esm/src/theme/motion/motion.mjs +13 -0
  40. package/dist/esm/src/theme/motion.mjs +45 -0
  41. package/dist/esm/src/theme/spacing/spacing.mjs +12 -0
  42. package/dist/esm/src/theme/type/type.mjs +184 -0
  43. package/dist/esm/src/utils/typography/typography.mjs +15 -0
  44. package/dist/esm/theme.mjs +7 -522
  45. package/dist/esm/utils.mjs +1 -0
  46. package/dist/types/native/index.d.ts +8 -4
  47. package/dist/types/native/src/components/SliceButton/SliceButton.d.ts +5 -0
  48. package/dist/types/native/src/components/SliceButton/_types.d.ts +47 -0
  49. package/dist/types/native/src/components/SliceButton/index.d.ts +2 -0
  50. package/dist/types/native/src/components/SliceIcon/SliceIcon.d.ts +2 -0
  51. package/dist/types/native/{components/Icon → src/components/SliceIcon}/icons.d.ts +1 -0
  52. package/dist/types/native/src/components/SliceIcon/index.d.ts +3 -0
  53. package/dist/types/native/src/components/SliceText/SliceText.d.ts +5 -0
  54. package/dist/types/native/src/components/SliceText/_types.d.ts +17 -0
  55. package/dist/types/native/src/components/SliceText/index.d.ts +2 -0
  56. package/dist/types/native/src/components/SliceTextInput/SliceTextInput.d.ts +2 -0
  57. package/dist/types/native/src/components/SliceTextInput/_types.d.ts +36 -0
  58. package/dist/types/native/src/components/SliceTextInput/index.d.ts +2 -0
  59. package/dist/types/native/src/components/index.d.ts +8 -0
  60. package/dist/types/native/src/hooks/index.d.ts +1 -0
  61. package/dist/types/native/src/hooks/useCreateThemedStyles/index.d.ts +1 -0
  62. package/dist/types/native/src/hooks/useCreateThemedStyles/useCreateThemedStyles.d.ts +7 -0
  63. package/dist/types/native/src/providers/SliceThemeProvider.d.ts +16 -0
  64. package/dist/types/native/src/providers/index.d.ts +2 -0
  65. package/dist/types/native/{theme → src/theme}/index.d.ts +5 -5
  66. package/dist/types/native/src/utils/index.d.ts +1 -0
  67. package/dist/types/native/src/utils/typography/index.d.ts +1 -0
  68. package/dist/types/native/src/utils/typography/typography.d.ts +7 -0
  69. package/package.json +32 -3
  70. package/dist/types/native/components/Icon/NativeIcon.d.ts +0 -2
  71. package/dist/types/native/components/Icon/index.d.ts +0 -3
  72. /package/dist/types/native/{components/Icon → src/components/SliceIcon}/_types.d.ts +0 -0
  73. /package/dist/types/native/{components/Icon → src/components/SliceIcon}/iconRegistry.d.ts +0 -0
  74. /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; other Slice components and a theme provider
5
- are not included. It is built and published independently
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 { Icon, SliceIcons } from '@apple-pie/slice-native';
9
+ import { SliceIcon, SliceIcons } from '@apple-pie/slice-native';
10
10
 
11
- <Icon
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
- `NativeIcon` is also exported as an alias of `Icon`. Supply native SVG props and
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/Icon/`.
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;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var useCreateThemedStyles = require('./src/hooks/useCreateThemedStyles/useCreateThemedStyles.js');
4
+
5
+
6
+
7
+ exports.useCreateThemedStyles = useCreateThemedStyles.useCreateThemedStyles;