@lt-three/love3 0.1.0 → 0.1.1
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.
- package/README.md +40 -40
- package/dist/native/analytics/animation.d.ts +1 -1
- package/dist/native/analytics/animation.js +1 -1
- package/dist/native/analytics/chart.types.d.ts +3 -3
- package/dist/native/analytics/metric-card.d.ts +3 -3
- package/dist/native/analytics/metric-card.js +3 -3
- package/dist/native/analytics/multi-line-chart.d.ts +9 -8
- package/dist/native/analytics/multi-line-chart.js +14 -13
- package/dist/native/analytics/pie-chart.d.ts +7 -7
- package/dist/native/analytics/pie-chart.js +8 -8
- package/dist/native/analytics/single-number.d.ts +4 -4
- package/dist/native/analytics/single-number.js +2 -2
- package/dist/native/atom/avatar.d.ts +6 -6
- package/dist/native/atom/avatar.js +2 -2
- package/dist/native/atom/badge.d.ts +5 -5
- package/dist/native/atom/button.d.ts +12 -12
- package/dist/native/atom/button.js +8 -8
- package/dist/native/atom/checkbox.d.ts +4 -4
- package/dist/native/atom/checkbox.js +2 -2
- package/dist/native/atom/colored-value.d.ts +4 -4
- package/dist/native/atom/colored-value.js +4 -4
- package/dist/native/atom/image.d.ts +7 -7
- package/dist/native/atom/image.js +2 -2
- package/dist/native/atom/label.d.ts +5 -5
- package/dist/native/atom/label.js +2 -2
- package/dist/native/atom/link.d.ts +5 -5
- package/dist/native/atom/link.js +5 -5
- package/dist/native/atom/readout.d.ts +7 -7
- package/dist/native/atom/readout.js +3 -3
- package/dist/native/atom/search-input.d.ts +2 -2
- package/dist/native/atom/search-input.js +2 -2
- package/dist/native/atom/select.d.ts +14 -14
- package/dist/native/atom/select.js +8 -8
- package/dist/native/atom/separator.d.ts +2 -3
- package/dist/native/atom/separator.js +2 -3
- package/dist/native/atom/skeleton.d.ts +3 -3
- package/dist/native/atom/skeleton.js +3 -3
- package/dist/native/atom/slider.d.ts +6 -6
- package/dist/native/atom/slider.js +3 -3
- package/dist/native/atom/spinner.d.ts +4 -4
- package/dist/native/atom/spinner.js +2 -2
- package/dist/native/atom/switch.d.ts +4 -4
- package/dist/native/atom/switch.js +3 -3
- package/dist/native/atom/symbol.d.ts +7 -7
- package/dist/native/atom/symbol.js +7 -7
- package/dist/native/atom/symbol.types.d.ts +8 -8
- package/dist/native/atom/symbol.types.js +7 -7
- package/dist/native/atom/text-field.d.ts +15 -15
- package/dist/native/atom/text-field.js +5 -5
- package/dist/native/atom/theme-toggle.d.ts +7 -7
- package/dist/native/atom/theme-toggle.js +4 -4
- package/dist/native/atom/timezone-select.d.ts +5 -5
- package/dist/native/atom/timezone-select.js +4 -4
- package/dist/native/atom/typography.d.ts +2 -2
- package/dist/native/atom/typography.js +2 -2
- package/dist/native/base/button.d.ts +13 -13
- package/dist/native/base/button.js +4 -4
- package/dist/native/base/form.d.ts +15 -15
- package/dist/native/base/form.js +11 -11
- package/dist/native/base/glass-card.d.ts +3 -3
- package/dist/native/base/glass-card.js +3 -3
- package/dist/native/base/input.d.ts +8 -8
- package/dist/native/base/input.js +7 -7
- package/dist/native/base/sheet.d.ts +27 -27
- package/dist/native/base/sheet.js +15 -15
- package/dist/native/form/checkbox.d.ts +3 -3
- package/dist/native/form/checkbox.js +2 -2
- package/dist/native/form/date-picker.d.ts +9 -9
- package/dist/native/form/date-picker.js +9 -9
- package/dist/native/form/form.d.ts +5 -6
- package/dist/native/form/form.js +4 -5
- package/dist/native/form/radio-group.d.ts +5 -5
- package/dist/native/form/radio-group.js +4 -4
- package/dist/native/form/select.d.ts +2 -2
- package/dist/native/form/select.js +2 -2
- package/dist/native/form/slider.d.ts +2 -2
- package/dist/native/form/slider.js +2 -2
- package/dist/native/form/switch.d.ts +2 -2
- package/dist/native/form/switch.js +2 -2
- package/dist/native/form/text-area.d.ts +2 -2
- package/dist/native/form/text-area.js +1 -1
- package/dist/native/form/text-input.d.ts +5 -5
- package/dist/native/form/text-input.js +8 -8
- package/dist/native/layout/accordion.d.ts +5 -5
- package/dist/native/layout/accordion.js +2 -2
- package/dist/native/layout/card.d.ts +8 -8
- package/dist/native/layout/card.js +3 -3
- package/dist/native/layout/description.d.ts +2 -2
- package/dist/native/layout/description.js +2 -2
- package/dist/native/layout/error.d.ts +5 -5
- package/dist/native/layout/error.js +2 -2
- package/dist/native/layout/information.d.ts +4 -4
- package/dist/native/layout/information.js +3 -3
- package/dist/native/layout/locked.d.ts +15 -15
- package/dist/native/layout/locked.js +7 -7
- package/dist/native/layout/modal.d.ts +8 -8
- package/dist/native/layout/modal.js +5 -5
- package/dist/native/layout/not-found.d.ts +4 -4
- package/dist/native/layout/not-found.js +3 -3
- package/dist/native/layout/page-frame.d.ts +8 -8
- package/dist/native/layout/page-frame.js +3 -3
- package/dist/native/layout/panel.d.ts +5 -5
- package/dist/native/layout/panel.js +5 -5
- package/dist/native/layout/reorderable-list.d.ts +14 -14
- package/dist/native/layout/reorderable-list.js +10 -10
- package/dist/native/layout/sheet.d.ts +10 -10
- package/dist/native/layout/sheet.js +4 -4
- package/dist/native/layout/simple-dialog.d.ts +3 -3
- package/dist/native/layout/simple-dialog.js +2 -2
- package/dist/native/layout/simple-table.d.ts +18 -18
- package/dist/native/layout/simple-table.js +1 -1
- package/dist/native/layout/tab-bar.d.ts +10 -10
- package/dist/native/layout/tab-bar.js +4 -4
- package/dist/native/layout/tabs.d.ts +6 -6
- package/dist/native/layout/tabs.js +4 -4
- package/dist/native/layout/tuning-panel.d.ts +10 -10
- package/dist/native/layout/tuning-panel.js +15 -15
- package/dist/native/lib/autocomplete.d.ts +1 -1
- package/dist/native/lib/autocomplete.js +1 -1
- package/dist/native/lib/breakpoints.d.ts +3 -3
- package/dist/native/lib/breakpoints.js +3 -3
- package/dist/native/lib/chart-palette.d.ts +2 -2
- package/dist/native/lib/chart-palette.js +2 -2
- package/dist/native/lib/confirm.d.ts +15 -16
- package/dist/native/lib/confirm.js +9 -10
- package/dist/native/lib/control.d.ts +9 -9
- package/dist/native/lib/external-store.d.ts +4 -5
- package/dist/native/lib/keyboard.d.ts +7 -7
- package/dist/native/lib/keyboard.js +7 -7
- package/dist/native/lib/labels.d.ts +6 -6
- package/dist/native/lib/labels.js +6 -6
- package/dist/native/lib/loading.d.ts +3 -3
- package/dist/native/lib/loading.js +3 -3
- package/dist/native/lib/network.d.ts +5 -6
- package/dist/native/lib/network.js +5 -6
- package/dist/native/lib/scheme.d.ts +7 -7
- package/dist/native/lib/scheme.js +3 -3
- package/dist/native/lib/snackbar.d.ts +12 -13
- package/dist/native/lib/snackbar.js +7 -8
- package/dist/native/lib/theme.d.ts +15 -15
- package/dist/native/lib/theme.js +15 -15
- package/dist/native/lib/timezone.d.ts +13 -13
- package/dist/native/lib/timezone.js +13 -13
- package/dist/native/lib/token-color.d.ts +1 -1
- package/dist/native/lib/token-color.js +1 -1
- package/dist/native/lib/tuning-context.d.ts +2 -2
- package/dist/native/lib/tuning.d.ts +10 -10
- package/dist/native/lib/tuning.js +8 -8
- package/dist/native/lib/typography.d.ts +3 -3
- package/dist/native/lib/typography.js +3 -3
- package/dist/native/lib/utils.d.ts +3 -3
- package/dist/native/lib/utils.js +3 -3
- package/dist/native/once/confirm.d.ts +2 -2
- package/dist/native/once/confirm.js +2 -2
- package/dist/native/once/error-boundary.d.ts +3 -3
- package/dist/native/once/error-boundary.js +2 -2
- package/dist/native/once/loading-lock.d.ts +3 -3
- package/dist/native/once/loading-lock.js +3 -3
- package/dist/native/once/offline-banner.d.ts +6 -6
- package/dist/native/once/offline-banner.js +5 -5
- package/dist/native/once/snackbar.d.ts +7 -7
- package/dist/native/once/snackbar.js +5 -5
- package/dist/native/styles.css +21 -21
- package/dist/shared/analytics.d.ts +23 -23
- package/dist/shared/button.d.ts +1 -1
- package/dist/shared/form.d.ts +7 -7
- package/dist/shared/form.js +2 -2
- package/dist/tokens/contrast-pairs.d.ts +9 -9
- package/dist/tokens/contrast-pairs.js +10 -10
- package/dist/tokens/index.d.ts +1 -1
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/styles.gen.css +87 -87
- package/dist/tokens/tokens.gen.d.ts +2 -2
- package/dist/tokens/tokens.gen.js +2 -2
- package/dist/tuning/catalog.d.ts +8 -8
- package/dist/tuning/catalog.js +9 -9
- package/dist/tuning/color.d.ts +4 -4
- package/dist/tuning/color.js +5 -5
- package/dist/tuning/css.d.ts +13 -13
- package/dist/tuning/css.js +17 -17
- package/dist/tuning/model.d.ts +11 -11
- package/dist/tuning/model.js +11 -11
- package/dist/tuning/native.d.ts +18 -18
- package/dist/tuning/native.js +18 -18
- package/dist/tuning/schema.d.ts +15 -15
- package/dist/tuning/schema.js +22 -22
- package/dist/tuning/types.d.ts +25 -25
- package/dist/tuning/types.js +6 -6
- package/dist/web/analytics/line-chart.d.ts +6 -6
- package/dist/web/analytics/line-chart.js +3 -3
- package/dist/web/analytics/metric-card.d.ts +6 -6
- package/dist/web/analytics/metric-card.js +5 -5
- package/dist/web/analytics/multi-line-chart.d.ts +23 -23
- package/dist/web/analytics/multi-line-chart.js +33 -33
- package/dist/web/atom/avatar.d.ts +1 -1
- package/dist/web/atom/checkbox.d.ts +6 -6
- package/dist/web/atom/checkbox.js +2 -2
- package/dist/web/atom/colored-value.d.ts +4 -4
- package/dist/web/atom/colored-value.js +4 -4
- package/dist/web/atom/help.d.ts +1 -1
- package/dist/web/atom/segmented-control.d.ts +13 -14
- package/dist/web/atom/segmented-control.js +6 -7
- package/dist/web/atom/select.d.ts +7 -7
- package/dist/web/atom/select.js +5 -5
- package/dist/web/atom/slider.d.ts +3 -3
- package/dist/web/atom/slider.js +2 -2
- package/dist/web/atom/switch.d.ts +3 -3
- package/dist/web/atom/text-area.d.ts +9 -8
- package/dist/web/atom/text-area.js +9 -8
- package/dist/web/atom/text-field.d.ts +5 -4
- package/dist/web/atom/text-field.js +5 -4
- package/dist/web/atom/toggle-chip.d.ts +6 -6
- package/dist/web/atom/toggle-chip.js +4 -4
- package/dist/web/atom/tooltip.d.ts +6 -6
- package/dist/web/atom/tooltip.js +2 -2
- package/dist/web/base/accordion.js +1 -1
- package/dist/web/base/breadcrumb.d.ts +1 -1
- package/dist/web/base/breadcrumb.js +1 -1
- package/dist/web/base/card.d.ts +3 -3
- package/dist/web/base/card.js +2 -2
- package/dist/web/base/dialog.d.ts +1 -1
- package/dist/web/base/dialog.js +1 -1
- package/dist/web/base/form.d.ts +7 -7
- package/dist/web/base/form.js +5 -5
- package/dist/web/base/pagination.d.ts +5 -5
- package/dist/web/base/pagination.js +1 -1
- package/dist/web/base/sheet.d.ts +1 -1
- package/dist/web/base/sheet.js +1 -1
- package/dist/web/base/slider.d.ts +1 -1
- package/dist/web/base/sonner.d.ts +2 -2
- package/dist/web/base/sonner.js +2 -2
- package/dist/web/base/spinner.js +1 -1
- package/dist/web/form/checkbox.d.ts +8 -8
- package/dist/web/form/checkbox.js +3 -3
- package/dist/web/form/radio-group.js +3 -3
- package/dist/web/form/select.js +1 -1
- package/dist/web/form/slider.d.ts +3 -3
- package/dist/web/form/slider.js +3 -3
- package/dist/web/form/switch.d.ts +3 -3
- package/dist/web/form/switch.js +4 -4
- package/dist/web/form/text-area.js +1 -1
- package/dist/web/form/text-input.d.ts +1 -1
- package/dist/web/form/text-input.js +1 -1
- package/dist/web/layout/accordion.d.ts +5 -5
- package/dist/web/layout/accordion.js +2 -2
- package/dist/web/layout/alert-modal.d.ts +11 -11
- package/dist/web/layout/alert-modal.js +7 -7
- package/dist/web/layout/card.d.ts +1 -1
- package/dist/web/layout/information.d.ts +9 -9
- package/dist/web/layout/information.js +7 -7
- package/dist/web/layout/modal.d.ts +1 -1
- package/dist/web/layout/page-frame.d.ts +14 -14
- package/dist/web/layout/page-frame.js +7 -7
- package/dist/web/layout/scroll-area.d.ts +1 -1
- package/dist/web/layout/sheet.d.ts +4 -4
- package/dist/web/layout/simple-table.d.ts +18 -18
- package/dist/web/layout/simple-table.js +2 -2
- package/dist/web/layout/tabs.d.ts +4 -4
- package/dist/web/layout/titled-modal.d.ts +10 -11
- package/dist/web/layout/titled-modal.js +7 -8
- package/dist/web/lib/css-vars.d.ts +6 -6
- package/dist/web/lib/css-vars.js +5 -5
- package/dist/web/lib/dialog.d.ts +4 -4
- package/dist/web/lib/labels.d.ts +8 -8
- package/dist/web/lib/labels.js +8 -8
- package/dist/web/lib/modal-open-focus.d.ts +7 -7
- package/dist/web/lib/modal-open-focus.js +9 -9
- package/dist/web/lib/restore-focus.d.ts +4 -4
- package/dist/web/lib/restore-focus.js +4 -4
- package/dist/web/styles.css +33 -33
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
# @lt-three/love3
|
|
2
2
|
|
|
3
|
-
<3
|
|
4
|
-
web
|
|
3
|
+
The shared design system of <3 (Less Than Three): layered backgrounds, hairline borders, soft shadows, and an indigo primary action.
|
|
4
|
+
It looks the same on web (React + Tailwind CSS v4) and React Native (NativeWind v5). The actual token values (color, radius, shadow, typeface) can also be read as a TS object.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Licensed under MIT.
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Installation
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
11
|
npm install @lt-three/love3
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
- **web**: `react` `react-dom
|
|
15
|
-
- **React Native**: `react
|
|
16
|
-
|
|
14
|
+
- **web**: install `react` and `react-dom` (`>=19.3.0 <20`) and `tailwindcss` (v4). The dependencies used by the web components (Radix, `@tanstack/charts`, and so on) are in this package's `dependencies`, so you do not need to install them separately.
|
|
15
|
+
- **React Native**: install `react`, `react-native`, `nativewind` (v5), `react-native-css`, and `tailwindcss`, plus the native dependencies pulled in by the components you use (`expo`, `expo-router`, `react-native-reanimated`, `react-native-svg`, and so on).
|
|
16
|
+
Native-only dependencies are **optional `peerDependencies`**. You do not need to install the dependencies of components you do not use (see the `peerDependencies` in `package.json` and the imports of each component to find out which component needs which).
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
The published files are in `dist/` (ESM `.js` and `.d.ts`). They keep the same structure as the source, one file per component. The dependencies of components you do not use are not pulled in.
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## Usage
|
|
21
21
|
|
|
22
|
-
| import |
|
|
23
|
-
| --------------------------------------------------------------------------- |
|
|
24
|
-
| `@lt-three/love3/styles.css` | Tailwind v4
|
|
25
|
-
| `@lt-three/love3/tokens` |
|
|
26
|
-
| `@lt-three/love3/tokens/contrast` |
|
|
27
|
-
| `@lt-three/love3/tuning` |
|
|
28
|
-
| `@lt-three/love3/web` / `@lt-three/love3/native` / `@lt-three/love3/shared` |
|
|
29
|
-
| `@lt-three/love3/web/atom/button.tsx
|
|
30
|
-
| `@lt-three/love3/web/styles.css` | web
|
|
31
|
-
| `@lt-three/love3/native/atom/button.tsx
|
|
32
|
-
| `@lt-three/love3/native/styles.css` |
|
|
33
|
-
| `@lt-three/love3/shared
|
|
22
|
+
| import | contents |
|
|
23
|
+
| --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
24
|
+
| `@lt-three/love3/styles.css` | Tailwind v4 `@theme` with light and dark. Shared by web and NativeWind |
|
|
25
|
+
| `@lt-three/love3/tokens` | The actual token values as a TS object (`tokens.light` / `tokens.dark`), `cssVar`, and types. For RN charts and Reanimated, where CSS is not available. Does not import `node:` built-ins |
|
|
26
|
+
| `@lt-three/love3/tokens/contrast` | The foreground / background pairs checked for contrast (`CONTRAST_PAIRS`) and the known exceptions with reasons (`KNOWN_CONTRAST_EXCEPTIONS`). Data only |
|
|
27
|
+
| `@lt-three/love3/tuning` | The format, validation, and application of "tuning", which overrides tokens at runtime (imports only `zod`) |
|
|
28
|
+
| `@lt-three/love3/web` / `@lt-three/love3/native` / `@lt-three/love3/shared` | The entry point of each layer (`index.ts`) |
|
|
29
|
+
| `@lt-three/love3/web/atom/button.tsx`, **with the extension** | Web components. `web/*.ts` (hooks and utilities) and `web/*.tsx` |
|
|
30
|
+
| `@lt-three/love3/web/styles.css` | Imported by a web app at its CSS entry. Tailwind, fonts, tokens, and base styles |
|
|
31
|
+
| `@lt-three/love3/native/atom/button.tsx`, **with the extension** | Native components |
|
|
32
|
+
| `@lt-three/love3/native/styles.css` | **The CSS entry for real devices (Metro / NativeWind v5)**. Tailwind, `nativewind/theme`, tokens, detection of component classes, and an override that maps `dark:` to `prefers-color-scheme` |
|
|
33
|
+
| `@lt-three/love3/shared/…` (`.ts` / `.tsx`) | Props types and variant definitions shared by web and native |
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
**Wildcard exports use keys with the file extension** (`./web/*.tsx` / `./web/*.ts`). `exports` does not search for extensions, so consumers import with the extension too
|
|
36
|
+
(enable `allowImportingTsExtensions` in TypeScript). Without the extension (`.../atom/button`) the specifier does not resolve. Specifiers point to the `.js` files and the `.d.ts` type declarations in `dist/`.
|
|
37
37
|
|
|
38
38
|
### web
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Import it once at your CSS entry.
|
|
41
41
|
|
|
42
42
|
```css
|
|
43
43
|
@import "@lt-three/love3/web/styles.css";
|
|
@@ -47,41 +47,41 @@ CSS の入口で 1 度だけ import する。
|
|
|
47
47
|
import { Button } from "@lt-three/love3/web/atom/button.tsx";
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
The Tailwind classes used by the components are picked up from `dist/` by `@source` in this CSS. Your own app source is left to Tailwind's automatic detection, based on the bundler's project root.
|
|
51
|
+
Switch to dark with `<html class="dark">`.
|
|
52
52
|
|
|
53
53
|
### React Native
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Import it once in your app's `global.css` (NativeWind v5 / react-native-css compiles it as Tailwind v4).
|
|
56
56
|
|
|
57
57
|
```css
|
|
58
58
|
@import "@lt-three/love3/native/styles.css";
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
native
|
|
62
|
-
|
|
61
|
+
On native, `dark:` is resolved by **the OS color scheme** (`prefers-color-scheme`), not by a class. With `.dark` as an ancestor selector, react-native-css treats that view as a container,
|
|
62
|
+
and a descendant ScrollView can no longer receive pans. Switch the in-app theme with `Appearance.setColorScheme()`.
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
The components that use SwiftUI Charts on iOS (`line-chart.ios.tsx` / `pie-chart.ios.tsx`) are imported explicitly, with the extension, by the iOS app.
|
|
65
65
|
|
|
66
|
-
###
|
|
66
|
+
### Tokens
|
|
67
67
|
|
|
68
68
|
```ts
|
|
69
69
|
import { cssVar, tokens } from "@lt-three/love3/tokens";
|
|
70
70
|
|
|
71
|
-
tokens.light["ink-900"]; //
|
|
71
|
+
tokens.light["ink-900"]; // the actual value ("#1b1c20")
|
|
72
72
|
cssVar("ink-900"); // "var(--ink-900)"
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
The variable names are shadcn-compatible names (`--background`, `--primary`, and so on) plus raw tokens such as `--ink-*`, `--line*`, and `--lt-three`.
|
|
76
76
|
|
|
77
|
-
##
|
|
77
|
+
## Note: `.theme-light` does not lighten semantic classes
|
|
78
78
|
|
|
79
|
-
`.theme-light
|
|
80
|
-
`--background` / `--foreground` / `--primary`
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
love3
|
|
79
|
+
`.theme-light` (a scope that forces light) redefines **only the raw tokens** (`--ink-*` / `--line*` / `--frame` / `--paper` / `--raised` / `--overlay` / `--wash` / `--scrim` / `--shadow-color` / `--action-ink` / `--state-*` / `--chart-*`).
|
|
80
|
+
Semantic variables such as `--background` / `--foreground` / `--primary` are declared on `:root` as `var(--paper)` and the like, and **are resolved on the element that declares them, then inherited by descendants**.
|
|
81
|
+
So even if you put `.theme-light` under `<html class="dark">`, classes such as `bg-background` / `text-foreground` / `bg-primary` **stay dark** in its descendants
|
|
82
|
+
(classes of raw tokens such as `bg-paper` / `text-ink-900` do become light).
|
|
83
|
+
love3 components do not use `.theme-light`. On a page that must always be light, use raw-token classes inside `.theme-light`, or also redeclare the semantic variables in `.theme-light`.
|
|
84
84
|
|
|
85
|
-
##
|
|
85
|
+
## License
|
|
86
86
|
|
|
87
87
|
[MIT](./LICENSE)
|
|
@@ -9,15 +9,15 @@ export type PieSlice = {
|
|
|
9
9
|
type ChartCommonProps = ChartCommonProps$1 & {
|
|
10
10
|
style?: ViewStyle;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Text shown on platforms without native chart support.
|
|
13
|
+
* This is a shared package, so it only provides a default; consumers pass their own translation.
|
|
14
14
|
*/
|
|
15
15
|
fallbackText?: string;
|
|
16
16
|
};
|
|
17
17
|
export type LineChartProps = ChartCommonProps & LineChartSharedProps;
|
|
18
18
|
export type PieChartProps = ChartCommonProps & {
|
|
19
19
|
data: PieSlice[];
|
|
20
|
-
/**
|
|
20
|
+
/** Renders a donut with a hollow center. */
|
|
21
21
|
donut?: boolean;
|
|
22
22
|
};
|
|
23
23
|
export type MultiLineChartProps = ChartCommonProps & MultiLineChartSharedProps;
|
|
@@ -2,9 +2,9 @@ import { MetricCardSharedProps } from "../../shared/analytics.js";
|
|
|
2
2
|
//#region src/native/analytics/metric-card.d.ts
|
|
3
3
|
export type MetricCardProps = MetricCardSharedProps;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* A single metric on a surface. Mirrors the web analytics metric-card.
|
|
6
|
+
* The content (label + large monospaced number + secondary text) lives in `atom/readout`;
|
|
7
|
+
* as on the web, this component only wraps it in the card chrome.
|
|
8
8
|
*/
|
|
9
9
|
export declare function MetricCard({ label, value, subValue, trend, className }: MetricCardProps): import("react").JSX.Element;
|
|
10
10
|
//#endregion
|
|
@@ -6,9 +6,9 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
6
|
|
|
7
7
|
//#region src/native/analytics/metric-card.tsx
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* A single metric on a surface. Mirrors the web analytics metric-card.
|
|
10
|
+
* The content (label + large monospaced number + secondary text) lives in `atom/readout`;
|
|
11
|
+
* as on the web, this component only wraps it in the card chrome.
|
|
12
12
|
*/
|
|
13
13
|
function MetricCard({ label, value, subValue, trend, className }) {
|
|
14
14
|
const up = useTokenColor("--state-success");
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { MultiLineChartProps } from "./chart.types.js";
|
|
2
2
|
//#region src/native/analytics/multi-line-chart.d.ts
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Multi-series line chart. The web counterpart is `analytics/multi-line-chart` (`@tanstack/charts`)
|
|
5
|
+
* (the props are shared via `shared/analytics.ts`).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* **The `@expo/ui` Chart can only draw a single series** (its type definitions also state that
|
|
8
|
+
* line/area are single-series), so use this component when two or more series share an axis.
|
|
9
|
+
* Splitting series with the same unit and axis (such as balance and equity) across two cards
|
|
10
|
+
* makes the relationship hard to read without comparing them vertically.
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
12
|
+
* Drawing uses react-native-svg. Unlike SwiftUI Charts it draws no outer frame, only the tick lines
|
|
13
|
+
* (a consumer wrapping it in a `Panel` would otherwise get a double border).
|
|
13
14
|
*
|
|
14
|
-
*
|
|
15
|
+
* Tapping reads out each series' value at that position, since tick marks alone only convey the rough shape.
|
|
15
16
|
*/
|
|
16
17
|
export declare function MultiLineChart({ series, height, formatValue, emptyText, style, accessibilityLabel }: MultiLineChartProps): import("react").JSX.Element;
|
|
17
18
|
//#endregion
|
|
@@ -8,17 +8,18 @@ import Svg, { Circle, Line, Path, Text as Text$1 } from "react-native-svg";
|
|
|
8
8
|
|
|
9
9
|
//#region src/native/analytics/multi-line-chart.tsx
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* Multi-series line chart. The web counterpart is `analytics/multi-line-chart` (`@tanstack/charts`)
|
|
12
|
+
* (the props are shared via `shared/analytics.ts`).
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* **The `@expo/ui` Chart can only draw a single series** (its type definitions also state that
|
|
15
|
+
* line/area are single-series), so use this component when two or more series share an axis.
|
|
16
|
+
* Splitting series with the same unit and axis (such as balance and equity) across two cards
|
|
17
|
+
* makes the relationship hard to read without comparing them vertically.
|
|
17
18
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
19
|
+
* Drawing uses react-native-svg. Unlike SwiftUI Charts it draws no outer frame, only the tick lines
|
|
20
|
+
* (a consumer wrapping it in a `Panel` would otherwise get a double border).
|
|
20
21
|
*
|
|
21
|
-
*
|
|
22
|
+
* Tapping reads out each series' value at that position, since tick marks alone only convey the rough shape.
|
|
22
23
|
*/
|
|
23
24
|
function MultiLineChart({ series, height = 220, formatValue = (value) => String(Math.round(value)), emptyText = "データがありません", style, accessibilityLabel }) {
|
|
24
25
|
const line = useTokenColor("--line");
|
|
@@ -173,9 +174,9 @@ function MultiLineChart({ series, height = 220, formatValue = (value) => String(
|
|
|
173
174
|
});
|
|
174
175
|
}
|
|
175
176
|
/**
|
|
176
|
-
*
|
|
177
|
-
* react-native-web
|
|
178
|
-
*
|
|
177
|
+
* The pressed position (x from the left edge of the pressed element). On a device this is `locationX`.
|
|
178
|
+
* react-native-web's `onPress` passes a DOM click (no `locationX`), so in that case it is computed from the difference to the element's left edge.
|
|
179
|
+
* Returns null for a click without a position (keyboard, etc.).
|
|
179
180
|
*/
|
|
180
181
|
function pressX(event) {
|
|
181
182
|
const { locationX } = event.nativeEvent;
|
|
@@ -185,12 +186,12 @@ function pressX(event) {
|
|
|
185
186
|
const target = event.currentTarget;
|
|
186
187
|
return dom.clientX - target.getBoundingClientRect().left;
|
|
187
188
|
}
|
|
188
|
-
/**
|
|
189
|
+
/** Turns a series into a single SVG path. */
|
|
189
190
|
function pathOf(entry, toX, toY) {
|
|
190
191
|
const count = entry.points.length;
|
|
191
192
|
return entry.points.map((point, index) => `${index === 0 ? "M" : "L"}${toX(index, count, point.t)},${toY(point.y)}`).join(" ");
|
|
192
193
|
}
|
|
193
|
-
/**
|
|
194
|
+
/** Returns the point nearest to the pressed x, together with its drawn position. */
|
|
194
195
|
function nearestPoint(entry, pickedX, toX) {
|
|
195
196
|
const count = entry.points.length;
|
|
196
197
|
let best;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { PieChartProps } from "./chart.types.js";
|
|
2
2
|
//#region src/native/analytics/pie-chart.d.ts
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* `@expo/ui
|
|
4
|
+
* Pie chart (react-native-svg). The default implementation for Android and web. The iOS SwiftUI Charts version (`pie-chart.ios.tsx`)
|
|
5
|
+
* needs `@expo/ui`, so iOS is drawn with this implementation too unless the app imports that file explicitly.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Android
|
|
7
|
+
* Drawing uses the same react-native-svg as `multi-line-chart`. It is **not** an "iOS only"
|
|
8
|
+
* placeholder because a screen's main content can be produced by this component alone,
|
|
9
|
+
* and on Android that content would be replaced entirely by a text message.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* **No legend here.** Consumers are expected to list the colored breakdown below the circle,
|
|
12
|
+
* so a legend here would show the same thing twice and eat into the circle's height.
|
|
13
13
|
*/
|
|
14
14
|
export declare function PieChart({ data, donut, height, style, accessibilityLabel }: PieChartProps): import("react").JSX.Element;
|
|
15
15
|
//#endregion
|
|
@@ -7,15 +7,15 @@ import Svg, { Circle, Path } from "react-native-svg";
|
|
|
7
7
|
|
|
8
8
|
//#region src/native/analytics/pie-chart.tsx
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
* `@expo/ui
|
|
10
|
+
* Pie chart (react-native-svg). The default implementation for Android and web. The iOS SwiftUI Charts version (`pie-chart.ios.tsx`)
|
|
11
|
+
* needs `@expo/ui`, so iOS is drawn with this implementation too unless the app imports that file explicitly.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* Android
|
|
13
|
+
* Drawing uses the same react-native-svg as `multi-line-chart`. It is **not** an "iOS only"
|
|
14
|
+
* placeholder because a screen's main content can be produced by this component alone,
|
|
15
|
+
* and on Android that content would be replaced entirely by a text message.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* **No legend here.** Consumers are expected to list the colored breakdown below the circle,
|
|
18
|
+
* so a legend here would show the same thing twice and eat into the circle's height.
|
|
19
19
|
*/
|
|
20
20
|
function PieChart({ data, donut, height = 220, style, accessibilityLabel }) {
|
|
21
21
|
const palette = useChartPalette();
|
|
@@ -57,7 +57,7 @@ function PieChart({ data, donut, height = 220, style, accessibilityLabel }) {
|
|
|
57
57
|
})
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
|
-
/**
|
|
60
|
+
/** Turns each slice into an SVG path. Slices run clockwise from 12 o'clock (the same direction as SwiftUI Charts). */
|
|
61
61
|
function slicePaths(data, total, radius, inner) {
|
|
62
62
|
let angle = -Math.PI / 2;
|
|
63
63
|
return data.map((slice) => {
|
|
@@ -4,16 +4,16 @@ export type SingleNumberProps = {
|
|
|
4
4
|
subTitle?: string;
|
|
5
5
|
value: number | null;
|
|
6
6
|
unit?: string;
|
|
7
|
-
/**
|
|
7
|
+
/** Value to compare against. When given, the difference and the percentage change are shown alongside. */
|
|
8
8
|
compareValue?: number;
|
|
9
9
|
compareTitle?: string;
|
|
10
|
-
/**
|
|
10
|
+
/** Flips the colors for metrics where an increase is bad (cost, etc.). */
|
|
11
11
|
reverseColor?: boolean;
|
|
12
12
|
className?: string;
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
15
|
-
* raised
|
|
16
|
-
*
|
|
15
|
+
* A metric showing a large number on a raised surface (surface corner radius, 1px hairline border).
|
|
16
|
+
* Mirrors the web analytics single-number. Increase/decrease uses the state colors (the surface does not invert, so the same theme values work).
|
|
17
17
|
*/
|
|
18
18
|
export declare function SingleNumber({ title, subTitle, value, unit, compareValue, compareTitle, reverseColor, className }: SingleNumberProps): import("react").JSX.Element;
|
|
19
19
|
//#endregion
|
|
@@ -8,8 +8,8 @@ import Feather from "@expo/vector-icons/Feather";
|
|
|
8
8
|
|
|
9
9
|
//#region src/native/analytics/single-number.tsx
|
|
10
10
|
/**
|
|
11
|
-
* raised
|
|
12
|
-
*
|
|
11
|
+
* A metric showing a large number on a raised surface (surface corner radius, 1px hairline border).
|
|
12
|
+
* Mirrors the web analytics single-number. Increase/decrease uses the state colors (the surface does not invert, so the same theme values work).
|
|
13
13
|
*/
|
|
14
14
|
function SingleNumber({ title, subTitle, value, unit, compareValue, compareTitle, reverseColor, className }) {
|
|
15
15
|
const up = useTokenColor("--state-success");
|
|
@@ -2,20 +2,20 @@ import { ReactElement } from "react";
|
|
|
2
2
|
//#region src/native/atom/avatar.d.ts
|
|
3
3
|
export type AvatarProps = {
|
|
4
4
|
src?: string;
|
|
5
|
-
/**
|
|
5
|
+
/** Alternative text for the image. Empty by default (decorative; assumes a name is shown next to it). For a standalone face with no name, pass the person's name (same as the web) */
|
|
6
6
|
alt?: string;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* What to show when there is no image or loading failed (initials, etc.). A string is wrapped in Text. **Omitted or empty shows a person icon**
|
|
9
|
+
* (the web shows nothing for an empty string). Numbers are not accepted (RN cannot render text directly under a View; pass a string).
|
|
10
10
|
*/
|
|
11
11
|
fallback?: string | ReactElement;
|
|
12
|
-
/**
|
|
12
|
+
/** Side length in px. Defaults to 24, the same as the web `size-6`. */
|
|
13
13
|
size?: number;
|
|
14
14
|
className?: string;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Same structure as the web atom/avatar (image + fallback).
|
|
18
|
+
* Drawn as a circle (`rounded-full`), like the web Avatar.
|
|
19
19
|
*/
|
|
20
20
|
export declare function Avatar({ src, alt, fallback, size, className }: AvatarProps): import("react").JSX.Element;
|
|
21
21
|
//#endregion
|
|
@@ -9,8 +9,8 @@ import { Image } from "expo-image";
|
|
|
9
9
|
|
|
10
10
|
//#region src/native/atom/avatar.tsx
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Same structure as the web atom/avatar (image + fallback).
|
|
13
|
+
* Drawn as a circle (`rounded-full`), like the web Avatar.
|
|
14
14
|
*/
|
|
15
15
|
function Avatar({ src, alt = "", fallback, size = 24, className }) {
|
|
16
16
|
const [failed, setFailed] = useState(false);
|
|
@@ -9,16 +9,16 @@ export type BadgeProps = {
|
|
|
9
9
|
children: ReactNode;
|
|
10
10
|
variant?: BadgeVariants;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Makes the badge tappable (filter chips, etc.). A native-only addition not present in the web Badge;
|
|
13
|
+
* it keeps the look unchanged and secures a tap area equivalent to 44pt via `hitSlop`.
|
|
14
14
|
*/
|
|
15
15
|
onPress?: () => void;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Name for screen readers and E2E. Always pass it when chips with the same text appear
|
|
18
|
+
* across different axes (to tell which axis a given "All" belongs to).
|
|
19
19
|
*/
|
|
20
20
|
accessibilityLabel?: string;
|
|
21
|
-
/**
|
|
21
|
+
/** Tells screen readers and E2E that this chip is selected. */
|
|
22
22
|
selected?: boolean;
|
|
23
23
|
className?: string;
|
|
24
24
|
textClassName?: string;
|
|
@@ -2,17 +2,17 @@ import { ReactNode } from "react";
|
|
|
2
2
|
import { VariantProps } from "class-variance-authority";
|
|
3
3
|
//#region src/native/atom/button.d.ts
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* A button with the same variants and look as the web base/button (indigo primary action, raised surface + faint border, control corner radius).
|
|
6
|
+
* Only the height differs: it is larger than the web's (default 36) because it is pressed with a finger.
|
|
7
7
|
*
|
|
8
|
-
* `base/button
|
|
9
|
-
*
|
|
8
|
+
* Where `base/button` (`@expo/ui`) renders an OS-native button (iOS 26 Liquid Glass, etc.),
|
|
9
|
+
* this one is an RN `Pressable`, so it can be painted with tokens. **Use this one wherever it should look the same as the web.**
|
|
10
10
|
*
|
|
11
|
-
* web
|
|
11
|
+
* The web's `hover:` does not exist in RN, so it is mapped to `pressed` while pressed.
|
|
12
12
|
*
|
|
13
|
-
* web
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* The web Button is `inline-flex`, so it shrinks to its content. An RN `Pressable` stretches across
|
|
14
|
+
* the parent's cross axis, so `self-start` gives it the same behavior. For a full-width CTA,
|
|
15
|
+
* pass `className="self-stretch"` from the consumer.
|
|
16
16
|
*/
|
|
17
17
|
declare const buttonVariants: (props?: ({
|
|
18
18
|
variant?: "<3" | "default" | "destructive" | "ghost" | "link" | "outline" | "plate" | "secondary" | null | undefined;
|
|
@@ -28,14 +28,14 @@ export type ButtonProps = ButtonVariants & {
|
|
|
28
28
|
onPress?: () => void;
|
|
29
29
|
disabled?: boolean;
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
* `@expo/vector-icons
|
|
31
|
+
* Elements placed to the left and right of the label. The web takes a lucide component type, but native
|
|
32
|
+
* icon renderers vary (`@expo/vector-icons`, `expo-symbols`, etc.), so it takes already-rendered elements.
|
|
33
33
|
*/
|
|
34
34
|
iconLeft?: ReactNode;
|
|
35
35
|
iconRight?: ReactNode;
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
37
|
+
* Name for screen readers and E2E. **Always pass it when buttons with the same text appear in a list
|
|
38
|
+
* (a per-row "Delete", etc.).** Without it VoiceOver cannot tell which row a button belongs to, and E2E cannot target them individually.
|
|
39
39
|
*/
|
|
40
40
|
accessibilityLabel?: string;
|
|
41
41
|
className?: string;
|
|
@@ -7,17 +7,17 @@ import { cva } from "class-variance-authority";
|
|
|
7
7
|
|
|
8
8
|
//#region src/native/atom/button.tsx
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* A button with the same variants and look as the web base/button (indigo primary action, raised surface + faint border, control corner radius).
|
|
11
|
+
* Only the height differs: it is larger than the web's (default 36) because it is pressed with a finger.
|
|
12
12
|
*
|
|
13
|
-
* `base/button
|
|
14
|
-
*
|
|
13
|
+
* Where `base/button` (`@expo/ui`) renders an OS-native button (iOS 26 Liquid Glass, etc.),
|
|
14
|
+
* this one is an RN `Pressable`, so it can be painted with tokens. **Use this one wherever it should look the same as the web.**
|
|
15
15
|
*
|
|
16
|
-
* web
|
|
16
|
+
* The web's `hover:` does not exist in RN, so it is mapped to `pressed` while pressed.
|
|
17
17
|
*
|
|
18
|
-
* web
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* The web Button is `inline-flex`, so it shrinks to its content. An RN `Pressable` stretches across
|
|
19
|
+
* the parent's cross axis, so `self-start` gives it the same behavior. For a full-width CTA,
|
|
20
|
+
* pass `className="self-stretch"` from the consumer.
|
|
21
21
|
*/
|
|
22
22
|
const buttonVariants = cva("flex-row items-center justify-center gap-2 self-start rounded-control border border-transparent", {
|
|
23
23
|
variants: {
|
|
@@ -4,9 +4,9 @@ import { ReactNode } from "react";
|
|
|
4
4
|
export type CheckboxProps = NamedControlA11yProps & {
|
|
5
5
|
checked: boolean;
|
|
6
6
|
onCheckedChange: (checked: boolean) => void;
|
|
7
|
-
/**
|
|
7
|
+
/** Label shown to the right of the checkbox. It is part of the tap area. */
|
|
8
8
|
label?: ReactNode;
|
|
9
|
-
/**
|
|
9
|
+
/** Name for screen readers. A string label is used as-is, so pass this when there is no label or it is not a string. */
|
|
10
10
|
accessibilityLabel?: string;
|
|
11
11
|
disabled?: boolean;
|
|
12
12
|
invalid?: boolean;
|
|
@@ -14,8 +14,8 @@ export type CheckboxProps = NamedControlA11yProps & {
|
|
|
14
14
|
wrapperClassName?: string;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* A 16px square with the control corner radius, identical to the web base/checkbox.
|
|
18
|
+
* Unchecked is a raised surface + a line-control border (3:1); checked is an indigo fill + a white check.
|
|
19
19
|
*/
|
|
20
20
|
export declare function Checkbox({ checked, onCheckedChange, label, accessibilityLabel, disabled, invalid, className, wrapperClassName, accessibilityHint, id, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }: CheckboxProps): import("react").JSX.Element;
|
|
21
21
|
//#endregion
|
|
@@ -8,8 +8,8 @@ import Feather from "@expo/vector-icons/Feather";
|
|
|
8
8
|
|
|
9
9
|
//#region src/native/atom/checkbox.tsx
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* A 16px square with the control corner radius, identical to the web base/checkbox.
|
|
12
|
+
* Unchecked is a raised surface + a line-control border (3:1); checked is an indigo fill + a white check.
|
|
13
13
|
*/
|
|
14
14
|
function Checkbox({ checked, onCheckedChange, label, accessibilityLabel, disabled, invalid, className, wrapperClassName, accessibilityHint, id, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }) {
|
|
15
15
|
const isInvalid = invalid ?? ariaInvalid;
|
|
@@ -3,10 +3,10 @@ import { ReactNode } from "react";
|
|
|
3
3
|
//#region src/native/atom/colored-value.d.ts
|
|
4
4
|
export type ColoredValueProps<TValue> = ColoredValueSharedProps<TValue>;
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* A number whose color changes with its sign. Same API as the web atom/colored-value (`shared/analytics.ts`).
|
|
7
|
+
* The default colors are the tokens `state-success` / `state-error` rather than Tailwind's fixed palette (green-500 / red-500),
|
|
8
|
+
* and they keep 4.5:1 contrast in dark mode too.
|
|
9
|
+
* Being a number, it is drawn monospaced (tabular).
|
|
10
10
|
*/
|
|
11
11
|
export declare function ColoredValue<TValue>({ value, format, isPositive, isNegative, positiveColor, negativeColor, className }: ColoredValueProps<TValue>): ReactNode;
|
|
12
12
|
//#endregion
|
|
@@ -5,10 +5,10 @@ import { jsx } from "react/jsx-runtime";
|
|
|
5
5
|
|
|
6
6
|
//#region src/native/atom/colored-value.tsx
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* A number whose color changes with its sign. Same API as the web atom/colored-value (`shared/analytics.ts`).
|
|
9
|
+
* The default colors are the tokens `state-success` / `state-error` rather than Tailwind's fixed palette (green-500 / red-500),
|
|
10
|
+
* and they keep 4.5:1 contrast in dark mode too.
|
|
11
|
+
* Being a number, it is drawn monospaced (tabular).
|
|
12
12
|
*/
|
|
13
13
|
function ColoredValue({ value, format, isPositive, isNegative, positiveColor = "text-state-success", negativeColor = "text-state-error", className }) {
|
|
14
14
|
const formatted = format ? format(value) : String(value);
|