astryx-dracula 0.5.0 → 0.6.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.
Files changed (129) hide show
  1. package/BRAND.md +3 -3
  2. package/README.md +7 -4
  3. package/USAGE.md +49 -49
  4. package/astryx-dracula.d.ts +2 -2
  5. package/astryx-dracula.js +25 -9
  6. package/astryx-dracula.variants.d.ts +2 -2
  7. package/astryx.integration.mjs +1 -1
  8. package/icons.mjs +21 -17
  9. package/icons.tsx +69 -62
  10. package/package.json +125 -120
  11. package/shared/auth-chrome-config.ts +6 -6
  12. package/shared/auth-chrome.tsx +143 -144
  13. package/shared/auth-copy.ts +14 -14
  14. package/shared/chaptered-doc-config.ts +48 -51
  15. package/shared/chaptered-doc.tsx +267 -289
  16. package/shared/chart-hues.ts +25 -10
  17. package/shared/chart-labels.tsx +31 -30
  18. package/shared/chart-legend.tsx +55 -56
  19. package/shared/chart-panel-style.ts +3 -3
  20. package/shared/data-bar.tsx +97 -102
  21. package/shared/format-money.ts +1 -1
  22. package/shared/gallery-image.ts +6 -6
  23. package/shared/login-demo.ts +1 -1
  24. package/shared/metric-card.tsx +101 -105
  25. package/shared/metric-delta.tsx +28 -27
  26. package/shared/order-desk.tsx +205 -216
  27. package/shared/revenue-chart.tsx +145 -165
  28. package/shared/scene-castle.tsx +206 -291
  29. package/shared/scene-frame.tsx +33 -32
  30. package/shared/scene-hues.ts +17 -17
  31. package/shared/scene-tile.tsx +88 -92
  32. package/shared/settings-data.ts +119 -125
  33. package/shared/settings-rows.tsx +122 -159
  34. package/shared/sparkline.tsx +75 -88
  35. package/shared/sso-icons.tsx +10 -22
  36. package/shared/stars.tsx +16 -25
  37. package/templates/ai-chat-landing.template.mjs +5 -4
  38. package/templates/ai-chat-landing.tsx +473 -460
  39. package/templates/ai-chat.template.mjs +5 -4
  40. package/templates/ai-chat.tsx +543 -612
  41. package/templates/blank.template.mjs +5 -4
  42. package/templates/blank.tsx +18 -14
  43. package/templates/centered-hero.template.mjs +5 -4
  44. package/templates/centered-hero.tsx +55 -68
  45. package/templates/classic-gallery.template.mjs +5 -4
  46. package/templates/classic-gallery.tsx +97 -104
  47. package/templates/contact-form.template.mjs +5 -4
  48. package/templates/contact-form.tsx +247 -282
  49. package/templates/dashboard-portfolio.template.mjs +5 -4
  50. package/templates/dashboard-portfolio.tsx +717 -548
  51. package/templates/dashboard.template.mjs +5 -4
  52. package/templates/dashboard.tsx +596 -567
  53. package/templates/detail-page.template.mjs +5 -4
  54. package/templates/detail-page.tsx +546 -603
  55. package/templates/documentation-design.template.mjs +5 -4
  56. package/templates/documentation-design.tsx +231 -243
  57. package/templates/documentation-technical.template.mjs +5 -4
  58. package/templates/documentation-technical.tsx +236 -239
  59. package/templates/documentation.template.mjs +5 -4
  60. package/templates/documentation.tsx +267 -279
  61. package/templates/editor.template.mjs +5 -4
  62. package/templates/editor.tsx +844 -877
  63. package/templates/file-explorer.template.mjs +5 -4
  64. package/templates/file-explorer.tsx +566 -590
  65. package/templates/form-two-column.template.mjs +5 -4
  66. package/templates/form-two-column.tsx +195 -210
  67. package/templates/gallery-hero.template.mjs +5 -4
  68. package/templates/gallery-hero.tsx +93 -114
  69. package/templates/ide.template.mjs +5 -4
  70. package/templates/ide.tsx +407 -453
  71. package/templates/incident-console.template.mjs +5 -4
  72. package/templates/incident-console.tsx +593 -575
  73. package/templates/kanban-board.template.mjs +5 -4
  74. package/templates/kanban-board.tsx +665 -683
  75. package/templates/library.template.mjs +5 -4
  76. package/templates/library.tsx +409 -430
  77. package/templates/login-card.template.mjs +5 -4
  78. package/templates/login-card.tsx +63 -72
  79. package/templates/login-split.template.mjs +5 -4
  80. package/templates/login-split.tsx +192 -193
  81. package/templates/login-sso.template.mjs +5 -4
  82. package/templates/login-sso.tsx +257 -258
  83. package/templates/login.template.mjs +5 -4
  84. package/templates/login.tsx +53 -49
  85. package/templates/messaging-shell.template.mjs +5 -4
  86. package/templates/messaging-shell.tsx +556 -574
  87. package/templates/mixed-gallery.template.mjs +5 -4
  88. package/templates/mixed-gallery.tsx +60 -58
  89. package/templates/payment-form.template.mjs +5 -4
  90. package/templates/payment-form.tsx +882 -991
  91. package/templates/product-detail.template.mjs +5 -4
  92. package/templates/product-detail.tsx +261 -272
  93. package/templates/product-gallery.template.mjs +5 -4
  94. package/templates/product-gallery.tsx +126 -137
  95. package/templates/product-tour.template.mjs +5 -4
  96. package/templates/product-tour.tsx +741 -773
  97. package/templates/settings-dialog.template.mjs +5 -4
  98. package/templates/settings-dialog.tsx +688 -717
  99. package/templates/settings-sidebar.template.mjs +5 -4
  100. package/templates/settings-sidebar.tsx +762 -807
  101. package/templates/settings.template.mjs +5 -4
  102. package/templates/settings.tsx +289 -304
  103. package/templates/shell-nav.template.mjs +5 -4
  104. package/templates/shell-nav.tsx +212 -219
  105. package/templates/shell-side-nav.template.mjs +5 -4
  106. package/templates/shell-side-nav.tsx +135 -157
  107. package/templates/shell-top-nav.template.mjs +5 -4
  108. package/templates/shell-top-nav.tsx +182 -203
  109. package/templates/side-gallery.template.mjs +5 -4
  110. package/templates/side-gallery.tsx +85 -90
  111. package/templates/table-grouped.template.mjs +5 -4
  112. package/templates/table-grouped.tsx +1000 -1053
  113. package/templates/table-page-chart.template.mjs +5 -4
  114. package/templates/table-page-chart.tsx +400 -398
  115. package/templates/table-page-heatmap-status.template.mjs +5 -4
  116. package/templates/table-page-heatmap-status.tsx +483 -512
  117. package/templates/table-page-shoe-store-heatmap.template.mjs +5 -4
  118. package/templates/table-page-shoe-store-heatmap.tsx +748 -746
  119. package/templates/table-page.template.mjs +5 -4
  120. package/templates/table-page.tsx +396 -405
  121. package/templates/table.template.mjs +5 -4
  122. package/templates/table.tsx +92 -93
  123. package/templates/tech-report.template.mjs +5 -4
  124. package/templates/tech-report.tsx +1316 -1304
  125. package/templates/theme-showcase.template.mjs +5 -4
  126. package/templates/theme-showcase.tsx +871 -951
  127. package/theme.css +35 -77
  128. package/theme.css.d.ts +9 -0
  129. package/tokens.css +373 -380
