@cdx-ui/components 0.2.3 → 0.2.4

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 (248) hide show
  1. package/AGENTS.md +24 -0
  2. package/README.md +2 -0
  3. package/coverage.svg +1 -1
  4. package/docs/components/accordion/content.md +538 -0
  5. package/docs/components/alert/content.md +203 -0
  6. package/docs/components/alert-dialog/content.md +319 -0
  7. package/docs/components/avatar/content.md +368 -0
  8. package/docs/components/avatar/design.md +202 -0
  9. package/docs/components/badge/content.md +235 -0
  10. package/docs/components/bottom-sheet/content.md +351 -0
  11. package/docs/components/bottom-sheet/design.md +249 -0
  12. package/docs/components/breadcrumbs/content.md +169 -0
  13. package/docs/components/button/content.md +398 -0
  14. package/docs/components/button/design.md +258 -0
  15. package/docs/components/calendar/content.md +137 -0
  16. package/docs/components/card/content.md +283 -0
  17. package/docs/components/carousel/content.md +416 -0
  18. package/docs/components/checkbox/content.md +236 -0
  19. package/docs/components/checkbox/design.md +214 -0
  20. package/docs/components/chip/content.md +439 -0
  21. package/docs/components/chip/design.md +418 -0
  22. package/docs/components/color-area/content.md +86 -0
  23. package/docs/components/color-field/content.md +134 -0
  24. package/docs/components/color-picker/content.md +208 -0
  25. package/docs/components/color-slider/content.md +120 -0
  26. package/docs/components/color-swatch/content.md +64 -0
  27. package/docs/components/color-swatch-picker/content.md +126 -0
  28. package/docs/components/content.md +97 -0
  29. package/docs/components/currency-input/content.md +205 -0
  30. package/docs/components/data-grid/content.md +522 -0
  31. package/docs/components/date-field/content.md +147 -0
  32. package/docs/components/date-picker/content.md +360 -0
  33. package/docs/components/date-range-picker/content.md +301 -0
  34. package/docs/components/date-time-field/content.md +157 -0
  35. package/docs/components/date-time-list/content.md +105 -0
  36. package/docs/components/date-time-picker/content.md +272 -0
  37. package/docs/components/dialog/content.md +436 -0
  38. package/docs/components/dialog/design.md +192 -0
  39. package/docs/components/divider/content.md +112 -0
  40. package/docs/components/drawer/content.md +436 -0
  41. package/docs/components/field/content.md +277 -0
  42. package/docs/components/form/content.md +62 -0
  43. package/docs/components/full-screen-dialog/content.md +881 -0
  44. package/docs/components/heading/content.md +55 -0
  45. package/docs/components/icon/content.md +190 -0
  46. package/docs/components/icon-button/content.md +200 -0
  47. package/docs/components/icon-button/design.md +165 -0
  48. package/docs/components/image/content.md +104 -0
  49. package/docs/components/input/content.md +281 -0
  50. package/docs/components/input/design.md +389 -0
  51. package/docs/components/insurance-disclosure/content.md +103 -0
  52. package/docs/components/link/content.md +180 -0
  53. package/docs/components/link/design.md +160 -0
  54. package/docs/components/list-item/content.md +695 -0
  55. package/docs/components/menu/content.md +1247 -0
  56. package/docs/components/month-calendar/content.md +84 -0
  57. package/docs/components/month-picker/content.md +273 -0
  58. package/docs/components/otp-input/content.md +327 -0
  59. package/docs/components/progress-bar/content.md +87 -0
  60. package/docs/components/progress-circle/content.md +176 -0
  61. package/docs/components/progress-segmented/content.md +119 -0
  62. package/docs/components/quick-action-button/content.md +154 -0
  63. package/docs/components/quick-action-button/design.md +170 -0
  64. package/docs/components/radio/content.md +224 -0
  65. package/docs/components/range-calendar/content.md +123 -0
  66. package/docs/components/reorderable-list/content.md +309 -0
  67. package/docs/components/scoped-theme/content.md +47 -0
  68. package/docs/components/scroll-shadow/content.md +686 -0
  69. package/docs/components/select/content.md +400 -0
  70. package/docs/components/select/design.md +301 -0
  71. package/docs/components/skeleton/content.md +103 -0
  72. package/docs/components/slider/content.md +423 -0
  73. package/docs/components/stack/content.md +161 -0
  74. package/docs/components/switch/content.md +150 -0
  75. package/docs/components/switch/design.md +208 -0
  76. package/docs/components/table/content.md +548 -0
  77. package/docs/components/table-pagination/content.md +177 -0
  78. package/docs/components/tabs/content.md +292 -0
  79. package/docs/components/text/content.md +142 -0
  80. package/docs/components/textarea/content.md +222 -0
  81. package/docs/components/tile/content.md +703 -0
  82. package/docs/components/toast/content.md +456 -0
  83. package/docs/components/toggle-button/content.md +505 -0
  84. package/docs/components/tooltip/content.md +350 -0
  85. package/docs/components/virtualized-list/content.md +250 -0
  86. package/docs/foundations/content.md +9 -0
  87. package/docs/foundations/expressions/icons/content.md +19 -0
  88. package/docs/foundations/styles/tokens/all-tokens/content.md +192 -0
  89. package/docs/foundations/styles/tokens/what-are-tokens/content.md +33 -0
  90. package/docs/foundations/styles/tokens/what-are-tokens/design.md +33 -0
  91. package/docs/getting-started/content.md +4 -0
  92. package/docs/getting-started/designers/content.md +13 -0
  93. package/docs/getting-started/designers/design.md +13 -0
  94. package/docs/getting-started/developers/accessibility/content.md +31 -0
  95. package/docs/getting-started/developers/content.md +612 -0
  96. package/docs/getting-started/developers/styling/content.md +193 -0
  97. package/docs/llms.txt +193 -0
  98. package/docs/patterns/account-management/content.md +75 -0
  99. package/docs/patterns/authentication/content.md +52 -0
  100. package/docs/patterns/content.md +10 -0
  101. package/docs/patterns/dashboard/content.md +39 -0
  102. package/docs/patterns/empty-states/content.md +31 -0
  103. package/docs/patterns/forms/content.md +109 -0
  104. package/docs/patterns/onboarding/content.md +69 -0
  105. package/docs/patterns/payments/content.md +35 -0
  106. package/docs/patterns/settings/content.md +72 -0
  107. package/docs/resources/content.md +9 -0
  108. package/docs/resources/figma-libraries/content.md +42 -0
  109. package/docs/resources/release-notes/0.0.1-beta.118/content.md +27 -0
  110. package/docs/resources/release-notes/0.0.1-beta.122/content.md +21 -0
  111. package/docs/resources/release-notes/0.0.1-beta.124/content.md +16 -0
  112. package/docs/resources/release-notes/0.0.1-beta.126/content.md +10 -0
  113. package/docs/resources/release-notes/0.0.1-beta.127/content.md +14 -0
  114. package/docs/resources/release-notes/0.0.1-beta.128/content.md +9 -0
  115. package/docs/resources/release-notes/0.0.1-beta.129/content.md +18 -0
  116. package/docs/resources/release-notes/0.0.1-beta.130/content.md +18 -0
  117. package/docs/resources/release-notes/0.0.1-beta.133/content.md +7 -0
  118. package/docs/resources/release-notes/0.0.1-beta.134/content.md +17 -0
  119. package/docs/resources/release-notes/0.0.1-beta.136/content.md +7 -0
  120. package/docs/resources/release-notes/0.0.1-beta.137/content.md +10 -0
  121. package/docs/resources/release-notes/0.0.1-beta.138/content.md +7 -0
  122. package/docs/resources/release-notes/0.0.1-beta.139/content.md +13 -0
  123. package/docs/resources/release-notes/0.0.1-beta.140/content.md +26 -0
  124. package/docs/resources/release-notes/0.0.1-beta.141/content.md +63 -0
  125. package/docs/resources/release-notes/0.0.1-beta.142/content.md +7 -0
  126. package/docs/resources/release-notes/0.0.1-beta.143/content.md +12 -0
  127. package/docs/resources/release-notes/0.0.1-beta.144/content.md +7 -0
  128. package/docs/resources/release-notes/0.0.1-beta.145/content.md +7 -0
  129. package/docs/resources/release-notes/0.0.1-beta.147/content.md +10 -0
  130. package/docs/resources/release-notes/0.0.1-beta.149/content.md +10 -0
  131. package/docs/resources/release-notes/0.0.1-beta.150/content.md +13 -0
  132. package/docs/resources/release-notes/0.0.1-beta.152/content.md +7 -0
  133. package/docs/resources/release-notes/0.0.1-beta.154/content.md +15 -0
  134. package/docs/resources/release-notes/0.0.1-beta.156/content.md +7 -0
  135. package/docs/resources/release-notes/0.0.1-beta.158/content.md +9 -0
  136. package/docs/resources/release-notes/0.0.1-beta.159/content.md +11 -0
  137. package/docs/resources/release-notes/0.0.1-beta.160/content.md +7 -0
  138. package/docs/resources/release-notes/0.0.1-beta.161/content.md +7 -0
  139. package/docs/resources/release-notes/0.0.1-beta.163/content.md +7 -0
  140. package/docs/resources/release-notes/0.0.1-beta.164/content.md +9 -0
  141. package/docs/resources/release-notes/0.0.1-beta.166/content.md +17 -0
  142. package/docs/resources/release-notes/0.0.1-beta.167/content.md +7 -0
  143. package/docs/resources/release-notes/0.0.1-beta.168/content.md +7 -0
  144. package/docs/resources/release-notes/0.0.1-beta.169/content.md +7 -0
  145. package/docs/resources/release-notes/0.0.1-beta.171/content.md +16 -0
  146. package/docs/resources/release-notes/0.0.1-beta.172/content.md +24 -0
  147. package/docs/resources/release-notes/0.0.1-beta.173/content.md +15 -0
  148. package/docs/resources/release-notes/0.0.1-beta.174/content.md +7 -0
  149. package/docs/resources/release-notes/0.0.1-beta.176/content.md +32 -0
  150. package/docs/resources/release-notes/0.0.1-beta.179/content.md +11 -0
  151. package/docs/resources/release-notes/0.0.1-beta.182/content.md +13 -0
  152. package/docs/resources/release-notes/0.0.1-beta.185/content.md +7 -0
  153. package/docs/resources/release-notes/0.0.1-beta.187/content.md +27 -0
  154. package/docs/resources/release-notes/0.1.1/content.md +23 -0
  155. package/docs/resources/release-notes/0.1.2/content.md +7 -0
  156. package/docs/resources/release-notes/0.1.4/content.md +19 -0
  157. package/docs/resources/release-notes/0.1.5/content.md +7 -0
  158. package/docs/resources/release-notes/0.1.6/content.md +7 -0
  159. package/docs/resources/release-notes/0.2.0/content.md +31 -0
  160. package/docs/resources/release-notes/0.2.1/content.md +17 -0
  161. package/docs/resources/release-notes/0.2.2/content.md +11 -0
  162. package/docs/resources/release-notes/0.2.3/content.md +15 -0
  163. package/docs/resources/release-notes/content.md +64 -0
  164. package/lib/commonjs/components/DateTimeList/index.js +11 -26
  165. package/lib/commonjs/components/DateTimeList/index.js.map +1 -1
  166. package/lib/commonjs/components/DateTimeList/styles.js +2 -12
  167. package/lib/commonjs/components/DateTimeList/styles.js.map +1 -1
  168. package/lib/commonjs/components/ListItem/index.js.map +1 -1
  169. package/lib/commonjs/components/ListItem/styles.js +2 -1
  170. package/lib/commonjs/components/ListItem/styles.js.map +1 -1
  171. package/lib/commonjs/components/Menu/index.js +11 -5
  172. package/lib/commonjs/components/Menu/index.js.map +1 -1
  173. package/lib/commonjs/components/ScrollShadow/gradient.js +29 -0
  174. package/lib/commonjs/components/ScrollShadow/gradient.js.map +1 -0
  175. package/lib/commonjs/components/ScrollShadow/index.js +171 -44
  176. package/lib/commonjs/components/ScrollShadow/index.js.map +1 -1
  177. package/lib/commonjs/components/ScrollShadow/styles.js +58 -14
  178. package/lib/commonjs/components/ScrollShadow/styles.js.map +1 -1
  179. package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js +63 -0
  180. package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
  181. package/lib/commonjs/components/ScrollShadow/useScrollShadow.js +48 -8
  182. package/lib/commonjs/components/ScrollShadow/useScrollShadow.js.map +1 -1
  183. package/lib/commonjs/components/Tabs/index.js +16 -23
  184. package/lib/commonjs/components/Tabs/index.js.map +1 -1
  185. package/lib/commonjs/components/Tabs/styles.js +1 -10
  186. package/lib/commonjs/components/Tabs/styles.js.map +1 -1
  187. package/lib/commonjs/figma/ListItem.SectionHeader.figma.js +20 -5
  188. package/lib/commonjs/figma/ListItem.SectionHeader.figma.js.map +1 -1
  189. package/lib/module/components/DateTimeList/index.js +12 -27
  190. package/lib/module/components/DateTimeList/index.js.map +1 -1
  191. package/lib/module/components/DateTimeList/styles.js +1 -11
  192. package/lib/module/components/DateTimeList/styles.js.map +1 -1
  193. package/lib/module/components/ListItem/index.js.map +1 -1
  194. package/lib/module/components/ListItem/styles.js +2 -1
  195. package/lib/module/components/ListItem/styles.js.map +1 -1
  196. package/lib/module/components/Menu/index.js +11 -5
  197. package/lib/module/components/Menu/index.js.map +1 -1
  198. package/lib/module/components/ScrollShadow/gradient.js +24 -0
  199. package/lib/module/components/ScrollShadow/gradient.js.map +1 -0
  200. package/lib/module/components/ScrollShadow/index.js +170 -48
  201. package/lib/module/components/ScrollShadow/index.js.map +1 -1
  202. package/lib/module/components/ScrollShadow/styles.js +57 -13
  203. package/lib/module/components/ScrollShadow/styles.js.map +1 -1
  204. package/lib/module/components/ScrollShadow/useComposedScrollHandler.js +57 -0
  205. package/lib/module/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
  206. package/lib/module/components/ScrollShadow/useScrollShadow.js +46 -8
  207. package/lib/module/components/ScrollShadow/useScrollShadow.js.map +1 -1
  208. package/lib/module/components/Tabs/index.js +17 -24
  209. package/lib/module/components/Tabs/index.js.map +1 -1
  210. package/lib/module/components/Tabs/styles.js +0 -9
  211. package/lib/module/components/Tabs/styles.js.map +1 -1
  212. package/lib/module/figma/ListItem.SectionHeader.figma.js +20 -5
  213. package/lib/module/figma/ListItem.SectionHeader.figma.js.map +1 -1
  214. package/lib/typescript/components/DateTimeList/index.d.ts.map +1 -1
  215. package/lib/typescript/components/DateTimeList/styles.d.ts +1 -4
  216. package/lib/typescript/components/DateTimeList/styles.d.ts.map +1 -1
  217. package/lib/typescript/components/ListItem/index.d.ts +5 -4
  218. package/lib/typescript/components/ListItem/index.d.ts.map +1 -1
  219. package/lib/typescript/components/ListItem/styles.d.ts +1 -1
  220. package/lib/typescript/components/ListItem/styles.d.ts.map +1 -1
  221. package/lib/typescript/components/Menu/index.d.ts.map +1 -1
  222. package/lib/typescript/components/ScrollShadow/gradient.d.ts +7 -0
  223. package/lib/typescript/components/ScrollShadow/gradient.d.ts.map +1 -0
  224. package/lib/typescript/components/ScrollShadow/index.d.ts +57 -15
  225. package/lib/typescript/components/ScrollShadow/index.d.ts.map +1 -1
  226. package/lib/typescript/components/ScrollShadow/styles.d.ts +8 -2
  227. package/lib/typescript/components/ScrollShadow/styles.d.ts.map +1 -1
  228. package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts +13 -0
  229. package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts.map +1 -0
  230. package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts +15 -2
  231. package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts.map +1 -1
  232. package/lib/typescript/components/Tabs/index.d.ts.map +1 -1
  233. package/lib/typescript/components/Tabs/styles.d.ts +0 -7
  234. package/lib/typescript/components/Tabs/styles.d.ts.map +1 -1
  235. package/lib/typescript/figma/ListItem.SectionHeader.figma.d.ts.map +1 -1
  236. package/package.json +8 -6
  237. package/src/components/DateTimeList/index.tsx +13 -26
  238. package/src/components/DateTimeList/styles.ts +1 -10
  239. package/src/components/ListItem/index.tsx +5 -4
  240. package/src/components/ListItem/styles.ts +1 -0
  241. package/src/components/Menu/index.tsx +11 -8
  242. package/src/components/ScrollShadow/gradient.ts +48 -0
  243. package/src/components/ScrollShadow/index.tsx +300 -69
  244. package/src/components/ScrollShadow/styles.ts +45 -28
  245. package/src/components/ScrollShadow/useComposedScrollHandler.ts +58 -0
  246. package/src/components/ScrollShadow/useScrollShadow.ts +72 -10
  247. package/src/components/Tabs/index.tsx +25 -35
  248. package/src/components/Tabs/styles.ts +0 -9
