@trading-game/design-intelligence-layer 1.0.1 → 1.0.2
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/AGENTS.md +7 -5
- package/README.md +5 -5
- package/dist/index.cjs +934 -367
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -14
- package/dist/index.d.ts +84 -14
- package/dist/index.js +948 -384
- package/dist/index.js.map +1 -1
- package/docs/components/bottom-navigation.md +1 -1
- package/docs/components/breadcrumb.md +1 -1
- package/docs/components/calendar.md +7 -7
- package/docs/components/card.md +2 -2
- package/docs/components/dialog.md +3 -3
- package/docs/components/empty.md +1 -1
- package/docs/components/input-otp.md +3 -3
- package/docs/components/item.md +1 -1
- package/docs/components/link.md +1 -1
- package/docs/components/navigation-button.md +2 -2
- package/docs/components/progress.md +42 -25
- package/docs/components/radio-group.md +1 -1
- package/docs/components/select.md +1 -1
- package/docs/components/sheet.md +2 -2
- package/docs/components/slide-to-confirm.md +68 -0
- package/docs/components/stepper.md +29 -37
- package/docs/components/steps.md +77 -0
- package/docs/components/switch.md +1 -1
- package/docs/components/tabs.md +1 -1
- package/docs/components/toggle.md +46 -13
- package/docs/foundations/colors.md +1 -1
- package/docs/foundations/shape-layout.md +1 -1
- package/docs/patterns/forms.md +1 -1
- package/package.json +3 -2
- package/src/styles.css +154 -9
- package/docs/components/toggle-group.md +0 -77
|
@@ -1,40 +1,70 @@
|
|
|
1
1
|
# Toggle
|
|
2
2
|
|
|
3
|
-
Two-state pressable button (Radix Toggle)
|
|
3
|
+
Two-state pressable button (Radix Toggle) wearing the Chip colour treatment on its rectangle: bordered primary surface at rest, solid brand with on-brand ink when on. Same shape as always — only the colours are chip. **Toggle Group** joins several of them into a segmented set and is documented here — one look, shared geometry, one page.
|
|
4
4
|
|
|
5
5
|
## When to use
|
|
6
6
|
|
|
7
7
|
- A single on/off tool control — bold in an editor, favourite a market, show/hide an overlay.
|
|
8
|
+
- A group for exclusive or multi-select among a few peer options that stay visible — chart interval (1m/5m/1h), order side, view density.
|
|
8
9
|
|
|
9
|
-
**When not:** For
|
|
10
|
+
**When not:** For switching content panels use [Tabs](./tabs.md). For settings that apply immediately use [Switch](./switch.md). For 5+ options use [Select](./select.md).
|
|
10
11
|
|
|
11
12
|
## Anatomy
|
|
12
13
|
|
|
13
|
-
- `Toggle` — Radix root styled by `toggleVariants` (cva, exported
|
|
14
|
+
- `Toggle` — Radix root styled by `toggleVariants` (cva, exported); `data-slot="toggle"`, `data-state="on|off"`.
|
|
15
|
+
- `ToggleGroup` — Radix root; publishes `size`/`spacing` through context and sets `--gap`; `data-slot="toggle-group"` with `data-size`, `data-spacing`.
|
|
16
|
+
- `ToggleGroupItem` — one segment, styled by the shared `toggleVariants`; `data-slot="toggle-group-item"`, `data-state="on|off"`.
|
|
14
17
|
|
|
15
18
|
## API
|
|
16
19
|
|
|
20
|
+
### Toggle
|
|
21
|
+
|
|
17
22
|
| Prop | Type | Default | Notes |
|
|
18
23
|
| --- | --- | --- | --- |
|
|
19
|
-
| `variant` | `"default" \| "outline"` | `"default"` | default is transparent at rest; outline adds `border-border-prominent-default`. |
|
|
20
24
|
| `size` | `"default" \| "sm" \| "lg"` | `"default"` | default `h-10 min-w-10 px-2.5` (40px), sm `h-8 min-w-8 px-1.5` (32px), lg `h-12 min-w-12 px-3` (48px) — on the 32/40/48 rail. |
|
|
21
25
|
| `pressed` / `defaultPressed` | `boolean` | — | Controlled / uncontrolled. |
|
|
22
26
|
| `onPressedChange` | `(pressed: boolean) => void` | — | Radix callback. |
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
### ToggleGroup
|
|
29
|
+
|
|
30
|
+
| Prop | Type | Default | Notes |
|
|
31
|
+
| --- | --- | --- | --- |
|
|
32
|
+
| `type` | `"single" \| "multiple"` | — | Radix prop; required. |
|
|
33
|
+
| `size` | as Toggle | — | Inherited by every item via context; context wins over per-item values. |
|
|
34
|
+
| `spacing` | `number` | `0` | Tailwind spacing units between items; `0` = joined segments. |
|
|
35
|
+
| `value` / `defaultValue`, `onValueChange` | Radix props | — | `string` for single, `string[]` for multiple. |
|
|
36
|
+
|
|
37
|
+
### ToggleGroupItem
|
|
38
|
+
|
|
39
|
+
| Prop | Type | Default | Notes |
|
|
40
|
+
| --- | --- | --- | --- |
|
|
41
|
+
| `value` | `string` | — | Required item identity. |
|
|
25
42
|
|
|
26
43
|
```tsx
|
|
27
|
-
import { Toggle } from "@trading-game/design-intelligence-layer"
|
|
44
|
+
import { Toggle, ToggleGroup, ToggleGroupItem } from "@trading-game/design-intelligence-layer"
|
|
28
45
|
import { Star } from "lucide-react"
|
|
29
46
|
|
|
30
47
|
<Toggle aria-label="Favourite"><Star /></Toggle>
|
|
31
|
-
<Toggle variant="outline" size="sm">1H</Toggle>
|
|
32
48
|
<Toggle size="lg" pressed={on} onPressedChange={setOn}>Overlay</Toggle>
|
|
49
|
+
|
|
50
|
+
// joined segments (default)
|
|
51
|
+
<ToggleGroup type="single" defaultValue="1h">
|
|
52
|
+
<ToggleGroupItem value="1m">1M</ToggleGroupItem>
|
|
53
|
+
<ToggleGroupItem value="5m">5M</ToggleGroupItem>
|
|
54
|
+
<ToggleGroupItem value="1h">1H</ToggleGroupItem>
|
|
55
|
+
</ToggleGroup>
|
|
56
|
+
|
|
57
|
+
// spaced multiple-select
|
|
58
|
+
<ToggleGroup type="multiple" spacing={2} size="sm">
|
|
59
|
+
<ToggleGroupItem value="ema">EMA</ToggleGroupItem>
|
|
60
|
+
<ToggleGroupItem value="vol">VOL</ToggleGroupItem>
|
|
61
|
+
</ToggleGroup>
|
|
33
62
|
```
|
|
34
63
|
|
|
35
64
|
## Tokens
|
|
36
65
|
|
|
37
|
-
**Colour (semantic):** `
|
|
66
|
+
**Colour (semantic):** the Chip treatment — `border-border-default-default` + `bg-background-primary-surface` + `text-text-prominent-default` (rest), `bg-background-secondary-surface` (hover), `bg-background-secondary-wash` (pressed), on-state `bg-background-brand-default` + `text-text-on-brand-static` with `border-transparent` (the brand flip in dark is the design), focus `border-ring-focus-default` + `ring-ring-focus-strong` at 3px, `border-border-error-default` + `ring-error-soft` ring (aria-invalid).
|
|
67
|
+
|
|
38
68
|
**Type (private):**
|
|
39
69
|
|
|
40
70
|
| Token | Value |
|
|
@@ -43,18 +73,21 @@ import { Star } from "lucide-react"
|
|
|
43
73
|
|
|
44
74
|
## Behaviour
|
|
45
75
|
|
|
46
|
-
- On-state = `bg-background-
|
|
76
|
+
- On-state = solid `bg-background-brand-default` fill + `text-text-on-brand-static` ink + transparent border — the Chip selected look.
|
|
47
77
|
- Radius is `rounded-md` (8px, the row radius); icons default to `size-4`.
|
|
78
|
+
- `spacing={0}` (default) joins segments: items lose their own radius (`rounded-none`), the first/last regain `rounded-l-md`/`rounded-r-md`, and segments share hairlines by dropping `border-l` on all but the first; any positive `spacing` separates them and each keeps `rounded-md`.
|
|
79
|
+
- Items are `w-auto min-w-0 shrink-0 px-3` and raise `z-10` on focus so the ring is never clipped by neighbours.
|
|
48
80
|
- Disabled: `pointer-events-none opacity-24`.
|
|
49
81
|
|
|
50
82
|
## Do / Don't
|
|
51
83
|
|
|
52
84
|
**Do**
|
|
53
85
|
- Give icon-only toggles an `aria-label`.
|
|
54
|
-
-
|
|
86
|
+
- Keep the group's default `spacing={0}` for segmented-control semantics; use spacing only when items act as independent toggles.
|
|
87
|
+
- Use `type="single"` with a `defaultValue` for interval/side pickers so one option is always on.
|
|
55
88
|
- Let the exported `toggleVariants` style any custom toggle-like control instead of re-deriving classes.
|
|
56
89
|
|
|
57
90
|
**Don't**
|
|
58
|
-
- Don't
|
|
59
|
-
- Don't
|
|
60
|
-
- Don't use a Toggle where the action navigates or submits — that is a Button.
|
|
91
|
+
- Don't invent variants — one look, three states (rest / hover / on); the former `outline` variant is removed.
|
|
92
|
+
- Don't mix sizes inside one group; the shared border geometry assumes uniform height.
|
|
93
|
+
- Don't use a Toggle where the action navigates or submits — that is a Button; a joined group used for navigation is [Tabs](./tabs.md).
|
|
@@ -16,7 +16,7 @@ Token grammar (Quill style): `{element}-{role}-{variant}` — e.g. `background-b
|
|
|
16
16
|
2. **Surfaces are always solid.** Alpha values are for *state layers on top of* a solid base (hover glazes, pressed glazes, glass, scrims, washes) — never for a resting surface. Dark surfaces are built as `color-mix()` of white over the canvas, producing a solid colour.
|
|
17
17
|
3. **Dark is not a mirror.** When a light construction fails on near-black (a 10% wash disappears, mid-blue ink loses contrast), the dark value diverges — that's what the `.dark` block is for. Never hardcode a light construction and assume it flips.
|
|
18
18
|
4. **Selection states use the `*-brand-selected` family** — never `brand-default/10` washes or `text-brand-default` ink for a selected/active element.
|
|
19
|
-
5. **No shadows anywhere
|
|
19
|
+
5. **No shadows anywhere,** bar two named exceptions (`shadow-chrome-default` on floating mobile chrome, `shadow-brand-glow` on the Slide to Confirm handle). Elevation is hairline borders and surface steps.
|
|
20
20
|
|
|
21
21
|
## Primitive scales
|
|
22
22
|
|
|
@@ -53,4 +53,4 @@ Tokens: `--semantic-layout-grid-columns`, `--semantic-layout-gutter`, `--semanti
|
|
|
53
53
|
|
|
54
54
|
## Elevation
|
|
55
55
|
|
|
56
|
-
Inline components carry none — **no shadows** — every component's `shadow-*` has been removed.
|
|
56
|
+
Inline components carry none — **no shadows** — every component's `shadow-*` has been removed. There are exactly two sanctioned exceptions, both per the Refined Mobile file. **Floating mobile chrome** (Bottom Navigation): a soft ambient lift (`shadow-chrome-default`, `0 12px 30px`) separates chrome from the content scrolling beneath it. **The Slide to Confirm handle**: a brand glow (`shadow-brand-glow`, `0 6px 16px` of `background-brand-default` at 35%, so it re-derives per theme) so a committed money action reads as liftable off its track. Neither token may be reused elsewhere. Elevation reads through the hairline (`border-default-default`) and surface steps (canvas → primary surface → secondary surface). On dark this is why surfaces are solid white-mixes: the step between `#00001F`, `#0F0F2C`, `#1F1F3A` is the elevation.
|
package/docs/patterns/forms.md
CHANGED
|
@@ -58,7 +58,7 @@ All text-entry controls share one construction: **hairline border (`border-defau
|
|
|
58
58
|
| [Native Select](../components/native-select.md) | OS-native option list, same rail |
|
|
59
59
|
| [Select](../components/select.md) | custom popup (opens below the trigger) |
|
|
60
60
|
| [Input OTP](../components/input-otp.md) | segmented code entry |
|
|
61
|
-
| [Stepper](../components/stepper.md) |
|
|
61
|
+
| [Stepper](../components/stepper.md) | the amount tray — frosted −/+ circles, centred editable amount |
|
|
62
62
|
| [Numpad](../components/numpad.md) | mobile amount entry — pairs with a display figure, not an input |
|
|
63
63
|
|
|
64
64
|
## Choice cards
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trading-game/design-intelligence-layer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Trading Game Design System — shadcn/ui components with Tailwind CSS v4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"start": "next start",
|
|
31
31
|
"lint": "eslint",
|
|
32
32
|
"prepublishOnly": "npm run build",
|
|
33
|
-
"check:tokens": "node scripts/check-token-docs.mjs"
|
|
33
|
+
"check:tokens": "node scripts/check-token-docs.mjs",
|
|
34
|
+
"predev": "rm -rf .next"
|
|
34
35
|
},
|
|
35
36
|
"files": [
|
|
36
37
|
"dist/",
|
package/src/styles.css
CHANGED
|
@@ -173,6 +173,9 @@
|
|
|
173
173
|
/* ── Named animations ── */
|
|
174
174
|
--animate-button-shimmer: button-shimmer 4s linear infinite;
|
|
175
175
|
--animate-skeleton-sweep: skeleton-sweep 1.6s var(--primitive-ease-standard) infinite;
|
|
176
|
+
/* Slide-to-confirm idle nudge — the handle drifts 10px and back, hinting
|
|
177
|
+
the gesture without moving far enough to read as progress. */
|
|
178
|
+
--animate-slide-confirm-nudge: slide-confirm-nudge 1.8s var(--primitive-ease-standard) infinite;
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
/* ══════════════════════════════════════════════════════════════
|
|
@@ -601,6 +604,10 @@
|
|
|
601
604
|
--background-chrome-default: rgb(255 255 255 / 78%);
|
|
602
605
|
--border-chrome-default: rgb(10 10 60 / 8%);
|
|
603
606
|
--shadow-chrome-default: 0 12px 30px rgb(10 10 60 / 14%);
|
|
607
|
+
/* Brand-action glow — the second (and only other) sanctioned shadow
|
|
608
|
+
besides floating chrome. Reserved for a committed primary action that
|
|
609
|
+
must read as lifted off its track: the Slide to Confirm handle. */
|
|
610
|
+
--shadow-brand-glow: 0 6px 16px color-mix(in srgb, var(--background-brand-default) 35%, transparent);
|
|
604
611
|
--text-chrome-subtle: var(--text-subtle-default);
|
|
605
612
|
--background-chrome-selected:
|
|
606
613
|
linear-gradient(rgb(255 255 255 / 55%), rgb(255 255 255 / 15%)),
|
|
@@ -777,7 +784,7 @@
|
|
|
777
784
|
/* Border */
|
|
778
785
|
--border-default-default: var(--primitive-white-alpha-12);
|
|
779
786
|
--border-prominent-default: var(--primitive-mono-50);
|
|
780
|
-
--border-neutral-default: var(--primitive-white-alpha-
|
|
787
|
+
--border-neutral-default: var(--primitive-white-alpha-24);
|
|
781
788
|
|
|
782
789
|
/* Text */
|
|
783
790
|
--text-prominent-default: var(--primitive-mono-50);
|
|
@@ -803,10 +810,10 @@
|
|
|
803
810
|
--shadow-chrome-default: 0 12px 30px rgb(0 0 20 / 50%);
|
|
804
811
|
--text-chrome-subtle: var(--text-subtle-default);
|
|
805
812
|
--background-chrome-selected:
|
|
806
|
-
linear-gradient(rgb(255 255 255 /
|
|
807
|
-
var(--
|
|
808
|
-
--chrome-highlight-default: var(--primitive-white-alpha-
|
|
809
|
-
--text-chrome-selected: var(--primitive-
|
|
813
|
+
linear-gradient(rgb(255 255 255 / 14%), rgb(255 255 255 / 0%)),
|
|
814
|
+
color-mix(in srgb, var(--primitive-blue-400) 45%, var(--primitive-blue-1000));
|
|
815
|
+
--chrome-highlight-default: var(--primitive-white-alpha-32);
|
|
816
|
+
--text-chrome-selected: var(--primitive-blue-100);
|
|
810
817
|
|
|
811
818
|
/* @deprecated aliases that don't resolve through a flipping token */
|
|
812
819
|
--primary-inverse: var(--primitive-mono-50);
|
|
@@ -1007,10 +1014,11 @@
|
|
|
1007
1014
|
--input-line-height-lg: var(--primitive-line-height-24);
|
|
1008
1015
|
--input-font-weight: var(--primitive-font-weight-regular);
|
|
1009
1016
|
/* ── Input OTP — component type tokens (private) ──
|
|
1010
|
-
Digits ride the input md step
|
|
1011
|
-
|
|
1012
|
-
--input-otp-font-
|
|
1013
|
-
--input-otp-
|
|
1017
|
+
Digits ride 20/semibold/28 — larger than the input md step so a
|
|
1018
|
+
6-digit code reads at a glance. */
|
|
1019
|
+
--input-otp-font-size: var(--primitive-font-size-20);
|
|
1020
|
+
--input-otp-font-weight: var(--primitive-font-weight-semibold);
|
|
1021
|
+
--input-otp-line-height: var(--primitive-line-height-28);
|
|
1014
1022
|
/* ── Native Select — component type tokens (private) ──
|
|
1015
1023
|
Same ladder as Input (12/14/16, regular). */
|
|
1016
1024
|
--native-select-font-size-sm: var(--primitive-font-size-12);
|
|
@@ -1054,6 +1062,43 @@
|
|
|
1054
1062
|
--bottom-navigation-label-font-weight: var(--primitive-font-weight-medium);
|
|
1055
1063
|
--bottom-navigation-label-line-height: var(--primitive-line-height-16);
|
|
1056
1064
|
--bottom-navigation-label-active-font-weight: var(--primitive-font-weight-semibold);
|
|
1065
|
+
|
|
1066
|
+
/* ── Stepper (stake variant) — component type tokens (private) ── */
|
|
1067
|
+
--stepper-stake-label-font-size: var(--primitive-font-size-12);
|
|
1068
|
+
--stepper-stake-label-font-weight: var(--primitive-font-weight-medium);
|
|
1069
|
+
--stepper-stake-label-line-height: var(--primitive-line-height-16);
|
|
1070
|
+
--stepper-stake-amount-font-size: var(--primitive-font-size-24);
|
|
1071
|
+
--stepper-stake-amount-font-weight: var(--primitive-font-weight-semibold);
|
|
1072
|
+
--stepper-stake-amount-line-height: var(--primitive-line-height-32);
|
|
1073
|
+
|
|
1074
|
+
/* ── Progress — component type tokens (private) ── */
|
|
1075
|
+
--progress-label-font-size: var(--primitive-font-size-12);
|
|
1076
|
+
--progress-label-font-weight: var(--primitive-font-weight-semibold);
|
|
1077
|
+
--progress-label-line-height: var(--primitive-line-height-16);
|
|
1078
|
+
--progress-value-font-size: var(--primitive-font-size-14);
|
|
1079
|
+
--progress-value-font-weight: var(--primitive-font-weight-semibold);
|
|
1080
|
+
--progress-value-line-height: var(--primitive-line-height-20);
|
|
1081
|
+
|
|
1082
|
+
/* ── Slide to Confirm — component type tokens (private) ── */
|
|
1083
|
+
--slide-to-confirm-label-font-size: var(--primitive-font-size-14);
|
|
1084
|
+
--slide-to-confirm-label-font-weight: var(--primitive-font-weight-medium);
|
|
1085
|
+
--slide-to-confirm-label-line-height: var(--primitive-line-height-20);
|
|
1086
|
+
--slide-to-confirm-label-confirmed-font-weight: var(--primitive-font-weight-semibold);
|
|
1087
|
+
|
|
1088
|
+
/* ── Steps — component type tokens (private) ── */
|
|
1089
|
+
--steps-indicator-font-size: var(--primitive-font-size-14);
|
|
1090
|
+
--steps-indicator-font-weight: var(--primitive-font-weight-semibold);
|
|
1091
|
+
--steps-indicator-line-height: var(--primitive-line-height-20);
|
|
1092
|
+
--steps-title-font-size: var(--primitive-font-size-14);
|
|
1093
|
+
--steps-title-font-weight: var(--primitive-font-weight-semibold);
|
|
1094
|
+
--steps-title-line-height: var(--primitive-line-height-20);
|
|
1095
|
+
--steps-description-font-size: var(--primitive-font-size-14);
|
|
1096
|
+
--steps-description-font-weight: var(--primitive-font-weight-regular);
|
|
1097
|
+
--steps-description-line-height: var(--primitive-line-height-20);
|
|
1098
|
+
--steps-tag-font-size: var(--primitive-font-size-10);
|
|
1099
|
+
--steps-tag-font-weight: var(--primitive-font-weight-semibold);
|
|
1100
|
+
--steps-tag-line-height: var(--primitive-line-height-16);
|
|
1101
|
+
|
|
1057
1102
|
/* ── Sidebar — component type tokens (private) ──
|
|
1058
1103
|
Menu rows 14/regular/20 (sm 12/16); labels + badges 12/medium/16.
|
|
1059
1104
|
Active rows go semibold via the data-active rule below. */
|
|
@@ -1196,6 +1241,18 @@
|
|
|
1196
1241
|
}
|
|
1197
1242
|
|
|
1198
1243
|
/* Skeleton — directional loading sweep (replaces the generic pulse) */
|
|
1244
|
+
/* Slide to Confirm — the confirmed check pops on the overshoot spring */
|
|
1245
|
+
@keyframes slide-confirm-pop {
|
|
1246
|
+
from { transform: scale(0); }
|
|
1247
|
+
to { transform: scale(1); }
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
/* Slide to Confirm — idle nudge on the handle, per the Refined spec */
|
|
1251
|
+
@keyframes slide-confirm-nudge {
|
|
1252
|
+
0%, 100% { transform: translateX(0); }
|
|
1253
|
+
50% { transform: translateX(10px); }
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1199
1256
|
@keyframes skeleton-sweep {
|
|
1200
1257
|
from { transform: translateX(-100%); }
|
|
1201
1258
|
to { transform: translateX(100%); }
|
|
@@ -1691,6 +1748,94 @@
|
|
|
1691
1748
|
font-weight: var(--bottom-navigation-label-font-weight);
|
|
1692
1749
|
}
|
|
1693
1750
|
|
|
1751
|
+
.type-stepper-stake-label {
|
|
1752
|
+
font-family: var(--font-plus-jakarta-sans);
|
|
1753
|
+
font-size: var(--stepper-stake-label-font-size);
|
|
1754
|
+
line-height: var(--stepper-stake-label-line-height);
|
|
1755
|
+
font-weight: var(--stepper-stake-label-font-weight);
|
|
1756
|
+
letter-spacing: 0.08em;
|
|
1757
|
+
text-transform: uppercase;
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
.type-stepper-stake-amount {
|
|
1761
|
+
font-family: var(--font-plus-jakarta-sans);
|
|
1762
|
+
font-size: var(--stepper-stake-amount-font-size);
|
|
1763
|
+
line-height: var(--stepper-stake-amount-line-height);
|
|
1764
|
+
font-weight: var(--stepper-stake-amount-font-weight);
|
|
1765
|
+
font-variant-numeric: tabular-nums;
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
.type-progress-label {
|
|
1769
|
+
font-family: var(--font-plus-jakarta-sans);
|
|
1770
|
+
font-size: var(--progress-label-font-size);
|
|
1771
|
+
line-height: var(--progress-label-line-height);
|
|
1772
|
+
font-weight: var(--progress-label-font-weight);
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
.type-progress-value {
|
|
1776
|
+
font-family: var(--font-plus-jakarta-sans);
|
|
1777
|
+
font-size: var(--progress-value-font-size);
|
|
1778
|
+
line-height: var(--progress-value-line-height);
|
|
1779
|
+
font-weight: var(--progress-value-font-weight);
|
|
1780
|
+
font-variant-numeric: tabular-nums;
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
.type-slide-to-confirm {
|
|
1784
|
+
font-family: var(--font-plus-jakarta-sans);
|
|
1785
|
+
font-size: var(--slide-to-confirm-label-font-size);
|
|
1786
|
+
line-height: var(--slide-to-confirm-label-line-height);
|
|
1787
|
+
font-weight: var(--slide-to-confirm-label-font-weight);
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
/* Confirmed label steps up to semibold via a data-attribute rule —
|
|
1791
|
+
.type-* classes can't be variant-gated. */
|
|
1792
|
+
[data-slot="slide-to-confirm"][data-confirmed] .type-slide-to-confirm {
|
|
1793
|
+
font-weight: var(--slide-to-confirm-label-confirmed-font-weight);
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
.type-steps-indicator {
|
|
1797
|
+
font-family: var(--font-plus-jakarta-sans);
|
|
1798
|
+
font-size: var(--steps-indicator-font-size);
|
|
1799
|
+
line-height: var(--steps-indicator-line-height);
|
|
1800
|
+
font-weight: var(--steps-indicator-font-weight);
|
|
1801
|
+
font-variant-numeric: tabular-nums;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
.type-steps-title {
|
|
1805
|
+
font-family: var(--font-plus-jakarta-sans);
|
|
1806
|
+
font-size: var(--steps-title-font-size);
|
|
1807
|
+
line-height: var(--steps-title-line-height);
|
|
1808
|
+
font-weight: var(--steps-title-font-weight);
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
.type-steps-description {
|
|
1812
|
+
font-family: var(--font-plus-jakarta-sans);
|
|
1813
|
+
font-size: var(--steps-description-font-size);
|
|
1814
|
+
line-height: var(--steps-description-line-height);
|
|
1815
|
+
font-weight: var(--steps-description-font-weight);
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
.type-steps-tag {
|
|
1819
|
+
font-family: var(--font-plus-jakarta-sans);
|
|
1820
|
+
font-size: var(--steps-tag-font-size);
|
|
1821
|
+
line-height: var(--steps-tag-line-height);
|
|
1822
|
+
font-weight: var(--steps-tag-font-weight);
|
|
1823
|
+
letter-spacing: 0.08em;
|
|
1824
|
+
text-transform: uppercase;
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
/* Steps sm — re-point the private type tokens at the 12/16 primitives */
|
|
1828
|
+
[data-slot="steps"][data-size="sm"] {
|
|
1829
|
+
--steps-indicator-font-size: var(--primitive-font-size-12);
|
|
1830
|
+
--steps-indicator-line-height: var(--primitive-line-height-16);
|
|
1831
|
+
--steps-title-font-size: var(--primitive-font-size-12);
|
|
1832
|
+
--steps-title-line-height: var(--primitive-line-height-16);
|
|
1833
|
+
--steps-description-font-size: var(--primitive-font-size-12);
|
|
1834
|
+
--steps-description-line-height: var(--primitive-line-height-16);
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
|
|
1838
|
+
|
|
1694
1839
|
/* Bottom Navigation — the arriving icon pops on an overshoot spring; the
|
|
1695
1840
|
label never moves. */
|
|
1696
1841
|
[data-slot="bottom-navigation-item"] svg {
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
# Toggle Group
|
|
2
|
-
|
|
3
|
-
A set of related toggles (Radix ToggleGroup) sharing size/variant, rendered joined by default.
|
|
4
|
-
|
|
5
|
-
## When to use
|
|
6
|
-
|
|
7
|
-
- Exclusive or multi-select among a few peer options that stay visible — chart interval (1m/5m/1h), order side, view density.
|
|
8
|
-
|
|
9
|
-
**When not:** For switching content panels use [Tabs](./tabs.md). For a single independent control use [Toggle](./toggle.md). For 5+ options use [Select](./select.md).
|
|
10
|
-
|
|
11
|
-
## Anatomy
|
|
12
|
-
|
|
13
|
-
- `ToggleGroup` — Radix root; publishes `variant`/`size`/`spacing` through context and sets `--gap`; `data-slot="toggle-group"` with `data-variant`, `data-size`, `data-spacing`.
|
|
14
|
-
- `ToggleGroupItem` — one segment, styled by the shared `toggleVariants` from Toggle; `data-slot="toggle-group-item"`, `data-state="on|off"`.
|
|
15
|
-
|
|
16
|
-
## API
|
|
17
|
-
|
|
18
|
-
### ToggleGroup
|
|
19
|
-
|
|
20
|
-
| Prop | Type | Default | Notes |
|
|
21
|
-
| --- | --- | --- | --- |
|
|
22
|
-
| `type` | `"single" \| "multiple"` | — | Radix prop; required. |
|
|
23
|
-
| `variant` | `"default" \| "outline"` | — | Inherited by every item via context. |
|
|
24
|
-
| `size` | `"default" \| "sm" \| "lg"` | — | Same rail as Toggle (36/32/40px). |
|
|
25
|
-
| `spacing` | `number` | `0` | Tailwind spacing units between items; `0` = joined segments. |
|
|
26
|
-
| `value` / `defaultValue`, `onValueChange` | Radix props | — | `string` for single, `string[]` for multiple. |
|
|
27
|
-
|
|
28
|
-
### ToggleGroupItem
|
|
29
|
-
|
|
30
|
-
| Prop | Type | Default | Notes |
|
|
31
|
-
| --- | --- | --- | --- |
|
|
32
|
-
| `value` | `string` | — | Required item identity. |
|
|
33
|
-
| `variant` / `size` | as Toggle | — | Context wins: group-level values override per-item ones. |
|
|
34
|
-
|
|
35
|
-
## Variants & sizes
|
|
36
|
-
|
|
37
|
-
```tsx
|
|
38
|
-
import { ToggleGroup, ToggleGroupItem } from "@trading-game/design-intelligence-layer"
|
|
39
|
-
|
|
40
|
-
// joined segments (default)
|
|
41
|
-
<ToggleGroup type="single" variant="outline" defaultValue="1h">
|
|
42
|
-
<ToggleGroupItem value="1m">1M</ToggleGroupItem>
|
|
43
|
-
<ToggleGroupItem value="5m">5M</ToggleGroupItem>
|
|
44
|
-
<ToggleGroupItem value="1h">1H</ToggleGroupItem>
|
|
45
|
-
</ToggleGroup>
|
|
46
|
-
|
|
47
|
-
// spaced multiple-select
|
|
48
|
-
<ToggleGroup type="multiple" spacing={2} size="sm">
|
|
49
|
-
<ToggleGroupItem value="ema">EMA</ToggleGroupItem>
|
|
50
|
-
<ToggleGroupItem value="vol">VOL</ToggleGroupItem>
|
|
51
|
-
</ToggleGroup>
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Tokens
|
|
55
|
-
|
|
56
|
-
**Colour (semantic):** everything from Toggle (`bg-background-hover-default` on-fill/hover, `text-text-brand-selected` on-ink, `border-border-prominent-default` outline), plus `border-border-brand-selected` on an on-segment's border in joined outline groups.
|
|
57
|
-
**Type (private):** shared `--toggle-*` family — 14 / medium (500) / 20.
|
|
58
|
-
|
|
59
|
-
## Behaviour
|
|
60
|
-
|
|
61
|
-
- `spacing={0}` (default) joins segments: items lose their own radius (`rounded-none`), the first/last regain `rounded-l-md`/`rounded-r-md`, and outline items share borders by dropping `border-l` on all but the first.
|
|
62
|
-
- In a joined outline group, an on segment restores its left border and colours its full border `border-border-brand-selected`, so the selected segment reads as outlined in brand.
|
|
63
|
-
- Group-level `variant`/`size` override per-item props through context (`context.variant || variant`).
|
|
64
|
-
- Items are `w-auto min-w-0 shrink-0 px-3` and raise `z-10` on focus so the ring is never clipped by neighbours.
|
|
65
|
-
- Any positive `spacing` separates the items and each keeps its own `rounded-md` shape.
|
|
66
|
-
|
|
67
|
-
## Do / Don't
|
|
68
|
-
|
|
69
|
-
**Do**
|
|
70
|
-
- Keep the default `spacing={0}` for segmented-control semantics; use spacing only when items act as independent toggles.
|
|
71
|
-
- Set `variant`/`size` on the group once; per-item overrides are ignored when the group sets them.
|
|
72
|
-
- Use `type="single"` with a `defaultValue` for interval/side pickers so one option is always on.
|
|
73
|
-
|
|
74
|
-
**Don't**
|
|
75
|
-
- Don't give on-segments a solid brand fill — selection is glaze + `text-brand-selected` ink, with `border-brand-selected` in joined outline groups.
|
|
76
|
-
- Don't mix sizes inside one group; the shared border geometry assumes uniform height.
|
|
77
|
-
- Don't use a joined group for navigation — that is [Tabs](./tabs.md).
|