@lt-three/love3 0.0.0 → 0.1.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 (377) hide show
  1. package/README.md +85 -1
  2. package/dist/native/analytics/animation.d.ts +4 -0
  3. package/dist/native/analytics/animation.js +6 -0
  4. package/dist/native/analytics/chart.types.d.ts +25 -0
  5. package/dist/native/analytics/chart.types.js +0 -0
  6. package/dist/native/analytics/line-chart.d.ts +4 -0
  7. package/dist/native/analytics/line-chart.ios.d.ts +4 -0
  8. package/dist/native/analytics/line-chart.ios.js +24 -0
  9. package/dist/native/analytics/line-chart.js +33 -0
  10. package/dist/native/analytics/metric-card.d.ts +10 -0
  11. package/dist/native/analytics/metric-card.js +29 -0
  12. package/dist/native/analytics/multi-line-chart.d.ts +17 -0
  13. package/dist/native/analytics/multi-line-chart.js +215 -0
  14. package/dist/native/analytics/pie-chart.d.ts +15 -0
  15. package/dist/native/analytics/pie-chart.ios.d.ts +4 -0
  16. package/dist/native/analytics/pie-chart.ios.js +24 -0
  17. package/dist/native/analytics/pie-chart.js +92 -0
  18. package/dist/native/analytics/single-number.d.ts +19 -0
  19. package/dist/native/analytics/single-number.js +101 -0
  20. package/dist/native/atom/avatar.d.ts +21 -0
  21. package/dist/native/atom/avatar.js +46 -0
  22. package/dist/native/atom/badge.d.ts +28 -0
  23. package/dist/native/atom/badge.js +51 -0
  24. package/dist/native/atom/button.d.ts +46 -0
  25. package/dist/native/atom/button.js +109 -0
  26. package/dist/native/atom/checkbox.d.ts +21 -0
  27. package/dist/native/atom/checkbox.js +47 -0
  28. package/dist/native/atom/colored-value.d.ts +12 -0
  29. package/dist/native/atom/colored-value.js +24 -0
  30. package/dist/native/atom/image.d.ts +21 -0
  31. package/dist/native/atom/image.js +72 -0
  32. package/dist/native/atom/label.d.ts +18 -0
  33. package/dist/native/atom/label.js +33 -0
  34. package/dist/native/atom/link.d.ts +18 -0
  35. package/dist/native/atom/link.js +25 -0
  36. package/dist/native/atom/readout.d.ts +22 -0
  37. package/dist/native/atom/readout.js +39 -0
  38. package/dist/native/atom/search-input.d.ts +12 -0
  39. package/dist/native/atom/search-input.js +36 -0
  40. package/dist/native/atom/select.d.ts +54 -0
  41. package/dist/native/atom/select.js +200 -0
  42. package/dist/native/atom/separator.d.ts +13 -0
  43. package/dist/native/atom/separator.js +17 -0
  44. package/dist/native/atom/skeleton.d.ts +12 -0
  45. package/dist/native/atom/skeleton.js +39 -0
  46. package/dist/native/atom/slider.d.ts +32 -0
  47. package/dist/native/atom/slider.js +75 -0
  48. package/dist/native/atom/spinner.d.ts +15 -0
  49. package/dist/native/atom/spinner.js +25 -0
  50. package/dist/native/atom/switch.d.ts +18 -0
  51. package/dist/native/atom/switch.js +52 -0
  52. package/dist/native/atom/symbol.d.ts +16 -0
  53. package/dist/native/atom/symbol.js +38 -0
  54. package/dist/native/atom/symbol.types.d.ts +25 -0
  55. package/dist/native/atom/symbol.types.js +49 -0
  56. package/dist/native/atom/text-field.d.ts +49 -0
  57. package/dist/native/atom/text-field.js +56 -0
  58. package/dist/native/atom/text.d.ts +2 -0
  59. package/dist/native/atom/text.js +3 -0
  60. package/dist/native/atom/theme-toggle.d.ts +21 -0
  61. package/dist/native/atom/theme-toggle.js +36 -0
  62. package/dist/native/atom/timezone-select.d.ts +16 -0
  63. package/dist/native/atom/timezone-select.js +28 -0
  64. package/dist/native/atom/typography.d.ts +13 -0
  65. package/dist/native/atom/typography.js +28 -0
  66. package/dist/native/base/button.d.ts +61 -0
  67. package/dist/native/base/button.js +92 -0
  68. package/dist/native/base/form.d.ts +72 -0
  69. package/dist/native/base/form.js +113 -0
  70. package/dist/native/base/glass-card.d.ts +15 -0
  71. package/dist/native/base/glass-card.js +38 -0
  72. package/dist/native/base/input.d.ts +29 -0
  73. package/dist/native/base/input.js +27 -0
  74. package/dist/native/base/sheet.d.ts +71 -0
  75. package/dist/native/base/sheet.js +187 -0
  76. package/dist/native/base/text.d.ts +14 -0
  77. package/dist/native/base/text.js +53 -0
  78. package/dist/native/form/checkbox.d.ts +13 -0
  79. package/dist/native/form/checkbox.js +55 -0
  80. package/dist/native/form/date-picker.d.ts +23 -0
  81. package/dist/native/form/date-picker.js +119 -0
  82. package/dist/native/form/form.d.ts +23 -0
  83. package/dist/native/form/form.js +45 -0
  84. package/dist/native/form/radio-group.d.ts +23 -0
  85. package/dist/native/form/radio-group.js +88 -0
  86. package/dist/native/form/select.d.ts +13 -0
  87. package/dist/native/form/select.js +45 -0
  88. package/dist/native/form/slider.d.ts +14 -0
  89. package/dist/native/form/slider.js +42 -0
  90. package/dist/native/form/switch.d.ts +9 -0
  91. package/dist/native/form/switch.js +59 -0
  92. package/dist/native/form/text-area.d.ts +11 -0
  93. package/dist/native/form/text-area.js +50 -0
  94. package/dist/native/form/text-input.d.ts +18 -0
  95. package/dist/native/form/text-input.js +90 -0
  96. package/dist/native/index.d.ts +1 -0
  97. package/dist/native/index.js +0 -0
  98. package/dist/native/layout/accordion.d.ts +25 -0
  99. package/dist/native/layout/accordion.js +54 -0
  100. package/dist/native/layout/card.d.ts +47 -0
  101. package/dist/native/layout/card.js +57 -0
  102. package/dist/native/layout/description.d.ts +16 -0
  103. package/dist/native/layout/description.js +32 -0
  104. package/dist/native/layout/error.d.ts +21 -0
  105. package/dist/native/layout/error.js +44 -0
  106. package/dist/native/layout/information.d.ts +25 -0
  107. package/dist/native/layout/information.js +35 -0
  108. package/dist/native/layout/locked.d.ts +38 -0
  109. package/dist/native/layout/locked.js +94 -0
  110. package/dist/native/layout/modal.d.ts +25 -0
  111. package/dist/native/layout/modal.js +93 -0
  112. package/dist/native/layout/not-found.d.ts +17 -0
  113. package/dist/native/layout/not-found.js +30 -0
  114. package/dist/native/layout/page-frame.d.ts +23 -0
  115. package/dist/native/layout/page-frame.js +46 -0
  116. package/dist/native/layout/panel.d.ts +18 -0
  117. package/dist/native/layout/panel.js +23 -0
  118. package/dist/native/layout/reorderable-list.d.ts +42 -0
  119. package/dist/native/layout/reorderable-list.js +52 -0
  120. package/dist/native/layout/sheet.d.ts +30 -0
  121. package/dist/native/layout/sheet.js +46 -0
  122. package/dist/native/layout/simple-dialog.d.ts +16 -0
  123. package/dist/native/layout/simple-dialog.js +20 -0
  124. package/dist/native/layout/simple-table.d.ts +50 -0
  125. package/dist/native/layout/simple-table.js +75 -0
  126. package/dist/native/layout/tab-bar.d.ts +33 -0
  127. package/dist/native/layout/tab-bar.js +48 -0
  128. package/dist/native/layout/tabs.d.ts +28 -0
  129. package/dist/native/layout/tabs.js +54 -0
  130. package/dist/native/layout/tuning-panel.d.ts +24 -0
  131. package/dist/native/layout/tuning-panel.js +246 -0
  132. package/dist/native/lib/autocomplete.d.ts +7 -0
  133. package/dist/native/lib/autocomplete.js +34 -0
  134. package/dist/native/lib/breakpoints.d.ts +14 -0
  135. package/dist/native/lib/breakpoints.js +17 -0
  136. package/dist/native/lib/chart-palette.d.ts +8 -0
  137. package/dist/native/lib/chart-palette.js +20 -0
  138. package/dist/native/lib/confirm.d.ts +49 -0
  139. package/dist/native/lib/confirm.js +70 -0
  140. package/dist/native/lib/control.d.ts +24 -0
  141. package/dist/native/lib/control.js +0 -0
  142. package/dist/native/lib/external-store.d.ts +17 -0
  143. package/dist/native/lib/external-store.js +30 -0
  144. package/dist/native/lib/keyboard.d.ts +15 -0
  145. package/dist/native/lib/keyboard.js +24 -0
  146. package/dist/native/lib/labels.d.ts +15 -0
  147. package/dist/native/lib/labels.js +17 -0
  148. package/dist/native/lib/loading.d.ts +10 -0
  149. package/dist/native/lib/loading.js +15 -0
  150. package/dist/native/lib/network.d.ts +12 -0
  151. package/dist/native/lib/network.js +21 -0
  152. package/dist/native/lib/scheme.d.ts +18 -0
  153. package/dist/native/lib/scheme.js +22 -0
  154. package/dist/native/lib/snackbar.d.ts +46 -0
  155. package/dist/native/lib/snackbar.js +60 -0
  156. package/dist/native/lib/theme.d.ts +34 -0
  157. package/dist/native/lib/theme.js +53 -0
  158. package/dist/native/lib/timezone.d.ts +26 -0
  159. package/dist/native/lib/timezone.js +95 -0
  160. package/dist/native/lib/token-color.d.ts +5 -0
  161. package/dist/native/lib/token-color.js +13 -0
  162. package/dist/native/lib/token-color.web.d.ts +4 -0
  163. package/dist/native/lib/token-color.web.js +7 -0
  164. package/dist/native/lib/tuning-context.d.ts +9 -0
  165. package/dist/native/lib/tuning-context.js +7 -0
  166. package/dist/native/lib/tuning.d.ts +24 -0
  167. package/dist/native/lib/tuning.js +42 -0
  168. package/dist/native/lib/typography.d.ts +10 -0
  169. package/dist/native/lib/typography.js +11 -0
  170. package/dist/native/lib/utils.d.ts +11 -0
  171. package/dist/native/lib/utils.js +21 -0
  172. package/dist/native/once/confirm.d.ts +7 -0
  173. package/dist/native/once/confirm.js +60 -0
  174. package/dist/native/once/error-boundary.d.ts +28 -0
  175. package/dist/native/once/error-boundary.js +55 -0
  176. package/dist/native/once/loading-lock.d.ts +8 -0
  177. package/dist/native/once/loading-lock.js +28 -0
  178. package/dist/native/once/offline-banner.d.ts +15 -0
  179. package/dist/native/once/offline-banner.js +35 -0
  180. package/dist/native/once/snackbar.d.ts +17 -0
  181. package/dist/native/once/snackbar.js +106 -0
  182. package/dist/native/styles.css +46 -0
  183. package/dist/shared/analytics.d.ts +71 -0
  184. package/dist/shared/analytics.js +0 -0
  185. package/dist/shared/button.d.ts +7 -0
  186. package/dist/shared/button.js +23 -0
  187. package/dist/shared/form.d.ts +45 -0
  188. package/dist/shared/form.js +46 -0
  189. package/dist/shared/index.d.ts +3 -0
  190. package/dist/shared/index.js +3 -0
  191. package/dist/tokens/contrast-pairs.d.ts +30 -0
  192. package/dist/tokens/contrast-pairs.js +404 -0
  193. package/dist/tokens/index.d.ts +6 -0
  194. package/dist/tokens/index.js +10 -0
  195. package/dist/tokens/styles.gen.css +250 -0
  196. package/dist/tokens/tokens.gen.d.ts +141 -0
  197. package/dist/tokens/tokens.gen.js +206 -0
  198. package/dist/tuning/catalog.d.ts +27 -0
  199. package/dist/tuning/catalog.gen.d.ts +4 -0
  200. package/dist/tuning/catalog.gen.js +397 -0
  201. package/dist/tuning/catalog.js +128 -0
  202. package/dist/tuning/color.d.ts +20 -0
  203. package/dist/tuning/color.js +80 -0
  204. package/dist/tuning/css.d.ts +35 -0
  205. package/dist/tuning/css.js +147 -0
  206. package/dist/tuning/index.d.ts +8 -0
  207. package/dist/tuning/index.js +9 -0
  208. package/dist/tuning/model.d.ts +33 -0
  209. package/dist/tuning/model.js +154 -0
  210. package/dist/tuning/native.d.ts +35 -0
  211. package/dist/tuning/native.js +80 -0
  212. package/dist/tuning/schema.d.ts +69 -0
  213. package/dist/tuning/schema.js +247 -0
  214. package/dist/tuning/types.d.ts +75 -0
  215. package/dist/tuning/types.js +39 -0
  216. package/dist/web/analytics/line-chart.d.ts +20 -0
  217. package/dist/web/analytics/line-chart.js +28 -0
  218. package/dist/web/analytics/metric-card.d.ts +18 -0
  219. package/dist/web/analytics/metric-card.js +40 -0
  220. package/dist/web/analytics/multi-line-chart.d.ts +39 -0
  221. package/dist/web/analytics/multi-line-chart.js +345 -0
  222. package/dist/web/atom/avatar.d.ts +11 -0
  223. package/dist/web/atom/avatar.js +24 -0
  224. package/dist/web/atom/badge.d.ts +2 -0
  225. package/dist/web/atom/badge.js +3 -0
  226. package/dist/web/atom/button.d.ts +23 -0
  227. package/dist/web/atom/button.js +35 -0
  228. package/dist/web/atom/checkbox.d.ts +19 -0
  229. package/dist/web/atom/checkbox.js +33 -0
  230. package/dist/web/atom/colored-value.d.ts +13 -0
  231. package/dist/web/atom/colored-value.js +24 -0
  232. package/dist/web/atom/help.d.ts +10 -0
  233. package/dist/web/atom/help.js +18 -0
  234. package/dist/web/atom/label.d.ts +2 -0
  235. package/dist/web/atom/label.js +3 -0
  236. package/dist/web/atom/segmented-control.d.ts +40 -0
  237. package/dist/web/atom/segmented-control.js +43 -0
  238. package/dist/web/atom/select.d.ts +43 -0
  239. package/dist/web/atom/select.js +93 -0
  240. package/dist/web/atom/separator.d.ts +2 -0
  241. package/dist/web/atom/separator.js +3 -0
  242. package/dist/web/atom/skeleton.d.ts +2 -0
  243. package/dist/web/atom/skeleton.js +3 -0
  244. package/dist/web/atom/slider.d.ts +33 -0
  245. package/dist/web/atom/slider.js +70 -0
  246. package/dist/web/atom/spinner.d.ts +8 -0
  247. package/dist/web/atom/spinner.js +14 -0
  248. package/dist/web/atom/switch.d.ts +11 -0
  249. package/dist/web/atom/switch.js +10 -0
  250. package/dist/web/atom/text-area.d.ts +22 -0
  251. package/dist/web/atom/text-area.js +26 -0
  252. package/dist/web/atom/text-field.d.ts +17 -0
  253. package/dist/web/atom/text-field.js +21 -0
  254. package/dist/web/atom/toggle-chip.d.ts +22 -0
  255. package/dist/web/atom/toggle-chip.js +28 -0
  256. package/dist/web/atom/tooltip.d.ts +23 -0
  257. package/dist/web/atom/tooltip.js +26 -0
  258. package/dist/web/atom/typography.d.ts +6 -0
  259. package/dist/web/atom/typography.js +23 -0
  260. package/dist/web/base/accordion.d.ts +9 -0
  261. package/dist/web/base/accordion.js +44 -0
  262. package/dist/web/base/alert.d.ts +11 -0
  263. package/dist/web/base/alert.js +37 -0
  264. package/dist/web/base/avatar.d.ts +8 -0
  265. package/dist/web/base/avatar.js +29 -0
  266. package/dist/web/base/badge.d.ts +12 -0
  267. package/dist/web/base/badge.js +26 -0
  268. package/dist/web/base/breadcrumb.d.ts +16 -0
  269. package/dist/web/base/breadcrumb.js +72 -0
  270. package/dist/web/base/button.d.ts +12 -0
  271. package/dist/web/base/button.js +47 -0
  272. package/dist/web/base/card.d.ts +19 -0
  273. package/dist/web/base/card.js +74 -0
  274. package/dist/web/base/checkbox.d.ts +6 -0
  275. package/dist/web/base/checkbox.js +21 -0
  276. package/dist/web/base/dialog.d.ts +20 -0
  277. package/dist/web/base/dialog.js +92 -0
  278. package/dist/web/base/dropdown-menu.d.ts +29 -0
  279. package/dist/web/base/dropdown-menu.js +125 -0
  280. package/dist/web/base/field.d.ts +27 -0
  281. package/dist/web/base/field.js +118 -0
  282. package/dist/web/base/form.d.ts +38 -0
  283. package/dist/web/base/form.js +110 -0
  284. package/dist/web/base/input.d.ts +9 -0
  285. package/dist/web/base/input.js +23 -0
  286. package/dist/web/base/label.d.ts +6 -0
  287. package/dist/web/base/label.js +15 -0
  288. package/dist/web/base/pagination.d.ts +34 -0
  289. package/dist/web/base/pagination.js +90 -0
  290. package/dist/web/base/popover.d.ts +11 -0
  291. package/dist/web/base/popover.js +37 -0
  292. package/dist/web/base/radio-group.d.ts +7 -0
  293. package/dist/web/base/radio-group.js +27 -0
  294. package/dist/web/base/scroll-area.d.ts +10 -0
  295. package/dist/web/base/scroll-area.js +41 -0
  296. package/dist/web/base/select.d.ts +17 -0
  297. package/dist/web/base/select.js +96 -0
  298. package/dist/web/base/separator.d.ts +6 -0
  299. package/dist/web/base/separator.js +17 -0
  300. package/dist/web/base/sheet.d.ts +19 -0
  301. package/dist/web/base/sheet.js +88 -0
  302. package/dist/web/base/skeleton.d.ts +5 -0
  303. package/dist/web/base/skeleton.js +14 -0
  304. package/dist/web/base/slider.d.ts +9 -0
  305. package/dist/web/base/slider.js +39 -0
  306. package/dist/web/base/sonner.d.ts +9 -0
  307. package/dist/web/base/sonner.js +25 -0
  308. package/dist/web/base/spinner.d.ts +5 -0
  309. package/dist/web/base/spinner.js +17 -0
  310. package/dist/web/base/switch.d.ts +6 -0
  311. package/dist/web/base/switch.js +19 -0
  312. package/dist/web/base/table.d.ts +14 -0
  313. package/dist/web/base/table.js +68 -0
  314. package/dist/web/base/tabs.d.ts +9 -0
  315. package/dist/web/base/tabs.js +36 -0
  316. package/dist/web/base/textarea.d.ts +9 -0
  317. package/dist/web/base/textarea.js +23 -0
  318. package/dist/web/base/tooltip.d.ts +9 -0
  319. package/dist/web/base/tooltip.js +36 -0
  320. package/dist/web/form/checkbox.d.ts +35 -0
  321. package/dist/web/form/checkbox.js +91 -0
  322. package/dist/web/form/radio-group.d.ts +24 -0
  323. package/dist/web/form/radio-group.js +75 -0
  324. package/dist/web/form/select.d.ts +16 -0
  325. package/dist/web/form/select.js +44 -0
  326. package/dist/web/form/slider.d.ts +19 -0
  327. package/dist/web/form/slider.js +51 -0
  328. package/dist/web/form/switch.d.ts +11 -0
  329. package/dist/web/form/switch.js +50 -0
  330. package/dist/web/form/text-area.d.ts +10 -0
  331. package/dist/web/form/text-area.js +31 -0
  332. package/dist/web/form/text-input.d.ts +10 -0
  333. package/dist/web/form/text-input.js +42 -0
  334. package/dist/web/index.d.ts +1 -0
  335. package/dist/web/index.js +0 -0
  336. package/dist/web/layout/accordion.d.ts +26 -0
  337. package/dist/web/layout/accordion.js +29 -0
  338. package/dist/web/layout/alert-modal.d.ts +41 -0
  339. package/dist/web/layout/alert-modal.js +71 -0
  340. package/dist/web/layout/card.d.ts +17 -0
  341. package/dist/web/layout/card.js +35 -0
  342. package/dist/web/layout/description.d.ts +12 -0
  343. package/dist/web/layout/description.js +20 -0
  344. package/dist/web/layout/information.d.ts +36 -0
  345. package/dist/web/layout/information.js +53 -0
  346. package/dist/web/layout/modal.d.ts +16 -0
  347. package/dist/web/layout/modal.js +37 -0
  348. package/dist/web/layout/page-frame.d.ts +37 -0
  349. package/dist/web/layout/page-frame.js +79 -0
  350. package/dist/web/layout/scroll-area.d.ts +10 -0
  351. package/dist/web/layout/scroll-area.js +13 -0
  352. package/dist/web/layout/sheet.d.ts +32 -0
  353. package/dist/web/layout/sheet.js +68 -0
  354. package/dist/web/layout/simple-dialog.d.ts +11 -0
  355. package/dist/web/layout/simple-dialog.js +24 -0
  356. package/dist/web/layout/simple-table.d.ts +49 -0
  357. package/dist/web/layout/simple-table.js +58 -0
  358. package/dist/web/layout/tabs.d.ts +26 -0
  359. package/dist/web/layout/tabs.js +42 -0
  360. package/dist/web/layout/titled-modal.d.ts +33 -0
  361. package/dist/web/layout/titled-modal.js +59 -0
  362. package/dist/web/lib/css-vars.d.ts +14 -0
  363. package/dist/web/lib/css-vars.js +18 -0
  364. package/dist/web/lib/dialog.d.ts +13 -0
  365. package/dist/web/lib/dialog.js +0 -0
  366. package/dist/web/lib/form.d.ts +2 -0
  367. package/dist/web/lib/form.js +3 -0
  368. package/dist/web/lib/labels.d.ts +27 -0
  369. package/dist/web/lib/labels.js +29 -0
  370. package/dist/web/lib/modal-open-focus.d.ts +17 -0
  371. package/dist/web/lib/modal-open-focus.js +44 -0
  372. package/dist/web/lib/restore-focus.d.ts +12 -0
  373. package/dist/web/lib/restore-focus.js +32 -0
  374. package/dist/web/lib/utils.d.ts +4 -0
  375. package/dist/web/lib/utils.js +10 -0
  376. package/dist/web/styles.css +162 -0
  377. package/package.json +203 -4
