@cosmicdrift/kumiko-renderer 0.257.0 → 0.258.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 +4 -4
- package/src/__tests__/merge-search-params-into-initial.test.ts +150 -0
- package/src/app/__tests__/action-form-shim.test.ts +49 -1
- package/src/app/__tests__/secret-mint-body.test.tsx +396 -0
- package/src/app/action-form-shim.ts +28 -10
- package/src/app/kumiko-screen.tsx +89 -4
- package/src/app/secret-mint-body.tsx +235 -0
- package/src/components/__tests__/render-edit-submit-actions.test.tsx +16 -0
- package/src/components/__tests__/render-field-password-format.test.tsx +101 -0
- package/src/components/render-edit.tsx +36 -14
- package/src/components/render-field.tsx +11 -0
- package/src/i18n-defaults.ts +8 -0
- package/src/index.ts +2 -0
- package/src/primitives.tsx +42 -4
package/src/i18n-defaults.ts
CHANGED
|
@@ -153,6 +153,14 @@ export const kumikoDefaultTranslations: TranslationsByLocale = {
|
|
|
153
153
|
"Found an open draft for this form. Do you want to resume it?",
|
|
154
154
|
"kumiko.form.draft.start-new": "Start new",
|
|
155
155
|
|
|
156
|
+
"kumiko.secretMint.title": "Your new secret",
|
|
157
|
+
"kumiko.secretMint.warning":
|
|
158
|
+
"Copy this now — it is shown only this once and cannot be retrieved later.",
|
|
159
|
+
"kumiko.secretMint.confirm": "I have copied it",
|
|
160
|
+
"kumiko.secretMint.copy": "Copy",
|
|
161
|
+
"kumiko.secretMint.copied": "Copied",
|
|
162
|
+
"kumiko.secretMint.done": "Done.",
|
|
163
|
+
|
|
156
164
|
"kumiko.validation.required": "Required.",
|
|
157
165
|
"kumiko.validation.invalid": "Invalid value.",
|
|
158
166
|
"kumiko.validation.too-short": "Too short (at least {min} characters).",
|
package/src/index.ts
CHANGED
package/src/primitives.tsx
CHANGED
|
@@ -88,7 +88,11 @@ export type ButtonProps = {
|
|
|
88
88
|
* die Container-Breite (Karten/Panels). Andere Breiten sind Layout-Sache
|
|
89
89
|
* des Containers, kein Button-Prop (Kit hält arbiträres Sizing draußen). */
|
|
90
90
|
readonly width?: "full" | "auto";
|
|
91
|
-
|
|
91
|
+
/** Optional for icon-only buttons (`size="icon"` with a resolved `icon`)
|
|
92
|
+
* — the icon carries the content then, `ariaLabel` the accessible name.
|
|
93
|
+
* Required in practice otherwise: without children and without `icon`
|
|
94
|
+
* the button stays empty. */
|
|
95
|
+
readonly children?: ReactNode;
|
|
92
96
|
readonly testId?: string;
|
|
93
97
|
/** Layout extras — Web merges via cn(), native impls ignore it
|
|
94
98
|
* (precedent: LinkProps.className). */
|
|
@@ -124,9 +128,11 @@ export type LinkProps = {
|
|
|
124
128
|
* Banner nicht edge-to-edge an den Main-Border klebt — relevant
|
|
125
129
|
* seit `<main>` kein eigenes Padding mehr hat. */
|
|
126
130
|
export type BannerProps = {
|
|
127
|
-
/** "error"
|
|
128
|
-
*
|
|
129
|
-
|
|
131
|
+
/** "error" for alerts (conflict, network error), "info" for neutral
|
|
132
|
+
* placeholders (not-found, loading), "loading" for load states, "warning"
|
|
133
|
+
* for a non-blocking but attention-grabbing notice (e.g. secretMint's
|
|
134
|
+
* "this is shown only once"). */
|
|
135
|
+
readonly variant?: "error" | "info" | "loading" | "warning";
|
|
130
136
|
readonly children: ReactNode;
|
|
131
137
|
/** Optional — weitere Knöpfe/Elemente rechts vom Text (z.B. "Neu
|
|
132
138
|
* laden"). Inline, nicht als eigener Block. */
|
|
@@ -216,6 +222,8 @@ export type InputProps =
|
|
|
216
222
|
readonly disabled?: boolean;
|
|
217
223
|
readonly required?: boolean;
|
|
218
224
|
readonly hasError?: boolean;
|
|
225
|
+
/** Hint text shown when the field is empty (analog to kind:"text"). */
|
|
226
|
+
readonly placeholder?: string;
|
|
219
227
|
/** "current-password" für Login, "new-password" für Reset/Signup —
|
|
220
228
|
* Browser-Password-Manager nutzen das für die Speicherentscheidung.
|
|
221
229
|
* Native: textContentType="password" / "newPassword". */
|
|
@@ -231,6 +239,8 @@ export type InputProps =
|
|
|
231
239
|
readonly disabled?: boolean;
|
|
232
240
|
readonly required?: boolean;
|
|
233
241
|
readonly hasError?: boolean;
|
|
242
|
+
/** Hint text shown when the field is empty (analog to kind:"text"). */
|
|
243
|
+
readonly placeholder?: string;
|
|
234
244
|
readonly testId?: string;
|
|
235
245
|
/** Closed FieldIconKey vocabulary (FIELD_ICONS registry, renderer-web). */
|
|
236
246
|
readonly icon?: FieldIconKey;
|
|
@@ -461,6 +471,8 @@ export type InputProps =
|
|
|
461
471
|
readonly disabled?: boolean;
|
|
462
472
|
readonly required?: boolean;
|
|
463
473
|
readonly hasError?: boolean;
|
|
474
|
+
/** Hint text shown when the field is empty (analog to kind:"text"). */
|
|
475
|
+
readonly placeholder?: string;
|
|
464
476
|
/** Read-only Textarea. Nicht `disabled` — bleibt fokussier-/
|
|
465
477
|
* kopierbar (analog zu kind:"text"). */
|
|
466
478
|
readonly readOnly?: boolean;
|
|
@@ -1165,6 +1177,28 @@ export type ActionOverflowMenuProps = {
|
|
|
1165
1177
|
readonly testId?: string;
|
|
1166
1178
|
};
|
|
1167
1179
|
|
|
1180
|
+
/** One revealed value on a `secretMint` screen's confirm phase (fw#2548). */
|
|
1181
|
+
export type SecretRevealValue = {
|
|
1182
|
+
readonly label: string;
|
|
1183
|
+
readonly value: string;
|
|
1184
|
+
readonly copyable: boolean;
|
|
1185
|
+
readonly multiline: boolean;
|
|
1186
|
+
/** Render `value` as a scannable QR code instead of monospaced text — for
|
|
1187
|
+
* an otpauth://-style enrollment URI. Platforms without a QR-capable
|
|
1188
|
+
* SecretReveal primitive fall back to the monospaced display. */
|
|
1189
|
+
readonly qr?: boolean;
|
|
1190
|
+
};
|
|
1191
|
+
|
|
1192
|
+
/** One-time secret reveal — mint-form confirm phase. Renders each value
|
|
1193
|
+
* monospaced (multiline splits it one line per entry, for recovery codes),
|
|
1194
|
+
* with a per-value copy control when `copyable`. */
|
|
1195
|
+
export type SecretRevealProps = {
|
|
1196
|
+
readonly values: readonly SecretRevealValue[];
|
|
1197
|
+
readonly copyLabel: string;
|
|
1198
|
+
readonly copiedLabel: string;
|
|
1199
|
+
readonly testId?: string;
|
|
1200
|
+
};
|
|
1201
|
+
|
|
1168
1202
|
// ---- Core-Registry (Kumiko-eigene Primitives) ----
|
|
1169
1203
|
|
|
1170
1204
|
export type CorePrimitives = {
|
|
@@ -1229,6 +1263,10 @@ export type CorePrimitives = {
|
|
|
1229
1263
|
/** Optional: without an implementation, callers with >2 header/row
|
|
1230
1264
|
* actions fall back to today's all-buttons-inline rendering (A7). */
|
|
1231
1265
|
readonly ActionOverflowMenu?: ComponentType<ActionOverflowMenuProps>;
|
|
1266
|
+
/** Optional (unlike the other Core-Primitives) so existing partial
|
|
1267
|
+
* CorePrimitives mocks in tests keep compiling — additive rollout of
|
|
1268
|
+
* a new primitive shouldn't force every test double to grow a stub. */
|
|
1269
|
+
readonly SecretReveal?: ComponentType<SecretRevealProps>;
|
|
1232
1270
|
};
|
|
1233
1271
|
|
|
1234
1272
|
/** Offene Extension-Zone für App-eigene Primitives. Devs erweitern
|