@olympusoss/canvas 3.2.1 → 5.0.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 (302) hide show
  1. package/README.md +75 -65
  2. package/package.json +11 -5
  3. package/src/atoms/avatar/avatar.md +185 -0
  4. package/src/atoms/avatar/avatar.styles.ts +48 -0
  5. package/src/atoms/avatar/avatar.tsx +99 -0
  6. package/src/atoms/badge/badge.md +237 -0
  7. package/src/atoms/badge/badge.styles.ts +79 -0
  8. package/src/atoms/badge/badge.tsx +86 -0
  9. package/src/atoms/breadcrumb/breadcrumb.md +233 -0
  10. package/src/atoms/breadcrumb/breadcrumb.styles.ts +40 -0
  11. package/src/atoms/breadcrumb/breadcrumb.tsx +130 -0
  12. package/src/atoms/button/button.android.tsx +6 -0
  13. package/src/atoms/button/button.ios.tsx +6 -0
  14. package/src/atoms/button/button.md +184 -0
  15. package/src/atoms/button/button.shared.tsx +79 -0
  16. package/src/atoms/button/button.styles.ts +152 -0
  17. package/src/atoms/button/button.tsx +6 -0
  18. package/src/atoms/button-group/button-group.android.tsx +6 -0
  19. package/src/atoms/button-group/button-group.ios.tsx +6 -0
  20. package/src/atoms/button-group/button-group.md +120 -0
  21. package/src/atoms/button-group/button-group.shared.tsx +398 -0
  22. package/src/atoms/button-group/button-group.styles.ts +483 -0
  23. package/src/atoms/button-group/button-group.tsx +6 -0
  24. package/src/atoms/checkbox/checkbox.android.tsx +6 -0
  25. package/src/atoms/checkbox/checkbox.ios.tsx +6 -0
  26. package/src/atoms/checkbox/checkbox.md +150 -0
  27. package/src/atoms/checkbox/checkbox.shared.tsx +103 -0
  28. package/src/atoms/checkbox/checkbox.styles.ts +106 -0
  29. package/src/atoms/checkbox/checkbox.tsx +6 -0
  30. package/src/atoms/combobox/combobox.android.tsx +6 -0
  31. package/src/atoms/combobox/combobox.ios.tsx +6 -0
  32. package/src/atoms/combobox/combobox.md +213 -0
  33. package/src/atoms/combobox/combobox.shared.tsx +160 -0
  34. package/src/atoms/combobox/combobox.styles.ts +270 -0
  35. package/src/atoms/combobox/combobox.tsx +6 -0
  36. package/src/atoms/divider/divider.md +140 -0
  37. package/src/atoms/divider/divider.styles.ts +35 -0
  38. package/src/atoms/divider/divider.tsx +67 -0
  39. package/src/atoms/dropdown/dropdown.android.tsx +6 -0
  40. package/src/atoms/dropdown/dropdown.ios.tsx +6 -0
  41. package/src/atoms/dropdown/dropdown.md +221 -0
  42. package/src/atoms/dropdown/dropdown.shared.tsx +190 -0
  43. package/src/atoms/dropdown/dropdown.styles.ts +233 -0
  44. package/src/atoms/dropdown/dropdown.tsx +6 -0
  45. package/src/atoms/icon/icon.md +131 -0
  46. package/src/atoms/icon/icon.styles.ts +30 -0
  47. package/src/atoms/icon/icon.tsx +328 -0
  48. package/src/atoms/index.ts +24 -0
  49. package/src/atoms/input/input.android.tsx +6 -0
  50. package/src/atoms/input/input.ios.tsx +6 -0
  51. package/src/atoms/input/input.md +118 -0
  52. package/src/atoms/input/input.shared.tsx +203 -0
  53. package/src/atoms/input/input.styles.ts +286 -0
  54. package/src/atoms/input/input.tsx +6 -0
  55. package/src/atoms/kbd/kbd.md +91 -0
  56. package/src/atoms/kbd/kbd.styles.ts +33 -0
  57. package/src/atoms/kbd/kbd.tsx +27 -0
  58. package/src/atoms/listbox/listbox.md +177 -0
  59. package/src/atoms/listbox/listbox.styles.ts +60 -0
  60. package/src/atoms/listbox/listbox.tsx +113 -0
  61. package/src/atoms/pagination/pagination.android.tsx +6 -0
  62. package/src/atoms/pagination/pagination.ios.tsx +6 -0
  63. package/src/atoms/pagination/pagination.md +133 -0
  64. package/src/atoms/pagination/pagination.shared.tsx +289 -0
  65. package/src/atoms/pagination/pagination.styles.ts +245 -0
  66. package/src/atoms/pagination/pagination.tsx +6 -0
  67. package/src/atoms/popover/popover.android.tsx +8 -0
  68. package/src/atoms/popover/popover.ios.tsx +6 -0
  69. package/src/atoms/popover/popover.md +87 -0
  70. package/src/atoms/popover/popover.shared.tsx +124 -0
  71. package/src/atoms/popover/popover.styles.ts +144 -0
  72. package/src/atoms/popover/popover.tsx +6 -0
  73. package/src/atoms/radio/radio.android.tsx +6 -0
  74. package/src/atoms/radio/radio.ios.tsx +6 -0
  75. package/src/atoms/radio/radio.md +173 -0
  76. package/src/atoms/radio/radio.shared.tsx +98 -0
  77. package/src/atoms/radio/radio.styles.ts +109 -0
  78. package/src/atoms/radio/radio.tsx +6 -0
  79. package/src/atoms/select/select.android.tsx +6 -0
  80. package/src/atoms/select/select.ios.tsx +6 -0
  81. package/src/atoms/select/select.md +156 -0
  82. package/src/atoms/select/select.shared.tsx +143 -0
  83. package/src/atoms/select/select.styles.ts +310 -0
  84. package/src/atoms/select/select.tsx +6 -0
  85. package/src/atoms/skeleton/skeleton.md +135 -0
  86. package/src/atoms/skeleton/skeleton.styles.ts +117 -0
  87. package/src/atoms/skeleton/skeleton.tsx +145 -0
  88. package/src/atoms/spinner/spinner.android.tsx +7 -0
  89. package/src/atoms/spinner/spinner.ios.tsx +7 -0
  90. package/src/atoms/spinner/spinner.md +94 -0
  91. package/src/atoms/spinner/spinner.shared.tsx +92 -0
  92. package/src/atoms/spinner/spinner.styles.tsx +115 -0
  93. package/src/atoms/spinner/spinner.tsx +7 -0
  94. package/src/atoms/switch/switch.android.tsx +6 -0
  95. package/src/atoms/switch/switch.ios.tsx +6 -0
  96. package/src/atoms/switch/switch.md +91 -0
  97. package/src/atoms/switch/switch.shared.tsx +97 -0
  98. package/src/atoms/switch/switch.styles.ts +79 -0
  99. package/src/atoms/switch/switch.tsx +6 -0
  100. package/src/atoms/textarea/textarea.android.tsx +6 -0
  101. package/src/atoms/textarea/textarea.ios.tsx +6 -0
  102. package/src/atoms/textarea/textarea.md +140 -0
  103. package/src/atoms/textarea/textarea.shared.tsx +74 -0
  104. package/src/atoms/textarea/textarea.styles.ts +116 -0
  105. package/src/atoms/textarea/textarea.tsx +6 -0
  106. package/src/atoms/tooltip/tooltip.android.tsx +6 -0
  107. package/src/atoms/tooltip/tooltip.ios.tsx +7 -0
  108. package/src/atoms/tooltip/tooltip.md +122 -0
  109. package/src/atoms/tooltip/tooltip.shared.tsx +113 -0
  110. package/src/atoms/tooltip/tooltip.styles.ts +113 -0
  111. package/src/atoms/tooltip/tooltip.tsx +6 -0
  112. package/src/atoms/typography/typography.md +330 -0
  113. package/src/atoms/typography/typography.styles.ts +95 -0
  114. package/src/atoms/typography/typography.tsx +76 -0
  115. package/src/index.ts +12 -2
  116. package/src/molecules/action-panels/action-panels.md +133 -0
  117. package/src/molecules/action-panels/action-panels.styles.ts +39 -0
  118. package/src/molecules/action-panels/action-panels.tsx +113 -0
  119. package/src/molecules/alert/alert.md +119 -0
  120. package/src/molecules/alert/alert.styles.ts +88 -0
  121. package/src/molecules/alert/alert.tsx +74 -0
  122. package/src/molecules/alert-dialog/alert-dialog.android.tsx +6 -0
  123. package/src/molecules/alert-dialog/alert-dialog.ios.tsx +6 -0
  124. package/src/molecules/alert-dialog/alert-dialog.md +177 -0
  125. package/src/molecules/alert-dialog/alert-dialog.shared.tsx +187 -0
  126. package/src/molecules/alert-dialog/alert-dialog.styles.ts +248 -0
  127. package/src/molecules/alert-dialog/alert-dialog.tsx +6 -0
  128. package/src/molecules/card/card.md +190 -0
  129. package/src/molecules/card/card.styles.ts +67 -0
  130. package/src/molecules/card/card.tsx +176 -0
  131. package/src/molecules/code-block/code-block.md +159 -0
  132. package/src/molecules/code-block/code-block.styles.ts +167 -0
  133. package/src/molecules/code-block/code-block.tsx +176 -0
  134. package/src/molecules/description-lists/description-lists.md +129 -0
  135. package/src/molecules/description-lists/description-lists.styles.ts +102 -0
  136. package/src/molecules/description-lists/description-lists.tsx +133 -0
  137. package/src/molecules/empty-state/empty-state.md +218 -0
  138. package/src/molecules/empty-state/empty-state.styles.ts +63 -0
  139. package/src/molecules/empty-state/empty-state.tsx +77 -0
  140. package/src/molecules/feeds/feeds.md +102 -0
  141. package/src/molecules/feeds/feeds.styles.ts +120 -0
  142. package/src/molecules/feeds/feeds.tsx +167 -0
  143. package/src/molecules/field/field.md +117 -0
  144. package/src/molecules/field/field.styles.ts +85 -0
  145. package/src/molecules/field/field.tsx +175 -0
  146. package/src/molecules/fieldset/fieldset.md +141 -0
  147. package/src/molecules/fieldset/fieldset.styles.ts +79 -0
  148. package/src/molecules/fieldset/fieldset.tsx +182 -0
  149. package/src/molecules/form/form.md +137 -0
  150. package/src/molecules/form/form.styles.ts +39 -0
  151. package/src/molecules/form/form.tsx +246 -0
  152. package/src/molecules/grid-lists/grid-lists.md +114 -0
  153. package/src/molecules/grid-lists/grid-lists.styles.ts +79 -0
  154. package/src/molecules/grid-lists/grid-lists.tsx +157 -0
  155. package/src/molecules/index.ts +16 -0
  156. package/src/molecules/media-objects/media-objects.md +87 -0
  157. package/src/molecules/media-objects/media-objects.styles.ts +94 -0
  158. package/src/molecules/media-objects/media-objects.tsx +128 -0
  159. package/src/molecules/stacked-lists/stacked-lists.md +116 -0
  160. package/src/molecules/stacked-lists/stacked-lists.styles.ts +111 -0
  161. package/src/molecules/stacked-lists/stacked-lists.tsx +195 -0
  162. package/src/molecules/stats/stats.md +166 -0
  163. package/src/molecules/stats/stats.styles.ts +91 -0
  164. package/src/molecules/stats/stats.tsx +88 -0
  165. package/src/organisms/calendar/calendar.android.tsx +6 -0
  166. package/src/organisms/calendar/calendar.ios.tsx +6 -0
  167. package/src/organisms/calendar/calendar.md +114 -0
  168. package/src/organisms/calendar/calendar.shared.tsx +146 -0
  169. package/src/organisms/calendar/calendar.styles.ts +315 -0
  170. package/src/organisms/calendar/calendar.tsx +6 -0
  171. package/src/organisms/charts/charts.md +326 -0
  172. package/src/organisms/charts/charts.styles.ts +135 -0
  173. package/src/organisms/charts/charts.tsx +124 -0
  174. package/src/organisms/command/command.md +117 -0
  175. package/src/organisms/command/command.styles.ts +179 -0
  176. package/src/organisms/command/command.tsx +164 -0
  177. package/src/organisms/data-table/data-table.md +182 -0
  178. package/src/organisms/data-table/data-table.styles.ts +103 -0
  179. package/src/organisms/data-table/data-table.tsx +105 -0
  180. package/src/organisms/dialog/dialog.android.tsx +6 -0
  181. package/src/organisms/dialog/dialog.ios.tsx +6 -0
  182. package/src/organisms/dialog/dialog.md +271 -0
  183. package/src/organisms/dialog/dialog.shared.tsx +230 -0
  184. package/src/organisms/dialog/dialog.styles.ts +272 -0
  185. package/src/organisms/dialog/dialog.tsx +6 -0
  186. package/src/organisms/filter-panel/filter-panel.md +116 -0
  187. package/src/organisms/filter-panel/filter-panel.styles.ts +83 -0
  188. package/src/organisms/filter-panel/filter-panel.tsx +91 -0
  189. package/src/organisms/index.ts +13 -0
  190. package/src/organisms/navbars/navbars.android.tsx +6 -0
  191. package/src/organisms/navbars/navbars.ios.tsx +6 -0
  192. package/src/organisms/navbars/navbars.md +144 -0
  193. package/src/organisms/navbars/navbars.shared.tsx +137 -0
  194. package/src/organisms/navbars/navbars.styles.ts +251 -0
  195. package/src/organisms/navbars/navbars.tsx +6 -0
  196. package/src/organisms/overlays/overlays.android.tsx +6 -0
  197. package/src/organisms/overlays/overlays.ios.tsx +6 -0
  198. package/src/organisms/overlays/overlays.md +123 -0
  199. package/src/organisms/overlays/overlays.shared.tsx +175 -0
  200. package/src/organisms/overlays/overlays.styles.ts +309 -0
  201. package/src/organisms/overlays/overlays.tsx +6 -0
  202. package/src/organisms/row-menu/row-menu.android.tsx +6 -0
  203. package/src/organisms/row-menu/row-menu.ios.tsx +6 -0
  204. package/src/organisms/row-menu/row-menu.md +102 -0
  205. package/src/organisms/row-menu/row-menu.shared.tsx +105 -0
  206. package/src/organisms/row-menu/row-menu.styles.ts +262 -0
  207. package/src/organisms/row-menu/row-menu.tsx +6 -0
  208. package/src/organisms/sidebar/sidebar.android.tsx +6 -0
  209. package/src/organisms/sidebar/sidebar.ios.tsx +6 -0
  210. package/src/organisms/sidebar/sidebar.md +188 -0
  211. package/src/organisms/sidebar/sidebar.shared.tsx +167 -0
  212. package/src/organisms/sidebar/sidebar.styles.ts +262 -0
  213. package/src/organisms/sidebar/sidebar.tsx +6 -0
  214. package/src/organisms/stepper/stepper.android.tsx +6 -0
  215. package/src/organisms/stepper/stepper.ios.tsx +6 -0
  216. package/src/organisms/stepper/stepper.md +150 -0
  217. package/src/organisms/stepper/stepper.shared.tsx +158 -0
  218. package/src/organisms/stepper/stepper.styles.ts +280 -0
  219. package/src/organisms/stepper/stepper.tsx +6 -0
  220. package/src/organisms/tabs/tabs.android.tsx +6 -0
  221. package/src/organisms/tabs/tabs.ios.tsx +6 -0
  222. package/src/organisms/tabs/tabs.md +127 -0
  223. package/src/organisms/tabs/tabs.shared.tsx +281 -0
  224. package/src/organisms/tabs/tabs.styles.ts +398 -0
  225. package/src/organisms/tabs/tabs.tsx +6 -0
  226. package/src/style/color.ts +17 -0
  227. package/src/style/index.ts +14 -0
  228. package/src/style/primitives.ts +26 -0
  229. package/src/style/responsive.ts +45 -0
  230. package/src/style/shadow.ts +21 -0
  231. package/src/style/theme.tsx +56 -0
  232. package/src/style/tokens.ts +487 -0
  233. package/styles/canvas.css +127 -74
  234. package/tsconfig.json +4 -2
  235. package/src/cn.ts +0 -3
  236. package/styles/atoms/avatar.css +0 -22
  237. package/styles/atoms/badge.css +0 -83
  238. package/styles/atoms/breadcrumb.css +0 -35
  239. package/styles/atoms/button-group.css +0 -23
  240. package/styles/atoms/button.css +0 -107
  241. package/styles/atoms/checkbox.css +0 -55
  242. package/styles/atoms/combobox.css +0 -76
  243. package/styles/atoms/dropdown.css +0 -54
  244. package/styles/atoms/icon.css +0 -8
  245. package/styles/atoms/input-group.css +0 -45
  246. package/styles/atoms/input.css +0 -56
  247. package/styles/atoms/kbd.css +0 -15
  248. package/styles/atoms/pagination.css +0 -48
  249. package/styles/atoms/popover.css +0 -14
  250. package/styles/atoms/radio.css +0 -28
  251. package/styles/atoms/select.css +0 -57
  252. package/styles/atoms/separator.css +0 -32
  253. package/styles/atoms/skeleton.css +0 -32
  254. package/styles/atoms/spinner.css +0 -26
  255. package/styles/atoms/switch.css +0 -45
  256. package/styles/atoms/textarea.css +0 -31
  257. package/styles/atoms/tooltip.css +0 -53
  258. package/styles/atoms/typography.css +0 -105
  259. package/styles/base.css +0 -17
  260. package/styles/molecules/alert.css +0 -66
  261. package/styles/molecules/card.css +0 -58
  262. package/styles/molecules/code-block.css +0 -18
  263. package/styles/molecules/empty-state.css +0 -17
  264. package/styles/molecules/field.css +0 -27
  265. package/styles/molecules/form.css +0 -27
  266. package/styles/molecules/page-header.css +0 -52
  267. package/styles/molecules/section-card.css +0 -49
  268. package/styles/molecules/stat-card.css +0 -71
  269. package/styles/molecules/toast.css +0 -95
  270. package/styles/organisms/app-shell.css +0 -46
  271. package/styles/organisms/calendar.css +0 -73
  272. package/styles/organisms/command.css +0 -95
  273. package/styles/organisms/data-table.css +0 -142
  274. package/styles/organisms/dialog.css +0 -72
  275. package/styles/organisms/filter-panel.css +0 -58
  276. package/styles/organisms/row-menu.css +0 -69
  277. package/styles/organisms/sheet.css +0 -70
  278. package/styles/organisms/sidebar.css +0 -146
  279. package/styles/organisms/stepper.css +0 -63
  280. package/styles/organisms/tabs.css +0 -40
  281. package/styles/organisms/topbar.css +0 -24
  282. package/styles/patterns/backdrops.css +0 -35
  283. package/styles/patterns/density.css +0 -66
  284. package/styles/patterns/focus.css +0 -22
  285. package/styles/patterns/glass.css +0 -85
  286. package/styles/patterns/high-contrast.css +0 -70
  287. package/styles/patterns/reduced-motion.css +0 -12
  288. package/styles/patterns/scrollbar.css +0 -10
  289. package/styles/reset.css +0 -89
  290. package/styles/tokens/colors.css +0 -108
  291. package/styles/tokens/motion.css +0 -33
  292. package/styles/tokens/radius.css +0 -10
  293. package/styles/tokens/shadows.css +0 -35
  294. package/styles/tokens/spacing.css +0 -19
  295. package/styles/tokens/typography.css +0 -6
  296. package/styles/tokens/z-index.css +0 -12
  297. package/styles/utilities/display.css +0 -66
  298. package/styles/utilities/flexbox.css +0 -240
  299. package/styles/utilities/gap.css +0 -288
  300. package/styles/utilities/grid.css +0 -138
  301. package/styles/utilities/position.css +0 -78
  302. package/styles/utilities/sizing.css +0 -138