package/README.md CHANGED
@@ -1,3 +1,87 @@
1
1
  # @lt-three/love3
2
2
 
3
- Placeholder. Real releases are published from CI.
3
+ <3(Less Than Three)共通のデザインシステム。Linear(linear.app)に寄せた、背景の階層・極薄の枠・淡い影・インディゴの主操作。
4
+ web(React + Tailwind CSS v4)と React Native(NativeWind v5)で同じ見た目になる。トークン(色・角丸・影・書体)の実値は TS オブジェクトとしても読める。
5
+
6
+ ライセンスは MIT。
7
+
8
+ ## インストール
9
+
10
+ ```sh
11
+ npm install @lt-three/love3
12
+ ```
13
+
14
+ - **web**: `react` `react-dom`(`>=19.3.0 <20`)と `tailwindcss`(v4)を入れる。web の部品が使う依存(Radix・`@tanstack/charts` など)はこのパッケージの `dependencies` に入っているので、別に入れなくてよい。
15
+ - **React Native**: `react` `react-native` `nativewind`(v5)`react-native-css` `tailwindcss` に加えて、使う部品が引く native 側の依存を入れる(`expo`・`expo-router`・`react-native-reanimated`・`react-native-svg` など)。
16
+ native 専用の依存は **optional な `peerDependencies`**。使わない部品の依存は入れなくてよい(どの部品がどれを引くかは `package.json` の `peerDependencies` と部品の import を見る)。
17
+
18
+ 公開物は `dist/`(ESM の `.js` と `.d.ts`)。ソースと同じ構造で、部品ごとに 1 ファイルずつ出る。使わない部品の依存は引かれない。
19
+
20
+ ## 使い方
21
+
22
+ | import | 中身 |
23
+ | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
24
+ | `@lt-three/love3/styles.css` | Tailwind v4 の `@theme` とライト・ダーク。web と NativeWind で共通 |
25
+ | `@lt-three/love3/tokens` | トークンの実値の TS オブジェクト(`tokens.light` / `tokens.dark`)・`cssVar`・型。CSS が使えない RN のチャート・Reanimated 向け。`node:` の組み込みも引かない |
26
+ | `@lt-three/love3/tokens/contrast` | コントラストを検査する前景 / 背景の組(`CONTRAST_PAIRS`)と、理由つきの既知の例外(`KNOWN_CONTRAST_EXCEPTIONS`)。データだけ |
27
+ | `@lt-three/love3/tuning` | トークンを実行時に上書きする「調整」の形式・検証・適用(`zod` だけを引く) |
28
+ | `@lt-three/love3/web` / `@lt-three/love3/native` / `@lt-three/love3/shared` | 各レイヤーの入口(`index.ts`) |
29
+ | `@lt-three/love3/web/atom/button.tsx` のように **拡張子つき** | web コンポーネント。`web/*.ts`(hook・util)と `web/*.tsx` |
30
+ | `@lt-three/love3/web/styles.css` | web のアプリが CSS の入口で import する。Tailwind・フォント・トークン・ベーススタイル |
31
+ | `@lt-three/love3/native/atom/button.tsx` のように **拡張子つき** | native コンポーネント |
32
+ | `@lt-three/love3/native/styles.css` | **実機(Metro / NativeWind v5)の CSS の入口**。Tailwind・`nativewind/theme`・トークン・部品のクラスの検出と、`dark:` を `prefers-color-scheme` にする上書き |
33
+ | `@lt-three/love3/shared/…`(`.ts` / `.tsx`) | web / native 共通の props 型・variant 定義 |
34
+
35
+ **ワイルドカードの export は拡張子つきのキー**(`./web/*.tsx` / `./web/*.ts`)。exports は拡張子を探してくれないので、利用側も拡張子つきで import する
36
+ (TypeScript では `allowImportingTsExtensions` を有効にする)。拡張子なし(`.../atom/button`)は解決できない。指定子が指す先は `dist/` の `.js` と型宣言の `.d.ts`。
37
+
38
+ ### web
39
+
40
+ CSS の入口で 1 度だけ import する。
41
+
42
+ ```css
43
+ @import "@lt-three/love3/web/styles.css";
44
+ ```
45
+
46
+ ```tsx
47
+ import { Button } from "@lt-three/love3/web/atom/button.tsx";
48
+ ```
49
+
50
+ 部品が使う Tailwind のクラスは、この CSS の `@source` が `dist/` から拾う。アプリ自身のソースは、バンドラのプロジェクトルートを基準にした Tailwind の自動検出に任せる。
51
+ ダークは `<html class="dark">` で切り替える。
52
+
53
+ ### React Native
54
+
55
+ アプリの `global.css` で 1 度だけ import する(NativeWind v5 / react-native-css が Tailwind v4 としてコンパイルする)。
56
+
57
+ ```css
58
+ @import "@lt-three/love3/native/styles.css";
59
+ ```
60
+
61
+ native の `dark:` は**クラスではなく OS の配色設定**(`prefers-color-scheme`)で解決する。`.dark` を祖先セレクタに持つと、react-native-css がそのビューを container として扱い、
62
+ 子孫の ScrollView が pan を受け取れなくなるため。アプリ内のテーマ設定は `Appearance.setColorScheme()` で切り替える。
63
+
64
+ iOS の SwiftUI Charts を使う部品(`line-chart.ios.tsx` / `pie-chart.ios.tsx`)は、iOS のアプリが拡張子つきで明示して import する。
65
+
66
+ ### トークン
67
+
68
+ ```ts
69
+ import { cssVar, tokens } from "@lt-three/love3/tokens";
70
+
71
+ tokens.light["ink-900"]; // 実値("#1b1c20")
72
+ cssVar("ink-900"); // "var(--ink-900)"
73
+ ```
74
+
75
+ 変数名は shadcn 互換の名前(`--background` / `--primary` など)に、`--ink-*` / `--line*` / `--lt-three` などの生トークンを足したもの。
76
+
77
+ ## 注意: `.theme-light` はセマンティックなクラスを明るくしない
78
+
79
+ `.theme-light`(ライト固定のスコープ)が再定義するのは**生トークンだけ**(`--ink-*` / `--line*` / `--frame` / `--paper` / `--raised` / `--overlay` / `--wash` / `--scrim` / `--shadow-color` / `--action-ink` / `--state-*` / `--chart-*`)。
80
+ `--background` / `--foreground` / `--primary` などのセマンティックな変数は `:root` で `var(--paper)` のように宣言されていて、**宣言した要素で解決されてから子孫へ継承される**。
81
+ そのため `<html class="dark">` の下に `.theme-light` を置いても、その子孫で `bg-background` / `text-foreground` / `bg-primary` などは**暗いまま**になる
82
+ (`bg-paper` / `text-ink-900` のような生トークンのクラスなら明るくなる)。
83
+ love3 の部品は `.theme-light` を使わない。常にライトにしたいページでは、`.theme-light` の中で生トークンのクラスを使うか、`.theme-light` にもセマンティックな変数の再宣言を足す。
84
+
85
+ ## ライセンス
86
+
87
+ [MIT](./LICENSE)
@@ -0,0 +1,4 @@
1
+ //#region src/native/analytics/animation.d.ts
2
+ /** チャートのアニメーション時間(ms)。web の analytics/animation と同じ値に揃える。 */
3
+ export declare const animationDuration = 250;
4
+ //#endregion
@@ -0,0 +1,6 @@
1
+ //#region src/native/analytics/animation.ts
2
+ /** チャートのアニメーション時間(ms)。web の analytics/animation と同じ値に揃える。 */
3
+ const animationDuration = 250;
4
+
5
+ //#endregion
6
+ export { animationDuration };
@@ -0,0 +1,25 @@
1
+ import { ChartCommonProps as ChartCommonProps$1, LineChartSharedProps, LinePoint, LineSeries, MultiLineChartSharedProps } from "../../shared/analytics.js";
2
+ import { ViewStyle } from "react-native";
3
+ //#region src/native/analytics/chart.types.d.ts
4
+ export type PieSlice = {
5
+ label: string;
6
+ value: number;
7
+ color?: string;
8
+ };
9
+ type ChartCommonProps = ChartCommonProps$1 & {
10
+ style?: ViewStyle;
11
+ /**
12
+ * ネイティブチャート非対応プラットフォームで出す文言。
13
+ * 共有パッケージなので既定値のみ持ち、翻訳は使用側が渡す。
14
+ */
15
+ fallbackText?: string;
16
+ };
17
+ export type LineChartProps = ChartCommonProps & LineChartSharedProps;
18
+ export type PieChartProps = ChartCommonProps & {
19
+ data: PieSlice[];
20
+ /** 中心を空けたドーナツ表示にする。 */
21
+ donut?: boolean;
22
+ };
23
+ export type MultiLineChartProps = ChartCommonProps & MultiLineChartSharedProps;
24
+ //#endregion
25
+ export type { LinePoint, LineSeries };
File without changes
@@ -0,0 +1,4 @@
1
+ import { LineChartProps } from "./chart.types.js";
2
+ //#region src/native/analytics/line-chart.d.ts
3
+ export declare function LineChart(props: LineChartProps): import("react").JSX.Element;
4
+ //#endregion
@@ -0,0 +1,4 @@
1
+ import { LineChartProps } from "./chart.types.js";
2
+ //#region src/native/analytics/line-chart.ios.d.ts
3
+ export declare function LineChart({ data, color, height, style }: LineChartProps): import("react").JSX.Element;
4
+ //#endregion
@@ -0,0 +1,24 @@
1
+ import { useChartPalette } from "../lib/chart-palette.js";
2
+ import { Chart, Host } from "@expo/ui/swift-ui";
3
+ import { jsx } from "react/jsx-runtime";
4
+
5
+ //#region src/native/analytics/line-chart.ios.tsx
6
+ function LineChart({ data, color, height = 220, style }) {
7
+ const palette = useChartPalette();
8
+ return /* @__PURE__ */ jsx(Host, {
9
+ style: [{ height }, style],
10
+ children: /* @__PURE__ */ jsx(Chart, {
11
+ data: data.map((point) => ({
12
+ x: point.x,
13
+ y: point.y
14
+ })),
15
+ type: "line",
16
+ showGrid: true,
17
+ animate: true,
18
+ lineStyle: { color: color ?? palette[0] }
19
+ })
20
+ });
21
+ }
22
+
23
+ //#endregion
24
+ export { LineChart };
@@ -0,0 +1,33 @@
1
+ import { Text as Text$1 } from "../base/text.js";
2
+ import { Suspense, lazy } from "react";
3
+ import { Platform, View } from "react-native";
4
+ import { jsx } from "react/jsx-runtime";
5
+
6
+ //#region src/native/analytics/line-chart.tsx
7
+ const SwiftUILineChart = lazy(() => import("./line-chart.ios.js").then((module) => ({ default: module.LineChart })));
8
+ const DEFAULT_FALLBACK_TEXT = "チャートは現在 iOS でのみ表示できます";
9
+ const DEFAULT_HEIGHT = 220;
10
+ function LineChart(props) {
11
+ const height = props.height ?? DEFAULT_HEIGHT;
12
+ if (Platform.OS !== "ios") return /* @__PURE__ */ jsx(LineChartFallback, {
13
+ height,
14
+ text: props.fallbackText
15
+ });
16
+ return /* @__PURE__ */ jsx(Suspense, {
17
+ fallback: /* @__PURE__ */ jsx(View, { style: { height } }),
18
+ children: /* @__PURE__ */ jsx(SwiftUILineChart, { ...props })
19
+ });
20
+ }
21
+ function LineChartFallback({ height, text }) {
22
+ return /* @__PURE__ */ jsx(View, {
23
+ style: { height },
24
+ className: "items-center justify-center",
25
+ children: /* @__PURE__ */ jsx(Text$1, {
26
+ className: "text-muted-foreground text-sm",
27
+ children: text ?? DEFAULT_FALLBACK_TEXT
28
+ })
29
+ });
30
+ }
31
+
32
+ //#endregion
33
+ export { LineChart };
@@ -0,0 +1,10 @@
1
+ import { MetricCardSharedProps } from "../../shared/analytics.js";
2
+ //#region src/native/analytics/metric-card.d.ts
3
+ export type MetricCardProps = MetricCardSharedProps;
4
+ /**
5
+ * 面付きの単一指標。`@lt-three/web` の analytics/metric-card に対応する。
6
+ * 中身(ラベル + 大型の等幅数値 + 補助)は `atom/readout` が持ち、
7
+ * ここは web と同じく Card 外装を着せる役だけを担う。
8
+ */
9
+ export declare function MetricCard({ label, value, subValue, trend, className }: MetricCardProps): import("react").JSX.Element;
10
+ //#endregion
@@ -0,0 +1,29 @@
1
+ import { useTokenColor } from "../lib/token-color.js";
2
+ import { cn } from "../lib/utils.js";
3
+ import { Readout } from "../atom/readout.js";
4
+ import { Panel } from "../layout/panel.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+
7
+ //#region src/native/analytics/metric-card.tsx
8
+ /**
9
+ * 面付きの単一指標。`@lt-three/web` の analytics/metric-card に対応する。
10
+ * 中身(ラベル + 大型の等幅数値 + 補助)は `atom/readout` が持ち、
11
+ * ここは web と同じく Card 外装を着せる役だけを担う。
12
+ */
13
+ function MetricCard({ label, value, subValue, trend, className }) {
14
+ const up = useTokenColor("--state-success");
15
+ const down = useTokenColor("--state-error");
16
+ const valueColor = trend === void 0 || trend === 0 ? void 0 : trend > 0 ? up : down;
17
+ return /* @__PURE__ */ jsx(Panel, {
18
+ className: cn("p-4", className),
19
+ children: /* @__PURE__ */ jsx(Readout, {
20
+ label,
21
+ value,
22
+ sub: subValue,
23
+ valueColor
24
+ })
25
+ });
26
+ }
27
+
28
+ //#endregion
29
+ export { MetricCard };
@@ -0,0 +1,17 @@
1
+ import { MultiLineChartProps } from "./chart.types.js";
2
+ //#region src/native/analytics/multi-line-chart.d.ts
3
+ /**
4
+ * 複数系列の折れ線。移植元は `@lt-three/web` の analytics/line-chart(Recharts・複数キー)で、web の love3 では
5
+ * `analytics/multi-line-chart`(`@tanstack/charts`)が対応する(props は `shared/analytics.ts` で同じ)。
6
+ *
7
+ * **`@expo/ui` の Chart は 1 系列しか描けない**(型定義にも line/area は single-series と
8
+ * 明記されている)ので、同じ軸に 2 本以上載せたいものはこちらを使う。残高とエクイティの
9
+ * ように単位も軸も同じ系列を 2 枚のカードに分けると、上下を見比べないと関係が読めない。
10
+ *
11
+ * 描画は react-native-svg。SwiftUI Charts と違って外枠は描かず、目盛りの罫線だけを敷く
12
+ * (使用側が `Panel` で囲うと枠が二重になるため)。
13
+ *
14
+ * タップすると、その位置の各系列の値を読み出す。折れ線は目盛りだけだと概形しか読めない。
15
+ */
16
+ export declare function MultiLineChart({ series, height, formatValue, emptyText, style, accessibilityLabel }: MultiLineChartProps): import("react").JSX.Element;
17
+ //#endregion
@@ -0,0 +1,215 @@
1
+ import { useTokenColor } from "../lib/token-color.js";
2
+ import { Text as Text$2 } from "../base/text.js";
3
+ import { tabularNums } from "../lib/typography.js";
4
+ import { useState } from "react";
5
+ import { Pressable, View } from "react-native";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import Svg, { Circle, Line, Path, Text as Text$1 } from "react-native-svg";
8
+
9
+ //#region src/native/analytics/multi-line-chart.tsx
10
+ /**
11
+ * 複数系列の折れ線。移植元は `@lt-three/web` の analytics/line-chart(Recharts・複数キー)で、web の love3 では
12
+ * `analytics/multi-line-chart`(`@tanstack/charts`)が対応する(props は `shared/analytics.ts` で同じ)。
13
+ *
14
+ * **`@expo/ui` の Chart は 1 系列しか描けない**(型定義にも line/area は single-series と
15
+ * 明記されている)ので、同じ軸に 2 本以上載せたいものはこちらを使う。残高とエクイティの
16
+ * ように単位も軸も同じ系列を 2 枚のカードに分けると、上下を見比べないと関係が読めない。
17
+ *
18
+ * 描画は react-native-svg。SwiftUI Charts と違って外枠は描かず、目盛りの罫線だけを敷く
19
+ * (使用側が `Panel` で囲うと枠が二重になるため)。
20
+ *
21
+ * タップすると、その位置の各系列の値を読み出す。折れ線は目盛りだけだと概形しか読めない。
22
+ */
23
+ function MultiLineChart({ series, height = 220, formatValue = (value) => String(Math.round(value)), emptyText = "データがありません", style, accessibilityLabel }) {
24
+ const line = useTokenColor("--line");
25
+ const mutedInk = useTokenColor("--ink-500");
26
+ const [width, setWidth] = useState(0);
27
+ const [pickedX, setPickedX] = useState(null);
28
+ const withData = series.filter((entry) => entry.points.length > 0);
29
+ const values = withData.flatMap((entry) => entry.points.map((point) => point.y));
30
+ if (withData.length === 0) return /* @__PURE__ */ jsx(View, {
31
+ style: [{ height }, style],
32
+ className: "items-center justify-center",
33
+ children: /* @__PURE__ */ jsx(Text$2, {
34
+ className: "text-muted-foreground text-sm",
35
+ children: emptyText
36
+ })
37
+ });
38
+ const padding = {
39
+ top: 8,
40
+ right: 8,
41
+ bottom: 8,
42
+ left: 72
43
+ };
44
+ const plotWidth = Math.max(width - padding.left - padding.right, 0);
45
+ const plotHeight = height - padding.top - padding.bottom;
46
+ const min = Math.min(...values);
47
+ const max = Math.max(...values);
48
+ const span = max - min || Math.max(Math.abs(max), 1);
49
+ const low = max === min ? min - span / 2 : min;
50
+ const high = max === min ? max + span / 2 : max;
51
+ const toY = (value) => padding.top + (1 - (value - low) / (high - low)) * plotHeight;
52
+ const times = withData.flatMap((entry) => entry.points.map((point) => point.t));
53
+ const timed = times.every((time) => time !== void 0) && times.length > 0;
54
+ const tMin = timed ? Math.min(...times) : 0;
55
+ const tSpan = (timed ? Math.max(...times) : 0) - tMin;
56
+ const toX = (index, count, time) => {
57
+ if (timed && time !== void 0) return padding.left + (tSpan === 0 ? plotWidth / 2 : (time - tMin) / tSpan * plotWidth);
58
+ return padding.left + (count === 1 ? plotWidth / 2 : index / (count - 1) * plotWidth);
59
+ };
60
+ const ticks = [
61
+ high,
62
+ (high + low) / 2,
63
+ low
64
+ ];
65
+ const picked = pickedX === null ? [] : withData.map((entry) => ({
66
+ entry,
67
+ hit: nearestPoint(entry, pickedX, toX)
68
+ })).filter((row) => row.hit !== null);
69
+ const marker = picked[0];
70
+ return /* @__PURE__ */ jsxs(View, {
71
+ style,
72
+ ...accessibilityLabel === void 0 ? {} : {
73
+ accessible: true,
74
+ accessibilityRole: "image",
75
+ accessibilityLabel
76
+ },
77
+ children: [
78
+ /* @__PURE__ */ jsx(Pressable, {
79
+ focusable: false,
80
+ tabIndex: -1,
81
+ onLayout: (event) => setWidth(event.nativeEvent.layout.width),
82
+ onPress: (event) => {
83
+ const x = pressX(event);
84
+ if (x === null) return;
85
+ setPickedX(x < padding.left || x > padding.left + plotWidth ? null : x);
86
+ },
87
+ children: /* @__PURE__ */ jsxs(Svg, {
88
+ width,
89
+ height,
90
+ children: [
91
+ ticks.map((tick) => /* @__PURE__ */ jsx(Line, {
92
+ x1: padding.left,
93
+ x2: padding.left + plotWidth,
94
+ y1: toY(tick),
95
+ y2: toY(tick),
96
+ stroke: line,
97
+ strokeWidth: 1
98
+ }, `grid-${tick}`)),
99
+ ticks.map((tick) => /* @__PURE__ */ jsx(Text$1, {
100
+ x: padding.left - 8,
101
+ y: toY(tick) + 4,
102
+ fontSize: 10,
103
+ fill: mutedInk,
104
+ textAnchor: "end",
105
+ children: formatValue(tick)
106
+ }, `label-${tick}`)),
107
+ withData.map((entry) => /* @__PURE__ */ jsx(Path, {
108
+ d: pathOf(entry, toX, toY),
109
+ stroke: entry.color,
110
+ strokeWidth: entry.dashed === true ? 1 : 1.5,
111
+ strokeDasharray: entry.dashed === true ? "4 3" : void 0,
112
+ fill: "none"
113
+ }, entry.key)),
114
+ marker !== void 0 && /* @__PURE__ */ jsx(Line, {
115
+ x1: marker.hit.x,
116
+ x2: marker.hit.x,
117
+ y1: padding.top,
118
+ y2: padding.top + plotHeight,
119
+ stroke: mutedInk,
120
+ strokeWidth: 1,
121
+ strokeDasharray: "2 2"
122
+ }),
123
+ picked.map((row) => /* @__PURE__ */ jsx(Circle, {
124
+ cx: row.hit.x,
125
+ cy: toY(row.hit.value.y),
126
+ r: 3,
127
+ fill: row.entry.color
128
+ }, `dot-${row.entry.key}`))
129
+ ]
130
+ })
131
+ }),
132
+ marker !== void 0 && /* @__PURE__ */ jsxs(View, {
133
+ className: "border-line bg-popover rounded-control mt-2 gap-1 border p-2.5 shadow-md",
134
+ children: [/* @__PURE__ */ jsx(Text$2, {
135
+ style: tabularNums,
136
+ className: "text-muted-foreground font-mono text-[11px]",
137
+ children: String(marker.hit.value.x)
138
+ }), picked.map((row) => /* @__PURE__ */ jsxs(View, {
139
+ className: "flex-row items-center justify-between gap-3",
140
+ children: [/* @__PURE__ */ jsxs(View, {
141
+ className: "flex-row items-center gap-1.5",
142
+ children: [/* @__PURE__ */ jsx(View, { style: {
143
+ width: 10,
144
+ height: 2,
145
+ backgroundColor: row.entry.color
146
+ } }), /* @__PURE__ */ jsx(Text$2, {
147
+ className: "text-muted-foreground text-[11px]",
148
+ children: row.entry.label
149
+ })]
150
+ }), /* @__PURE__ */ jsx(Text$2, {
151
+ style: tabularNums,
152
+ className: "text-foreground font-mono text-[13px] font-semibold",
153
+ children: formatValue(row.hit.value.y)
154
+ })]
155
+ }, `read-${row.entry.key}`))]
156
+ }),
157
+ /* @__PURE__ */ jsx(View, {
158
+ className: "flex-row flex-wrap gap-x-4 gap-y-1 px-1 pt-2",
159
+ children: series.map((entry) => /* @__PURE__ */ jsxs(View, {
160
+ className: "flex-row items-center gap-1.5",
161
+ children: [/* @__PURE__ */ jsx(View, { style: {
162
+ width: 10,
163
+ height: 2,
164
+ backgroundColor: entry.color,
165
+ opacity: entry.points.length > 0 ? 1 : .4
166
+ } }), /* @__PURE__ */ jsx(Text$2, {
167
+ className: "text-muted-foreground text-[11px]",
168
+ children: entry.label
169
+ })]
170
+ }, `legend-${entry.key}`))
171
+ })
172
+ ]
173
+ });
174
+ }
175
+ /**
176
+ * 押した位置(押した要素の左端からの x)。実機は `locationX`。
177
+ * react-native-web の `onPress` は DOM の click を渡す(`locationX` が無い)ので、そのときは要素の左端との差で求める。
178
+ * 位置の無い click(キーボード等)は null。
179
+ */
180
+ function pressX(event) {
181
+ const { locationX } = event.nativeEvent;
182
+ if (typeof locationX === "number" && Number.isFinite(locationX)) return locationX;
183
+ const dom = event.nativeEvent;
184
+ if (dom.detail === 0) return null;
185
+ const target = event.currentTarget;
186
+ return dom.clientX - target.getBoundingClientRect().left;
187
+ }
188
+ /** 系列を 1 本の SVG パスにする。 */
189
+ function pathOf(entry, toX, toY) {
190
+ const count = entry.points.length;
191
+ return entry.points.map((point, index) => `${index === 0 ? "M" : "L"}${toX(index, count, point.t)},${toY(point.y)}`).join(" ");
192
+ }
193
+ /** 押した x にいちばん近い点を、その描画位置ごと返す。 */
194
+ function nearestPoint(entry, pickedX, toX) {
195
+ const count = entry.points.length;
196
+ let best;
197
+ let bestX = 0;
198
+ let bestDistance = Number.POSITIVE_INFINITY;
199
+ for (let index = 0; index < count; index++) {
200
+ const x = toX(index, count, entry.points[index]?.t);
201
+ const distance = Math.abs(x - pickedX);
202
+ if (distance < bestDistance) {
203
+ bestDistance = distance;
204
+ bestX = x;
205
+ best = entry.points[index];
206
+ }
207
+ }
208
+ return best === void 0 ? null : {
209
+ x: bestX,
210
+ value: best
211
+ };
212
+ }
213
+
214
+ //#endregion
215
+ export { MultiLineChart };
@@ -0,0 +1,15 @@
1
+ import { PieChartProps } from "./chart.types.js";
2
+ //#region src/native/analytics/pie-chart.d.ts
3
+ /**
4
+ * 円グラフ(react-native-svg)。移植元の既定(Android / web)実装。iOS の SwiftUI Charts 版(`pie-chart.ios.tsx`)は
5
+ * `@expo/ui` が要るので、placeholder の仕組み(G5)と一緒に足す。足すまでは iOS もこの実装で描く。
6
+ *
7
+ * 描画は `multi-line-chart` と同じ react-native-svg。**「iOS のみ」のプレースホルダに
8
+ * しない**のは、勝敗比率・ロング / ショート・銘柄内訳がこのコンポーネントだけで出ており、
9
+ * Android では画面の主役が丸ごと文言に置き換わってしまうため。
10
+ *
11
+ * **凡例はここで持たない。** 使用側(口座のチャート)が色付きの内訳リストを円の下に
12
+ * 必ず並べるので、ここで凡例を出すと同じものが 2 段になる。円の高さもそのぶん削れる。
13
+ */
14
+ export declare function PieChart({ data, donut, height, style, accessibilityLabel }: PieChartProps): import("react").JSX.Element;
15
+ //#endregion
@@ -0,0 +1,4 @@
1
+ import { PieChartProps } from "./chart.types.js";
2
+ //#region src/native/analytics/pie-chart.ios.d.ts
3
+ export declare function PieChart({ data, donut, height, style }: PieChartProps): import("react").JSX.Element;
4
+ //#endregion
@@ -0,0 +1,24 @@
1
+ import { useChartPalette } from "../lib/chart-palette.js";
2
+ import { Chart, Host } from "@expo/ui/swift-ui";
3
+ import { jsx } from "react/jsx-runtime";
4
+
5
+ //#region src/native/analytics/pie-chart.ios.tsx
6
+ function PieChart({ data, donut, height = 220, style }) {
7
+ const palette = useChartPalette();
8
+ return /* @__PURE__ */ jsx(Host, {
9
+ style: [{ height }, style],
10
+ children: /* @__PURE__ */ jsx(Chart, {
11
+ data: data.map((slice, index) => ({
12
+ x: slice.label,
13
+ y: slice.value,
14
+ color: slice.color ?? palette[index % palette.length]
15
+ })),
16
+ type: "pie",
17
+ animate: true,
18
+ pieStyle: donut ? { innerRadius: .6 } : void 0
19
+ })
20
+ });
21
+ }
22
+
23
+ //#endregion
24
+ export { PieChart };
@@ -0,0 +1,92 @@
1
+ import { useTokenColor } from "../lib/token-color.js";
2
+ import { useChartPalette } from "../lib/chart-palette.js";
3
+ import { Text as Text$2 } from "../base/text.js";
4
+ import { View } from "react-native";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import Svg, { Circle, Path } from "react-native-svg";
7
+
8
+ //#region src/native/analytics/pie-chart.tsx
9
+ /**
10
+ * 円グラフ(react-native-svg)。移植元の既定(Android / web)実装。iOS の SwiftUI Charts 版(`pie-chart.ios.tsx`)は
11
+ * `@expo/ui` が要るので、placeholder の仕組み(G5)と一緒に足す。足すまでは iOS もこの実装で描く。
12
+ *
13
+ * 描画は `multi-line-chart` と同じ react-native-svg。**「iOS のみ」のプレースホルダに
14
+ * しない**のは、勝敗比率・ロング / ショート・銘柄内訳がこのコンポーネントだけで出ており、
15
+ * Android では画面の主役が丸ごと文言に置き換わってしまうため。
16
+ *
17
+ * **凡例はここで持たない。** 使用側(口座のチャート)が色付きの内訳リストを円の下に
18
+ * 必ず並べるので、ここで凡例を出すと同じものが 2 段になる。円の高さもそのぶん削れる。
19
+ */
20
+ function PieChart({ data, donut, height = 220, style, accessibilityLabel }) {
21
+ const palette = useChartPalette();
22
+ const fallbackColor = useTokenColor("--chart-1");
23
+ const total = data.reduce((sum, slice) => sum + Math.max(slice.value, 0), 0);
24
+ const colorOf = (slice, index) => slice.color ?? palette[index % palette.length] ?? fallbackColor;
25
+ const size = height;
26
+ const radius = size / 2;
27
+ const inner = donut ? radius * .6 : 0;
28
+ return /* @__PURE__ */ jsx(View, {
29
+ style,
30
+ ...accessibilityLabel === void 0 ? {} : {
31
+ accessible: true,
32
+ accessibilityRole: "image",
33
+ accessibilityLabel
34
+ },
35
+ children: /* @__PURE__ */ jsx(View, {
36
+ style: { height: size },
37
+ className: "items-center justify-center",
38
+ children: total > 0 ? /* @__PURE__ */ jsx(Svg, {
39
+ width: size,
40
+ height: size,
41
+ viewBox: `0 0 ${size} ${size}`,
42
+ children: data.length === 1 && data[0] ? /* @__PURE__ */ jsx(Circle, {
43
+ cx: radius,
44
+ cy: radius,
45
+ r: (radius + inner) / 2,
46
+ stroke: colorOf(data[0], 0),
47
+ strokeWidth: radius - inner,
48
+ fill: "none"
49
+ }) : slicePaths(data, total, radius, inner).map(({ slice, d }, index) => /* @__PURE__ */ jsx(Path, {
50
+ d,
51
+ fill: colorOf(slice, index)
52
+ }, slice.label))
53
+ }) : /* @__PURE__ */ jsx(Text$2, {
54
+ className: "text-muted-foreground text-sm",
55
+ children: "–"
56
+ })
57
+ })
58
+ });
59
+ }
60
+ /** 各スライスを SVG のパスにする。12 時から時計回りに並べる(SwiftUI Charts と同じ向き)。 */
61
+ function slicePaths(data, total, radius, inner) {
62
+ let angle = -Math.PI / 2;
63
+ return data.map((slice) => {
64
+ const sweep = Math.max(slice.value, 0) / total * Math.PI * 2;
65
+ const end = angle + sweep;
66
+ const large = sweep > Math.PI ? 1 : 0;
67
+ const outerStart = point(radius, radius, radius, angle);
68
+ const outerEnd = point(radius, radius, radius, end);
69
+ const innerEnd = point(radius, radius, inner, end);
70
+ const innerStart = point(radius, radius, inner, angle);
71
+ angle = end;
72
+ return {
73
+ slice,
74
+ d: [
75
+ `M ${outerStart.x} ${outerStart.y}`,
76
+ `A ${radius} ${radius} 0 ${large} 1 ${outerEnd.x} ${outerEnd.y}`,
77
+ `L ${innerEnd.x} ${innerEnd.y}`,
78
+ inner > 0 ? `A ${inner} ${inner} 0 ${large} 0 ${innerStart.x} ${innerStart.y}` : "",
79
+ "Z"
80
+ ].filter(Boolean).join(" ")
81
+ };
82
+ });
83
+ }
84
+ function point(cx, cy, r, angle) {
85
+ return {
86
+ x: cx + r * Math.cos(angle),
87
+ y: cy + r * Math.sin(angle)
88
+ };
89
+ }
90
+
91
+ //#endregion
92
+ export { PieChart };
@@ -0,0 +1,19 @@
1
+ //#region src/native/analytics/single-number.d.ts
2
+ export type SingleNumberProps = {
3
+ title: string;
4
+ subTitle?: string;
5
+ value: number | null;
6
+ unit?: string;
7
+ /** 比較対象の値。渡すと差分と増減率を併記する。 */
8
+ compareValue?: number;
9
+ compareTitle?: string;
10
+ /** 増が悪い指標(コスト等)で色を反転する。 */
11
+ reverseColor?: boolean;
12
+ className?: string;
13
+ };
14
+ /**
15
+ * raised 面(surface 角丸・1px の極薄の罫線)に大きな数値を載せる指標。
16
+ * `@lt-three/web` の analytics/single-number に対応する。増減は state の色(面が反転しないので、同じテーマの値でよい)。
17
+ */
18
+ export declare function SingleNumber({ title, subTitle, value, unit, compareValue, compareTitle, reverseColor, className }: SingleNumberProps): import("react").JSX.Element;
19
+ //#endregion