package/package.json CHANGED
@@ -1,122 +1,127 @@
1
1
  {
2
- "author": "Yuzu Octopus",
3
- "bugs": {
4
- "url": "https://github.com/yuzu-octopus/astryx-dracula/issues"
5
- },
6
- "dependencies": {
7
- "lucide-react": "^1.45.0"
8
- },
9
- "description": "Pure Dracula brand theme for Astryx React sites. Dark-only tokens, syntax highlighting, and chart colors with prebuilt CSS.",
10
- "devDependencies": {
11
- "@astryxdesign/cli": "0.6.3",
12
- "@astryxdesign/core": "0.6.3",
13
- "@types/bun": "^1.4.2",
14
- "@types/node": "^26.5.1",
15
- "@types/react": "^19.3.0",
16
- "@types/react-dom": "^19.3.0",
17
- "@vitejs/plugin-react": "^6.1.1",
18
- "typescript": "^7.0.2",
19
- "vite": "^8.3.0"
20
- },
21
- "exports": {
22
- "./shared/auth-chrome": "./shared/auth-chrome.tsx",
23
- "./shared/auth-chrome-config": "./shared/auth-chrome-config.ts",
24
- "./shared/auth-copy": "./shared/auth-copy.ts",
25
- "./shared/chaptered-doc": "./shared/chaptered-doc.tsx",
26
- "./shared/chaptered-doc-config": "./shared/chaptered-doc-config.ts",
27
- "./shared/chart-hues": "./shared/chart-hues.ts",
28
- "./shared/chart-labels": "./shared/chart-labels.tsx",
29
- "./shared/chart-legend": "./shared/chart-legend.tsx",
30
- "./shared/chart-panel-style": "./shared/chart-panel-style.ts",
31
- "./shared/data-bar": "./shared/data-bar.tsx",
32
- "./shared/gallery-image": "./shared/gallery-image.ts",
33
- "./shared/login-demo": "./shared/login-demo.ts",
34
- "./shared/metric-delta": "./shared/metric-delta.tsx",
35
- "./shared/order-desk": "./shared/order-desk.tsx",
36
- "./shared/revenue-chart": "./shared/revenue-chart.tsx",
37
- "./shared/scene-castle": "./shared/scene-castle.tsx",
38
- "./shared/scene-frame": "./shared/scene-frame.tsx",
39
- "./shared/scene-hues": "./shared/scene-hues.ts",
40
- "./shared/scene-tile": "./shared/scene-tile.tsx",
41
- "./shared/settings-data": "./shared/settings-data.ts",
42
- "./shared/settings-rows": "./shared/settings-rows.tsx",
43
- "./shared/sparkline": "./shared/sparkline.tsx",
44
- "./shared/format-money": "./shared/format-money.ts",
45
- "./shared/metric-card": "./shared/metric-card.tsx",
46
- "./shared/stars": "./shared/stars.tsx",
47
- "./shared/sso-icons": "./shared/sso-icons.tsx",
48
- ".": {
49
- "types": "./astryx-dracula.d.ts",
50
- "default": "./astryx-dracula.js"
51
- },
52
- "./astryx.integration.mjs": "./astryx.integration.mjs",
53
- "./package.json": "./package.json",
54
- "./templates/*": "./templates/*",
55
- "./theme.css": "./theme.css",
56
- "./tokens.css": "./tokens.css"
57
- },
58
- "files": [
59
- "BRAND.md",
60
- "LICENSE",
61
- "README.md",
62
- "USAGE.md",
63
- "astryx-dracula.d.ts",
64
- "astryx-dracula.js",
65
- "astryx-dracula.variants.d.ts",
66
- "fonts/",
67
- "icons.mjs",
68
- "icons.tsx",
69
- "shared/",
70
- "theme.css",
71
- "tokens.css",
72
- "templates/",
73
- "astryx.integration.mjs"
74
- ],
75
- "keywords": [
76
- "astryx",
77
- "dracula",
78
- "dracula-theme",
79
- "theme",
80
- "design-system",
81
- "dark-theme",
82
- "react",
83
- "tokens"
84
- ],
85
- "license": "MIT",
86
- "name": "astryx-dracula",
87
- "peerDependencies": {
88
- "@astryxdesign/core": "^0.6.3",
89
- "lucide-react": "^1.45.0",
90
- "react": ">=19.0.0",
91
- "react-dom": ">=19.0.0"
92
- },
93
- "repository": {
94
- "type": "git",
95
- "url": "git+https://github.com/yuzu-octopus/astryx-dracula.git"
96
- },
97
- "scripts": {
98
- "audit": "bun run fonts:sync && bun scripts/check.ts",
99
- "fonts:sync": "mkdir -p public/fonts && cp fonts/*.woff2 public/fonts/",
100
- "build": "tsc --noEmit && vite build",
101
- "dev": "vite",
102
- "preview": "vite preview",
103
- "theme:build": "bun run icons:build && bunx astryx theme build astryx-theme.ts -o theme.css --icons-specifier ./icons.mjs",
104
- "icons:build": "bun build icons.tsx --outfile icons.mjs --format esm --external react --external lucide-react",
105
- "theme:check": "bun run icons:check && bunx astryx theme build astryx-theme.ts -o theme.css --icons-specifier ./icons.mjs --check --json | bun -e 'const r = JSON.parse(await Bun.stdin.text()); if (r.type !== \"theme.build.check\") { console.error(\"theme:check: unexpected CLI response \" + JSON.stringify(r).slice(0, 200)); process.exit(1); } const stale = r.data.stale.filter(s => s.path !== \"astryx-dracula.js\"); for (const s of stale) console.error(\"stale: \" + s.path + \" (\" + s.reason + \")\"); if (stale.length) process.exit(1); const entry = await import(\"./astryx-dracula.js\"); if (!entry.astryxDraculaTheme || !entry.draculaIconRegistry) { console.error(\"astryx-dracula.js is missing its theme or icon registry export\"); process.exit(1); } console.log(\"theme outputs up to date; astryx-dracula.js (hand-maintained) loads and exports\");' && bun run entry:check",
106
- "icons:check": "bun build icons.tsx --outfile .tmp-icons.mjs --format esm --external react --external lucide-react; s=$?; cmp -s .tmp-icons.mjs icons.mjs; c=$?; rm -f .tmp-icons.mjs; [ $s -eq 0 ] && [ $c -eq 0 ] || { echo 'stale: icons.mjs (rerun bun run icons:build)'; exit 1; }",
107
- "entry:check": "node -e \"const{pathToFileURL}=require('url');const{resolve}=require('path');import(pathToFileURL(resolve('astryx-dracula.js')).href).then(m=>{if(!m.astryxDraculaTheme||!m.draculaIconRegistry){console.error('astryx-dracula.js is missing its theme or icon registry export');process.exit(1)}console.log('astryx-dracula.js loads under plain Node ESM')}).catch(e=>{console.error('astryx-dracula.js is not importable by Node ESM: '+e.message);process.exit(1)})\"",
108
- "prepublishOnly": "bun run theme:check && bun run icons:check && bun run entry:check && bun run audit && tsc --noEmit && bunx react-doctor@latest --score"
109
- },
110
- "sideEffects": [
111
- "**/*.css"
112
- ],
113
- "trustedDependencies": [
114
- "@astryxdesign/core",
115
- "@astryxdesign/cli"
116
- ],
117
- "type": "module",
118
- "version": "0.5.0",
119
- "patchedDependencies": {
120
- "@astryxdesign/core@0.6.3": "patches/@astryxdesign%2Fcore@0.6.3.patch"
121
- }
2
+ "author": "Yuzu Octopus",
3
+ "bugs": {
4
+ "url": "https://github.com/yuzu-octopus/astryx-dracula/issues"
5
+ },
6
+ "dependencies": {
7
+ "lucide-react": "^1.61.0"
8
+ },
9
+ "description": "Pure Dracula brand theme for Astryx React sites. Dark-only tokens, syntax highlighting, and chart colors with prebuilt CSS.",
10
+ "devDependencies": {
11
+ "@astryxdesign/cli": "0.7.2",
12
+ "@astryxdesign/core": "0.7.2",
13
+ "@biomejs/biome": "2.6.2",
14
+ "@types/bun": "^1.4.3",
15
+ "@types/node": "^26.6.5",
16
+ "@types/react": "^19.3.0",
17
+ "@types/react-dom": "^19.3.0",
18
+ "@vitejs/plugin-react": "^6.1.2",
19
+ "typescript": "^7.0.2",
20
+ "vite": "^8.3.5"
21
+ },
22
+ "exports": {
23
+ "./shared/auth-chrome": "./shared/auth-chrome.tsx",
24
+ "./shared/auth-chrome-config": "./shared/auth-chrome-config.ts",
25
+ "./shared/auth-copy": "./shared/auth-copy.ts",
26
+ "./shared/chaptered-doc": "./shared/chaptered-doc.tsx",
27
+ "./shared/chaptered-doc-config": "./shared/chaptered-doc-config.ts",
28
+ "./shared/chart-hues": "./shared/chart-hues.ts",
29
+ "./shared/chart-labels": "./shared/chart-labels.tsx",
30
+ "./shared/chart-legend": "./shared/chart-legend.tsx",
31
+ "./shared/chart-panel-style": "./shared/chart-panel-style.ts",
32
+ "./shared/data-bar": "./shared/data-bar.tsx",
33
+ "./shared/gallery-image": "./shared/gallery-image.ts",
34
+ "./shared/login-demo": "./shared/login-demo.ts",
35
+ "./shared/metric-delta": "./shared/metric-delta.tsx",
36
+ "./shared/order-desk": "./shared/order-desk.tsx",
37
+ "./shared/revenue-chart": "./shared/revenue-chart.tsx",
38
+ "./shared/scene-castle": "./shared/scene-castle.tsx",
39
+ "./shared/scene-frame": "./shared/scene-frame.tsx",
40
+ "./shared/scene-hues": "./shared/scene-hues.ts",
41
+ "./shared/scene-tile": "./shared/scene-tile.tsx",
42
+ "./shared/settings-data": "./shared/settings-data.ts",
43
+ "./shared/settings-rows": "./shared/settings-rows.tsx",
44
+ "./shared/sparkline": "./shared/sparkline.tsx",
45
+ "./shared/format-money": "./shared/format-money.ts",
46
+ "./shared/metric-card": "./shared/metric-card.tsx",
47
+ "./shared/stars": "./shared/stars.tsx",
48
+ "./shared/sso-icons": "./shared/sso-icons.tsx",
49
+ ".": {
50
+ "types": "./astryx-dracula.d.ts",
51
+ "default": "./astryx-dracula.js"
52
+ },
53
+ "./astryx.integration.mjs": "./astryx.integration.mjs",
54
+ "./package.json": "./package.json",
55
+ "./templates/*": "./templates/*",
56
+ "./theme.css": {
57
+ "types": "./theme.css.d.ts",
58
+ "default": "./theme.css"
59
+ },
60
+ "./tokens.css": "./tokens.css"
61
+ },
62
+ "files": [
63
+ "BRAND.md",
64
+ "LICENSE",
65
+ "README.md",
66
+ "USAGE.md",
67
+ "astryx-dracula.d.ts",
68
+ "astryx-dracula.js",
69
+ "astryx-dracula.variants.d.ts",
70
+ "fonts/",
71
+ "icons.mjs",
72
+ "icons.tsx",
73
+ "shared/",
74
+ "theme.css.d.ts",
75
+ "theme.css",
76
+ "tokens.css",
77
+ "templates/",
78
+ "astryx.integration.mjs"
79
+ ],
80
+ "keywords": [
81
+ "astryx",
82
+ "dracula",
83
+ "dracula-theme",
84
+ "theme",
85
+ "design-system",
86
+ "dark-theme",
87
+ "react",
88
+ "tokens"
89
+ ],
90
+ "license": "MIT",
91
+ "name": "astryx-dracula",
92
+ "peerDependencies": {
93
+ "@astryxdesign/core": "^0.7.2",
94
+ "lucide-react": "^1.45.0",
95
+ "react": ">=19.0.0",
96
+ "react-dom": ">=19.0.0"
97
+ },
98
+ "repository": {
99
+ "type": "git",
100
+ "url": "git+https://github.com/yuzu-octopus/astryx-dracula.git"
101
+ },
102
+ "scripts": {
103
+ "audit": "bun run fonts:sync && bun scripts/check.ts",
104
+ "fonts:sync": "mkdir -p public/fonts && cp fonts/*.woff2 public/fonts/",
105
+ "build": "bun check && vite build",
106
+ "dev": "vite",
107
+ "preview": "vite preview",
108
+ "theme:build": "bun run icons:build && bunx astryx theme build astryx-theme.ts -o theme.css --icons-specifier ./icons.mjs",
109
+ "icons:build": "NODE_ENV=production bun build icons.tsx --outfile icons.mjs --format esm --external react --external lucide-react",
110
+ "theme:check": "bun run icons:check && bunx astryx theme build astryx-theme.ts -o theme.css --icons-specifier ./icons.mjs --check --json | bun -e 'const r = JSON.parse(await Bun.stdin.text()); if (r.type !== \"theme.build.check\") { console.error(\"theme:check: unexpected CLI response \" + JSON.stringify(r).slice(0, 200)); process.exit(1); } const stale = r.data.stale; for (const s of stale) console.error(\"stale: \" + s.path + \" (\" + s.reason + \")\"); if (stale.length) process.exit(1); const entry = await import(\"./astryx-dracula.js\"); if (!entry.astryxDraculaTheme || !entry.draculaIconRegistry) { console.error(\"astryx-dracula.js is missing its theme or icon registry export\"); process.exit(1); } console.log(\"theme outputs up to date; astryx-dracula.js (hand-maintained) loads and exports\");' && bun run entry:check",
111
+ "icons:check": "NODE_ENV=production bun build icons.tsx --outfile .tmp-icons.mjs --format esm --external react --external lucide-react; s=$?; cmp -s .tmp-icons.mjs icons.mjs; c=$?; rm -f .tmp-icons.mjs; [ $s -eq 0 ] && [ $c -eq 0 ] || { echo 'stale: icons.mjs (rerun bun run icons:build)'; exit 1; }",
112
+ "entry:check": "node -e \"const{pathToFileURL}=require('url');const{resolve}=require('path');import(pathToFileURL(resolve('astryx-dracula.js')).href).then(m=>{if(!m.astryxDraculaTheme||!m.draculaIconRegistry){console.error('astryx-dracula.js is missing its theme or icon registry export');process.exit(1)}console.log('astryx-dracula.js loads under plain Node ESM')}).catch(e=>{console.error('astryx-dracula.js is not importable by Node ESM: '+e.message);process.exit(1)})\"",
113
+ "prepublishOnly": "bun run theme:check && bun run icons:check && bun run entry:check && bun run audit && bun check && bun run fmt:check && bun run lint && bunx react-doctor@latest --score",
114
+ "fmt": "bun fmt '**/*.{ts,tsx,mjs,js,jsx,json,css}'",
115
+ "fmt:check": "bun fmt --check '**/*.{ts,tsx,mjs,js,jsx,json,css}'",
116
+ "lint": "biome lint"
117
+ },
118
+ "sideEffects": [
119
+ "**/*.css"
120
+ ],
121
+ "trustedDependencies": [
122
+ "@astryxdesign/core",
123
+ "@astryxdesign/cli"
124
+ ],
125
+ "type": "module",
126
+ "version": "0.6.2"
122
127
  }
