@multiplatform.one/forms 6.3.0 → 6.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/forms",
3
- "version": "6.3.0",
3
+ "version": "6.4.0",
4
4
  "description": "Cross-platform form components with URL state management",
5
5
  "keywords": [
6
6
  "cross-platform",
@@ -69,9 +69,9 @@
69
69
  "perfect-freehand": "^1.2.3",
70
70
  "react-native-svg": "15.15.4",
71
71
  "tamagui": "2.0.0-rc.41",
72
- "@multiplatform.one/router": "6.3.0",
73
- "@multiplatform.one/table-primitives": "6.3.0",
74
- "@multiplatform.one/theme": "6.3.0"
72
+ "@multiplatform.one/router": "6.4.0",
73
+ "@multiplatform.one/table-primitives": "6.4.0",
74
+ "@multiplatform.one/theme": "6.4.0"
75
75
  },
76
76
  "devDependencies": {
77
77
  "@tamagui/build": "2.0.0-rc.41",
@@ -92,9 +92,9 @@
92
92
  "react-i18next": "^16.6.6",
93
93
  "react-native-web": "^0.21.2",
94
94
  "vitest": "^4.1.5",
95
- "@multiplatform.one/storybook": "6.3.0",
96
- "@multiplatform.one/config": "6.3.0",
97
- "@multiplatform.one/test-utils": "6.3.0"
95
+ "@multiplatform.one/storybook": "6.4.0",
96
+ "@multiplatform.one/test-utils": "6.4.0",
97
+ "@multiplatform.one/config": "6.4.0"
98
98
  },
