@deriv-ds/design-intelligence-layer 0.5.1 → 0.5.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.
@@ -517,6 +517,7 @@ import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, Dialog
517
517
  | DirectionProvider | [simple] | — |
518
518
  | Drawer | [complex] | DrawerTrigger, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription, DrawerClose |
519
519
  | DropdownMenu | [composed] | DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuShortcut |
520
+ | EmailOrPhoneInput | [simple] | — (login field that auto-morphs from email Input to PhoneInput when the user types 2+ leading digits) |
520
521
  | Empty | [composed] | EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent |
521
522
  | Field | [complex] | FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSet, FieldContent, FieldTitle, FieldSeparator |
522
523
  | Form | [complex] | FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage |
@@ -532,6 +533,7 @@ import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, Dialog
532
533
  | NavigationMenu | [complex] | NavigationMenuList, NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, navigationMenuTriggerStyle |
533
534
  | NativeSelect | [simple] | NativeSelectOption, NativeSelectOptGroup |
534
535
  | Pagination | [composed] | PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis |
536
+ | PhoneInput | [simple] | — (country dial-code dropdown + numeric phone field; also exports `COUNTRIES`, `DEFAULT_COUNTRY`, `Country`) |
535
537
  | Popover | [composed] | PopoverTrigger, PopoverContent, PopoverHeader, PopoverTitle, PopoverDescription |
536
538
  | Progress | [simple] | — |
537
539
  | RadioGroup | [composed] | RadioGroupItem |
@@ -564,6 +566,8 @@ These are styling behaviors you can't discover from TypeScript types alone:
564
566
  | Button | `font-display font-bold`, sentence case (no `uppercase`). Primary: `text-on-prominent-static-inverse`. Tertiary hover: `bg-primary/[0.08]` |
565
567
  | Card | Flat by default (no shadow). Add elevation manually: `className="shadow-sm"` |
566
568
  | Input | Resting: `border-input`. Focus: `border-ring` + `ring-[3px] ring-ring/50`. Radius: `rounded-sm` (6px) |
569
+ | PhoneInput | Numeric-only field (non-digits blocked on keydown). Flags load from `@deriv/quill-icons/Flags` via the country's `flagKey`. Pass `floatingLabel` for the inset-label layout (mirrors Input). `onDialCodeChange(dialCode, country)` returns the full `Country`. |
570
+ | EmailOrPhoneInput | Single login field — renders `Input` (email) until 2+ leading digits are typed, then swaps to `PhoneInput`, carrying the digits across; clearing them reverts. `onValueChange(value, mode, dialCode?)` reports `"email"`/`"phone"`. `showLastUsed` clips a "Last used" Tag above the top-right corner. |
567
571
  | Tooltip | Bubble: `bg-primary` + `text-on-prominent-static-inverse` (not `bg-popover`). Always wrap in `<TooltipProvider>` |
568
572
  | Sidebar | Menu buttons use `rounded-sm`. Selection: `bg-secondary-hover` + `text-primary` + `font-semibold` |
569
573
  | Breadcrumb | Active page: `text-primary font-medium`. Links: `text-on-subtle` |
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "@deriv-ds/design-intelligence-layer",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "Deriv Design System — shadcn/ui components with Tailwind CSS v4",
5
- "license": "UNLICENSED",
6
5
  "type": "module",
7
6
  "main": "./dist/index.cjs",
8
7
  "module": "./dist/index.js",
@@ -31,6 +30,8 @@
31
30
  "build:next": "next build",
32
31
  "start": "next start",
33
32
  "lint": "eslint",
33
+ "test": "vitest run",
34
+ "test:watch": "vitest",
34
35
  "prepublishOnly": "npm run build"
35
36
  },
36
37
  "files": [
@@ -43,7 +44,8 @@
43
44
  "public/assets/icon-more.png",
44
45
  "public/assets/logo-deriv-x.png",
45
46
  "AGENTS.md",
46
- "README.md"
47
+ "README.md",
48
+ "CHANGELOG.md"
47
49
  ],
48
50
  "peerDependencies": {
49
51
  "react": ">=18",
@@ -74,11 +76,15 @@
74
76
  },