@@ -2,17 +2,17 @@
2
2
  // reason as shared/scene-hues.ts: a .tsx exporting non-components breaks React
3
3
  // Fast Refresh. Five templates import these, so they are genuinely shared --
4
4
  // they were only ever co-located by accident of history.
5
- import type {CSSProperties} from 'react';
5
+ import type { CSSProperties } from "react";
6
6
 
7
7
  // Standalone auth pages paint their own body background (no host shell).
8
8
  export const authPageStyle: CSSProperties = {
9
- minHeight: '100%',
10
- backgroundColor: 'var(--color-background-body)',
11
- padding: 'var(--spacing-6)',
9
+ minHeight: "100%",
10
+ backgroundColor: "var(--color-background-body)",
11
+ padding: "var(--spacing-6)",
12
12
  };
13
13
  // Cap the column at 400px but let it shrink to fit narrow screens.
14
- export const authContentStyle: CSSProperties = {width: '100%', maxWidth: 400};
14
+ export const authContentStyle: CSSProperties = { width: "100%", maxWidth: 400 };
15
15
  // WCAG 1.3.5 autocomplete: TextInput forwards unknown props to <input> but its
16
16
  // prop type omits input-only attributes, so spread through a widened record.
17
17
  export const inputAutoComplete = (value: string) =>
