@butternutbox/pawprint-native 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/.turbo/turbo-build.log +15 -15
  2. package/CHANGELOG.md +30 -0
  3. package/COMPONENT_GUIDELINES.md +111 -4
  4. package/dist/index.cjs +12413 -1459
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +1111 -13
  7. package/dist/index.d.ts +1111 -13
  8. package/dist/index.js +12365 -1457
  9. package/dist/index.js.map +1 -1
  10. package/package.json +29 -11
  11. package/src/__mocks__/asset-stub.ts +1 -0
  12. package/src/__mocks__/emotion-native.tsx +18 -0
  13. package/src/__mocks__/react-native-gesture-handler.tsx +41 -0
  14. package/src/__mocks__/react-native-reanimated.tsx +79 -0
  15. package/src/__mocks__/react-native-safe-area-context.tsx +6 -0
  16. package/src/__mocks__/react-native-svg.tsx +27 -0
  17. package/src/__mocks__/react-native-worklets.tsx +11 -0
  18. package/src/__mocks__/react-native.tsx +338 -0
  19. package/src/__mocks__/rn-primitives/avatar.tsx +24 -0
  20. package/src/__mocks__/rn-primitives/checkbox.tsx +19 -0
  21. package/src/__mocks__/rn-primitives/select.tsx +116 -0
  22. package/src/__mocks__/rn-primitives/slider.tsx +40 -0
  23. package/src/__mocks__/rn-primitives/slot.tsx +30 -0
  24. package/src/__mocks__/rn-primitives/switch.tsx +24 -0
  25. package/src/__mocks__/rn-primitives/toggle.tsx +16 -0
  26. package/src/components/atoms/Avatar/Avatar.stories.tsx +57 -49
  27. package/src/components/atoms/Avatar/Avatar.test.tsx +269 -0
  28. package/src/components/atoms/Avatar/Avatar.tsx +68 -22
  29. package/src/components/atoms/Avatar/index.ts +1 -6
  30. package/src/components/atoms/Badge/Badge.stories.tsx +5 -29
  31. package/src/components/atoms/Badge/Badge.test.tsx +90 -0
  32. package/src/components/atoms/Button/Button.test.tsx +123 -0
  33. package/src/components/atoms/Button/Button.tsx +1 -1
  34. package/src/components/atoms/CarouselControls/CarouselControls.stories.tsx +217 -0
  35. package/src/components/atoms/CarouselControls/CarouselControls.tsx +127 -0
  36. package/src/components/atoms/CarouselControls/index.ts +2 -0
  37. package/src/components/atoms/Hint/Hint.test.tsx +36 -0
  38. package/src/components/atoms/Icon/Icon.test.tsx +98 -0
  39. package/src/components/atoms/Icon/Icon.tsx +5 -1
  40. package/src/components/atoms/IconButton/IconButton.test.tsx +101 -0
  41. package/src/components/atoms/Illustration/Illustration.stories.tsx +2 -2
  42. package/src/components/atoms/Illustration/Illustration.test.tsx +55 -0
  43. package/src/components/atoms/Illustration/Illustration.tsx +3 -3
  44. package/src/components/atoms/Input/Input.stories.tsx +129 -86
  45. package/src/components/atoms/Input/Input.test.tsx +306 -0
  46. package/src/components/atoms/Input/Input.tsx +9 -1
  47. package/src/components/atoms/Input/InputField.tsx +226 -74
  48. package/src/components/atoms/Link/Link.test.tsx +89 -0
  49. package/src/components/atoms/Link/Link.tsx +7 -6
  50. package/src/components/atoms/Logo/Logo.registry.ts +30 -5
  51. package/src/components/atoms/Logo/Logo.stories.tsx +108 -0
  52. package/src/components/atoms/Logo/Logo.test.tsx +56 -0
  53. package/src/components/atoms/Logo/assets/BCorp.tsx +113 -0
  54. package/src/components/atoms/Logo/assets/ButternutFavicon.tsx +33 -0
  55. package/src/components/atoms/Logo/assets/ButternutPrimary.tsx +294 -0
  56. package/src/components/atoms/Logo/assets/ButternutTabbedBottom.tsx +294 -0
  57. package/src/components/atoms/Logo/assets/ButternutTabbedTop.tsx +294 -0
  58. package/src/components/atoms/Logo/assets/ButternutWordmark.tsx +274 -0
  59. package/src/components/atoms/Logo/assets/PsiBufetFavicon.tsx +45 -0
  60. package/src/components/atoms/Logo/assets/PsiBufetPrimary.tsx +218 -0
  61. package/src/components/atoms/Logo/assets/PsiBufetTabbedBottom.tsx +218 -0
  62. package/src/components/atoms/Logo/assets/PsiBufetTabbedTop.tsx +218 -0
  63. package/src/components/atoms/Logo/assets/PsiBufetWordmark.tsx +195 -0
  64. package/src/components/atoms/Logo/assets/index.ts +11 -0
  65. package/src/components/atoms/NumberInput/NumberInput.stories.tsx +183 -0
  66. package/src/components/atoms/NumberInput/NumberInput.test.tsx +261 -0
  67. package/src/components/atoms/NumberInput/NumberInput.tsx +129 -0
  68. package/src/components/atoms/NumberInput/NumberInputField.tsx +77 -0
  69. package/src/components/atoms/NumberInput/index.ts +4 -0
  70. package/src/components/atoms/Spinner/Spinner.test.tsx +46 -0
  71. package/src/components/atoms/Spinner/Spinner.tsx +14 -5
  72. package/src/components/atoms/Switch/Switch.test.tsx +92 -0
  73. package/src/components/atoms/Switch/Switch.tsx +28 -17
  74. package/src/components/atoms/Tag/Tag.test.tsx +70 -0
  75. package/src/components/atoms/TextArea/TextArea.stories.tsx +303 -0
  76. package/src/components/atoms/TextArea/TextArea.test.tsx +416 -0
  77. package/src/components/atoms/TextArea/TextArea.tsx +171 -0
  78. package/src/components/atoms/TextArea/TextAreaField.tsx +304 -0
  79. package/src/components/atoms/TextArea/TextAreaLabel.tsx +103 -0
  80. package/src/components/atoms/TextArea/index.ts +6 -0
  81. package/src/components/atoms/Typography/Typography.test.tsx +94 -0
  82. package/src/components/atoms/index.ts +3 -0
  83. package/src/components/molecules/Accordion/Accordion.stories.tsx +177 -0
  84. package/src/components/molecules/Accordion/Accordion.test.tsx +185 -0
  85. package/src/components/molecules/Accordion/Accordion.tsx +284 -0
  86. package/src/components/molecules/Accordion/index.ts +6 -0
  87. package/src/components/molecules/Animated/Animated.stories.tsx +254 -0
  88. package/src/components/molecules/Animated/Animated.tsx +283 -0
  89. package/src/components/molecules/Animated/index.ts +10 -0
  90. package/src/components/molecules/ButtonDock/ButtonDock.stories.tsx +44 -25
  91. package/src/components/molecules/ButtonDock/ButtonDock.test.tsx +83 -0
  92. package/src/components/molecules/ButtonDock/ButtonDock.tsx +16 -13
  93. package/src/components/molecules/ButtonGroup/ButtonGroup.stories.tsx +48 -29
  94. package/src/components/molecules/ButtonGroup/ButtonGroup.test.tsx +73 -0
  95. package/src/components/molecules/ButtonGroup/ButtonGroup.tsx +25 -3
  96. package/src/components/molecules/Checkbox/Checkbox.stories.tsx +72 -0
  97. package/src/components/molecules/Checkbox/Checkbox.test.tsx +117 -0
  98. package/src/components/molecules/Checkbox/Checkbox.tsx +101 -95
  99. package/src/components/molecules/CopyField/CopyField.stories.tsx +313 -0
  100. package/src/components/molecules/CopyField/CopyField.test.tsx +431 -0
  101. package/src/components/molecules/CopyField/CopyField.tsx +156 -0
  102. package/src/components/molecules/CopyField/CopyFieldInput.tsx +127 -0
  103. package/src/components/molecules/CopyField/hooks/index.ts +1 -0
  104. package/src/components/molecules/CopyField/hooks/useCopyField.ts +25 -0
  105. package/src/components/molecules/CopyField/index.ts +4 -0
  106. package/src/components/molecules/DatePicker/DatePicker.stories.tsx +298 -0
  107. package/src/components/molecules/DatePicker/DatePicker.test.tsx +201 -0
  108. package/src/components/molecules/DatePicker/DatePicker.tsx +590 -0
  109. package/src/components/molecules/DatePicker/index.ts +2 -0
  110. package/src/components/molecules/Drawer/Drawer.stories.tsx +285 -0
  111. package/src/components/molecules/Drawer/Drawer.test.tsx +180 -0
  112. package/src/components/molecules/Drawer/Drawer.tsx +187 -0
  113. package/src/components/molecules/Drawer/DrawerBody.tsx +80 -0
  114. package/src/components/molecules/Drawer/DrawerClose.tsx +76 -0
  115. package/src/components/molecules/Drawer/DrawerContent.tsx +339 -0
  116. package/src/components/molecules/Drawer/DrawerContext.ts +19 -0
  117. package/src/components/molecules/Drawer/DrawerDescription.tsx +31 -0
  118. package/src/components/molecules/Drawer/DrawerDragContext.ts +11 -0
  119. package/src/components/molecules/Drawer/DrawerFooter.tsx +49 -0
  120. package/src/components/molecules/Drawer/DrawerFooterContext.ts +6 -0
  121. package/src/components/molecules/Drawer/DrawerGrabber.tsx +62 -0
  122. package/src/components/molecules/Drawer/DrawerHeader.tsx +244 -0
  123. package/src/components/molecules/Drawer/DrawerHeaderContext.ts +13 -0
  124. package/src/components/molecules/Drawer/DrawerOverlay.tsx +53 -0
  125. package/src/components/molecules/Drawer/DrawerTitle.tsx +32 -0
  126. package/src/components/molecules/Drawer/index.ts +12 -0
  127. package/src/components/molecules/FilterTab/FilterTab.stories.tsx +210 -0
  128. package/src/components/molecules/FilterTab/FilterTab.tsx +310 -0
  129. package/src/components/molecules/FilterTab/index.ts +2 -0
  130. package/src/components/molecules/MessageCard/MessageCard.stories.tsx +169 -0
  131. package/src/components/molecules/MessageCard/MessageCard.tsx +362 -0
  132. package/src/components/molecules/MessageCard/index.ts +10 -0
  133. package/src/components/molecules/Notification/Notification.stories.tsx +219 -0
  134. package/src/components/molecules/Notification/Notification.tsx +426 -0
  135. package/src/components/molecules/Notification/index.ts +2 -0
  136. package/src/components/molecules/NumberField/NumberField.stories.tsx +231 -0
  137. package/src/components/molecules/NumberField/NumberField.tsx +186 -0
  138. package/src/components/molecules/NumberField/NumberFieldInput.tsx +287 -0
  139. package/src/components/molecules/NumberField/index.ts +2 -0
  140. package/src/components/molecules/PasswordField/PasswordField.stories.tsx +362 -0
  141. package/src/components/molecules/PasswordField/PasswordField.test.tsx +369 -0
  142. package/src/components/molecules/PasswordField/PasswordField.tsx +194 -0
  143. package/src/components/molecules/PasswordField/PasswordFieldError.tsx +53 -0
  144. package/src/components/molecules/PasswordField/PasswordFieldInput.tsx +73 -0
  145. package/src/components/molecules/PasswordField/PasswordFieldRequirements.tsx +95 -0
  146. package/src/components/molecules/PasswordField/hooks/index.ts +2 -0
  147. package/src/components/molecules/PasswordField/hooks/usePasswordField.ts +113 -0
  148. package/src/components/molecules/PasswordField/index.ts +10 -0
  149. package/src/components/molecules/PictureSelector/PictureSelector.stories.tsx +204 -0
  150. package/src/components/molecules/PictureSelector/PictureSelector.tsx +335 -0
  151. package/src/components/molecules/PictureSelector/index.ts +5 -0
  152. package/src/components/molecules/Progress/Progress.stories.tsx +145 -0
  153. package/src/components/molecules/Progress/Progress.tsx +184 -0
  154. package/src/components/molecules/Progress/index.ts +2 -0
  155. package/src/components/molecules/Radio/Radio.test.tsx +104 -0
  156. package/src/components/molecules/Radio/Radio.tsx +1 -2
  157. package/src/components/molecules/SearchField/SearchField.stories.tsx +242 -0
  158. package/src/components/molecules/SearchField/SearchField.test.tsx +318 -0
  159. package/src/components/molecules/SearchField/SearchField.tsx +143 -0
  160. package/src/components/molecules/SearchField/SearchFieldInput.tsx +63 -0
  161. package/src/components/molecules/SearchField/hooks/index.ts +1 -0
  162. package/src/components/molecules/SearchField/hooks/useSearchField.ts +56 -0
  163. package/src/components/molecules/SearchField/index.ts +4 -0
  164. package/src/components/molecules/SegmentedControl/SegmentedControl.stories.tsx +31 -8
  165. package/src/components/molecules/SegmentedControl/SegmentedControl.test.tsx +141 -0
  166. package/src/components/molecules/SegmentedControl/SegmentedControl.tsx +237 -23
  167. package/src/components/molecules/SelectField/SelectField.stories.tsx +320 -0
  168. package/src/components/molecules/SelectField/SelectField.test.tsx +254 -0
  169. package/src/components/molecules/SelectField/SelectField.tsx +236 -0
  170. package/src/components/molecules/SelectField/SelectFieldContent.tsx +85 -0
  171. package/src/components/molecules/SelectField/SelectFieldItem.tsx +133 -0
  172. package/src/components/molecules/SelectField/SelectFieldTrigger.tsx +170 -0
  173. package/src/components/molecules/SelectField/SelectFieldValue.tsx +31 -0
  174. package/src/components/molecules/SelectField/hooks/index.ts +2 -0
  175. package/src/components/molecules/SelectField/hooks/useSelectField.ts +84 -0
  176. package/src/components/molecules/SelectField/index.ts +10 -0
  177. package/src/components/molecules/Slider/Slider.test.tsx +102 -0
  178. package/src/components/molecules/Slider/Slider.tsx +293 -180
  179. package/src/components/molecules/Tooltip/Tooltip.stories.tsx +168 -0
  180. package/src/components/molecules/Tooltip/Tooltip.tsx +326 -0
  181. package/src/components/molecules/Tooltip/index.ts +2 -0
  182. package/src/components/molecules/index.ts +15 -0
  183. package/src/test-utils.tsx +20 -0
  184. package/tsconfig.json +1 -1
  185. package/tsup.config.ts +16 -2
  186. package/vitest.config.ts +114 -0
  187. package/vitest.setup.ts +16 -0