@@ -0,0 +1,330 @@
1
+ # Typography
2
+
3
+ Type scale classes for headings, body text, and helper styles.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <Typography h1>The quick brown fox</Typography>
9
+ ```
10
+
11
+ ## Variants
12
+
13
+ ### Style - display
14
+
15
+ ```tsx
16
+ <Typography display>The quick brown fox</Typography>
17
+ ```
18
+
19
+ ### Style - h2
20
+
21
+ ```tsx
22
+ <Typography h2>The quick brown fox</Typography>
23
+ ```
24
+
25
+ ### Style - h3
26
+
27
+ ```tsx
28
+ <Typography h3>The quick brown fox</Typography>
29
+ ```
30
+
31
+ ### Style - h4
32
+
33
+ ```tsx
34
+ <Typography h4>The quick brown fox</Typography>
35
+ ```
36
+
37
+ ### Style - h5
38
+
39
+ ```tsx
40
+ <Typography h5>The quick brown fox</Typography>
41
+ ```
42
+
43
+ ### Style - body
44
+
45
+ ```tsx
46
+ <Typography body>The quick brown fox</Typography>
47
+ ```
48
+
49
+ ### Style - small
50
+
51
+ ```tsx
52
+ <Typography small>The quick brown fox</Typography>
53
+ ```
54
+
55
+ ### Style - tiny
56
+
57
+ ```tsx
58
+ <Typography tiny>The quick brown fox</Typography>
59
+ ```
60
+
61
+ ### Style - muted
62
+
63
+ ```tsx
64
+ <Typography muted>The quick brown fox</Typography>
65
+ ```
66
+
67
+ ### Style - caption
68
+
69
+ ```tsx
70
+ <Typography caption>The quick brown fox</Typography>
71
+ ```
72
+
73
+ ### Style - code
74
+
75
+ ```tsx
76
+ <Typography code>The quick brown fox</Typography>
77
+ ```
78
+
79
+ ### Style - mono
80
+
81
+ ```tsx
82
+ <Typography mono>The quick brown fox</Typography>
83
+ ```
84
+
85
+ ## Do & Don't
86
+
87
+ ### display
88
+
89
+ **Do** — Use display once per hero, then drop to a muted line for the supporting copy.
90
+
91
+ ```tsx
92
+ <View>
93
+ <Typography display>Welcome</Typography>
94
+ <Typography muted style={{ marginTop: 8 }}>Sign in to pick up where you left off.</Typography>
95
+ </View>
96
+ ```
97
+
98
+ **Don't** — Two display-size lines in one view fight for attention and leave no clear focal point.
99
+
100
+ ```tsx
101
+ <View style={{ gap: 8 }}>
102
+ <Typography display>Welcome</Typography>
103
+ <Typography display>Get started</Typography>
104
+ </View>
105
+ ```
106
+
107
+ ### h1
108
+
109
+ **Do** — Give each page a single h1, then step down to h2 for the sections beneath it.
110
+
111
+ ```tsx
112
+ <View>
113
+ <Typography h1>Billing</Typography>
114
+ <Typography h2 style={{ marginTop: 16 }}>Invoices</Typography>
115
+ </View>
116
+ ```
117
+
118
+ **Don't** — Two h1 titles on a page break the document outline and confuse assistive tech.
119
+
120
+ ```tsx
121
+ <View style={{ gap: 4 }}>
122
+ <Typography h1>Billing</Typography>
123
+ <Typography h1>Invoices</Typography>
124
+ </View>
125
+ ```
126
+
127
+ ### h2
128
+
129
+ **Do** — Follow an h1 with h2 for its top-level sections; don't skip the scale.
130
+
131
+ ```tsx
132
+ <View>
133
+ <Typography h1>Settings</Typography>
134
+ <Typography h2 style={{ marginTop: 16 }}>Profile</Typography>
135
+ </View>
136
+ ```
137
+
138
+ **Don't** — Jumping from h1 straight to h4 skips a level and flattens the visible hierarchy.
139
+
140
+ ```tsx
141
+ <View>
142
+ <Typography h1>Settings</Typography>
143
+ <Typography h4 style={{ marginTop: 16 }}>Profile</Typography>
144
+ </View>
145
+ ```
146
+
147
+ ### h3
148
+
149
+ **Do** — Reserve heading styles for titles; set running text in a small body utility.
150
+
151
+ ```tsx
152
+ <View style={{ maxWidth: 340 }}>
153
+ <Typography h3>About Canvas</Typography>
154
+ <Typography body style={{ marginTop: 4 }}>Canvas is a universal React Native UI kit for building consistent product interfaces.</Typography>
155
+ </View>
156
+ ```
157
+
158
+ **Don't** — Body copy set in a heading style is hard to read in bulk and flattens the hierarchy.
159
+
160
+ ```tsx
161
+ <Typography h3 style={{ maxWidth: 340 }}>Canvas is a universal React Native UI kit for building consistent product interfaces.</Typography>
162
+ ```
163
+
164
+ ### h4
165
+
166
+ **Do** — Keep h4 to a short label and carry the explanation in a small supporting line.
167
+
168
+ ```tsx
169
+ <View>
170
+ <Typography h4>Notifications</Typography>
171
+ <Typography small style={{ marginTop: 4 }}>Choose how and when we reach you.</Typography>
172
+ </View>
173
+ ```
174
+
175
+ **Don't** — h4 is a minor heading, not a place for full sentences; long text at this weight reads as a wall.
176
+
177
+ ```tsx
178
+ <View style={{ gap: 4 }}>
179
+ <Typography h4>Notifications</Typography>
180
+ <Typography h4>A long descriptive sentence that explains everything in detail.</Typography>
181
+ </View>
182
+ ```
183
+
184
+ ### h5
185
+
186
+ **Do** — Use h5 only for the label; render the value in body so the pair stays scannable.
187
+
188
+ ```tsx
189
+ <View>
190
+ <Typography h5>Members</Typography>
191
+ <Typography body style={{ marginTop: 2 }}>Aisha, Bao, Cleo, and 9 others have access.</Typography>
192
+ </View>
193
+ ```
194
+
195
+ **Don't** — Setting the value in h5 too makes the label and its data indistinguishable.
196
+
197
+ ```tsx
198
+ <View style={{ gap: 4 }}>
199
+ <Typography h5>Members</Typography>
200
+ <Typography h5>Aisha, Bao, Cleo, and 9 others have access.</Typography>
201
+ </View>
202
+ ```
203
+
204
+ ### body
205
+
206
+ **Do** — Keep body copy in sentence case and let inline code carry the technical emphasis.
207
+
208
+ ```tsx
209
+ <Typography body style={{ maxWidth: 340 }}>
210
+ Run
211
+ <Typography code>npm install</Typography>
212
+ , then restart the dev server before you continue.
213
+ </Typography>
214
+ ```
215
+
216
+ **Don't** — All-caps emphasis inside body copy shouts and undercuts the relaxed reading rhythm.
217
+
218
+ ```tsx
219
+ <Typography body style={{ maxWidth: 340 }}>
220
+ <Typography code>npm install</Typography>
221
+ THEN restart the dev server BEFORE you continue.
222
+ </Typography>
223
+ ```
224
+
225
+ ### small
226
+
227
+ **Do** — Use small for secondary captions on a plain surface, not for the primary label.
228
+
229
+ ```tsx
230
+ <View>
231
+ <Typography body>Save changes</Typography>
232
+ <Typography small style={{ marginTop: 2 }}>Last saved 2 minutes ago.</Typography>
233
+ </View>
234
+ ```
235
+
236
+ **Don't** — small is muted-foreground; on a colored button it loses contrast and looks disabled.
237
+
238
+ ```tsx
239
+ <Button secondary>
240
+ <Typography small>Save changes</Typography>
241
+ </Button>
242
+ ```
243
+
244
+ ### tiny
245
+
246
+ **Do** — Reserve tiny for short metadata like timestamps and counts beside the main text.
247
+
248
+ ```tsx
249
+ <View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
250
+ <Typography body>Deploy succeeded</Typography>
251
+ <Typography tiny>3m ago</Typography>
252
+ </View>
253
+ ```
254
+
255
+ **Don't** — tiny is for metadata, not legal prose; long copy at 12px strains the eye.
256
+
257
+ ```tsx
258
+ <Typography tiny style={{ maxWidth: 300 }}>These terms govern your use of the service and your data; please read them carefully before you continue past this screen.</Typography>
259
+ ```
260
+
261
+ ### muted
262
+
263
+ **Do** — Keep muted for de-emphasized context; give the actual action full foreground or primary color.
264
+
265
+ ```tsx
266
+ <Typography body style={{ maxWidth: 340 }}>
267
+ Payment due May 31.
268
+ <Typography body style={{ color: tokens.primary, textDecorationLine: "underline" }}>View invoices</Typography>
269
+ </Typography>
270
+ ```
271
+
272
+ **Don't** — A primary, clickable action in muted-foreground reads as disabled and is easy to miss.
273
+
274
+ ```tsx
275
+ <Typography muted style={{ alignSelf: "flex-start", textDecorationLine: "underline" }}>View your invoices</Typography>
276
+ ```
277
+
278
+ ### caption
279
+
280
+ **Do** — Use caption as a short eyebrow label above a section, then explain in body.
281
+
282
+ ```tsx
283
+ <View>
284
+ <Typography caption>Billing</Typography>
285
+ <Typography body style={{ marginTop: 4 }}>Your subscription renews automatically each month.</Typography>
286
+ </View>
287
+ ```
288
+
289
+ **Don't** — Uppercase, letter-spaced caption text is illegible for anything longer than a label.
290
+
291
+ ```tsx
292
+ <Typography caption style={{ maxWidth: 320 }}>Your subscription renews automatically each month unless you cancel from the billing page.</Typography>
293
+ ```
294
+
295
+ ### code
296
+
297
+ **Do** — Use code for inline tokens inside a sentence; reach for the code block component for multi-line snippets.
298
+
299
+ ```tsx
300
+ <Typography body>
301
+ Create a branch with
302
+ <Typography code>git checkout -b feature</Typography>
303
+ before committing.
304
+ </Typography>
305
+ ```
306
+
307
+ **Don't** — The inline code utility has tight padding and no scroll; multi-line blocks overflow and clip.
308
+
309
+ ```tsx
310
+ <Typography code>git checkout -b feature
311
+ git add .
312
+ git commit -m "wip"</Typography>
313
+ ```
314
+
315
+ ### mono
316
+
317
+ **Do** — Use mono for identifiers, hashes, and tabular values where character alignment matters.
318
+
319
+ ```tsx
320
+ <View style={{ flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: 16 }}>
321
+ <Typography small>Request ID</Typography>
322
+ <Typography mono>req_8f2c10ab</Typography>
323
+ </View>
324
+ ```
325
+
326
+ **Don't** — Mono spacing makes prose sentences sparse and slow to read; it is meant for fixed-width data.
327
+
328
+ ```tsx
329
+ <Typography mono style={{ maxWidth: 320 }}>We could not process your request because the upstream service returned an unexpected response.</Typography>
330
+ ```
@@ -0,0 +1,95 @@
1
+ import { type TextStyle } from "react-native";
2
+ import { type ColorTokens } from "../../style/index.js";
3
+
4
+ // Co-located Typography styles. One axis (role), each role mapping to a single
5
+ // TextStyle built from the active brand tokens (so the type color follows
6
+ // light/dark and the glass surface). The component resolves the active role by
7
+ // first-match precedence and spreads the matching fragment.
8
+ //
9
+ // Every fragment is a TextStyle: Typography renders a single Text, so layout +
10
+ // type + color all live on the Text. The `code` role additionally carries the
11
+ // muted fill and pill padding (a Text can hold backgroundColor/padding in RN).
12
+
13
+ export type Role =
14
+ | "display"
15
+ | "h1"
16
+ | "h2"
17
+ | "h3"
18
+ | "h4"
19
+ | "h5"
20
+ | "body"
21
+ | "small"
22
+ | "tiny"
23
+ | "muted"
24
+ | "caption"
25
+ | "code"
26
+ | "mono";
27
+
28
+ // Type + layout per role, color-free (the parts that don't read a token).
29
+ // Mirrors the docs' typeScale: heading sizes get the tight tracking, body gets
30
+ // the relaxed line height, caption gets uppercase + wide tracking, and `code`
31
+ // carries the self-start pill box (radius + padding).
32
+ export const roleType: Record<Role, TextStyle> = {
33
+ // text-5xl font-bold tracking-tight
34
+ display: { fontSize: 48, lineHeight: 48, fontWeight: "700", letterSpacing: -0.4 },
35
+ // text-4xl font-bold tracking-tight
36
+ h1: { fontSize: 36, lineHeight: 40, fontWeight: "700", letterSpacing: -0.4 },
37
+ // text-3xl font-semibold tracking-tight
38
+ h2: { fontSize: 30, lineHeight: 36, fontWeight: "600", letterSpacing: -0.4 },
39
+ // text-2xl font-semibold tracking-tight
40
+ h3: { fontSize: 24, lineHeight: 32, fontWeight: "600", letterSpacing: -0.4 },
41
+ // text-xl font-semibold tracking-tight
42
+ h4: { fontSize: 20, lineHeight: 28, fontWeight: "600", letterSpacing: -0.4 },
43
+ // text-lg font-semibold
44
+ h5: { fontSize: 18, lineHeight: 28, fontWeight: "600" },
45
+ // text-sm leading-relaxed (the relaxed line height overrides text-sm's 20)
46
+ body: { fontSize: 14, lineHeight: 28 },
47
+ // text-sm
48
+ small: { fontSize: 14, lineHeight: 20 },
49
+ // text-xs
50
+ tiny: { fontSize: 12, lineHeight: 16 },
51
+ // text-sm
52
+ muted: { fontSize: 14, lineHeight: 20 },
53
+ // text-xs uppercase tracking-wide
54
+ caption: { fontSize: 12, lineHeight: 16, textTransform: "uppercase", letterSpacing: 0.4 },
55
+ // self-start rounded bg-muted px-1.5 py-0.5 text-sm (fill added in roleColor)
56
+ code: {
57
+ alignSelf: "flex-start",
58
+ borderRadius: 4,
59
+ paddingHorizontal: 6,
60
+ paddingVertical: 2,
61
+ fontSize: 14,
62
+ lineHeight: 20,
63
+ },
64
+ // text-sm
65
+ mono: { fontSize: 14, lineHeight: 20 },
66
+ };
67
+
68
+ // Text color (and the `code` role's muted fill) per role. The docs relied on
69
+ // inherited page color; RN text does not cascade, so every role names its color
70
+ // token explicitly: headings/body/code/mono on `foreground`, the helper styles
71
+ // on `muted-foreground`.
72
+ export function roleColor(tokens: ColorTokens, role: Role): TextStyle {
73
+ switch (role) {
74
+ case "display":
75
+ case "h1":
76
+ case "h2":
77
+ case "h3":
78
+ case "h4":
79
+ case "h5":
80
+ case "body":
81
+ case "mono":
82
+ return { color: tokens.foreground };
83
+ case "code":
84
+ return { color: tokens.foreground, backgroundColor: tokens.muted };
85
+ case "small":
86
+ case "tiny":
87
+ case "muted":
88
+ case "caption":
89
+ return { color: tokens["muted-foreground"] };
90
+ }
91
+ }
92
+
93
+ // Roles whose face is monospace; RN has no font-family utility, so the component
94
+ // supplies the cross-platform monospace alias inline (matches Badge's mono).
95
+ export const MONO_ROLES = new Set<Role>(["code", "mono"]);
@@ -0,0 +1,76 @@
1
+ import { type ReactNode } from "react";
2
+ import { Text, useTheme, type StyleProp, type TextStyle } from "../../style/index.js";
3
+ import { type Role, roleType, roleColor, MONO_ROLES } from "./typography.styles.js";
4
+
5
+ // Typography: the Canvas type scale as a single styled Text. One boolean role
6
+ // prop per style (display / h1..h5 / body / small / tiny / muted / caption /
7
+ // code / mono) selects a token-backed style set; omit all for the plain body
8
+ // look. The foundation's `Text` primitive is the host element, so the public
9
+ // component is named `Typography` (the bare `Text` name belongs to the
10
+ // foundation).
11
+ //
12
+ // Boolean-prop API: one boolean per role on a single axis, first-match
13
+ // precedence (mirrors Button's intentOf / Badge's toneOf). Roles are mutually
14
+ // exclusive; pass at most one. The text content comes from children.
15
+ //
16
+ // Two roles want a monospace face (code, mono). There is no font-family
17
+ // utility, so each requests RN's cross-platform monospace alias via inline
18
+ // style, the same pattern Badge's `mono` modifier uses. The docs set `code` at
19
+ // text-[13px]; the type scale resolves only token sizes, so it falls back to the
20
+ // nearest one (text-sm), as Kbd does for its 11px label.
21
+
22
+ export interface TypographyProps {
23
+ children?: ReactNode;
24
+ // Role (pick one; default is the plain body style). First-match precedence.
25
+ display?: boolean;
26
+ h1?: boolean;
27
+ h2?: boolean;
28
+ h3?: boolean;
29
+ h4?: boolean;
30
+ h5?: boolean;
31
+ body?: boolean;
32
+ small?: boolean;
33
+ tiny?: boolean;
34
+ muted?: boolean;
35
+ caption?: boolean;
36
+ code?: boolean;
37
+ mono?: boolean;
38
+ /** Escape hatch for layout/positioning composition (margins, alignment). */
39
+ style?: StyleProp<TextStyle>;
40
+ }
41
+
42
+ // Role precedence when more than one is passed: first match wins. Order runs
43
+ // largest-to-smallest, headings before helper styles, so a conflicting pair
44
+ // resolves to the more prominent role.
45
+ function roleOf(p: TypographyProps): Role {
46
+ if (p.display) return "display";
47
+ if (p.h1) return "h1";
48
+ if (p.h2) return "h2";
49
+ if (p.h3) return "h3";
50
+ if (p.h4) return "h4";
51
+ if (p.h5) return "h5";
52
+ if (p.code) return "code";
53
+ if (p.mono) return "mono";
54
+ if (p.caption) return "caption";
55
+ if (p.muted) return "muted";
56
+ if (p.small) return "small";
57
+ if (p.tiny) return "tiny";
58
+ if (p.body) return "body";
59
+ return "body";
60
+ }
61
+
62
+ export function Typography(props: TypographyProps) {
63
+ const { children, style } = props;
64
+ const { tokens } = useTheme();
65
+ const role = roleOf(props);
66
+
67
+ // The mono/code roles ask for a monospace face; there is no font-family
68
+ // utility, so request the cross-platform monospace alias via inline style.
69
+ const monoStyle = MONO_ROLES.has(role) ? { fontFamily: "monospace" as const } : null;
70
+
71
+ return (
72
+ <Text style={[roleType[role], roleColor(tokens, role), monoStyle, style]}>
73
+ {children}
74
+ </Text>
75
+ );
76
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- export { cn } from "./cn.js";
2
1
  export { token, hsl } from "./tokens.js";
3
2
  export {
4
3
  getTheme,
@@ -10,4 +9,15 @@ export {
10
9
  setDensity,
11
10
  } from "./theme.js";
12
11
 
13
- export type { Theme, Surface, Density } from "./theme.js";
12
+ export type { Theme, Density } from "./theme.js";
13
+
14
+ // The style foundation: design tokens, the theme runtime (ThemeProvider/useTheme),
15
+ // desktop-first responsive helpers, the shadow/alpha helpers, and the raw React
16
+ // Native primitives (View/Text/Pressable/Image/TextInput/ScrollView). This also
17
+ // exports the Surface type (the glass/default theming switch).
18
+ export * from "./style/index.js";
19
+
20
+ // Components, grouped by atomic-design level (atoms / molecules / organisms).
21
+ export * from "./atoms/index.js";
22
+ export * from "./molecules/index.js";
23
+ export * from "./organisms/index.js";
@@ -0,0 +1,133 @@
1
+ # Action Panels
2
+
3
+ Section card with headline, body text, and a primary action. Used to surface a single decision or call-to-action.
4
+
5
+ ## Usage
6
+
7
+ ```tsx
8
+ <ActionPanel
9
+ title="Delete this project"
10
+ description="Once you delete a project, there is no going back. Please be certain."
11
+ actionLabel="Delete project"
12
+ destructive
13
+ />
14
+ ```
15
+
16
+ ## Variants
17
+
18
+ ### Variant - side-by-side
19
+
20
+ ```tsx
21
+ <ActionPanel
22
+ title="Delete this project"
23
+ description="You have unsaved edits in this form. Leaving now will lose all progress."
24
+ actionLabel="Discard"
25
+ destructive
26
+ inline
27
+ />
28
+ ```
29
+
30
+ ### Variant - toggle
31
+
32
+ ```tsx
33
+ <ActionPanel
34
+ title="Delete this project"
35
+ description="Add an extra layer of security to your account by requiring a verification code on login."
36
+ toggle
37
+ checked
38
+ />
39
+ ```
40
+
41
+ ## Do & Don't
42
+
43
+ ### Simple
44
+
45
+ **Do** — Spell out the consequence above the button so the stakes are clear before the click.
46
+
47
+ ```tsx
48
+ <ActionPanel title="Delete this project" description="Once you delete a project, there is no going back. Please be certain." actionLabel="Delete project" destructive style={{ maxWidth: 420 }} />
49
+ ```
50
+
51
+ **Don't** — A destructive action with no consequence copy invites accidental, irreversible clicks.
52
+
53
+ ```tsx
54
+ <ActionPanel title="Delete this project" actionLabel="Delete project" destructive style={{ maxWidth: 420 }} />
55
+ ```
56
+
57
+ ### With form inline
58
+
59
+ **Do** — Keep the input and its submit button on one row so the input + action reads as one step.
60
+
61
+ ```tsx
62
+ <Card padded style={{ maxWidth: 420, gap: 16 }}>
63
+ <View style={{ gap: 4 }}>
64
+ <Text style={{ fontSize: 15, fontWeight: "600", color: tokens["card-foreground"] }}>Subscribe to updates</Text>
65
+ <Text style={{ fontSize: 14, lineHeight: 20, color: tokens["muted-foreground"] }}>We'll send you a weekly digest of what changed.</Text>
66
+ </View>
67
+ <View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
68
+ <Input placeholder="you@example.com" style={{ flexGrow: 1, flexShrink: 1, flexBasis: "0%" }} />
69
+ <Button primary>Subscribe</Button>
70
+ </View>
71
+ </Card>
72
+ ```
73
+
74
+ **Don't** — Stacking the field above its button breaks the single-decision rhythm and adds a row of dead space.
75
+
76
+ ```tsx
77
+ <Card padded style={{ maxWidth: 420, gap: 16 }}>
78
+ <View style={{ gap: 4 }}>
79
+ <Text style={{ fontSize: 15, fontWeight: "600", color: tokens["card-foreground"] }}>Subscribe to updates</Text>
80
+ <Text style={{ fontSize: 14, lineHeight: 20, color: tokens["muted-foreground"] }}>We'll send you a weekly digest of what changed.</Text>
81
+ </View>
82
+ <Input placeholder="you@example.com" />
83
+ <View style={{ alignItems: "flex-start" }}>
84
+ <Button primary>Subscribe</Button>
85
+ </View>
86
+ </Card>
87
+ ```
88
+
89
+ ### Side-by-side
90
+
91
+ **Do** — Style only the irreversible action as destructive; keep the cancel/escape as a quiet outline button.
92
+
93
+ ```tsx
94
+ <Card padded style={{ maxWidth: 460, flexDirection: "row", alignItems: "flex-start", gap: 24 }}>
95
+ <View style={{ flexGrow: 1, flexShrink: 1, flexBasis: "0%", gap: 4 }}>
96
+ <Text style={{ fontSize: 15, fontWeight: "600", color: tokens["card-foreground"] }}>Discard unsaved changes?</Text>
97
+ <Text style={{ fontSize: 14, lineHeight: 20, color: tokens["muted-foreground"] }}>You have unsaved edits in this form. Leaving now will lose all progress.</Text>
98
+ </View>
99
+ <View style={{ flexShrink: 0, flexDirection: "row", gap: 8 }}>
100
+ <Button outline small>Cancel</Button>
101
+ <Button destructive small>Discard</Button>
102
+ </View>
103
+ </Card>
104
+ ```
105
+
106
+ **Don't** — Two destructive-styled buttons make the safe escape (Cancel) look as dangerous as the discard.
107
+
108
+ ```tsx
109
+ <Card padded style={{ maxWidth: 460, flexDirection: "row", alignItems: "flex-start", gap: 24 }}>
110
+ <View style={{ flexGrow: 1, flexShrink: 1, flexBasis: "0%", gap: 4 }}>
111
+ <Text style={{ fontSize: 15, fontWeight: "600", color: tokens["card-foreground"] }}>Discard unsaved changes?</Text>
112
+ <Text style={{ fontSize: 14, lineHeight: 20, color: tokens["muted-foreground"] }}>You have unsaved edits in this form. Leaving now will lose all progress.</Text>
113
+ </View>
114
+ <View style={{ flexShrink: 0, flexDirection: "row", gap: 8 }}>
115
+ <Button destructive small>Discard</Button>
116
+ <Button destructive small>Cancel</Button>
117
+ </View>
118
+ </Card>
119
+ ```
120
+
121
+ ### With toggle
122
+
123
+ **Do** — Pair the switch with a one-line explanation of what turning it on or off does.
124
+
125
+ ```tsx
126
+ <ActionPanel title="Two-factor authentication" description="Add an extra layer of security to your account by requiring a verification code on login." toggle checked style={{ maxWidth: 460 }} />
127
+ ```
128
+
129
+ **Don't** — A bare switch with no description leaves the user guessing what flipping it actually changes.
130
+
131
+ ```tsx
132
+ <ActionPanel title="Two-factor authentication" toggle checked style={{ maxWidth: 460 }} />
133
+ ```
@@ -0,0 +1,39 @@
1
+ import { type ViewStyle, type TextStyle } from "react-native";
2
+ import { type ColorTokens, palette } from "../../style/index.js";
3
+
4
+ // Co-located ActionPanel styles. Layout-only fragments are static objects; the
5
+ // title color is a function of the active tokens (neutral) or the dark scheme
6
+ // (the destructive danger-zone red, which rides the Tailwind palette so it stays
7
+ // fixed per scheme rather than following the semantic tokens).
8
+
9
+ export type Tone = "destructive" | "neutral";
10
+ export type Layout = "inline" | "stacked";
11
+
12
+ // The card surface caps its width; passed to the Card child via its `style` prop.
13
+ export const cardWidth: ViewStyle = { maxWidth: 560 };
14
+
15
+ // The copy block: title stacked above its consequence line. In the inline layout
16
+ // it grows to push the action to the right (flex-1); stacked, it stays natural.
17
+ export const copyBlock: ViewStyle = { gap: 4 };
18
+ export const copyGrow: ViewStyle = { flexGrow: 1, flexShrink: 1, flexBasis: "0%" };
19
+
20
+ // The action wrapper: pinned (shrink-0) in the inline/toggle layouts, or
21
+ // left-aligned (items-start) on its own line in the stacked layout.
22
+ export const actionPinned: ViewStyle = { flexShrink: 0 };
23
+ export const actionStacked: ViewStyle = { alignItems: "flex-start" };
24
+
25
+ // The two body layouts: a side-by-side row (inline/toggle) or a vertical stack.
26
+ export const inlineBody: ViewStyle = { flexDirection: "row", alignItems: "flex-start", gap: 24 };
27
+ export const stackedBody: ViewStyle = { gap: 16 };
28
+
29
+ // Title and description share Canvas's settings-row type scale (text-sm).
30
+ export function titleText(tokens: ColorTokens, dark: boolean, tone: Tone): TextStyle {
31
+ // Danger-zone red rides the palette (fixed per scheme); neutral follows the
32
+ // semantic card foreground so it tracks light/dark/glass.
33
+ const color = tone === "destructive" ? (dark ? palette["red-400"] : palette["red-700"]) : tokens["card-foreground"];
34
+ return { fontSize: 14, lineHeight: 20, fontWeight: "600", color };
35
+ }
36
+
37
+ export function descriptionText(tokens: ColorTokens): TextStyle {
38
+ return { fontSize: 14, lineHeight: 20, color: tokens["muted-foreground"] };
39
+ }