18
- ({autoComplete: value}) as Record<string, string>;
18
+ ({ autoComplete: value }) as Record<string, string>;
@@ -1,41 +1,40 @@
1
1
  // Shared login chrome: page wash + 400px column + Moon brand row + the
2
2
  // autocomplete widen-record TextInput needs (prop type omits input attrs).
3
- import type {ReactNode} from 'react';
4
- import {Moon} from 'lucide-react';
5
- import {VStack} from '@astryxdesign/core/Layout';
6
- import {Text} from '@astryxdesign/core/Text';
7
- import {Icon} from '@astryxdesign/core/Icon';
8
- import {Card} from '@astryxdesign/core/Card';
9
- import {Link} from '@astryxdesign/core/Link';
10
- import {TextInput} from '@astryxdesign/core/TextInput';
11
- import {Button} from '@astryxdesign/core/Button';
12
- import {Heading} from '@astryxdesign/core/Text';
13
- import {
14
- AUTH_BRAND_NAME,
15
- AUTH_HEADING,
16
- AUTH_SUBTITLE,
17
- AUTH_PRIMARY_CTA,
18
- AUTH_SIGNUP_PROMPT,
19
- AUTH_SIGNUP_LINK,
20
- AUTH_FORGOT_PASSWORD,
21
- AUTH_EMAIL_PLACEHOLDER,
22
- AUTH_PASSWORD_PLACEHOLDER,
23
- AUTH_TERMS_PREFIX,
24
- AUTH_TERMS_SERVICE,
25
- AUTH_TERMS_PRIVACY,
26
- } from 'astryx-dracula/shared/auth-copy';
27
- import {inputAutoComplete} from 'astryx-dracula/shared/auth-chrome-config';
28
3
 