@@ -7,24 +7,24 @@
7
7
  CJS Build start
8
8
  ESM Build start
9
9
  DTS Build start
10
- CJS dist/ida-narrow-500-normal-C6I2PK4T.woff2 47.41 KB
11
- CJS dist/ida-narrow-700-normal-UPHPRIN6.woff2 49.90 KB
12
- CJS dist/ibm-plex-sans-condensed-400-normal-I2XLJNNB.woff2 19.33 KB
13
- CJS dist/ibm-plex-sans-condensed-500-normal-IEQBNVGX.woff2 19.48 KB
14
- CJS dist/ibm-plex-sans-condensed-600-normal-UX5ZU5T6.woff2 19.35 KB
15
- CJS dist/ibm-plex-sans-condensed-700-normal-4PFYFTSO.woff2 18.90 KB
16
- CJS dist/index.cjs 120.33 KB
17
- CJS dist/index.cjs.map 266.09 KB
18
- CJS ⚡️ Build success in 2528ms
19
10
  ESM dist/ida-narrow-500-normal-C6I2PK4T.woff2 47.41 KB
20
11
  ESM dist/ida-narrow-700-normal-UPHPRIN6.woff2 49.90 KB
21
12
  ESM dist/ibm-plex-sans-condensed-400-normal-I2XLJNNB.woff2 19.33 KB