@@ -0,0 +1,389 @@
1
+ # Input Field — Design (https://design.candescent.com/docs/components/input)
2
+
3
+ ## Usage
4
+
5
+ **Example**
6
+
7
+ **Common alternative names**: Text input, text box, text area, free-response, form control
8
+
9
+ ---
10
+
11
+ ## **Anatomy**
12
+
13
+ An input field is the simplest and most common form of user input. Its simplicity makes it flexible enough to support many different input types.
14
+
15
+ **Anatomy\_input-field**
16
+
17
+ 1. **Label**: Text describing what the input field is asking for.
18
+ 2. **Placeholder text**: optional assistive text that appears within an empty field.
19
+ 3. **Helper text**: An optional line of assistive text attached to the bottom of the field.
20
+ 4. **Start adornment**: An optional icon, text string, or button shown at the start of the field.
21
+ 5. **Value**: The current value of the field.
22
+ 6. **End adornment**: An optional icon, text string, or button shown at the end of the field.
23
+
24
+ ### **Size**
25
+
26
+ Input fields are available in 2 sizes: **Default** and **Small**. These sizes give you flexibility when building layouts, but a consistent size should be used for all input fields on the same page.
27
+
28
+ - **size: default**
29
+
30
+ The default size and the most commonly used size. Has a height of 72px when used without helper text.
31
+
32
+ ### **Required**
33
+
34
+ An input field can be designated as a required input. The user will be required to enter a value before continuing or submitting the form.
35
+
36
+ - **size: default**
37
+
38
+ The default size and the most commonly used size. Has a height of 72px when used without helper text.
39
+ - **size: small**
40
+
41
+ A smaller size that should only be used when space is limited, or in complex forms. Has a height of 44px when used without helper text.
42
+
43
+ ### **Helper text**
44
+
45
+ Helper text is an optional line of assistive text attached to the bottom of an input field. It can provide critical information, instructions, format, acceptance criteria, or other important information that will help users complete the input. It should also be used to provide an explanation when the field is in an error state.
46
+
47
+ - **Show Helper Text?: true**
48
+
49
+ A line of small text is shown below the field. This variant increases the field height.
50
+
51
+ ### **Placeholder text**
52
+
53
+ Placeholder text is optional assistive text that appears within a field before it contains a value. It can provide hints or examples of what the user should enter into the field. It disappears when the user starts typing.
54
+
55
+ - **Show Placeholder?: true**
56
+
57
+ A line of assistive text is shown in grey inside the field.
58
+
59
+ ### **Adornments**
60
+
61
+ Adornments are used to add a prefix, a suffix, or an action to an input field. For example, you can add an icon button to reveal/hide the contents of a password field, or add a currency symbol to the start of a money input.
62
+
63
+ - **Show Leading Adornment?: true**
64
+
65
+ An optional icon, text string, or button shown at the start of the field. Vertically aligned with the value.
66
+ - **Show Trailing Adornment?: true**
67
+
68
+ An optional icon, text string, or button shown at the end of the field. Vertically centered in the field.
69
+
70
+ ### **Hidden label**
71
+
72
+ When absolutely necessary, the label of a input field can be hidden. There are very, very few places where hiding the field’s label is recommended, so avoid using this variant whenever possible.
73
+
74
+ - **Show Label?: false**
75
+
76
+ The field label is hidden.
77
+
78
+ ---
79
+
80
+ **Usage**
81
+
82
+ Input fields should be used in forms to collect freeform text. The text can range in length from a single word to a few lines. However, if the text input is predictable and could be selected from a pre-defined list of options, consider using a [Select field](https://design.candescent.com/docs/components/select/content.md) or Autocomplete instead.
83
+
84
+ ### **When to use**
85
+
86
+ > [!TIP]
87
+ >
88
+ > **Free response questions**
89
+ >
90
+ > - ex: “First name” or “Last name” on a form
91
+ > - ex: The “Subject” field in an email
92
+ > - ex: A “Comments” field on a product review form
93
+
94
+ > [!TIP]
95
+ >
96
+ > **For collecting information that should follow a specific format**
97
+ >
98
+ > - ex: Email address
99
+ > - ex: Phone number
100
+ > - ex: ZIP code in a shipping address form
101
+ > - ex: Dollar amount in a money transfer form
102
+
103
+ ### **When not to use**
104
+
105
+ > [!CAUTION]
106
+ >
107
+ > **When the user needs to choose an option from a finite list**
108
+ >
109
+ > - ex: Select an account to use in a money transfer form
110
+ > - ex: A yes or no question
111
+ > - ex: Select a sorting option when viewing a list of transactions
112
+
113
+ ### **Layout and placement**
114
+
115
+ Input fields are typically found on forms. When placing the component, make sure it is appropriately spaced from other form fields to prevent confusion.
116
+
117
+ When using a input field in a form, please see the Form Pattern for additional guidance about layout and placement.
118
+
119
+ ### **Using helper text**
120
+
121
+ Helper text is an optional line of assistive text attached to the bottom of an input. It can provide instructions, format, acceptance criteria, or other important information that will help the user complete the field.
122
+
123
+ #### **When to use helper text**
124
+
125
+ Helper text should only be used when necessary. Too much helper text will clutter the screen, and may overload the user. Use these guidelines to decide if helper text would be beneficial for your input field:
126
+
127
+ - Does the field require a specific format to be valid/accepted?
128
+ - Does the field require or prohibit specific characters?
129
+ - Will most users need additional information to understand what the input is asking for?
130
+ - Will users want to know why, how, or where their response will be used? Will they hesitate to answer without that info?
131
+
132
+ Addressing these needs will help the user complete the input more quickly and with less errors.
133
+
134
+ - **Do:** Include helper text when the input requires a specific format. Placeholder text is not enough.
135
+ - **Do:** Include helper text when the input has character limits or a character restriction.
136
+ - **Do:** Include helper text when the user needs additional info to understand exactly what the input is asking for.
137
+
138
+ #### **When not to use helper text**
139
+
140
+ Do not use helper text in place of a label, or to indicate that the input is required.
141
+
142
+ - **Don't:** Don’t use helper text to indicate that an input is required.
143
+ - **Don't:** Don’t use helper text in place of an input label.
144
+
145
+ ### **Using placeholder text**
146
+
147
+ Placeholder text is an optional line of assistive text that appears within a field before it contains a value. It can provide hints or examples of what the user should enter into the field.
148
+
149
+ #### **When to use placeholder text**
150
+
151
+ Placeholder text can cause usability problems. Users may see placeholder text in a field and assume that the have already completed the field. Due to this risk, ensure that placeholder text is only used when necessary.
152
+
153
+ Use these guidelines to decide if placeholder text would be beneficial for your input field:
154
+
155
+ - Will the placeholder text complement the field’s helper text in a useful way?
156
+ - Would users benefit from seeing an example of the value format as placeholder text?
157
+ - Will the placeholder text help clarify the purpose of a field?
158
+ - _**Will the benefits of using the placeholder text outweigh the potential usability risks?**_
159
+
160
+ * **Do:** Placeholder text is acceptable in a search field, especially if it doesn’t have a visible label. Search fields are one of the only acceptable implementations of the hiddenLabel property.
161
+ * **Caution:** Placeholder text can be used to provide an example of the desired format. This example informs users that they should enter their standard 5 digit ZIP code, not the expanded 9-digit code used by USPS. Keep in mind that this example will disappear once the user starts typing.
162
+
163
+ #### **When not to use placeholder text**
164
+
165
+ Placeholder text disappears once the user starts typing in the field. Therefore, it should not be used to convey instructions, format, acceptance criteria, or other important information the user will need to complete the field. In most cases, helper text is the preferred method of providing assistive text.
166
+
167
+ - **Don't:** Don’t user placeholder text to inform users about the desired format. Use helper text instead.
168
+ - **Don't:** Don’t use placeholder text to inform users about length requirements, character restrictions, or other acceptance criteria. Use helper text instead.
169
+ - **Don't:** Don’t repeat the field’s label as placeholder text, and don’t instruct the user to fill out the field with placeholder text.
170
+
171
+ ### **Character limits**
172
+
173
+ Character limits on input fields should be used sparingly. They should not be imposed on the user unless there is some technical limitation or logical reason. Use these guidelines to decide if imposing a character limit is a good idea:
174
+
175
+ **❓** **Does an API, database, or other technical service have a character limit?**
176
+
177
+ - ex: When a form is submitted, the API used to submit the information to the system can only accept values less than 255 characters
178
+ - ex: The specific database structure being used for a product limits the length of strings to 100 characters
179
+
180
+ **❓ Does the input type have a common-knowledge or standardized character limit?**
181
+
182
+ - ex: All credit card numbers are 19 digits or less
183
+ - ex: Credit card CVV/CVC numbers are 3 or 4 digits
184
+
185
+ **❓ Will the value of the input be displayed on a physical object with a limited area?**
186
+
187
+ - ex: The name printed on a credit card has a limit of 26 characters based on the physical width of the card
188
+
189
+ If you decide to enforce a character limit on your field, see the Enforcing character limit section for enforcement and behavior guidelines.
190
+
191
+ ### **Character restrictions**
192
+
193
+ The types of characters a user can enter into an input field should not be restricted unless there is some technical limitation or logical reason. In general, all Unicode characters should be permitted whenever possible. This includes:
194
+
195
+ - Spaces and punctuation
196
+ - Numbers
197
+ - Supplemental alphabet characters (ñ, ç, ř)
198
+ - Characters from other alphabets (Π, Ϛ, Я)
199
+ - Special characters (▲, ✻, ➔) and Emoji (😁, ✌️, ♿)
200
+
201
+ Use these guidelines to decide if imposing a restriction on special characters is a good idea:
202
+
203
+ **❓ Does an API, database, or other technical service have character restrictions?**
204
+
205
+ - ex: When a form is submitted, the API used to submit the information to the system cannot accept Emoji
206
+ - ex: ex: A specific bank only allows their transaction memos to include alphanumeric characters
207
+
208
+ **❓ Does the input type have a common-knowledge or standardized character restrictions?**
209
+
210
+ - ex: Credit card numbers are only numeric characters
211
+ - ex: Street addresses do not contain Emoji
212
+
213
+ **❓ Will the value of the input be displayed on a physical object with a limited character set?**
214
+
215
+ - ex: The name printed on a credit card cannot contain special characters or diacritics (Raúl Núñez becomes RAUL NUNEZ)
216
+
217
+ In this example, the financial institution is using an API that does not restrict any characters from being used in an account name.
218
+
219
+ - **Do:** Allow all unicode characters when possible.
220
+ - **Caution:** Don’t restrict characters without a logical reason or technical limitation.
221
+
222
+ If you decide to enforce a character limit on your field, see the Enforcing character restrictions section for enforcement and behavior guidelines.
223
+
224
+ ---
225
+
226
+ ## **Behavior**
227
+
228
+ ### **Interaction states**
229
+
230
+ The default state of an input field is clickable and editable. The appearance of the field will respond as the user interacts with it.
231
+
232
+ - **Resting**
233
+
234
+ Default state. User is not interacting with or typing in the field.
235
+ - **Hover**
236
+
237
+ When the user’s cursor is hovering over the field.
238
+ - **Focus**
239
+
240
+ When a keyboard user is focused on the field using tab navigation controls. In this state, the user can type into the field.
241
+
242
+ ### **Disabled**
243
+
244
+ The input field can be disabled, which prevents the user from clicking on or interacting with the field in any way, including editing the current value. Using disabled fields can cause accessibility issues, so avoid using this state wherever possible.
245
+
246
+ - **isDisabled: true**
247
+
248
+ In this state, the user cannot interact with the field or edit its current value. The value appears greyed out.
249
+
250
+ ### **Read only**
251
+
252
+ The input field component can be set to read only mode, which prevents the user from editing the value of the field. Unlike the disabled state, the user can still interact with this field through hover and keyboard focus, allowing screen readers to read out the current value of the field.
253
+
254
+ - **isReadOnly: true**
255
+
256
+ In this state, the user cannot edit the value of the field. However, the value remains fully visible, and the user can still interact with the field.
257
+
258
+ ### **Error state**
259
+
260
+ When the user enters an invalid value or otherwise makes a mistake, the input field should react by switching to the error state. The input field should highlight red, and the helper text should show an error message.
261
+
262
+ - **error: true**
263
+
264
+ When the user enters an invalid value or otherwise makes a mistake.
265
+
266
+ #### **Showing error helper text**
267
+
268
+ Helper text is **required** when the input is in an error state. If the input already had helper text before the error state, the helper text should change. If no helper text was present before the error, the error helper text should push down any content below the field.
269
+
270
+ - **Example 1: Changing helper text**
271
+
272
+ In this example, the original field already had helper text. It should change when the field is in an error state.
273
+ - **Example 2: New helper text**
274
+
275
+ In this example, the original did not have helper text. It should be added in when the field moves to an error state. Notice how the content below the field is pushed down.
276
+
277
+ See the Writing error helper text section for details on how error helper text should be phrased.
278
+
279
+ ### **Placeholder text is temporary**
280
+
281
+ If placeholder text is used, keep in mind that it will disappear once the user starts typing. See the previous Using placeholder text section to decide if placeholder text is right for your input field.
282
+
283
+ _behavior\_placeholder\_01-ex_
284
+
285
+ ### **Enforcing character limit**
286
+
287
+ See the previous Character limits section to determine if a character limit should be enforced on your input field.
288
+
289
+ If a field does have a character limit, it’s important to consider when and how the user should be informed about the character limit. Use the following guidelines based on how likely the user is to reach the character limit.
290
+
291
+ #### **Reaching the limit is common**
292
+
293
+ If it is common for the user to reach the character limit in a field:
294
+
295
+ 1. Inform them of the character limit in the helper text before they begin typing:
296
+ - _Max length is_ _**X**_ _characters_
297
+ 2. As the user begins typing, the helper text does not change.
298
+ 3. Once the user’s input reaches 80% of the character limit, change the helper text to:
299
+ - _**X**_ _characters remaining_
300
+ 4. Continue changing the count as the user types. If they go back below 80%, revert to the original helper text.
301
+ 5. If the input reaches the character limit, allow the user to keep typing. Change the field to an error state, and change the helper text to:
302
+ - _**X**_ _characters over limit_
303
+
304
+ #### **Reaching the limit is NOT common**
305
+
306
+ If it is uncommon for the user to reach the character limit in a field:
307
+
308
+ 1. Don’t inform them of the character limit in the helper text before they begin typing.
309
+ 2. If the input does reach 80% of the character limit, then introduce helper text:
310
+ - _**X**_ _characters remaining_
311
+ 3. Continue changing the count as the user types. If they go back below 80%, hide the helper text.
312
+ 4. If the input reaches the character limit, allow the user to keep typing. Change the field to an error state, and change the helper text to:
313
+ - _**X**_ _characters over limit_
314
+
315
+ ### **Enforcing character restrictions**
316
+
317
+ See the previous Character restrictions section to determine if a character limit should be enforced on your input field.
318
+
319
+ If a field does have character restrictions, it’s important to consider when and how the user should be informed about the character limit. Use the following guidelines to determine how to best enforce character limits for your field.
320
+
321
+ If there are only a few restricted characters, but they are **common** characters, the user should be informed of the restrictions in the helper text. In the example below, the financial institution is using an API that does not allow a few common characters: **$** **%** **#**
322
+
323
+ - **Do:** When only a characters are restricted, and they are common characters, list them out in the helper text before the user starts typing.
324
+ - **Don't:** When the restricted characters are common, don’t wait until a validation error occurs to inform the user of the restriction.
325
+
326
+ If there are only a few restricted characters, but they are **uncommon** characters, the user does not need to be informed in the helper text until a validation error occurs. In the example below, the financial institution is using an API that does not allow a few uncommon characters: **§** **‡**
327
+
328
+ - **Do:** If it is unlikely that the user will enter the restricted characters, wait until they actually input a restricted character before informing them.
329
+ - **Caution:** While informing users about character restrictions in the helper text is usually recommended, including it for very uncommon characters will take up unnecessary vertical space.
330
+
331
+ If only a specific set of characters is allowed, the user should be informed of the restrictions in the helper text. When possible, summarize the allowed characters instead of listing them out. In the example below, the financial institution is using an API that only allows alphanumeric characters in an account name.
332
+
333
+ - **Do:** Summarize what characters are allowed in the helper text to inform the user before they begin typing.
334
+ - **Don't:** When only a specific set of characters is allowed, don’t wait until a validation error occurs to inform the user of the restriction.
335
+
336
+ If a field has character restrictions that are common-knowledge, the restrictions do not need to be explained in the helper text. If the user does enter a non-permitted character, the error should be explained in the helper text.
337
+
338
+ - **Do:** For fields with common-knowledge restrictions, wait until the user makes an error to inform them that their input is invalid. In this example, email addresses have other validation steps aside from what characters are allowed, so checking for restricted characters should just be part of that validation process.
339
+ - **Don't:** Don’t use the helper text to try and explain long and/or complicated rules to the user. It is not practical or useful to the user. If the user were creating an email address in this example, then explaining some rules may be helpful. But it should not be done in the helper text.
340
+
341
+ ## Content
342
+
343
+ ## **Label**
344
+
345
+ Every input field in a form should have a corresponding label that helps the user understand what the input means. Labels should clearly and concisely describe the value or response requested from the user.
346
+
347
+ Use these guidelines when writing labels:
348
+
349
+ - Use between 1 to 3 words when possible
350
+ - Labels should be written in sentence case (aside from proper nouns)
351
+ - Don’t include a colon (:) after the label
352
+
353
+ * **Do:** In this example, the labels are short, but are also clearly asking the user to create a name and select a type for the new account they are creating.
354
+ * **Don't:** In this example, the labels are too short, so they becomes ambiguous. Is “Name” asking for the user’s name, the bank’s name, or the account’s name? And what is “Type” referring to? The user can’t know for sure before responding.
355
+ * **Don't:** In this example, the labels are too long. The user already understands that they are being asked to complete the form, so the action verbs are not necessary.
356
+
357
+ **Helper text**
358
+
359
+ Helper text should be short and concise, and only provide information that is crucial to helping the user complete the form. Use these guidelines when writing helper text:
360
+
361
+ - Aim for 1 line of text
362
+ - Longer helper text should wrap to the next line, and not go too far past the longest option label
363
+ - Helper text should be written in sentence case (aside from proper nouns)
364
+
365
+ * **Do:** When writing helper text, aim for a single line of text. If the text must be longer, it should wrap down to a second line.
366
+ * **Don't:** Helper text should not be longer than the input area. Wrap longer text down to a second line.
367
+
368
+ ### **Error helper text**
369
+
370
+ Helper text must always be included when the input is an an error state. The combination of the icon, red color, and text must help the user understand:
371
+
372
+ 1. The field has an error
373
+ 2. What the error is
374
+ 3. How the user can correct their input and resolve the error
375
+
376
+ - **Do:** This example concisely tells the user that there is an error, what the error is, and what they can do to resolve it.
377
+ - **Caution:** Avoid vague explanations. This example tells the user that there is an error, but is not specific enough about why the value is invalid.
378
+ - **Don't:** Don’t write unnecessarily long helper text. This example meets all the criteria listed above, but it is too long.
379
+
380
+ **Placeholder text**
381
+
382
+ If you do decide to use placeholder text, it should should be short and concise. It disappears when the user starts typing, so it should only provide information or hints that are not crucial. Use these guidelines when writing helper text:
383
+
384
+ - Do not exceed the bounds of the input field (truncation)
385
+ - Use anonymized values instead of real ones when possible
386
+ - Do not repeat the field’s label as placeholder text
387
+
388
+ * **Do:** Use anonymized values in placeholder text to avoid confusion. The inclusion of “e.g.” before the example helps the user understand that this is an example, not a value they have actually filled in.
389
+ * **Don't:** Don’t use values in placeholder text that look real or are real. This may accidentally trick users into thinking they already completed the field, which will lead to an error when they try to submit the form.
@@ -0,0 +1,103 @@
1
+ # FDIC Digital Sign (https://design.candescent.com/docs/components/insurance-disclosure)
2
+
3
+ Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=8550-3291), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/domain-insurancedisclosure--default)
4
+
5
+ Presents the official FDIC lockup alongside optional disclosure copy. When `logoSource` is omitted, the bundled FDIC mark is rendered. Logo, accessible label, and copy are controlled via props — not a compound component.
6
+
7
+ ```tsx
8
+ import { InsuranceDisclosure } from '@cdx-ui/components';
9
+ ```
10
+
11
+ ## Basic
12
+
13
+ Unframed disclosure with Figma statement copy. This is the default layout — no border or padding on the root.
14
+
15
+ ```tsx
16
+ import { InsuranceDisclosure } from '@cdx-ui/components';
17
+
18
+ const FIGMA_STATEMENT = 'FDIC-Insured—Backed by the full faith and credit of the U.S. Government';
19
+
20
+ export default function InsuranceDisclosureBasicDemo() {
21
+ return <InsuranceDisclosure label={FIGMA_STATEMENT} />;
22
+ }
23
+ ```
24
+
25
+ ## Framed
26
+
27
+ Pass `framed` to add surface chrome (background, border, radius, and padding). Prior versions always rendered this chrome; existing usages that need it must opt in with `framed`.
28
+
29
+ ```tsx
30
+ import { InsuranceDisclosure } from '@cdx-ui/components';
31
+
32
+ const FIGMA_STATEMENT = 'FDIC-Insured—Backed by the full faith and credit of the U.S. Government';
33
+
34
+ export default function InsuranceDisclosureFramedDemo() {
35
+ return <InsuranceDisclosure framed label={FIGMA_STATEMENT} />;
36
+ }
37
+ ```
38
+
39
+ ## Logo only
40
+
41
+ Omit `label` to render just the bundled FDIC lockup.
42
+
43
+ ```tsx
44
+ import { InsuranceDisclosure } from '@cdx-ui/components';
45
+
46
+ export default function InsuranceDisclosureLogoOnlyDemo() {
47
+ return <InsuranceDisclosure />;
48
+ }
49
+ ```
50
+
51
+ ## Long copy
52
+
53
+ Longer disclosure text wraps within the row; constrain width at the layout level when needed.
54
+
55
+ ```tsx
56
+ import { Box, InsuranceDisclosure } from '@cdx-ui/components';
57
+
58
+ export default function InsuranceDisclosureLongCopyDemo() {
59
+ return (
60
+ <Box className="max-w-md">
61
+ <InsuranceDisclosure
62
+ label={
63
+ 'FDIC-Insured—Backed by the full faith and credit of the U.S. Government. ' +
64
+ 'Deposits are insured up to the maximum amount permitted by law. ' +
65
+ 'Please contact your financial institution for full terms and coverage details.'
66
+ }
67
+ />
68
+ </Box>
69
+ );
70
+ }
71
+ ```
72
+
73
+ ## API
74
+
75
+ ### InsuranceDisclosure
76
+
77
+ | Prop | Type | Default | Description |
78
+ | --- | --- | --- | --- |
79
+ | `className?` | `string` | — | — |
80
+ | `space?` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| '3xl' \| '4xl' \| '5xl' \| '6xl'` | — | — |
81
+ | `reversed?` | `boolean` | — | — |
82
+ | `logoSource?` | `string \| ImageSourcePropType` | — | — |
83
+ | `logoAccessibilityLabel?` | `string` | — | — |
84
+ | `framed?` | `boolean` | — | — |
85
+ | `label?` | `string` | — | — |
86
+
87
+ Wraps `HStack` — all `HStackProps` except `children` are supported (`space`, `reversed`, and [`ViewProps`](https://reactnative.dev/docs/view#props)).
88
+
89
+ ## Anatomy
90
+
91
+ Renders an `HStack` with `space="md"` containing the FDIC lockup and, when `label` is provided, italic disclosure text. When `framed` is `true`, the root also has surface chrome (`bg-surface-primary`, border, radius, `px-3 py-2`). Content is driven by props, not sub-components.
92
+
93
+ | `data-slot` | Element |
94
+ | ------------------------------ | ---------------------------------------- |
95
+ | `insurance-disclosure` | Root row |
96
+ | `insurance-disclosure-logo` | Logo (bundled SVG or custom image) |
97
+ | `insurance-disclosure-content` | Label wrapper (only when `label` is set) |
98
+
99
+ ## Accessibility
100
+
101
+ - When `logoSource` is omitted, the bundled FDIC lockup uses `accessibilityLabel="FDIC"`.
102
+ - When `logoSource` is set, `logoAccessibilityLabel` is **required** — the custom logo is exposed via `accessibilityLabel`.
103
+ - The disclosure `label` is static text and is not a live region; announce dynamic regulatory changes elsewhere.
@@ -0,0 +1,180 @@
1
+ # Link (https://design.candescent.com/docs/components/link)
2
+
3
+ Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=457-874), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/actions-link--open-in-new-tab)
4
+
5
+ A compound component with sub-components for label and icon. Router-agnostic — integrate with Expo Router, React Navigation, or Next.js via `LinkProvider`.
6
+
7
+ ```tsx
8
+ import { Link } from '@cdx-ui/components';
9
+ ```
10
+
11
+ ## Basic
12
+
13
+ ```tsx
14
+ import { Link } from '@cdx-ui/components';
15
+
16
+ export default function LinkBasicDemo() {
17
+ return (
18
+ <Link href="https://example.com">
19
+ <Link.Label>Settings</Link.Label>
20
+ </Link>
21
+ );
22
+ }
23
+ ```
24
+
25
+ ## With icons
26
+
27
+ Use `Link.Icon` for a leading or trailing icon alongside the label.
28
+
29
+ ```tsx
30
+ import { Link, Box } from '@cdx-ui/components';
31
+ import { ChevronRight, Link2 } from '@cdx-ui/icons';
32
+
33
+ export default function LinkWithIconDemo() {
34
+ return (
35
+ <Box className="gap-4">
36
+ <Link href="https://example.com/manage">
37
+ <Link.Label>Manage</Link.Label>
38
+ <Link.Icon as={ChevronRight} />
39
+ </Link>
40
+ <Link href="https://example.com/details">
41
+ <Link.Icon as={Link2} />
42
+ <Link.Label>Details</Link.Label>
43
+ </Link>
44
+ </Box>
45
+ );
46
+ }
47
+ ```
48
+
49
+ ## Open in new tab
50
+
51
+ Pass web-only anchor attributes through `webProps`.
52
+
53
+ ```tsx
54
+ import { Link } from '@cdx-ui/components';
55
+
56
+ export default function LinkOpenInNewTabDemo() {
57
+ return (
58
+ <Link href="https://example.com" webProps={{ target: '_blank', rel: 'noopener' }}>
59
+ <Link.Label>Open in new tab</Link.Label>
60
+ </Link>
61
+ );
62
+ }
63
+ ```
64
+
65
+ ## Inline with text
66
+
67
+ On web, `Link` flows inline with surrounding text. On native, use a flex row layout instead of nesting inside `Text`.
68
+
69
+ ```tsx
70
+ import { Link, Text } from '@cdx-ui/components';
71
+
72
+ export default function LinkInlineDemo() {
73
+ return (
74
+ <Text>
75
+ Read our{' '}
76
+ <Link href="https://example.com/terms">
77
+ <Link.Label>Terms of Service</Link.Label>
78
+ </Link>{' '}
79
+ and{' '}
80
+ <Link href="https://example.com/privacy">
81
+ <Link.Label>Privacy Policy</Link.Label>
82
+ </Link>
83
+ .
84
+ </Text>
85
+ );
86
+ }
87
+ ```
88
+
89
+ ## Visited
90
+
91
+ On web, visited styling uses the native CSS `:visited` pseudo-class. On native, pass `isVisited`.
92
+
93
+ ```tsx
94
+ import { Link, Box } from '@cdx-ui/components';
95
+
96
+ export default function LinkVisitedDemo() {
97
+ return (
98
+ <Box className="gap-4">
99
+ <Link href="https://example.com">
100
+ <Link.Label>Default link</Link.Label>
101
+ </Link>
102
+ <Link href="https://example.com/visited" isVisited>
103
+ <Link.Label>Visited link</Link.Label>
104
+ </Link>
105
+ </Box>
106
+ );
107
+ }
108
+ ```
109
+
110
+ ## API
111
+
112
+ ### Link
113
+
114
+ | Prop | Type | Default | Description |
115
+ | --- | --- | --- | --- |
116
+ | `className?` | `string` | — | — |
117
+ | `children?` | `ReactNode` | — | Either children or a render prop that receives a boolean reflecting whether the component is currently pressed. |
118
+ | `asChild?` | `boolean` | — | Renders the consumer's child element in place of the default pressable host. |
119
+ | `href?` | `string` | — | URL or route path opened on press. Omit when the link only runs `onPress`. |
120
+ | `action?` | `'navigate' \| 'push' \| 'replace'` | — | Navigation action forwarded to the `LinkProvider`. Defaults to `'navigate'`. |
121
+ | `isVisited?` | `boolean` | — | If true, the link will render in its visited style (native). On web, visited styling is driven by the CSS `:visited` pseudo-class. |
122
+ | `webProps?` | `React.AnchorHTMLAttributes<HTMLAnchorElement>` | — | HTML anchor attributes applied only on web. Ignored on native platforms. `target`, `rel`, and `download` are forwarded via react-native-web's `hrefAttrs`. |
123
+
124
+ Inherits all [`PressableProps`](https://reactnative.dev/docs/pressable#props) (including `onPress`).
125
+
126
+ ## Sub-components
127
+
128
+ ### Link.Label
129
+
130
+ Styled text content inside the link. Uses `text-content-link` with underline and offset.
131
+
132
+ | Prop | Type | Default | Description |
133
+ | --- | --- | --- | --- |
134
+ | `className?` | `string` | — | — |
135
+ | `children?` | `ReactNode` | — | — |
136
+ | `asChild?` | `boolean` | — | Renders the consumer's child element in place of the default `Text` host. |
137
+
138
+ Inherits all [`TextProps`](https://reactnative.dev/docs/text#props).
139
+
140
+ ### Link.Icon
141
+
142
+ Renders a Forge icon inside the link. Sized to match the label with `text-content-link` color.
143
+
144
+ | Prop | Type | Default | Description |
145
+ | --- | --- | --- | --- |
146
+ | `className?` | `string` | — | Utility classes for size (`size-*`) and placement, merged after the defaults. |
147
+ | `filled?` | `boolean` | — | When `true`, renders the filled variant of the icon (if available). Defaults to `false` (outlined). |
148
+ | `size?` | `string \| number` | — | Width and height of the icon, in pixels or any SVG length. The bare icon renders at 24 when omitted. |
149
+ | `data-testid?` | `string` | — | Test identifier forwarded to the rendered SVG. |
150
+ | `as` | `ForgeIcon` | — | The `@cdx-ui/icons` component to render. |
151
+
152
+ Inherits all `ForgeIconProps` (react-native-svg `SvgProps` plus `filled` and `size`).
153
+
154
+ ## LinkProvider
155
+
156
+ Wrap your app to integrate `Link` with your router. Without a provider, links behave like `<a>` on web and call `Linking.openURL` on native.
157
+
158
+ | Prop | Type | Default | Description |
159
+ | --- | --- | --- | --- |
160
+ | `navigate` | `(href: string, action: LinkAction) => void \| Promise<void>` | — | Global navigation handler for `<Link>` instances whose `href` passes the `shouldNavigate` check. Called with the `href` and the per-instance `action`. |
161
+ | `shouldNavigate?` | `((href: string) => boolean)` | — | Optional predicate evaluated at **render time** to decide whether the provider should handle a given `href`. - Returns `true` → the provider's `navigate` is called on press; on web the native `<a href>` is **removed** so the browser doesn't follow the link. - Returns `false` → the provider is bypassed; on web the `<a href>` is preserved (cmd-click, SEO, etc.); on native `Linking.openURL` is used. Defaults to `() => true` when omitted (all hrefs go through the provider). |
162
+ | `children` | `ReactNode` | — | — |
163
+
164
+ Use `shouldNavigate` to keep external URLs on the native `<a>` / `Linking.openURL` path (preserves cmd-click and “Copy link address” on web).
165
+
166
+ ```tsx
167
+ import { LinkProvider, type LinkAction } from '@cdx-ui/components';
168
+
169
+ function shouldNavigate(href: string): boolean {
170
+ return !/^https?:\/\//.test(href);
171
+ }
172
+
173
+ function navigate(href: string, action: LinkAction) {
174
+ // e.g. router.navigate / router.push / router.replace
175
+ }
176
+
177
+ <LinkProvider navigate={navigate} shouldNavigate={shouldNavigate}>
178
+ {children}
179
+ </LinkProvider>
180
+ ```