@incodetech/prizma-core-screens 0.1.3 → 0.2.4

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 (80) hide show
  1. package/dist/DemoScreensConfigScreen.d.ts +36 -0
  2. package/dist/DemoScreensConfigScreen.js +30 -0
  3. package/dist/DemoScreensConfigSheetScreen.d.ts +39 -0
  4. package/dist/DemoScreensConfigSheetScreen.js +33 -0
  5. package/dist/DemoScreensEditSheetScreen.d.ts +30 -0
  6. package/dist/DemoScreensEditSheetScreen.js +28 -0
  7. package/dist/DemoScreensEndScreen.d.ts +9 -21
  8. package/dist/DemoScreensEndScreen.js +9 -14
  9. package/dist/DemoScreensLaunchScreen.d.ts +28 -0
  10. package/dist/DemoScreensLaunchScreen.js +26 -0
  11. package/dist/DemoScreensLayout.css +542 -0
  12. package/dist/DemoScreensRedirectScreen.d.ts +50 -0
  13. package/dist/DemoScreensRedirectScreen.js +38 -0
  14. package/dist/DemoScreensResultScreen.d.ts +52 -0
  15. package/dist/DemoScreensResultScreen.js +46 -0
  16. package/dist/DemoScreensRunningScreen.d.ts +22 -0
  17. package/dist/DemoScreensRunningScreen.js +16 -0
  18. package/dist/DemoScreensSettingsScreen.d.ts +37 -0
  19. package/dist/DemoScreensSettingsScreen.js +40 -0
  20. package/dist/DemoScreensSplashScreen.d.ts +27 -0
  21. package/dist/DemoScreensSplashScreen.js +25 -0
  22. package/dist/DemoScreensStartScreen.d.ts +38 -0
  23. package/dist/DemoScreensStartScreen.js +37 -0
  24. package/dist/DemoScreensStrings.d.ts +192 -0
  25. package/dist/DemoScreensStrings.js +11 -11
  26. package/dist/DemoScreensTermsScreen.d.ts +28 -0
  27. package/dist/DemoScreensTermsScreen.js +26 -0
  28. package/dist/EkybAddressDetailsScreen.js +9 -5
  29. package/dist/EkybBusinessDetailsScreen.js +6 -3
  30. package/dist/EkybOwnersScreen.d.ts +4 -0
  31. package/dist/EkybOwnersScreen.js +13 -5
  32. package/dist/EkybStrings.d.ts +12 -1
  33. package/dist/EkycCountryCatalog.d.ts +46 -0
  34. package/dist/EkycCountryCatalog.js +139 -0
  35. package/dist/EkycCountryFormScreen.d.ts +36 -0
  36. package/dist/EkycCountryFormScreen.js +94 -0
  37. package/dist/EkycDetailsScreen.js +11 -4
  38. package/dist/EkycLayout.css +23 -0
  39. package/dist/EkycLicenseScreen.js +7 -3
  40. package/dist/EkycStrings.d.ts +26 -0
  41. package/dist/FaceMatchComparisonScreen.d.ts +4 -2
  42. package/dist/FaceMatchComparisonScreen.js +3 -1
  43. package/dist/FaceMatchLayout.css +53 -3
  44. package/dist/FormScreen.css +74 -0
  45. package/dist/FormScreen.d.ts +17 -0
  46. package/dist/FormScreen.js +12 -1
  47. package/dist/index.d.ts +15 -2
  48. package/dist/index.js +13 -0
  49. package/dist/styles.css +1 -0
  50. package/package.json +64 -3
  51. package/src/DemoScreensConfigScreen.tsx +101 -0
  52. package/src/DemoScreensConfigSheetScreen.tsx +120 -0
  53. package/src/DemoScreensEditSheetScreen.tsx +103 -0
  54. package/src/DemoScreensEndScreen.tsx +14 -38
  55. package/src/DemoScreensLaunchScreen.tsx +96 -0
  56. package/src/DemoScreensLayout.css +542 -0
  57. package/src/DemoScreensRedirectScreen.tsx +190 -0
  58. package/src/DemoScreensResultScreen.tsx +115 -0
  59. package/src/DemoScreensRunningScreen.tsx +45 -0
  60. package/src/DemoScreensSettingsScreen.tsx +101 -0
  61. package/src/DemoScreensSplashScreen.tsx +47 -0
  62. package/src/DemoScreensStartScreen.tsx +105 -0
  63. package/src/DemoScreensStrings.ts +204 -11
  64. package/src/DemoScreensTermsScreen.tsx +82 -0
  65. package/src/EkybAddressDetailsScreen.tsx +7 -1
  66. package/src/EkybBusinessDetailsScreen.tsx +6 -1
  67. package/src/EkybOwnersScreen.tsx +46 -2
  68. package/src/EkybStrings.ts +12 -0
  69. package/src/EkycCountryCatalog.ts +199 -0
  70. package/src/EkycCountryFormScreen.tsx +184 -0
  71. package/src/EkycDetailsScreen.tsx +29 -20
  72. package/src/EkycLayout.css +23 -0
  73. package/src/EkycLicenseScreen.tsx +22 -16
  74. package/src/EkycStrings.ts +25 -0
  75. package/src/FaceMatchComparisonScreen.tsx +11 -3
  76. package/src/FaceMatchLayout.css +53 -3
  77. package/src/FormScreen.css +74 -0
  78. package/src/FormScreen.tsx +27 -1
  79. package/src/index.ts +65 -1
  80. package/src/styles.css +1 -0