22
13
  ESM dist/ibm-plex-sans-condensed-500-normal-IEQBNVGX.woff2 19.48 KB
23
14
  ESM dist/ibm-plex-sans-condensed-600-normal-UX5ZU5T6.woff2 19.35 KB
24
15
  ESM dist/ibm-plex-sans-condensed-700-normal-4PFYFTSO.woff2 18.90 KB
25
- ESM dist/index.js 113.16 KB
26
- ESM dist/index.js.map 265.43 KB
27
- ESM ⚡️ Build success in 2529ms
28
- DTS ⚡️ Build success in 12741ms
29
- DTS dist/index.d.cts 31.31 KB
30
- DTS dist/index.d.ts 31.31 KB
16
+ ESM dist/index.js 1.61 MB
17
+ ESM dist/index.js.map 2.44 MB
18
+ ESM ⚡️ Build success in 11141ms
19
+ CJS dist/ida-narrow-500-normal-C6I2PK4T.woff2 47.41 KB
20
+ CJS dist/ida-narrow-700-normal-UPHPRIN6.woff2 49.90 KB
21
+ CJS dist/ibm-plex-sans-condensed-400-normal-I2XLJNNB.woff2 19.33 KB
22
+ CJS dist/ibm-plex-sans-condensed-500-normal-IEQBNVGX.woff2 19.48 KB
23
+ CJS dist/ibm-plex-sans-condensed-600-normal-UX5ZU5T6.woff2 19.35 KB
24
+ CJS dist/ibm-plex-sans-condensed-700-normal-4PFYFTSO.woff2 18.90 KB
25
+ CJS dist/index.cjs 1.67 MB
26
+ CJS dist/index.cjs.map 2.44 MB
27
+ CJS ⚡️ Build success in 11143ms
28
+ DTS ⚡️ Build success in 21900ms
29
+ DTS dist/index.d.cts 76.91 KB
30
+ DTS dist/index.d.ts 76.91 KB
package/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # @butternutbox/pawprint-native
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ecc629f: updates to illustraions, icons and tokens
8
+ - b237a0d: Bump versions to all be inline
9
+
10
+ ### Patch Changes
11
+
12
+ - 30f896c: add rn-primitives/select to dependencies
13
+ - Updated dependencies [ecc629f]
14
+ - Updated dependencies [b237a0d]
15
+ - @butternutbox/pawprint-tokens@0.2.0
16
+
17
+ ## 0.1.0
18
+
19
+ ### Minor Changes
20
+
21
+ - 44da3ae: creates new components for web and app
22
+
23
+ ### Patch Changes
24
+
25
+ - 0c6ed0c: regenerates release with missing yarn install immutable tag
26
+ - 8461dee: Updated UI after QA
27
+ - Updated dependencies [0c6ed0c]
28
+ - Updated dependencies [44da3ae]
29
+ - Updated dependencies [8461dee]
30
+ - @butternutbox/pawprint-tokens@0.1.0
@@ -485,7 +485,114 @@ import type { PawprintIllustration } from "../Illustration"
485
485
  - Import paths are the same: `@butternutbox/pawprint-icons/core` — Metro resolves the `.native.js` build automatically