4
+ import { Button } from "@astryxdesign/core/Button";
5
+ import { Card } from "@astryxdesign/core/Card";
6
+ import { Icon } from "@astryxdesign/core/Icon";
7
+ import { VStack } from "@astryxdesign/core/Layout";
8
+ import { Link } from "@astryxdesign/core/Link";
9
+ import { Heading, Text } from "@astryxdesign/core/Text";
10
+ import { TextInput } from "@astryxdesign/core/TextInput";
11
+ import { inputAutoComplete } from "astryx-dracula/shared/auth-chrome-config";
12
+ import {
13
+ AUTH_BRAND_NAME,
14
+ AUTH_EMAIL_PLACEHOLDER,
15
+ AUTH_FORGOT_PASSWORD,
16
+ AUTH_HEADING,
17
+ AUTH_PASSWORD_PLACEHOLDER,
18
+ AUTH_PRIMARY_CTA,
19
+ AUTH_SIGNUP_LINK,
20
+ AUTH_SIGNUP_PROMPT,
21
+ AUTH_SUBTITLE,
22
+ AUTH_TERMS_PREFIX,
23
+ AUTH_TERMS_PRIVACY,
24
+ AUTH_TERMS_SERVICE,
25
+ } from "astryx-dracula/shared/auth-copy";
26
+ import { Moon } from "lucide-react";
27
+ import type { ReactNode } from "react";
29
28
 