@@ -0,0 +1,46 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { PrizmaResultScreen } from './ResultScreen';
5
+ import './ScreenLayout.css';
6
+ const MARK = {
7
+ approved: 'success',
8
+ rejected: 'error',
9
+ // No mark while a human decides: a tick or a cross here would claim a
10
+ // verdict the session never reached.
11
+ inReview: 'none',
12
+ // A broken flow reads as an error, not as a pending result (dev spec).
13
+ notCompleted: 'error',
14
+ };
15
+ const RESTART_BY_DEFAULT = {
16
+ approved: false,
17
+ rejected: true,
18
+ inReview: false,
19
+ notCompleted: true,
20
+ };
21
+ /**
22
+ * Demo screens — the end of a session, on the Result archetype
23
+ * (GUIDELINES §6-F, `PrizmaResultScreen`).
24
+ *
25
+ * Figma:
26
+ * `approved` `demo_7` (2010:5745) "Thank you!" · green mark
27
+ * `rejected` `demo_8` (2010:5808) "Verification failed" · red mark · Restart
28
+ * `inReview` `63:399` "Verification complete!" · bare title
29
+ * `notCompleted` "DemoApp: End Screens" › `Processnotcompleted` · red mark · Restart
30
+ *
31
+ * One component for the four because they are one screen with one axis: the
32
+ * host learns the session status and passes it through. `DemoScreensEndScreen`
33
+ * stays exported as the `inReview` case under its original name.
34
+ */
35
+ export const DemoScreensResultScreen = forwardRef(({ strings, status, showRestart = RESTART_BY_DEFAULT[status], screenId = `demo-screens-result-${status}`, overrides, onAction, ...shell }, ref) => {
36
+ const copy = status === 'approved'
37
+ ? strings.result.approved
38
+ : status === 'rejected'
39
+ ? strings.result.rejected
40
+ : status === 'inReview'
41
+ ? strings.end
42
+ : strings.notCompleted;
43
+ return (_jsx(PrizmaResultScreen, { ref: ref, status: MARK[status], title: copy.title, subtitle: copy.subtitle, ctaLabel: showRestart ? strings.result.restartLabel : undefined, verifiedLabel: strings.verifiedLabel, navLabel: strings.navLabel, screenId: screenId, overrides: overrides, onAction: onAction, ...shell }));
44
+ });
45
+ DemoScreensResultScreen.displayName = 'DemoScreensResultScreen';
46
+ export default DemoScreensResultScreen;
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { type PrizmaProcessingScreenProps } from './ProcessingScreen';
3
+ import type { PrizmaScreenActionHandler, PrizmaScreenOverrides } from './types';
4
+ import type { DemoScreensStrings } from './DemoScreensStrings';
5
+ import './ScreenLayout.css';
6
+ export interface DemoScreensRunningScreenProps extends Omit<PrizmaProcessingScreenProps, 'status' | 'title' | 'subtitle' | 'verifiedLabel' | 'navLabel'> {
7
+ /** Family copy — this screen reads the `running` slice. */
8
+ strings: DemoScreensStrings;
9
+ screenId?: string;
10
+ overrides?: PrizmaScreenOverrides;
11
+ onAction?: PrizmaScreenActionHandler;
12
+ }
13
+ /**
14
+ * Demo screens — "Hold on a sec…", `demo_6` (2010:6180): the wait while the
15
+ * session is scored, between the last module and the verdict.
16
+ *
17
+ * Archetype C (`PrizmaProcessingScreen`, GUIDELINES §6-C) in its pure form:
18
+ * spinner, title, one line under it, the tag. No CTA — there is nothing for
19
+ * the prospect to do but wait, and the frame draws no button.
20
+ */
21
+ export declare const DemoScreensRunningScreen: React.ForwardRefExoticComponent<DemoScreensRunningScreenProps & React.RefAttributes<HTMLDivElement>>;
22
+ export default DemoScreensRunningScreen;
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { PrizmaProcessingScreen } from './ProcessingScreen';
5
+ import './ScreenLayout.css';
6
+ /**
7
+ * Demo screens — "Hold on a sec…", `demo_6` (2010:6180): the wait while the
8
+ * session is scored, between the last module and the verdict.
9
+ *
10
+ * Archetype C (`PrizmaProcessingScreen`, GUIDELINES §6-C) in its pure form:
11
+ * spinner, title, one line under it, the tag. No CTA — there is nothing for
12
+ * the prospect to do but wait, and the frame draws no button.
13
+ */
14
+ export const DemoScreensRunningScreen = forwardRef(({ strings, screenId = 'demo-screens-running', overrides, onAction, ...shell }, ref) => (_jsx(PrizmaProcessingScreen, { ref: ref, status: "loading", title: strings.running.title, subtitle: strings.running.subtitle, verifiedLabel: strings.verifiedLabel, navLabel: strings.navLabel, screenId: screenId, overrides: overrides, onAction: onAction, ...shell })));
15
+ DemoScreensRunningScreen.displayName = 'DemoScreensRunningScreen';
16
+ export default DemoScreensRunningScreen;
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { type PrizmaScreenShellProps } from './ScreenShell';
3
+ import type { PrizmaScreenActionHandler } from './types';
4
+ import type { DemoScreensStrings } from './DemoScreensStrings';
5
+ import './ScreenLayout.css';
6
+ import './DemoScreensLayout.css';
7
+ export interface DemoScreensSettingsScreenProps extends Omit<PrizmaScreenShellProps, 'dark' | 'title' | 'children'> {
8
+ /** Family copy — this screen reads the `settings` slice. */
9
+ strings: DemoScreensStrings;
10
+ /** The selected language, by `DemoScreensLanguage.value`. Defaults to the
11
+ * first one listed. */
12
+ value?: string;
13
+ /** Documentation-only: render the language menu open (`demo_4`). */
14
+ menuOpen?: boolean;
15
+ screenId?: string;
16
+ onAction?: PrizmaScreenActionHandler;
17
+ }
18
+ /**
19
+ * Demo screens — the settings sheet, `demo_3` (2010:6002) closed and `demo_4`
20
+ * (2010:6060) with the language menu open, in `Demo App - Latest Design`.
21
+ *
22
+ * Core's Navigation with the logo off and the close X on, a left-aligned H2,
23
+ * one searchable Dropdown, one CTA. No verified tag — the frame draws none on
24
+ * a settings surface.
25
+ *
26
+ * Archetype E (`PrizmaFormScreen`) is the near miss: it insists on the logo nav
27
+ * (or its reserved row) and has no close affordance, and the frame has neither
28
+ * a logo nor a back chevron. So the shell is composed here with the same
29
+ * layout classes E uses; the Spacing/32 between the title and the field is the
30
+ * one measure the file adds (`DemoScreensLayout.css`).
31
+ *
32
+ * Flags: the option rows draw the canonical raster where the bank has one
33
+ * (`US`, `RS`); rows without one draw the label alone rather than an emoji
34
+ * (DEVIATIONS #GEN-8 — Mexico and Spain are missing from the bank).
35
+ */
36
+ export declare const DemoScreensSettingsScreen: React.ForwardRefExoticComponent<DemoScreensSettingsScreenProps & React.RefAttributes<HTMLDivElement>>;
37
+ export default DemoScreensSettingsScreen;
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { PrizmaButton } from '@incodetech/prizma-core-web/button';
5
+ import { PrizmaTitle } from '@incodetech/prizma-core-web/title';
6
+ import { PrizmaNavigation } from '@incodetech/prizma-core-web/navigation';
7
+ import { PrizmaDropdown } from '@incodetech/prizma-core-web/dropdown';
8
+ import { PrizmaCountryFlag } from '@incodetech/prizma-core-web/combined';
9
+ import { PrizmaScreenShell } from './ScreenShell';
10
+ import './ScreenLayout.css';
11
+ import './DemoScreensLayout.css';
12
+ /**
13
+ * Demo screens — the settings sheet, `demo_3` (2010:6002) closed and `demo_4`
14
+ * (2010:6060) with the language menu open, in `Demo App - Latest Design`.
15
+ *
16
+ * Core's Navigation with the logo off and the close X on, a left-aligned H2,
17
+ * one searchable Dropdown, one CTA. No verified tag — the frame draws none on
18
+ * a settings surface.
19
+ *
20
+ * Archetype E (`PrizmaFormScreen`) is the near miss: it insists on the logo nav
21
+ * (or its reserved row) and has no close affordance, and the frame has neither
22
+ * a logo nor a back chevron. So the shell is composed here with the same
23
+ * layout classes E uses; the Spacing/32 between the title and the field is the
24
+ * one measure the file adds (`DemoScreensLayout.css`).
25
+ *
26
+ * Flags: the option rows draw the canonical raster where the bank has one
27
+ * (`US`, `RS`); rows without one draw the label alone rather than an emoji
28
+ * (DEVIATIONS #GEN-8 — Mexico and Spain are missing from the bank).
29
+ */
30
+ export const DemoScreensSettingsScreen = forwardRef(({ strings, value, menuOpen = false, screenId = 'demo-screens-settings', onAction, ...shell }, ref) => {
31
+ const { settings } = strings;
32
+ const options = settings.languages.map(l => ({ value: l.value, label: l.label }));
33
+ const flagFor = (option) => {
34
+ const lang = settings.languages.find(l => l.value === option.value);
35
+ return lang?.countryCode ? (_jsx(PrizmaCountryFlag, { country: { code: lang.countryCode, name: lang.label, dialCode: '', flag: '' } })) : null;
36
+ };
37
+ return (_jsxs(PrizmaScreenShell, { ref: ref, "data-screen-id": screenId, ...shell, children: [_jsx("div", { className: "demo-screens-settings__nav", children: _jsx(PrizmaNavigation, { showIncodeLogo: false, showRightIcon: true, closeLabel: settings.closeLabel, onRightIconClick: () => onAction?.({ type: 'help', screenId }), "aria-label": strings.navLabel }) }), _jsxs("div", { className: "prizma-screen-layout__content", children: [_jsx(PrizmaTitle, { variant: "left", title: settings.title }), _jsx("div", { className: "demo-screens-settings__fields", children: _jsx(PrizmaDropdown, { label: settings.languageLabel, options: options, defaultValue: value ?? settings.languages[0]?.value ?? null, showRequiredMarker: false, searchable: true, searchPlaceholder: settings.searchPlaceholder, clearSearchLabel: settings.clearSearchLabel, renderLeading: flagFor, forceOpen: menuOpen }) })] }), _jsx("div", { className: "prizma-screen-layout__band prizma-screen-layout__band--bare demo-screens-band", children: _jsx("div", { className: "prizma-screen-layout__band__ctas", children: _jsx(PrizmaButton, { variant: "primary", size: "L", onClick: () => onAction?.({ type: 'cta', screenId }), children: settings.ctaLabel }) }) })] }));
38
+ });
39
+ DemoScreensSettingsScreen.displayName = 'DemoScreensSettingsScreen';
40
+ export default DemoScreensSettingsScreen;
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { type PrizmaScreenShellProps } from './ScreenShell';
3
+ import type { DemoScreensStrings } from './DemoScreensStrings';
4
+ import './ScreenLayout.css';
5
+ import './DemoScreensLayout.css';
6
+ export interface DemoScreensSplashScreenProps extends Omit<PrizmaScreenShellProps, 'dark' | 'title' | 'children'> {
7
+ /** Family copy — this screen reads `appName`. */
8
+ strings: DemoScreensStrings;
9
+ screenId?: string;
10
+ }
11
+ /**
12
+ * Demo screens — the splash, `demo_1` (2010:5868) in `Demo App - Latest Design`.
13
+ *
14
+ * The brand moment before the front door: the whole stage is Surface/Brand/500,
15
+ * the wordmark and the app name sit white in the middle. No nav, no CTA, no
16
+ * verified tag — the frame draws none, and there is nothing to verify yet.
17
+ *
18
+ * Not an archetype (GUIDELINES §6 has no "stage" template), so the shell gets
19
+ * one modifier class and the wordmark block is the same one the start screen
20
+ * draws. The colour goes through the shell's background and Core's two opt-in
21
+ * hooks (`--prizma-logo-fill`, Text/Body/0 static); no hex, no new palette.
22
+ *
23
+ * The desktop frame (2010:6362) is this same stage filling a 1440 browser
24
+ * window; the column does not centre, the colour does.
25
+ */
26
+ export declare const DemoScreensSplashScreen: React.ForwardRefExoticComponent<DemoScreensSplashScreenProps & React.RefAttributes<HTMLDivElement>>;
27
+ export default DemoScreensSplashScreen;
@@ -0,0 +1,25 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { PrizmaLogo } from '@incodetech/prizma-core-web/logo';
5
+ import { PrizmaScreenShell } from './ScreenShell';
6
+ import './ScreenLayout.css';
7
+ import './DemoScreensLayout.css';
8
+ /**
9
+ * Demo screens — the splash, `demo_1` (2010:5868) in `Demo App - Latest Design`.
10
+ *
11
+ * The brand moment before the front door: the whole stage is Surface/Brand/500,
12
+ * the wordmark and the app name sit white in the middle. No nav, no CTA, no
13
+ * verified tag — the frame draws none, and there is nothing to verify yet.
14
+ *
15
+ * Not an archetype (GUIDELINES §6 has no "stage" template), so the shell gets
16
+ * one modifier class and the wordmark block is the same one the start screen
17
+ * draws. The colour goes through the shell's background and Core's two opt-in
18
+ * hooks (`--prizma-logo-fill`, Text/Body/0 static); no hex, no new palette.
19
+ *
20
+ * The desktop frame (2010:6362) is this same stage filling a 1440 browser
21
+ * window; the column does not centre, the colour does.
22
+ */
23
+ export const DemoScreensSplashScreen = forwardRef(({ strings, screenId = 'demo-screens-splash', className, ...shell }, ref) => (_jsx(PrizmaScreenShell, { ref: ref, "data-screen-id": screenId, className: ['demo-screens-splash', className ?? ''].filter(Boolean).join(' '), ...shell, children: _jsxs("div", { className: "demo-screens-wordmark", children: [_jsx(PrizmaLogo, { variant: "incode" }), _jsx("p", { className: "demo-screens-wordmark__caption", children: strings.appName })] }) })));
24
+ DemoScreensSplashScreen.displayName = 'DemoScreensSplashScreen';
25
+ export default DemoScreensSplashScreen;
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import { type PrizmaScreenShellProps } from './ScreenShell';
3
+ import type { PrizmaScreenActionHandler } from './types';
4
+ import type { DemoScreensStrings } from './DemoScreensStrings';
5
+ import './ScreenLayout.css';
6
+ import './DemoScreensLayout.css';
7
+ export interface DemoScreensStartScreenProps extends Omit<PrizmaScreenShellProps, 'dark' | 'title' | 'children'> {
8
+ /** Family copy — this screen reads `appName`, `start` and `settings.languages`. */
9
+ strings: DemoScreensStrings;
10
+ /** The CTA is pressed and the session is being created (`2082:8743`). */
11
+ loading?: boolean;
12
+ screenId?: string;
13
+ onAction?: PrizmaScreenActionHandler;
14
+ }
15
+ /**
16
+ * Demo screens — the front door, `demo_2` (2010:5925) in `Demo App - Latest
17
+ * Design`, and its loading twin `2082:8743`.
18
+ *
19
+ * Header row: the current language (label over value, the flag from the
20
+ * canonical bank) on the left and the menu affordance on the right. Middle: the
21
+ * wordmark block the splash also draws. Bottom: one primary CTA. No verified
22
+ * tag — the frame draws none; nothing has been verified yet.
23
+ *
24
+ * Not an archetype: §6 has no template with a two-slot header and a centred
25
+ * wordmark, so the row is composed here from the nav row's own measures
26
+ * (`DemoScreensLayout.css`). The menu glyph is drawn locally — the frame's
27
+ * three-dot "Info menu" is not in the canonical bank yet, and the owner asked
28
+ * for the dots rather than a stand-in (Elena, 2026-09-24). It sits in
29
+ * Navigation's own icon button so size, colour and focus are Core's; the
30
+ * geometry is the only new thing, named as such in DEVIATIONS #GEN-10.
31
+ *
32
+ * `onAction`: `cta` when the CTA is pressed, `help` for the menu (the
33
+ * settings sheet is what it opens in the app).
34
+ */
35
+ /** The three-dot menu glyph, 24 box, currentColor — pending its bank entry. */
36
+ export declare const MenuDotsGlyph: React.FC;
37
+ export declare const DemoScreensStartScreen: React.ForwardRefExoticComponent<DemoScreensStartScreenProps & React.RefAttributes<HTMLDivElement>>;
38
+ export default DemoScreensStartScreen;
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { PrizmaButton } from '@incodetech/prizma-core-web/button';
5
+ import { PrizmaLogo } from '@incodetech/prizma-core-web/logo';
6
+ import { PrizmaCountryFlag } from '@incodetech/prizma-core-web/combined';
7
+ import { PrizmaScreenShell } from './ScreenShell';
8
+ import './ScreenLayout.css';
9
+ import './DemoScreensLayout.css';
10
+ /**
11
+ * Demo screens — the front door, `demo_2` (2010:5925) in `Demo App - Latest
12
+ * Design`, and its loading twin `2082:8743`.
13
+ *
14
+ * Header row: the current language (label over value, the flag from the
15
+ * canonical bank) on the left and the menu affordance on the right. Middle: the
16
+ * wordmark block the splash also draws. Bottom: one primary CTA. No verified
17
+ * tag — the frame draws none; nothing has been verified yet.
18
+ *
19
+ * Not an archetype: §6 has no template with a two-slot header and a centred
20
+ * wordmark, so the row is composed here from the nav row's own measures
21
+ * (`DemoScreensLayout.css`). The menu glyph is drawn locally — the frame's
22
+ * three-dot "Info menu" is not in the canonical bank yet, and the owner asked
23
+ * for the dots rather than a stand-in (Elena, 2026-09-24). It sits in
24
+ * Navigation's own icon button so size, colour and focus are Core's; the
25
+ * geometry is the only new thing, named as such in DEVIATIONS #GEN-10.
26
+ *
27
+ * `onAction`: `cta` when the CTA is pressed, `help` for the menu (the
28
+ * settings sheet is what it opens in the app).
29
+ */
30
+ /** The three-dot menu glyph, 24 box, currentColor — pending its bank entry. */
31
+ export const MenuDotsGlyph = () => (_jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [_jsx("circle", { cx: "5", cy: "12", r: "2", fill: "currentColor" }), _jsx("circle", { cx: "12", cy: "12", r: "2", fill: "currentColor" }), _jsx("circle", { cx: "19", cy: "12", r: "2", fill: "currentColor" })] }));
32
+ export const DemoScreensStartScreen = forwardRef(({ strings, loading = false, screenId = 'demo-screens-start', onAction, ...shell }, ref) => {
33
+ const current = strings.settings.languages.find(l => l.label === strings.start.languageValue);
34
+ return (_jsxs(PrizmaScreenShell, { ref: ref, "data-screen-id": screenId, ...shell, children: [_jsxs("header", { className: "demo-screens-start__header", "aria-label": strings.navLabel, children: [_jsxs("div", { className: "demo-screens-start__language", children: [_jsx("span", { className: "demo-screens-start__language-label", children: strings.start.languageLabel }), _jsxs("span", { className: "demo-screens-start__language-value", children: [current?.countryCode ? (_jsx(PrizmaCountryFlag, { country: { code: current.countryCode, name: current.label, dialCode: '', flag: '' } })) : null, strings.start.languageValue] })] }), _jsx("button", { type: "button", className: "prizma-nav__icon demo-screens-start__menu", "aria-label": strings.start.menuLabel, onClick: () => onAction?.({ type: 'help', screenId }), children: _jsx(MenuDotsGlyph, {}) })] }), _jsx("div", { className: "prizma-screen-layout__content", children: _jsx("div", { className: "demo-screens-start__middle", children: _jsxs("div", { className: "demo-screens-wordmark", children: [_jsx(PrizmaLogo, { variant: "incode" }), _jsx("p", { className: "demo-screens-wordmark__caption", children: strings.appName })] }) }) }), _jsx("div", { className: "prizma-screen-layout__band prizma-screen-layout__band--bare demo-screens-band", children: _jsx("div", { className: "prizma-screen-layout__band__ctas", children: _jsx(PrizmaButton, { variant: "primary", size: "L", loading: loading, onClick: () => onAction?.({ type: 'cta', screenId }), children: strings.start.ctaLabel }) }) })] }));
35
+ });
36
+ DemoScreensStartScreen.displayName = 'DemoScreensStartScreen';
37
+ export default DemoScreensStartScreen;
@@ -1,11 +1,203 @@
1
+ export interface DemoScreensLanguage {
2
+ /** The dropdown option value — a BCP 47 tag (`en-US`, `es-MX`). */
3
+ value: string;
4
+ /** The row label, exactly as the app lists it ("English (US)"). */
5
+ label: string;
6
+ /** ISO 3166-1 alpha-2 code for the canonical flag bank (`US`, `RS`). Absent
7
+ * when the bank has no raster for that country yet — the row then draws
8
+ * no flag rather than an emoji. */
9
+ countryCode?: string;
10
+ }
11
+ /** One row of a picker: an environment, a flow. */
12
+ export interface DemoScreensOption {
13
+ value: string;
14
+ label: string;
15
+ }
1
16
  export interface DemoScreensStrings {
2
17
  /** Accessible name for the logo nav region (i18n — no baked-in English). */
3
18
  navLabel?: string;
4
19
  /** "verified by" attribution copy for the footer tag. */
5
20
  verifiedLabel: string;
21
+ /** The caption under the wordmark on the splash and the start screen. */
22
+ appName: string;
23
+ /** NATIVE · `Configuration` (2010:4704) — Client ID + Environment before the
24
+ * app knows who you are. `demo_2` empty, `demo_4` filled, `demo_3` custom
25
+ * URL, `Error Client ID` (2116:10697). */
26
+ config: {
27
+ clientIdLabel: string;
28
+ clientIdPlaceholder: string;
29
+ /** The value the filled states show. */
30
+ clientIdValue: string;
31
+ /** Error line under a Client ID the backend rejected. */
32
+ clientIdError: string;
33
+ environmentLabel: string;
34
+ environmentPlaceholder: string;
35
+ environments: DemoScreensOption[];
36
+ /** The environment whose choice reveals the URL field. */
37
+ customEnvironment: string;
38
+ urlLabel: string;
39
+ urlValue: string;
40
+ ctaLabel: string;
41
+ };
42
+ /** NATIVE · `Accept Terms` (2010:4923 · 4012:8731) — two documents, each
43
+ * with its consent checkbox. */
44
+ terms: {
45
+ /** "Last Modified: August 5, 2024" — the line under the logo. */
46
+ lastModified: string;
47
+ documents: Record<'terms' | 'privacy', {
48
+ consentLabel: string;
49
+ body: string;
50
+ }>;
51
+ ctaLabel: string;
52
+ };
53
+ /** NATIVE · `Launch screen` (2010:5024) · `Loading` (2082:8004) — the app
54
+ * is configured; one CTA runs the flow. */
55
+ launch: {
56
+ /** "Flow: Digital ID Flow" — the header's left text. */
57
+ flowLabel: string;
58
+ menuLabel: string;
59
+ ctaLabel: string;
60
+ /** "Environment:" — the caption under the CTA … */
61
+ environmentCaption: string;
62
+ /** … and its highlighted value ("Stage"). */
63
+ environmentValue: string;
64
+ /** Snackbar after the configuration sheet saved ("Flow saved"). */
65
+ savedSnackbar: string;
66
+ };
67
+ /** NATIVE · `Configuration › Demo config screen` (2118:20999) — the sheet
68
+ * the menu opens: pick a flow, or go edit Client ID / Environment. */
69
+ configSheet: {
70
+ title: string;
71
+ subtitle: string;
72
+ closeLabel: string;
73
+ flowLabel: string;
74
+ /** The flow shown before any change ("Build Predefined"). */
75
+ flowValue: string;
76
+ /** The flow the `selected` state shows ("uxv2"). */
77
+ flowSelected: string;
78
+ flows: DemoScreensOption[];
79
+ searchPlaceholder: string;
80
+ clearSearchLabel: string;
81
+ /** The two read-only lines under the picker. */
82
+ clientIdLine: string;
83
+ environmentLine: string;
84
+ saveLabel: string;
85
+ editLinkLabel: string;
86
+ /** "Build: 2020" — the caption at the foot of both sheets. */
87
+ buildLabel: string;
88
+ savedSnackbar: string;
89
+ };
90
+ /** NATIVE · `Edit Client ID or Environment` (2118:21000 …) — the second
91
+ * sheet, reached from the first. */
92
+ editSheet: {
93
+ title: string;
94
+ subtitle: string;
95
+ backLabel: string;
96
+ closeLabel: string;
97
+ clientIdLabel: string;
98
+ clientIdValue: string;
99
+ clientIdError: string;
100
+ environmentLabel: string;
101
+ /** The environment shown before any change ("Kubernetes Stage"). */
102
+ environmentValue: string;
103
+ /** The environment the `filled` state shows ("Demo"). */
104
+ environmentSelected: string;
105
+ environments: DemoScreensOption[];
106
+ ctaLabel: string;
107
+ buildLabel: string;
108
+ };
109
+ /** DESKTOP · `Redirect` (4272:11166) — the browser page that hands the
110
+ * session to a phone: a QR, or a link by SMS, or carry on right here. */
111
+ redirect: {
112
+ title: string;
113
+ /** Under the title when both QR and SMS are offered. */
114
+ subtitle: string;
115
+ /** Under the title when only the QR is offered, with the desktop option … */
116
+ subtitleQrDesktop: string;
117
+ /** … and without it. */
118
+ subtitleQrOnly: string;
119
+ tabs: {
120
+ qr: string;
121
+ sms: string;
122
+ };
123
+ /** "Scan the QR code to verify on your mobile device." */
124
+ qrHint: string;
125
+ /** "Enter your phone number to receive a link to verify via SMS" */
126
+ smsHint: string;
127
+ phoneLabel: string;
128
+ phonePlaceholder: string;
129
+ /** The typed number the filled state shows. */
130
+ phoneValue: string;
131
+ /** ISO code of the country the picker opens on (`RS`). */
132
+ countryCode: string;
133
+ sendLabel: string;
134
+ /** "or" — between the phone leg and the desktop option. */
135
+ orLabel: string;
136
+ desktopLabel: string;
137
+ sent: {
138
+ title: string;
139
+ /** "To" — followed by the dial code and number. */
140
+ toPrefix: string;
141
+ /** "Resend in 30s" — the countdown state. */
142
+ resendIn: string;
143
+ /** "Resend" — once the countdown is over. */
144
+ resend: string;
145
+ changeLabel: string;
146
+ resentSnackbar: string;
147
+ };
148
+ tooMany: {
149
+ title: string;
150
+ subtitle: string;
151
+ changeLabel: string;
152
+ };
153
+ };
154
+ /** WEB · `demo_2` — the front door: language, the wordmark, one CTA. */
155
+ start: {
156
+ /** Small label over the current language, top left. */
157
+ languageLabel: string;
158
+ /** The current language as the front door shows it ("English (US)"). */
159
+ languageValue: string;
160
+ /** Accessible name for the menu affordance, top right. */
161
+ menuLabel: string;
162
+ ctaLabel: string;
163
+ };
164
+ /** `demo_3` … `demo_5` — the settings sheet: one dropdown, Done. */
165
+ settings: {
166
+ title: string;
167
+ closeLabel: string;
168
+ languageLabel: string;
169
+ languages: DemoScreensLanguage[];
170
+ searchPlaceholder: string;
171
+ clearSearchLabel: string;
172
+ ctaLabel: string;
173
+ };
174
+ /** `demo_6` — the wait while the session is scored. */
175
+ running: {
176
+ title: string;
177
+ subtitle?: string;
178
+ };
179
+ /** `demo_7` / `demo_8` — the two verdicts the production app renders. */
180
+ result: {
181
+ approved: {
182
+ title: string;
183
+ subtitle?: string;
184
+ };
185
+ rejected: {
186
+ title: string;
187
+ subtitle?: string;
188
+ };
189
+ /** The CTA under a verdict ("Restart onboarding"). */
190
+ restartLabel: string;
191
+ };
6
192
  /** `63:399` — the demo is over and the result is with a human. */
7
193
  end: {
8
194
  title: string;
9
195
  subtitle?: string;
10
196
  };
197
+ /** "DemoApp: End Screens" · `Processnotcompleted` — the flow broke before a
198
+ * verdict; the app currently shows this title over the error's message. */
199
+ notCompleted: {
200
+ title: string;
201
+ subtitle?: string;
202
+ };
11
203
  }
