@mindees/atlas 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tokens.js ADDED
@@ -0,0 +1,185 @@
1
+ import { useColorScheme } from "./environment.js";
2
+ //#region src/tokens.ts
3
+ /**
4
+ * Design tokens + theming — the 2026-UI/UX-handbook token layer (§7–24, §31).
5
+ *
6
+ * Two tiers (the recommended default): **primitive** scales (raw `space`/`radius`/type/
7
+ * motion/color values) and **semantic** tokens (a {@link Theme}: `bg`/`surface`/`text`/
8
+ * `primary`/…) that carry intent. Dark mode is a **token-set swap** (§23/§31): the same
9
+ * semantic names resolve to different primitives. {@link useTheme} returns a reactive theme
10
+ * driven by {@link useColorScheme}, so themed UI re-themes light↔dark fine-grained — only
11
+ * the color nodes update.
12
+ *
13
+ * @module
14
+ */
15
+ /** Spacing scale — 8pt system with 4 as the half-step (handbook §8). */
16
+ const space = {
17
+ none: 0,
18
+ "3xs": 2,
19
+ "2xs": 4,
20
+ xs: 8,
21
+ sm: 12,
22
+ md: 16,
23
+ lg: 24,
24
+ xl: 32,
25
+ "2xl": 48,
26
+ "3xl": 64
27
+ };
28
+ /** Corner-radius scale (handbook §19). */
29
+ const radius = {
30
+ none: 0,
31
+ sm: 8,
32
+ md: 12,
33
+ lg: 16,
34
+ xl: 20,
35
+ "2xl": 28,
36
+ full: 9999
37
+ };
38
+ /** Type scale (≈1.25 ratio, base 16) — handbook §9. */
39
+ const fontSize = {
40
+ caption: 12,
41
+ footnote: 13,
42
+ body: 16,
43
+ callout: 17,
44
+ headline: 20,
45
+ title3: 25,
46
+ title2: 31,
47
+ title1: 39,
48
+ display: 49
49
+ };
50
+ /** Line-height (leading) ratios (handbook §9). */
51
+ const lineHeight = {
52
+ tight: 1.2,
53
+ snug: 1.3,
54
+ normal: 1.5,
55
+ relaxed: 1.6
56
+ };
57
+ /** Font weights (handbook §9 — regular + semibold/bold do most of the work). */
58
+ const fontWeight = {
59
+ regular: 400,
60
+ medium: 500,
61
+ semibold: 600,
62
+ bold: 700,
63
+ heavy: 800
64
+ };
65
+ /** Motion durations in ms (handbook §21: micro/standard/large). */
66
+ const duration = {
67
+ micro: 150,
68
+ standard: 250,
69
+ large: 400
70
+ };
71
+ /** Easing curves (handbook §21: ease-out for enter, ease-in for exit). */
72
+ const easing = {
73
+ standard: "cubic-bezier(0.2, 0, 0, 1)",
74
+ decelerate: "cubic-bezier(0, 0, 0, 1)",
75
+ accelerate: "cubic-bezier(0.3, 0, 1, 1)"
76
+ };
77
+ /** Raw color ramps (primitive tier — never apply directly; go through a {@link Theme}). */
78
+ const palette = {
79
+ white: "#ffffff",
80
+ black: "#000000",
81
+ neutral: {
82
+ 50: "#f8fafc",
83
+ 100: "#f1f5f9",
84
+ 200: "#e2e8f0",
85
+ 300: "#cbd5e1",
86
+ 400: "#94a3b8",
87
+ 500: "#64748b",
88
+ 600: "#475569",
89
+ 700: "#334155",
90
+ 800: "#1e293b",
91
+ 900: "#0f172a",
92
+ 950: "#020617"
93
+ },
94
+ blue: {
95
+ 400: "#60a5fa",
96
+ 500: "#3b82f6",
97
+ 600: "#2563eb",
98
+ 700: "#1d4ed8"
99
+ },
100
+ green: {
101
+ 400: "#4ade80",
102
+ 500: "#22c55e",
103
+ 600: "#16a34a",
104
+ 700: "#15803d"
105
+ },
106
+ amber: {
107
+ 400: "#fbbf24",
108
+ 500: "#f59e0b",
109
+ 600: "#d97706",
110
+ 700: "#b45309"
111
+ },
112
+ red: {
113
+ 400: "#f87171",
114
+ 500: "#ef4444",
115
+ 600: "#dc2626",
116
+ 700: "#b91c1c"
117
+ }
118
+ };
119
+ /** Non-color scales, grouped for convenience. */
120
+ const tokens = {
121
+ space,
122
+ radius,
123
+ fontSize,
124
+ lineHeight,
125
+ fontWeight,
126
+ duration,
127
+ easing
128
+ };
129
+ const lightTheme = {
130
+ colorScheme: "light",
131
+ color: {
132
+ bg: palette.neutral[50],
133
+ surface: palette.white,
134
+ surfaceVariant: palette.neutral[100],
135
+ text: palette.neutral[900],
136
+ textMuted: palette.neutral[500],
137
+ border: palette.neutral[200],
138
+ primary: palette.blue[600],
139
+ onPrimary: palette.white,
140
+ success: palette.green[700],
141
+ warning: palette.amber[700],
142
+ danger: palette.red[700],
143
+ info: palette.blue[700],
144
+ onTone: palette.white
145
+ }
146
+ };
147
+ const darkTheme = {
148
+ colorScheme: "dark",
149
+ color: {
150
+ bg: palette.neutral[950],
151
+ surface: palette.neutral[900],
152
+ surfaceVariant: palette.neutral[800],
153
+ text: palette.neutral[50],
154
+ textMuted: palette.neutral[400],
155
+ border: palette.neutral[700],
156
+ primary: palette.blue[500],
157
+ onPrimary: palette.white,
158
+ success: palette.green[400],
159
+ warning: palette.amber[400],
160
+ danger: palette.red[400],
161
+ info: palette.blue[400],
162
+ onTone: palette.neutral[950]
163
+ }
164
+ };
165
+ /** The theme for a given color scheme (non-reactive). */
166
+ function getTheme(colorScheme) {
167
+ return colorScheme === "dark" ? darkTheme : lightTheme;
168
+ }
169
+ /**
170
+ * The active theme as a reactive accessor — flips light↔dark with
171
+ * {@link useColorScheme}. Use it in accessor styles so dark mode is an automatic,
172
+ * fine-grained token swap (only color nodes re-run).
173
+ *
174
+ * @example
175
+ * const theme = useTheme()
176
+ * <View style={() => ({ backgroundColor: theme().color.surface })} />
177
+ */
178
+ function useTheme() {
179
+ const colorScheme = useColorScheme();
180
+ return () => getTheme(colorScheme());
181
+ }
182
+ //#endregion
183
+ export { duration, easing, fontSize, fontWeight, getTheme, lineHeight, palette, radius, space, tokens, useTheme };
184
+
185
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","names":[],"sources":["../src/tokens.ts"],"sourcesContent":["/**\n * Design tokens + theming — the 2026-UI/UX-handbook token layer (§7–24, §31).\n *\n * Two tiers (the recommended default): **primitive** scales (raw `space`/`radius`/type/\n * motion/color values) and **semantic** tokens (a {@link Theme}: `bg`/`surface`/`text`/\n * `primary`/…) that carry intent. Dark mode is a **token-set swap** (§23/§31): the same\n * semantic names resolve to different primitives. {@link useTheme} returns a reactive theme\n * driven by {@link useColorScheme}, so themed UI re-themes light↔dark fine-grained — only\n * the color nodes update.\n *\n * @module\n */\n\nimport { type ColorScheme, useColorScheme } from './environment'\n\n// --- Primitive scales --------------------------------------------------------\n\n/** Spacing scale — 8pt system with 4 as the half-step (handbook §8). */\nexport const space = {\n none: 0,\n '3xs': 2,\n '2xs': 4,\n xs: 8,\n sm: 12,\n md: 16,\n lg: 24,\n xl: 32,\n '2xl': 48,\n '3xl': 64,\n} as const\n\n/** Corner-radius scale (handbook §19). */\nexport const radius = {\n none: 0,\n sm: 8,\n md: 12,\n lg: 16,\n xl: 20,\n '2xl': 28,\n full: 9999,\n} as const\n\n/** Type scale (≈1.25 ratio, base 16) — handbook §9. */\nexport const fontSize = {\n caption: 12,\n footnote: 13,\n body: 16,\n callout: 17,\n headline: 20,\n title3: 25,\n title2: 31,\n title1: 39,\n display: 49,\n} as const\n\n/** Line-height (leading) ratios (handbook §9). */\nexport const lineHeight = { tight: 1.2, snug: 1.3, normal: 1.5, relaxed: 1.6 } as const\n\n/** Font weights (handbook §9 — regular + semibold/bold do most of the work). */\nexport const fontWeight = {\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n heavy: 800,\n} as const\n\n/** Motion durations in ms (handbook §21: micro/standard/large). */\nexport const duration = { micro: 150, standard: 250, large: 400 } as const\n\n/** Easing curves (handbook §21: ease-out for enter, ease-in for exit). */\nexport const easing = {\n standard: 'cubic-bezier(0.2, 0, 0, 1)',\n decelerate: 'cubic-bezier(0, 0, 0, 1)',\n accelerate: 'cubic-bezier(0.3, 0, 1, 1)',\n} as const\n\n/** Raw color ramps (primitive tier — never apply directly; go through a {@link Theme}). */\nexport const palette = {\n white: '#ffffff',\n black: '#000000',\n neutral: {\n 50: '#f8fafc',\n 100: '#f1f5f9',\n 200: '#e2e8f0',\n 300: '#cbd5e1',\n 400: '#94a3b8',\n 500: '#64748b',\n 600: '#475569',\n 700: '#334155',\n 800: '#1e293b',\n 900: '#0f172a',\n 950: '#020617',\n },\n blue: { 400: '#60a5fa', 500: '#3b82f6', 600: '#2563eb', 700: '#1d4ed8' },\n green: { 400: '#4ade80', 500: '#22c55e', 600: '#16a34a', 700: '#15803d' },\n amber: { 400: '#fbbf24', 500: '#f59e0b', 600: '#d97706', 700: '#b45309' },\n red: { 400: '#f87171', 500: '#ef4444', 600: '#dc2626', 700: '#b91c1c' },\n} as const\n\n/** Non-color scales, grouped for convenience. */\nexport const tokens = { space, radius, fontSize, lineHeight, fontWeight, duration, easing } as const\n\n// --- Semantic tier (themes) --------------------------------------------------\n\n/** Semantic color roles (handbook §10/§31) — the layer components and apps consume. */\nexport interface ThemeColors {\n /** App background. */\n readonly bg: string\n /** Default surface (cards, sheets). */\n readonly surface: string\n /** A raised/recessed surface variant. */\n readonly surfaceVariant: string\n /** High-emphasis text. */\n readonly text: string\n /** Secondary/muted text. */\n readonly textMuted: string\n /** Hairline borders/dividers. */\n readonly border: string\n /** Brand/primary action. */\n readonly primary: string\n /** Foreground on `primary`. */\n readonly onPrimary: string\n readonly success: string\n readonly warning: string\n readonly danger: string\n readonly info: string\n /** Foreground on the semantic tone colors. */\n readonly onTone: string\n}\n\n/** A resolved theme: a color scheme + its semantic colors. */\nexport interface Theme {\n readonly colorScheme: ColorScheme\n readonly color: ThemeColors\n}\n\nconst lightTheme: Theme = {\n colorScheme: 'light',\n color: {\n bg: palette.neutral[50],\n surface: palette.white,\n surfaceVariant: palette.neutral[100],\n text: palette.neutral[900],\n textMuted: palette.neutral[500],\n border: palette.neutral[200],\n primary: palette.blue[600],\n onPrimary: palette.white,\n // -700 tones carry white at ≥4.5:1 (handbook §11).\n success: palette.green[700],\n warning: palette.amber[700],\n danger: palette.red[700],\n info: palette.blue[700],\n onTone: palette.white,\n },\n}\n\nconst darkTheme: Theme = {\n colorScheme: 'dark',\n color: {\n // Not pure black (handbook §23); surfaces get lighter with elevation.\n bg: palette.neutral[950],\n surface: palette.neutral[900],\n surfaceVariant: palette.neutral[800],\n text: palette.neutral[50],\n textMuted: palette.neutral[400],\n border: palette.neutral[700],\n primary: palette.blue[500],\n onPrimary: palette.white,\n // Brighter tones in dark mode; dark text reads on them (handbook §23 desaturate/contrast).\n success: palette.green[400],\n warning: palette.amber[400],\n danger: palette.red[400],\n info: palette.blue[400],\n onTone: palette.neutral[950],\n },\n}\n\n/** The theme for a given color scheme (non-reactive). */\nexport function getTheme(colorScheme: ColorScheme): Theme {\n return colorScheme === 'dark' ? darkTheme : lightTheme\n}\n\n/**\n * The active theme as a reactive accessor — flips light↔dark with\n * {@link useColorScheme}. Use it in accessor styles so dark mode is an automatic,\n * fine-grained token swap (only color nodes re-run).\n *\n * @example\n * const theme = useTheme()\n * <View style={() => ({ backgroundColor: theme().color.surface })} />\n */\nexport function useTheme(): () => Theme {\n const colorScheme = useColorScheme()\n return () => getTheme(colorScheme())\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,MAAa,QAAQ;CACnB,MAAM;CACN,OAAO;CACP,OAAO;CACP,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;AACT;;AAGA,MAAa,SAAS;CACpB,MAAM;CACN,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,MAAM;AACR;;AAGA,MAAa,WAAW;CACtB,SAAS;CACT,UAAU;CACV,MAAM;CACN,SAAS;CACT,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;AACX;;AAGA,MAAa,aAAa;CAAE,OAAO;CAAK,MAAM;CAAK,QAAQ;CAAK,SAAS;AAAI;;AAG7E,MAAa,aAAa;CACxB,SAAS;CACT,QAAQ;CACR,UAAU;CACV,MAAM;CACN,OAAO;AACT;;AAGA,MAAa,WAAW;CAAE,OAAO;CAAK,UAAU;CAAK,OAAO;AAAI;;AAGhE,MAAa,SAAS;CACpB,UAAU;CACV,YAAY;CACZ,YAAY;AACd;;AAGA,MAAa,UAAU;CACrB,OAAO;CACP,OAAO;CACP,SAAS;EACP,IAAI;EACJ,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;CACP;CACA,MAAM;EAAE,KAAK;EAAW,KAAK;EAAW,KAAK;EAAW,KAAK;CAAU;CACvE,OAAO;EAAE,KAAK;EAAW,KAAK;EAAW,KAAK;EAAW,KAAK;CAAU;CACxE,OAAO;EAAE,KAAK;EAAW,KAAK;EAAW,KAAK;EAAW,KAAK;CAAU;CACxE,KAAK;EAAE,KAAK;EAAW,KAAK;EAAW,KAAK;EAAW,KAAK;CAAU;AACxE;;AAGA,MAAa,SAAS;CAAE;CAAO;CAAQ;CAAU;CAAY;CAAY;CAAU;AAAO;AAoC1F,MAAM,aAAoB;CACxB,aAAa;CACb,OAAO;EACL,IAAI,QAAQ,QAAQ;EACpB,SAAS,QAAQ;EACjB,gBAAgB,QAAQ,QAAQ;EAChC,MAAM,QAAQ,QAAQ;EACtB,WAAW,QAAQ,QAAQ;EAC3B,QAAQ,QAAQ,QAAQ;EACxB,SAAS,QAAQ,KAAK;EACtB,WAAW,QAAQ;EAEnB,SAAS,QAAQ,MAAM;EACvB,SAAS,QAAQ,MAAM;EACvB,QAAQ,QAAQ,IAAI;EACpB,MAAM,QAAQ,KAAK;EACnB,QAAQ,QAAQ;CAClB;AACF;AAEA,MAAM,YAAmB;CACvB,aAAa;CACb,OAAO;EAEL,IAAI,QAAQ,QAAQ;EACpB,SAAS,QAAQ,QAAQ;EACzB,gBAAgB,QAAQ,QAAQ;EAChC,MAAM,QAAQ,QAAQ;EACtB,WAAW,QAAQ,QAAQ;EAC3B,QAAQ,QAAQ,QAAQ;EACxB,SAAS,QAAQ,KAAK;EACtB,WAAW,QAAQ;EAEnB,SAAS,QAAQ,MAAM;EACvB,SAAS,QAAQ,MAAM;EACvB,QAAQ,QAAQ,IAAI;EACpB,MAAM,QAAQ,KAAK;EACnB,QAAQ,QAAQ,QAAQ;CAC1B;AACF;;AAGA,SAAgB,SAAS,aAAiC;CACxD,OAAO,gBAAgB,SAAS,YAAY;AAC9C;;;;;;;;;;AAWA,SAAgB,WAAwB;CACtC,MAAM,cAAc,eAAe;CACnC,aAAa,SAAS,YAAY,CAAC;AACrC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindees/atlas",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "MindeesNative Atlas - accessible, signals-native UI primitives + a virtualized recycling list. Renderer-agnostic (web real, native research track).",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "type": "module",
@@ -20,6 +20,10 @@
20
20
  "./list": {
21
21
  "types": "./dist/list.d.ts",
22
22
  "import": "./dist/list.js"
23
+ },
24
+ "./for": {
25
+ "types": "./dist/for.d.ts",
26
+ "import": "./dist/for.js"
23
27
  }
24
28
  },
25
29
  "publishConfig": {
@@ -31,11 +35,11 @@
31
35
  "directory": "packages/atlas"
32
36
  },
33
37
  "dependencies": {
34
- "@mindees/core": "0.1.0"
38
+ "@mindees/core": "0.3.0"
35
39
  },
36
40
  "devDependencies": {
37
41
  "happy-dom": "20.9.0",
38
- "@mindees/renderer": "0.1.0"
42
+ "@mindees/renderer": "0.3.0"
39
43
  },
40
44
  "scripts": {
41
45
  "build": "tsdown",