75
77
  "devDependencies": {
76
78
  "@tailwindcss/postcss": "^4",
79
+ "@testing-library/jest-dom": "^6.9.1",
80
+ "@testing-library/react": "^16.3.2",
81
+ "@testing-library/user-event": "^14.6.1",
77
82
  "@types/node": "^20",
78
83
  "@types/react": "^19",
79
84
  "@types/react-dom": "^19",
80
85
  "eslint": "^9",
81
86
  "eslint-config-next": "16.2.6",
87
+ "jsdom": "^25.0.1",
82
88
  "next": "16.2.6",
83
89
  "react": "19.2.3",
84
90
  "react-dom": "19.2.3",
@@ -86,7 +92,8 @@
86
92
  "tailwindcss": "^4",
87
93
  "tsup": "^8.5.1",
88
94
  "tw-animate-css": "^1.4.0",
89
- "typescript": "^5"
95
+ "typescript": "^5",
96
+ "vitest": "^3.2.6"
90
97
  },
91
98
  "overrides": {
92
99
  "lodash": "^4.18.0",
package/src/styles.css CHANGED
@@ -42,6 +42,17 @@
42
42
  --color-prominent: var(--text-prominent-default);
43
43
  --color-subtle: var(--text-subtle-default);
44
44
  --color-on-prominent-static-inverse: var(--on-prominent-static-inverse);
45
+ /* ── Paired on-surface foreground tokens ──
46
+ * For every surface there is a matching legible foreground, so a pairing such as
47
+ * `bg-prominent text-on-prominent` is always self-consistent (and theme-aware).
48
+ * These alias the foreground value already correct for each surface — additive only,
49
+ * no existing component is rewired, so rendering is unchanged. */
50
+ --color-on-primary-surface: var(--text-prominent-default);
51
+ --color-on-primary-canvas: var(--text-prominent-default);
52
+ --color-on-secondary-surface: var(--text-prominent-default);
53
+ --color-on-secondary-canvas: var(--text-prominent-default);
54
+ --color-on-prominent: var(--on-prominent-static-inverse);
55
+ --color-on-subtle: var(--text-subtle-default);
45
56
  --font-sans: var(--font-inter);
46
57
  --font-body: var(--font-inter);
47
58
  --font-display: var(--font-inter);
@@ -150,6 +161,13 @@
150
161
  --color-button-ghost-text: var(--button-ghost-normal-text);
151
162
  --color-button-ghost-bg-hover: var(--button-ghost-normal-bg-hover);
152
163
  --color-button-ghost-bg-pressed: var(--button-ghost-normal-bg-pressed);
164
+ /* Social button — neutral overlays (Figma: border 8%, primary fill 4%); flip in dark mode */
165
+ --button-social-border: var(--primitive-black-alpha-100);
166
+ --button-social-primary-bg: oklch(0 0 0 / 4%);
167
+ --button-social-primary-bg-hover: var(--primitive-black-alpha-100);
168
+ --button-social-primary-bg-pressed: var(--primitive-black-alpha-200);
169
+ --button-social-secondary-bg-hover: var(--primitive-black-alpha-100);
170
+ --button-social-secondary-bg-pressed: var(--primitive-black-alpha-200);
153
171
  /* ── Badge component colour bridges ── */
154
172
  --color-badge-bg-number: var(--badge-bg-number);
155
173
  --color-badge-text: var(--badge-text-default);
@@ -1817,6 +1835,9 @@
1817
1835
  --feedback-success-bg: var(--primitive-slate-1200);
1818
1836
  --feedback-success-tag-border: var(--primitive-slate-200);
1819
1837
 
1838
+ /* Referral block */
1839
+ --referral-text-body: var(--primitive-slate-alpha-900); /* #181C25 @ 72% — step body text */
1840
+
1820
1841
  /* Notification */
1821
1842
  --notification-title-banner: var(--primitive-slate-50);
1822
1843
  --notification-title-item: var(--primitive-slate-1200);
@@ -2010,36 +2031,63 @@
2010
2031
  ══════════════════════════════════════════════════════════════ */
2011
2032
  :root {
2012
2033
  /* ── Button ── */
2013
- --button-sm-height: var(--semantic-size-width-height-32);
2034
+ --button-sm-height: var(--semantic-size-width-height-24);
2014
2035
  --button-sm-padding-horizontal: var(--semantic-size-spacing-12);
2015
2036
  --button-sm-min-width: var(--semantic-size-width-height-64);
2016
2037
  --button-sm-gap: var(--semantic-size-spacing-8);
2017
- --button-sm-font-size: var(--semantic-size-width-height-14);
2038
+ --button-sm-font-size: var(--semantic-size-width-height-12);
2018
2039
  --button-sm-font-weight: 600;
2019
2040
  --button-sm-radius: var(--semantic-size-radius-999);
2020
2041
  --button-sm-border-width: var(--semantic-size-border-1-5);
2021
- --button-sm-icon-size: var(--semantic-size-width-height-32);
2042
+ --button-sm-icon-size: var(--semantic-size-width-height-24);
2022
2043
 
2023
- --button-md-height: var(--semantic-size-width-height-40);
2044
+ --button-md-height: var(--semantic-size-width-height-32);
2024
2045
  --button-md-padding-horizontal: var(--semantic-size-spacing-16);
2025
2046
  --button-md-min-width: var(--semantic-size-width-height-80);
2026
2047
  --button-md-gap: var(--semantic-size-spacing-8);
2027
- --button-md-font-size: var(--semantic-size-width-height-16);
2048
+ --button-md-font-size: var(--semantic-size-width-height-14);
2028
2049
  --button-md-font-weight: 600;
2029
2050
  --button-md-radius: var(--semantic-size-radius-999);
2030
2051
  --button-md-border-width: var(--semantic-size-border-1-5);
2031
- --button-md-icon-size: var(--semantic-size-width-height-40);
2052
+ --button-md-icon-size: var(--semantic-size-width-height-32);
2032
2053
 
2033
2054
  --button-lg-height: var(--semantic-size-width-height-48);
2034
2055
  --button-lg-padding-horizontal: var(--semantic-size-spacing-20);
2035
2056
  --button-lg-min-width: var(--semantic-size-width-height-96);
2036
2057
  --button-lg-gap: var(--semantic-size-spacing-8);
2037
- --button-lg-font-size: var(--semantic-size-width-height-18);
2058
+ --button-lg-font-size: var(--semantic-size-width-height-16);
2038
2059
  --button-lg-font-weight: 600;
2039
2060
  --button-lg-radius: var(--semantic-size-radius-999);
2040
2061
  --button-lg-border-width: var(--semantic-size-border-1-5);
2041
2062
  --button-lg-icon-size: var(--semantic-size-width-height-48);
2042
2063
 
2064
+ --button-xl-height: var(--semantic-size-width-height-64);
2065
+ --button-xl-padding-horizontal: var(--semantic-size-width-height-32); /* no spacing-32 token; 32px per Figma */
2066
+ --button-xl-min-width: var(--semantic-size-width-height-96);
2067
+ --button-xl-gap: var(--semantic-size-spacing-12);
2068
+ --button-xl-font-size: var(--semantic-size-width-height-18);
2069
+ --button-xl-font-weight: 600;
2070
+ --button-xl-radius: var(--semantic-size-radius-999);
2071
+ --button-xl-border-width: var(--semantic-size-border-1-5);
2072
+ --button-xl-icon-size: var(--semantic-size-width-height-64);
2073
+
2074
+ /* ── Social button size tokens (md=40, lg=48, xl=64; 1px border per Figma) ── */
2075
+ --button-social-md-height: var(--semantic-size-width-height-40);
2076
+ --button-social-md-padding-horizontal: var(--semantic-size-spacing-16);
2077
+ --button-social-md-gap: var(--semantic-size-spacing-8);
2078
+ --button-social-md-font-size: var(--semantic-size-width-height-16);
2079
+ --button-social-md-border-width: var(--semantic-size-border-1);
2080
+ --button-social-lg-height: var(--semantic-size-width-height-48);
2081
+ --button-social-lg-padding-horizontal: var(--semantic-size-spacing-20);
2082
+ --button-social-lg-gap: var(--semantic-size-spacing-8);
2083
+ --button-social-lg-font-size: var(--semantic-size-width-height-16);
2084
+ --button-social-lg-border-width: var(--semantic-size-border-1);
2085
+ --button-social-xl-height: var(--semantic-size-width-height-64);
2086
+ --button-social-xl-padding-horizontal: var(--semantic-size-spacing-20);
2087
+ --button-social-xl-gap: var(--semantic-size-spacing-8);
2088
+ --button-social-xl-font-size: var(--semantic-size-width-height-18);
2089
+ --button-social-xl-border-width: var(--semantic-size-border-1);
2090
+
2043
2091
  /* ── Badge ── */
2044
2092
  --badge-sm-height: var(--semantic-size-width-height-20);
2045
2093
  --badge-sm-padding-horizontal: var(--semantic-size-spacing-6);
@@ -2292,13 +2340,13 @@
2292
2340
  --snackbar-padding-v: var(--semantic-size-spacing-8);
2293
2341
  --snackbar-text-max-width: 528px; /* ⚠ no semantic-size-528 */
2294
2342
  --snackbar-shadow: 0 2px 4px 0 #0000000a, 0 8px 24px -4px #00000014, 0 16px 48px -6px #0000000a;
2295
- /* Button sm/ghost-static-dark tokens for snackbar action + close buttons */
2296
- --snackbar-btn-height: var(--button-sm-height);
2297
- --snackbar-btn-radius: var(--button-sm-radius);
2298
- --snackbar-btn-padding-h: var(--button-sm-padding-horizontal);
2299
- --snackbar-btn-gap: var(--button-sm-gap);
2343
+ /* Button md/ghost-static-dark tokens for snackbar action + close buttons */
2344
+ --snackbar-btn-height: var(--button-md-height);
2345
+ --snackbar-btn-radius: var(--button-md-radius);
2346
+ --snackbar-btn-padding-h: var(--button-md-padding-horizontal);
2347
+ --snackbar-btn-gap: var(--button-md-gap);
2300
2348
  --snackbar-btn-icon-size: var(--semantic-size-width-height-16);
2301
- --snackbar-btn-icon-btn-width: var(--button-sm-icon-size);
2349
+ --snackbar-btn-icon-btn-width: var(--button-md-icon-size);
2302
2350
  --snackbar-btn-text: var(--button-ghost-static-dark-text);
2303
2351
  --snackbar-btn-icon: var(--button-ghost-static-dark-icon);
2304
2352
  --snackbar-btn-bg-hover: var(--button-ghost-static-dark-bg-hover);
@@ -2356,6 +2404,13 @@
2356
2404
  --button-secondary-normal-border: var(--primitive-slate-50);
2357
2405
  --button-secondary-normal-text: var(--primitive-slate-50);
2358
2406
  --button-secondary-normal-icon: var(--primitive-slate-50);
2407
+ /* Social button — neutral overlays inverted for dark */
2408
+ --button-social-border: var(--primitive-white-alpha-100);
2409
+ --button-social-primary-bg: oklch(1 0 0 / 4%);
2410
+ --button-social-primary-bg-hover: var(--primitive-white-alpha-100);
2411
+ --button-social-primary-bg-pressed: var(--primitive-white-alpha-200);
2412
+ --button-social-secondary-bg-hover: var(--primitive-white-alpha-100);
2413
+ --button-social-secondary-bg-pressed: var(--primitive-white-alpha-200);
2359
2414
  --button-secondary-inverse-bg-hover: var(--primitive-slate-alpha-100);
2360
2415
  --button-secondary-inverse-bg-pressed: var(--primitive-slate-alpha-200);
2361
2416
  --button-secondary-inverse-border: var(--primitive-slate-1200);
@@ -2589,6 +2644,9 @@
2589
2644
  --feedback-success-bg: var(--primitive-slate-1200);
2590
2645
  --feedback-success-tag-border: var(--primitive-slate-200);
2591
2646
 
2647
+ /* Referral block — dark */
2648
+ --referral-text-body: var(--primitive-white-alpha-900); /* #FFFFFF @ 72% — step body text */
2649
+
2592
2650
  /* Chip */
2593
2651
  --chip-text-prominent: var(--primitive-slate-50);
2594
2652
  --chip-text-disabled: var(--primitive-white-alpha-200);