@@ -1,19 +1,19 @@
1
1
  // Demo screens — copy contract for the GENERIC family.
2
2
  //
3
- // Figma: `Module Generic Screens` (qGJjfL4O0JSjz1x4tOjJn8), frame `63:399`.
3
+ // Figma, two sources:
4
+ // · `Demo App - Latest Design` (FA4ZXKH3meKQnFmDsBsMdk), page "Full flow map",
5
+ // section `Web` (2010:5731) — the flow the Demo App runs in production on
6
+ // the web, phone and desktop: splash → start → (settings) → running →
7
+ // approved / rejected. Traced 2026-09-24.
8
+ // · `Module Generic Screens` (qGJjfL4O0JSjz1x4tOjJn8), frame `63:399`, and the
9
+ // same file's "DemoApp: End Screens" thread — the two end screens that are
10
+ // not a verdict: the result is with a human (`end`), or the flow broke
11
+ // before it reached one (`notCompleted`).
4
12
  //
5
13
  // The screens that bracket a DEMO session rather than a real one — what a
6
- // prospect sees at the two ends of a sample flow. They are generic by
7
- // definition: the demo does not belong to any module, it strings several of
14
+ // prospect sees before the first module and after the last. They are generic
15
+ // by definition: the demo does not belong to any module, it strings several of
8
16
  // them together.