30
29
  export function LoginBrand() {
31
- return (
32
- <VStack gap={2} hAlign="center">
33
- <Icon icon={Moon} size="lg" color="secondary" />
34
- <Text type="body" weight="semibold" size="lg">
35
- {AUTH_BRAND_NAME}
36
- </Text>
37
- </VStack>
38
- );
30
+ return (
31
+ <VStack gap={2} hAlign="center">
32
+ <Icon icon={Moon} size="lg" color="secondary" />
33
+ <Text type="body" weight="semibold" size="lg">
34
+ {AUTH_BRAND_NAME}
35
+ </Text>
36
+ </VStack>
37
+ );
39
38
  }
40
39
 
41
40
  // Shared password-login core: the centered header, credential fields, primary
@@ -45,43 +44,43 @@ export function LoginBrand() {
45
44
  // shell — login-split's two-column grid and login-sso's step machine keep
46
45
  // their own markup and take the pieces below instead of this whole card.
47
46
  export function AuthCard({
48
- selfHash,
49
- signupLink = AUTH_SIGNUP_LINK,
50
- children,
47
+ selfHash,
48
+ signupLink = AUTH_SIGNUP_LINK,
49
+ children,
51
50
  }: {
52
- selfHash: string;
53
- signupLink?: string;
54
- children: ReactNode;
51
+ selfHash: string;
52
+ signupLink?: string;
53
+ children: ReactNode;
55
54
  }) {
56
- return (
57
- <>
58
- <Card padding={4} width="100%">
59
- <VStack gap={4} hAlign="stretch">
60
- <VStack gap={1} hAlign="center">
61
- <Heading level={1} type="display-2" justify="center">
62
- {AUTH_HEADING}
63
- </Heading>
64
- <Text type="body" color="secondary">
65
- {AUTH_SUBTITLE}
66
- </Text>
67
- </VStack>
68
- {children}
69
- {/* Prose link: colour alone is not a cue inside a sentence
55
+ return (
56
+ <>
57
+ <Card padding={4} width="100%">
58
+ <VStack gap={4} hAlign="stretch">
59
+ <VStack gap={1} hAlign="center">
60
+ <Heading level={1} type="display-2" justify="center">
61
+ {AUTH_HEADING}
62
+ </Heading>
63
+ <Text type="body" color="secondary">
64
+ {AUTH_SUBTITLE}
65
+ </Text>
66
+ </VStack>
67
+ {children}
68
+ {/* Prose link: colour alone is not a cue inside a sentence
70
69
  (WCAG 1.4.1 / F73), so it asks for the underline the kit
71
70
  only gives on hover. */}
72
- <VStack hAlign="center">
73
- <Text type="supporting" color="secondary">
74
- {AUTH_SIGNUP_PROMPT}{' '}
75
- <Link href={selfHash} type="supporting" hasUnderline>
76
- {signupLink}
77
- </Link>
78
- </Text>
79
- </VStack>
80
- </VStack>
81
- </Card>
82
- <AuthTerms selfHash={selfHash} />
83
- </>
84
- );
71
+ <VStack hAlign="center">
72
+ <Text type="supporting" color="secondary">
73
+ {AUTH_SIGNUP_PROMPT}{" "}
74
+ <Link href={selfHash} type="supporting" hasUnderline>
75
+ {signupLink}
76
+ </Link>
77
+ </Text>
78
+ </VStack>
79
+ </VStack>
80
+ </Card>
81
+ <AuthTerms selfHash={selfHash} />
82
+ </>
83
+ );
85
84
  }