99
99
  "peerDependencies": {
100
100
  "expo-maps": "*",
@@ -184,7 +184,7 @@ function CalendarDayGrid({
184
184
  {isSelected ? (
185
185
  <Button.Text
186
186
  key="text-selected"
187
- transition="quicker"
187
+ transition="quick"
188
188
  enterStyle={{ opacity: 0, y: 20 }}
189
189
  exitStyle={{ opacity: 0, y: 20 }}
190
190
  opacity={1}
@@ -203,7 +203,7 @@ function RangeDayGrid({
203
203
  {isSelected ? (
204
204
  <Button.Text
205
205
  key="text-selected"
206
- transition="quicker"
206
+ transition="quick"
207
207
  enterStyle={{ opacity: 0, y: 20 }}
208
208
  exitStyle={{ opacity: 0, y: 20 }}
209
209
  opacity={1}
@@ -197,7 +197,7 @@ function DayGrid({ calendarData, selectedDate, onSelectDate, minDate, maxDate }:
197
197
  {isSelected ? (
198
198
  <Button.Text
199
199
  key="text-selected"
200
- transition="quicker"
200
+ transition="quick"
201
201
  enterStyle={{ opacity: 0, y: 20 }}
202
202
  exitStyle={{ opacity: 0, y: 20 }}
203
203
  opacity={1}
@@ -141,7 +141,7 @@ function MultiDayGrid({
141
141
  {isSelected ? (
142
142
  <Button.Text
143
143
  key="text-selected"
144
- transition="quicker"
144
+ transition="quick"
145
145
  enterStyle={{ opacity: 0, y: 20 }}
146
146
  exitStyle={{ opacity: 0, y: 20 }}
147
147
  opacity={1}
@@ -143,7 +143,7 @@ function DayGrid({ calendarData, selectedDate, onSelectDate, minDate, maxDate }:
143
143
  {isSelected ? (
144
144
  <Button.Text
145
145
  key="text-selected"
146
- transition="quicker"
146
+ transition="quick"
147
147
  enterStyle={{ opacity: 0, y: 20 }}
148
148
  exitStyle={{ opacity: 0, y: 20 }}
149
149
  opacity={1}
@@ -1,5 +1,6 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { AnyFormApi } from "../../types";
3
+ import { Intent } from "@multiplatform.one/theme";
3
4
  import type { LabelProps, SizeTokens } from "tamagui";
4
5
  import {
5
6
  Progress as TamaguiProgress,
@@ -36,6 +37,26 @@ const ProgressIndicator = styled(TamaguiProgress.Indicator, {
36
37
  backgroundColor: formControlColors.border,
37
38
  });
38
39
 
40
+ /** Semantic indicator intent — matches the theme's Intent union. */
41
+ export type ProgressIntent = "accent" | "error" | "warning" | "success";
42
+
43
+ /**
44
+ * Semantic intents ride their hue sub-theme (`<Intent name>` → `$color9`,
45
+ * tint-independent, LC-05); `accent` stays on the base theme's
46
+ * `$accentBackground` (the "accent" sub-theme is the SOLID ramp — wrong for
47
+ * a fill on the page surface, same reasoning as Gantt bars / Toast).
48
+ */
49
+ function IndicatorIntentWrap({
50
+ intent,
51
+ children,
52
+ }: {
53
+ intent?: ProgressIntent;
54
+ children: ReactNode;
55
+ }) {
56
+ if (!intent || intent === "accent") return <>{children}</>;
57
+ return <Intent name={intent}>{children}</Intent>;
58
+ }
59
+
39
60
  export interface ProgressProps {
40
61
  name?: string;
41
62
  form?: AnyFormApi;
@@ -53,6 +74,13 @@ export interface ProgressProps {
53
74
  max?: number;
54
75
  onBlur?: (...args: any[]) => void;
55
76
  progressProps?: Omit<TamaguiProgressProps, "value" | "max" | "id" | "children">;
77
+ /**
78
+ * Semantic indicator fill resolved via the theme ramps (LC-05): `accent`
79
+ * fills with the base theme's `$accentBackground`; `error`/`warning`/
80
+ * `success` ride their hue sub-theme's `$color9`. Omit to keep the gray
81
+ * form ramp.
82
+ */
83
+ intent?: ProgressIntent;
56
84
  /** When true, renders a skeleton placeholder instead of the progress bar */
57
85
  skeleton?: boolean;
58
86
  /** When true, uses compact sizing */
@@ -75,6 +103,7 @@ export function Progress({
75
103
  max = 100,
76
104
  onBlur,
77
105
  progressProps,
106
+ intent,
78
107
  skeleton,
79
108
  compact,
80
109
  }: ProgressProps) {
@@ -101,6 +130,12 @@ export function Progress({
101
130
  blurHandler?: (...args: any[]) => void,
102
131
  hasError?: boolean,
103
132
  ) => {
133
+ // undefined keeps the styled default (gray form ramp) for existing consumers.
134
+ const indicatorFill = intent
135
+ ? intent === "accent"
136
+ ? ("$accentBackground" as const)
137
+ : ("$color9" as const)
138
+ : undefined;
104
139
  const progressElement = (
105
140
  <ProgressFrame
106
141
  width="100%"
@@ -117,7 +152,9 @@ export function Progress({
117
152
  aria-required={required || undefined}
118
153
  aria-invalid={hasError || undefined}
119
154
  >
120
- <ProgressIndicator />
155
+ <IndicatorIntentWrap intent={intent}>
156
+ <ProgressIndicator backgroundColor={indicatorFill} />
157
+ </IndicatorIntentWrap>
121
158
  </ProgressFrame>
122
159
  );
123
160
 
@@ -0,0 +1,35 @@
1
+ import { writeFileSync } from "node:fs";
2
+ import { describe, it } from "vitest";
3
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
4
+ import { View } from "tamagui";
5
+
6
+ describe("scratch", () => {
7
+ it("dumps config + view classes", () => {
8
+ const lines: string[] = [];
9
+ const { container } = renderWithProviders(
10
+ <>
11
+ <View data-testid="v-color7" backgroundColor="$color7" />
12
+ <View data-testid="v-accentbg" backgroundColor="$accentBackground" />
13
+ <View data-testid="v-color9" backgroundColor="$color9" />
14
+ </>,
15
+ );
16
+ for (const id of ["v-color7", "v-accentbg", "v-color9"]) {
17
+ const el = container.querySelector(`[data-testid='${id}']`) as HTMLElement;
18
+ lines.push(`${id}: class=${el?.className}`);
19
+ lines.push(`${id}: style=${el?.getAttribute("style")}`);
20
+ }
21
+ const { configWithoutAnimations } = require("@tamagui/config");
22
+ const themeNames = Object.keys(configWithoutAnimations.themes ?? {});
23
+ lines.push(`\nTHEME COUNT: ${themeNames.length}`);
24
+ lines.push(
25
+ `INTENT-ISH THEMES: ${themeNames.filter((n) => /error|warning|success|accent|red|green|yellow/.test(n)).join(", ")}`,
26
+ );
27
+ const light = (configWithoutAnimations.themes ?? {}).light ?? {};
28
+ lines.push(
29
+ `LIGHT KEYS (accent/color7/color9): ${Object.keys(light)
30
+ .filter((k) => /accent|color7|color9|^background$/.test(k))
31
+ .join(", ")}`,
32
+ );
33
+ writeFileSync("/tmp/progress-config-dump.txt", lines.join("\n"));
34
+ });
35
+ });
package/src/index.ts CHANGED
@@ -124,7 +124,7 @@ export { Spinner } from "./Spinner";
124
124
  export type { SpinnerProps } from "./Spinner";
125
125
 
126
126
  export { Progress } from "./fields/Progress";
127
- export type { ProgressProps } from "./fields/Progress";
127
+ export type { ProgressIntent, ProgressProps } from "./fields/Progress";
128
128
 
129
129
  // ── Compound Components ──────────────────────────────────────
130
130
  export {