9
17
  //
10
- // ONLY the end screen exists so far. The owner is supplying the start screen
11
- // separately (Camila 2026-09-03: "that's the end screen but we need the start
12
- // too, I will add it some other time"), so `start` is deliberately absent from
13
- // this contract rather than guessed — an invented start screen would be a
14
- // second source of truth for a frame that already exists in someone's file.
15
- //
16
- // The family has no flow of its own. Core Lab lists it as a library of states.
17
- //
18
18
  // No hardcoded English anywhere in a screen: every visible string arrives here.
19
19
  export {};
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { type PrizmaScreenShellProps } from './ScreenShell';
3
+ import type { PrizmaScreenActionHandler } from './types';
4
+ import type { DemoScreensStrings } from './DemoScreensStrings';
5
+ import './ScreenLayout.css';
6
+ import './DemoScreensLayout.css';
7
+ export interface DemoScreensTermsScreenProps extends Omit<PrizmaScreenShellProps, 'dark' | 'title' | 'children'> {
8
+ /** Family copy — this screen reads the `terms` slice. */
9
+ strings: DemoScreensStrings;
10
+ /** Which document is on screen. Default `terms`. */
11
+ document?: 'terms' | 'privacy';
12
+ /** The consent box is ticked and Continue is live. */
13
+ accepted?: boolean;
14
+ screenId?: string;
15
+ onAction?: PrizmaScreenActionHandler;
16
+ }
17
+ /**
18
+ * Demo screens · NATIVE — `Accept Terms` (2010:4923 · 4012:8731): the logo on
19
+ * the left, the "Last Modified" line, the document scrolling in the middle,
20
+ * and the consent checkbox over the CTA. Two documents, Terms of Use then
21
+ * Privacy Policy, each in an unchecked and a checked state.
22
+ *
23
+ * No archetype has a left-aligned logo or a scrolling document body, so the
24
+ * screen composes Core's Logo, Checkbox and Button over the layout classes.
25
+ * The document text arrives through `strings`, as every other string does.
26
+ */
27
+ export declare const DemoScreensTermsScreen: React.ForwardRefExoticComponent<DemoScreensTermsScreenProps & React.RefAttributes<HTMLDivElement>>;
28
+ export default DemoScreensTermsScreen;
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { PrizmaButton } from '@incodetech/prizma-core-web/button';
5
+ import { PrizmaCheckbox } from '@incodetech/prizma-core-web/checkbox';
6
+ import { PrizmaLogo } from '@incodetech/prizma-core-web/logo';
7
+ import { PrizmaScreenShell } from './ScreenShell';
8
+ import './ScreenLayout.css';
9
+ import './DemoScreensLayout.css';
10
+ /**
11
+ * Demo screens · NATIVE — `Accept Terms` (2010:4923 · 4012:8731): the logo on
12
+ * the left, the "Last Modified" line, the document scrolling in the middle,
13
+ * and the consent checkbox over the CTA. Two documents, Terms of Use then
14
+ * Privacy Policy, each in an unchecked and a checked state.
15
+ *
16
+ * No archetype has a left-aligned logo or a scrolling document body, so the
17
+ * screen composes Core's Logo, Checkbox and Button over the layout classes.
18
+ * The document text arrives through `strings`, as every other string does.
19
+ */
20
+ export const DemoScreensTermsScreen = forwardRef(({ strings, document = 'terms', accepted = false, screenId = `demo-screens-${document}${accepted ? '-accepted' : ''}`, onAction, ...shell }, ref) => {
21
+ const t = strings.terms;
22
+ const doc = t.documents[document];
23
+ return (_jsxs(PrizmaScreenShell, { ref: ref, "data-screen-id": screenId, ...shell, children: [_jsx("header", { className: "demo-screens-terms__header", "aria-label": strings.navLabel, children: _jsx(PrizmaLogo, { variant: "incode" }) }), _jsxs("div", { className: "prizma-screen-layout__content", children: [_jsx("p", { className: "demo-screens-terms__meta", children: t.lastModified }), _jsx("div", { className: "demo-screens-terms__body", children: doc.body })] }), _jsxs("div", { className: "prizma-screen-layout__band prizma-screen-layout__band--bare demo-screens-band", children: [_jsx("div", { className: "demo-screens-terms__consent", children: _jsx(PrizmaCheckbox, { size: "M", checked: accepted, label: doc.consentLabel, onCheckedChange: () => onAction?.({ type: 'secondary', screenId }) }) }), _jsx("div", { className: "prizma-screen-layout__band__ctas", children: _jsx(PrizmaButton, { variant: "primary", size: "L", disabled: !accepted, onClick: () => onAction?.({ type: 'cta', screenId }), children: t.ctaLabel }) })] })] }));
24
+ });
25
+ DemoScreensTermsScreen.displayName = 'DemoScreensTermsScreen';
26
+ export default DemoScreensTermsScreen;
@@ -5,7 +5,7 @@ import { PrizmaTextField } from '@incodetech/prizma-core-web/text-field';
5
5
  import { PrizmaDropdown } from '@incodetech/prizma-core-web/dropdown';