86
85
 
87
86
  // Email + password fields with the shared error/forgot-password rhythm, plus
@@ -89,87 +88,87 @@ export function AuthCard({
89
88
  // not the outer 16px: without the group the two inputs sat twice as far
90
89
  // apart as the fields below them.
91
90
  export function AuthLoginFields({
92
- email,
93
- password,
94
- error,
95
- selfHash,
96
- isLoading,
97
- onEmailChange,
98
- onPasswordChange,
99
- onSubmit,
91
+ email,
92
+ password,
93
+ error,
94
+ selfHash,
95
+ isLoading,
96
+ onEmailChange,
97
+ onPasswordChange,
98
+ onSubmit,
100
99
  }: {
101
- email: string;
102
- password: string;
103
- error: string | null;
104
- selfHash: string;
105
- isLoading: boolean;
106
- onEmailChange: (value: string) => void;
107
- onPasswordChange: (value: string) => void;
108
- onSubmit: () => void;
100
+ email: string;
101
+ password: string;
102
+ error: string | null;
103
+ selfHash: string;
104
+ isLoading: boolean;
105
+ onEmailChange: (value: string) => void;
106
+ onPasswordChange: (value: string) => void;
107
+ onSubmit: () => void;
109
108
  }) {
110
- return (
111
- <>
112
- <VStack gap={2}>
113
- <TextInput
114
- label="Email"
115
- isLabelHidden
116
- value={email}
117
- onChange={onEmailChange}
118
- placeholder={AUTH_EMAIL_PLACEHOLDER}
119
- type="email"
120
- {...inputAutoComplete('email')}
121
- size="lg"
122
- onEnter={onSubmit}
123
- status={error ? {type: 'error', message: error} : undefined}
124
- />
125
- <VStack gap={1}>
126
- <TextInput
127
- label="Password"
128
- isLabelHidden
129
- value={password}
130
- onChange={onPasswordChange}
131
- placeholder={AUTH_PASSWORD_PLACEHOLDER}
132
- type="password"
133
- {...inputAutoComplete('current-password')}
134
- size="lg"
135
- onEnter={onSubmit}
136
- status={error ? {type: 'error', message: error} : undefined}
137
- />
138
- {error && (
139
- <VStack hAlign="end">
140
- <Link href={selfHash} color="secondary" isStandalone>
141
- {AUTH_FORGOT_PASSWORD}
142
- </Link>
143
- </VStack>
144
- )}
145
- </VStack>
146
- </VStack>
147
- <Button
148
- label={AUTH_PRIMARY_CTA}
149
- variant="primary"
150
- size="lg"
151
- isLoading={isLoading}
152
- onClick={onSubmit}
153
- />
154
- </>
155
- );
109
+ return (
110
+ <>
111
+ <VStack gap={2}>
112
+ <TextInput
113
+ label="Email"
114
+ isLabelHidden
115
+ value={email}
116
+ onChange={onEmailChange}
117
+ placeholder={AUTH_EMAIL_PLACEHOLDER}
118
+ type="email"
119
+ {...inputAutoComplete("email")}
120
+ size="lg"
121
+ onEnter={onSubmit}
122
+ status={error ? { type: "error", message: error } : undefined}
123
+ />
124
+ <VStack gap={1}>
125
+ <TextInput
126
+ label="Password"
127
+ isLabelHidden
128
+ value={password}
129
+ onChange={onPasswordChange}
130
+ placeholder={AUTH_PASSWORD_PLACEHOLDER}
131
+ type="password"
132
+ {...inputAutoComplete("current-password")}
133
+ size="lg"
134
+ onEnter={onSubmit}
135
+ status={error ? { type: "error", message: error } : undefined}
136
+ />
137
+ {error && (
138
+ <VStack hAlign="end">
139
+ <Link href={selfHash} color="secondary" isStandalone>
140
+ {AUTH_FORGOT_PASSWORD}
141
+ </Link>
142
+ </VStack>
143
+ )}
144
+ </VStack>
145
+ </VStack>
146
+ <Button
147
+ label={AUTH_PRIMARY_CTA}
148
+ variant="primary"
149
+ size="lg"
150
+ isLoading={isLoading}
151
+ onClick={onSubmit}
152
+ />
153
+ </>
154
+ );
156
155
  }
157
156
 
158
157
  // The family terms line, rendered below the card in the page column.
159
- export function AuthTerms({selfHash}: {selfHash: string}) {
160
- return (
161
- <VStack hAlign="center" width="100%">
162
- <Text type="supporting" color="secondary" justify="center">
163
- {AUTH_TERMS_PREFIX}{' '}
164
- <Link href={selfHash} type="supporting" hasUnderline>
165
- {AUTH_TERMS_SERVICE}
166
- </Link>{' '}
167
- and{' '}
168
- <Link href={selfHash} type="supporting" hasUnderline>
169
- {AUTH_TERMS_PRIVACY}
170
- </Link>
171
- .
172
- </Text>
173
- </VStack>
174
- );
158
+ export function AuthTerms({ selfHash }: { selfHash: string }) {
159
+ return (
160
+ <VStack hAlign="center" width="100%">
161
+ <Text type="supporting" color="secondary" justify="center">
162
+ {AUTH_TERMS_PREFIX}{" "}
163
+ <Link href={selfHash} type="supporting" hasUnderline>
164
+ {AUTH_TERMS_SERVICE}
165
+ </Link>{" "}
166
+ and{" "}
167
+ <Link href={selfHash} type="supporting" hasUnderline>
168
+ {AUTH_TERMS_PRIVACY}
169
+ </Link>
170
+ .
171
+ </Text>
172
+ </VStack>
173
+ );
175
174
  }