486
486
  - No `fill="currentColor"` — native icons receive `color` as a prop
487
487
 
488
- ### **14. Performance Considerations**
488
+ ### **14. Animations with Reanimated**
489
+
490
+ Use `react-native-reanimated` (v4+) for all animations — never React Native's legacy `Animated` API.
491
+
492
+ **The `Animated` molecule** covers the common case: enter/exit animations driven by conditional rendering.
493
+
494
+ ```tsx
495
+ import { Animated } from "@butternutbox/pawprint-native"
496
+
497
+ // Enter on mount — Reanimated handles exit automatically on unmount
498
+ {
499
+ visible && (
500
+ <Animated variant="fadeUp">
501
+ <Card />
502
+ </Animated>
503
+ )
504
+ }
505
+
506
+ // Sequenced elements with delay
507
+ {
508
+ items.map((item, i) => (
509
+ <Animated key={item.id} variant="fadeUp" delay={i * 0.08}>
510
+ <Row {...item} />
511
+ </Animated>
512
+ ))
513
+ }
514
+ ```
515
+
516
+ Available variants: `fade`, `fadeUp`, `fadeDown`, `scale`, `slideIn`, `slideOut`, `drawerSlide`.
517
+
518
+ **No `AnimatePresence` needed** — Reanimated intercepts unmounts and runs the `exiting` animation before the component is removed. Conditionally render directly.
519
+
520
+ **Custom / imperative animations** — use `useSharedValue`, `useAnimatedStyle`, `withTiming`, `withSpring` directly. This is the right pattern when a headless library controls mounting internally (e.g. the Drawer), or when the animation must compose with a gesture in real time.
521
+
522
+ ```tsx
523
+ import Reanimated, {
524
+ useSharedValue,
525
+ useAnimatedStyle,
526
+ withTiming,
527
+ Easing
528
+ } from "react-native-reanimated"
529
+
530
+ const opacity = useSharedValue(0)
531
+ const animatedStyle = useAnimatedStyle(() => ({ opacity: opacity.value }))
532
+
533
+ // Drive the animation imperatively
534
+ opacity.value = withTiming(1, {
535
+ duration: 200,
536
+ easing: Easing.out(Easing.ease)
537
+ })
538
+ ```
539
+
540
+ **Stagger without a container** — pass incremental `delay` to `Animated`. For direct `Reanimated.View` usage, use the exported animation preset objects:
541
+
542
+ ```tsx
543
+ import { fadeUpAnimation } from "@butternutbox/pawprint-native"
544
+
545
+ // Each call to .duration() creates a fresh builder instance — safe to chain
546
+ <Reanimated.View entering={fadeUpAnimation.entering.duration(200).delay(80)}>
547
+ ```
548
+
549
+ **Custom builders** — extend `ComplexAnimationBuilder` and override `build` as a property (arrow function):
550
+
551
+ ```tsx
552
+ import {
553
+ ComplexAnimationBuilder,
554
+ BaseAnimationBuilder,
555
+ withTiming,
556
+ type EntryExitAnimationFunction
557
+ } from "react-native-reanimated"
558
+
559
+ class MyEnter extends ComplexAnimationBuilder {
560
+ static override createInstance<T extends typeof BaseAnimationBuilder>(
561
+ this: T
562
+ ): InstanceType<T> {
563
+ return new (this as unknown as new () => InstanceType<T>)()
564
+ }
565
+
566
+ override build = (): EntryExitAnimationFunction => {
567
+ const delay = this.getDelay()
568
+ const duration = this.getDuration()
569
+ const delayFn = this.getDelayFunction()
570
+ const callback = this.callbackV
571
+
572
+ return () => {
573
+ "worklet"
574
+ return {
575
+ initialValues: { opacity: 0 },
576
+ animations: { opacity: delayFn(delay, withTiming(1, { duration })) },
577
+ callback
578
+ }
579
+ }
580
+ }
581
+ }
582
+ ```
583
+
584
+ **Reduced motion** — `useReducedMotion()` from Reanimated returns `true` when the OS accessibility setting is on. Set `duration: 0` to skip animations:
585
+
586
+ ```tsx
587
+ import { useReducedMotion } from "react-native-reanimated"
588
+
589
+ const reducedMotion = useReducedMotion()
590
+ const duration = reducedMotion ? 0 : 200
591
+ ```
592
+
593
+ The `Animated` molecule handles this automatically.
594
+
595
+ ### **15. Performance Considerations**
489
596
 