6
6
  import { PrizmaButton } from '@incodetech/prizma-core-web/button';
7
7
  import { PrizmaStepper } from '@incodetech/prizma-core-web/stepper';
8
- import { PrizmaFormScreen } from './FormScreen';
8
+ import { PrizmaFormScreen, PrizmaFormRow } from './FormScreen';
9
9
  import './ScreenLayout.css';
10
10
  /**
11
11
  * eKYB — step 2 of the wizard, the registered address, built on the Form
@@ -54,10 +54,14 @@ export const EkybAddressDetailsScreen = forwardRef(({ strings, state = 'empty',
54
54
  548 tall against a middle that cannot be. No module CSS. */
55
55
  scrollFields: true,
56
56
  /* Step 2 of 3. `showIcons={false}`: the eKYB bar is a bare 5px rail. */
57
- progress: _jsx(PrizmaStepper, { steps: 3, currentState: 2, showIcons: false, "aria-label": strings.stepperLabel }), title: copy.title, subtitle: copy.subtitle, ctaLabel: copy.ctaLabel, linkContent: _jsx(PrizmaButton, { variant: "secondary", size: "L", onClick: () => onAction?.({ type: 'secondary', screenId }), children: strings.backLabel }), verifiedLabel: strings.verifiedLabel, navLabel: strings.navLabel, screenId: screenId, overrides: { align: overrides?.align ?? 'left', logo: overrides?.logo }, onAction: onAction, ...shell, children: [_jsx(PrizmaTextField, { label: copy.street.label, placeholder: copy.street.placeholder, required: true, requiredHint: strings.requiredHint, autoComplete: "off", defaultValue: values?.street ?? '' }), _jsx(PrizmaTextField, { label: copy.houseNumber.label, placeholder: copy.houseNumber.placeholder, required: true, requiredHint: strings.requiredHint, autoComplete: "off", defaultValue: values?.houseNumber ?? '' }), _jsx(PrizmaTextField, { label: copy.addressLine2.label, placeholder: copy.addressLine2.placeholder, autoComplete: "off", defaultValue: values?.addressLine2 ?? '' }), _jsx(PrizmaTextField, { label: copy.city.label, placeholder: copy.city.placeholder, required: true, requiredHint: strings.requiredHint, autoComplete: "off", defaultValue: values?.city ?? '' }), _jsx(PrizmaDropdown, { label: copy.state.label, placeholder: copy.state.placeholder, required: true, requiredHint: strings.requiredHint, options: states,
58
- /* Both sections draw the placeholder unless the host supplies a
59
- value — see the docstring note on 6340:38197. */
60
- defaultValue: values?.state ?? null }), _jsx(PrizmaTextField, { label: copy.postalCode.label, placeholder: copy.postalCode.placeholder, required: true, requiredHint: strings.requiredHint, autoComplete: "off", defaultValue: values?.postalCode ?? '' })] }));
57
+ progress: _jsx(PrizmaStepper, { steps: 3, currentState: 2, showIcons: false, "aria-label": strings.stepperLabel }), title: copy.title, subtitle: copy.subtitle, ctaLabel: copy.ctaLabel, linkContent: _jsx(PrizmaButton, { variant: "secondary", size: "L", onClick: () => onAction?.({ type: 'secondary', screenId }), children: strings.backLabel }), verifiedLabel: strings.verifiedLabel, navLabel: strings.navLabel, screenId: screenId, overrides: { align: overrides?.align ?? 'left', logo: overrides?.logo }, onAction: onAction,
58
+ /* Exploration ekyb-desktop: on a wide frame only State + Postal code
59
+ share a row (Figma 6407:43637); the four text fields above span the
60
+ column. On the phone nothing changes. */
61
+ responsive: true, ...shell, children: [_jsx(PrizmaTextField, { label: copy.street.label, placeholder: copy.street.placeholder, required: true, requiredHint: strings.requiredHint, autoComplete: "off", defaultValue: values?.street ?? '' }), _jsx(PrizmaTextField, { label: copy.houseNumber.label, placeholder: copy.houseNumber.placeholder, required: true, requiredHint: strings.requiredHint, autoComplete: "off", defaultValue: values?.houseNumber ?? '' }), _jsx(PrizmaTextField, { label: copy.addressLine2.label, placeholder: copy.addressLine2.placeholder, autoComplete: "off", defaultValue: values?.addressLine2 ?? '' }), _jsx(PrizmaTextField, { label: copy.city.label, placeholder: copy.city.placeholder, required: true, requiredHint: strings.requiredHint, autoComplete: "off", defaultValue: values?.city ?? '' }), _jsxs(PrizmaFormRow, { children: [_jsx(PrizmaDropdown, { label: copy.state.label, placeholder: copy.state.placeholder, required: true, requiredHint: strings.requiredHint, options: states,
62
+ /* Both sections draw the placeholder unless the host supplies a
63
+ value — see the docstring note on 6340:38197. */
64
+ defaultValue: values?.state ?? null }), _jsx(PrizmaTextField, { label: copy.postalCode.label, placeholder: copy.postalCode.placeholder, required: true, requiredHint: strings.requiredHint, autoComplete: "off", defaultValue: values?.postalCode ?? '' })] })] }));
61
65
  });
62
66
  EkybAddressDetailsScreen.displayName = 'EkybAddressDetailsScreen';
63
67
  export default EkybAddressDetailsScreen;