490
597
  ```tsx
491
598
  // ✅ GOOD: Stable style references
@@ -513,7 +620,7 @@ const opacity = useRef(new Animated.Value(0)).current
513
620
  - Use `React.memo` sparingly — only for expensive renders with stable props
514
621
  - Use `Animated` or `Reanimated` for animations, not `setState`
515
622
 
516
- ### **15. Error Handling & Validation**
623
+ ### **16. Error Handling & Validation**
517
624
 
518
625
  ```tsx
519
626
  export const Icon = React.forwardRef<View, IconProps>(
@@ -541,7 +648,7 @@ export const Icon = React.forwardRef<View, IconProps>(
541
648
  )
542
649
  ```
543
650
 
544
- ### **16. Parity with pawprint-web**
651
+ ### **17. Parity with pawprint-web**
545
652
 
546
653
  Native components should mirror the web API where possible:
547
654
 
@@ -557,7 +664,7 @@ Native components should mirror the web API where possible:
557
664
  - Web uses `styled()` from `@mui/system` — native uses `styled()` from `@emotion/native`
558
665
  - Web has `shouldForwardProp` — native relies on prop name prefixing
559
666
 
560
- ### **17. Documentation Standards**
667
+ ### **18. Documentation Standards**
561
668
 
562
669
  **Add JSDoc comments for all exported components:**
563
670