@ankhorage/zora 2.5.5 → 2.6.1

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 (48) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +3 -1
  3. package/dist/components/progress/meta.d.ts +38 -3
  4. package/dist/components/progress/meta.d.ts.map +1 -1
  5. package/dist/components/progress/meta.js +39 -3
  6. package/dist/components/progress/meta.js.map +1 -1
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/metadata/componentMeta.d.ts.map +1 -1
  12. package/dist/metadata/componentMeta.js +3 -1
  13. package/dist/metadata/componentMeta.js.map +1 -1
  14. package/dist/patterns/auth/OAuthProviderButton.d.ts +10 -0
  15. package/dist/patterns/auth/OAuthProviderButton.d.ts.map +1 -0
  16. package/dist/patterns/auth/OAuthProviderButton.js +21 -0
  17. package/dist/patterns/auth/OAuthProviderButton.js.map +1 -0
  18. package/dist/patterns/auth/OAuthProviderList.d.ts +7 -0
  19. package/dist/patterns/auth/OAuthProviderList.d.ts.map +1 -0
  20. package/dist/patterns/auth/OAuthProviderList.js +16 -0
  21. package/dist/patterns/auth/OAuthProviderList.js.map +1 -0
  22. package/dist/patterns/auth/index.d.ts +4 -1
  23. package/dist/patterns/auth/index.d.ts.map +1 -1
  24. package/dist/patterns/auth/index.js +3 -0
  25. package/dist/patterns/auth/index.js.map +1 -1
  26. package/dist/patterns/auth/meta.d.ts +16 -0
  27. package/dist/patterns/auth/meta.d.ts.map +1 -1
  28. package/dist/patterns/auth/meta.js +16 -0
  29. package/dist/patterns/auth/meta.js.map +1 -1
  30. package/dist/patterns/auth/oauthProviders.d.ts +74 -0
  31. package/dist/patterns/auth/oauthProviders.d.ts.map +1 -0
  32. package/dist/patterns/auth/oauthProviders.js +66 -0
  33. package/dist/patterns/auth/oauthProviders.js.map +1 -0
  34. package/dist/patterns/auth/types.d.ts +38 -0
  35. package/dist/patterns/auth/types.d.ts.map +1 -1
  36. package/dist/patterns/auth/types.js.map +1 -1
  37. package/package.json +2 -2
  38. package/src/components/progress/meta.ts +39 -3
  39. package/src/index.ts +16 -1
  40. package/src/metadata/componentMeta.test.ts +12 -0
  41. package/src/metadata/componentMeta.ts +4 -0
  42. package/src/patterns/auth/OAuthProviderButton.tsx +51 -0
  43. package/src/patterns/auth/OAuthProviderList.tsx +54 -0
  44. package/src/patterns/auth/index.ts +12 -0
  45. package/src/patterns/auth/meta.ts +18 -0
  46. package/src/patterns/auth/oauthProviders.test.ts +31 -0
  47. package/src/patterns/auth/oauthProviders.ts +79 -0
  48. package/src/patterns/auth/types.ts +43 -0
@@ -1 +1 @@
1
- {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/patterns/auth/meta.ts"],"names":[],"mappings":"AAEA,MAAM,SAAS,GAAG,mEAAmE,CAAC;AAEtF,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,IAAI,EAAE,oBAAoB;IAC1B,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,EAAE;CAC2B,CAAC;AAEvC,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,EAAE;CAC2B,CAAC;AAEvC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,YAAY;IAClB,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,EAAE;CAC2B,CAAC;AAEvC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,YAAY;IAClB,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,EAAE;CAC2B,CAAC","sourcesContent":["import type { ZoraComponentMeta } from '../../metadata';\n\nconst AUTH_NOTE = 'Auth pattern component; not represented as a manifest node in v1.';\n\nexport const forgotPasswordFormMeta = {\n name: 'ForgotPasswordForm',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: AUTH_NOTE,\n props: {},\n} as const satisfies ZoraComponentMeta;\n\nexport const otpFormMeta = {\n name: 'OtpForm',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: AUTH_NOTE,\n props: {},\n} as const satisfies ZoraComponentMeta;\n\nexport const signInFormMeta = {\n name: 'SignInForm',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: AUTH_NOTE,\n props: {},\n} as const satisfies ZoraComponentMeta;\n\nexport const signUpFormMeta = {\n name: 'SignUpForm',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: AUTH_NOTE,\n props: {},\n} as const satisfies ZoraComponentMeta;\n"]}
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/patterns/auth/meta.ts"],"names":[],"mappings":"AAEA,MAAM,SAAS,GAAG,mEAAmE,CAAC;AAEtF,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,IAAI,EAAE,oBAAoB;IAC1B,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,EAAE;CAC2B,CAAC;AAEvC,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,EAAE;CAC2B,CAAC;AAEvC,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,mBAAmB;IACzB,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,EAAE;CAC2B,CAAC;AAEvC,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,EAAE;CAC2B,CAAC;AAEvC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,YAAY;IAClB,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,EAAE;CAC2B,CAAC;AAEvC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,YAAY;IAClB,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,EAAE;CAC2B,CAAC","sourcesContent":["import type { ZoraComponentMeta } from '../../metadata';\n\nconst AUTH_NOTE = 'Auth pattern component; not represented as a manifest node in v1.';\n\nexport const forgotPasswordFormMeta = {\n name: 'ForgotPasswordForm',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: AUTH_NOTE,\n props: {},\n} as const satisfies ZoraComponentMeta;\n\nexport const oauthProviderButtonMeta = {\n name: 'OAuthProviderButton',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: AUTH_NOTE,\n props: {},\n} as const satisfies ZoraComponentMeta;\n\nexport const oauthProviderListMeta = {\n name: 'OAuthProviderList',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: AUTH_NOTE,\n props: {},\n} as const satisfies ZoraComponentMeta;\n\nexport const otpFormMeta = {\n name: 'OtpForm',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: AUTH_NOTE,\n props: {},\n} as const satisfies ZoraComponentMeta;\n\nexport const signInFormMeta = {\n name: 'SignInForm',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: AUTH_NOTE,\n props: {},\n} as const satisfies ZoraComponentMeta;\n\nexport const signUpFormMeta = {\n name: 'SignUpForm',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: AUTH_NOTE,\n props: {},\n} as const satisfies ZoraComponentMeta;\n"]}
@@ -0,0 +1,74 @@
1
+ import type { OAuthProviderIconSpec } from './types';
2
+ export declare const DEFAULT_OAUTH_PROVIDER_ICONS: {
3
+ readonly apple: {
4
+ readonly provider: "FontAwesome";
5
+ readonly name: "apple";
6
+ };
7
+ readonly azure: {
8
+ readonly provider: "FontAwesome5";
9
+ readonly name: "microsoft";
10
+ };
11
+ readonly bitbucket: {
12
+ readonly provider: "FontAwesome";
13
+ readonly name: "bitbucket";
14
+ };
15
+ readonly discord: {
16
+ readonly provider: "FontAwesome5";
17
+ readonly name: "discord";
18
+ };
19
+ readonly facebook: {
20
+ readonly provider: "FontAwesome";
21
+ readonly name: "facebook";
22
+ };
23
+ readonly figma: {
24
+ readonly provider: "FontAwesome5";
25
+ readonly name: "figma";
26
+ };
27
+ readonly github: {
28
+ readonly provider: "FontAwesome";
29
+ readonly name: "github";
30
+ };
31
+ readonly gitlab: {
32
+ readonly provider: "FontAwesome5";
33
+ readonly name: "gitlab";
34
+ };
35
+ readonly google: {
36
+ readonly provider: "FontAwesome";
37
+ readonly name: "google";
38
+ };
39
+ readonly linkedin: {
40
+ readonly provider: "FontAwesome";
41
+ readonly name: "linkedin";
42
+ };
43
+ readonly microsoft: {
44
+ readonly provider: "FontAwesome5";
45
+ readonly name: "microsoft";
46
+ };
47
+ readonly slack: {
48
+ readonly provider: "FontAwesome5";
49
+ readonly name: "slack";
50
+ };
51
+ readonly spotify: {
52
+ readonly provider: "FontAwesome";
53
+ readonly name: "spotify";
54
+ };
55
+ readonly twitch: {
56
+ readonly provider: "FontAwesome5";
57
+ readonly name: "twitch";
58
+ };
59
+ readonly twitter: {
60
+ readonly provider: "FontAwesome";
61
+ readonly name: "twitter";
62
+ };
63
+ readonly x: {
64
+ readonly provider: "FontAwesome6";
65
+ readonly name: "x-twitter";
66
+ };
67
+ readonly zoom: {
68
+ readonly provider: "FontAwesome5";
69
+ readonly name: "video";
70
+ };
71
+ };
72
+ export declare function resolveOAuthProviderIcon(providerId: string): OAuthProviderIconSpec | undefined;
73
+ export declare function resolveOAuthProviderLabel(providerId: string): string;
74
+ //# sourceMappingURL=oauthProviders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauthProviders.d.ts","sourceRoot":"","sources":["../../../src/patterns/auth/oauthProviders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkBiB,CAAC;AA4B3D,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAM9F;AAED,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKpE"}
@@ -0,0 +1,66 @@
1
+ export const DEFAULT_OAUTH_PROVIDER_ICONS = {
2
+ apple: { provider: 'FontAwesome', name: 'apple' },
3
+ azure: { provider: 'FontAwesome5', name: 'microsoft' },
4
+ bitbucket: { provider: 'FontAwesome', name: 'bitbucket' },
5
+ discord: { provider: 'FontAwesome5', name: 'discord' },
6
+ facebook: { provider: 'FontAwesome', name: 'facebook' },
7
+ figma: { provider: 'FontAwesome5', name: 'figma' },
8
+ github: { provider: 'FontAwesome', name: 'github' },
9
+ gitlab: { provider: 'FontAwesome5', name: 'gitlab' },
10
+ google: { provider: 'FontAwesome', name: 'google' },
11
+ linkedin: { provider: 'FontAwesome', name: 'linkedin' },
12
+ microsoft: { provider: 'FontAwesome5', name: 'microsoft' },
13
+ slack: { provider: 'FontAwesome5', name: 'slack' },
14
+ spotify: { provider: 'FontAwesome', name: 'spotify' },
15
+ twitch: { provider: 'FontAwesome5', name: 'twitch' },
16
+ twitter: { provider: 'FontAwesome', name: 'twitter' },
17
+ x: { provider: 'FontAwesome6', name: 'x-twitter' },
18
+ zoom: { provider: 'FontAwesome5', name: 'video' },
19
+ };
20
+ const DEFAULT_OAUTH_PROVIDER_LABELS = {
21
+ apple: 'Apple',
22
+ azure: 'Microsoft',
23
+ bitbucket: 'Bitbucket',
24
+ discord: 'Discord',
25
+ facebook: 'Facebook',
26
+ figma: 'Figma',
27
+ github: 'GitHub',
28
+ gitlab: 'GitLab',
29
+ google: 'Google',
30
+ kakao: 'Kakao',
31
+ keycloak: 'Keycloak',
32
+ linkedin: 'LinkedIn',
33
+ microsoft: 'Microsoft',
34
+ notion: 'Notion',
35
+ slack: 'Slack',
36
+ spotify: 'Spotify',
37
+ twitch: 'Twitch',
38
+ twitter: 'Twitter',
39
+ workos: 'WorkOS',
40
+ x: 'X',
41
+ zoom: 'Zoom',
42
+ };
43
+ const oauthProviderLabels = DEFAULT_OAUTH_PROVIDER_LABELS;
44
+ export function resolveOAuthProviderIcon(providerId) {
45
+ const normalizedProviderId = normalizeOAuthProviderId(providerId);
46
+ return DEFAULT_OAUTH_PROVIDER_ICONS[normalizedProviderId];
47
+ }
48
+ export function resolveOAuthProviderLabel(providerId) {
49
+ const normalizedProviderId = normalizeOAuthProviderId(providerId);
50
+ const knownLabel = oauthProviderLabels[normalizedProviderId];
51
+ return knownLabel ?? titleCaseProviderId(normalizedProviderId);
52
+ }
53
+ function normalizeOAuthProviderId(providerId) {
54
+ return providerId.trim().toLowerCase();
55
+ }
56
+ function titleCaseProviderId(providerId) {
57
+ const words = providerId
58
+ .split(/[-_\s]+/u)
59
+ .map((word) => word.trim())
60
+ .filter((word) => word.length > 0);
61
+ if (words.length === 0) {
62
+ return 'Provider';
63
+ }
64
+ return words.map((word) => `${word.charAt(0).toUpperCase()}${word.slice(1)}`).join(' ');
65
+ }
66
+ //# sourceMappingURL=oauthProviders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauthProviders.js","sourceRoot":"","sources":["../../../src/patterns/auth/oauthProviders.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OAuthProviderIconSpec } from './types';\n\nexport const DEFAULT_OAUTH_PROVIDER_ICONS = {\n apple: { provider: 'FontAwesome', name: 'apple' },\n azure: { provider: 'FontAwesome5', name: 'microsoft' },\n bitbucket: { provider: 'FontAwesome', name: 'bitbucket' },\n discord: { provider: 'FontAwesome5', name: 'discord' },\n facebook: { provider: 'FontAwesome', name: 'facebook' },\n figma: { provider: 'FontAwesome5', name: 'figma' },\n github: { provider: 'FontAwesome', name: 'github' },\n gitlab: { provider: 'FontAwesome5', name: 'gitlab' },\n google: { provider: 'FontAwesome', name: 'google' },\n linkedin: { provider: 'FontAwesome', name: 'linkedin' },\n microsoft: { provider: 'FontAwesome5', name: 'microsoft' },\n slack: { provider: 'FontAwesome5', name: 'slack' },\n spotify: { provider: 'FontAwesome', name: 'spotify' },\n twitch: { provider: 'FontAwesome5', name: 'twitch' },\n twitter: { provider: 'FontAwesome', name: 'twitter' },\n x: { provider: 'FontAwesome6', name: 'x-twitter' },\n zoom: { provider: 'FontAwesome5', name: 'video' },\n} as const satisfies Record<string, OAuthProviderIconSpec>;\n\nconst DEFAULT_OAUTH_PROVIDER_LABELS = {\n apple: 'Apple',\n azure: 'Microsoft',\n bitbucket: 'Bitbucket',\n discord: 'Discord',\n facebook: 'Facebook',\n figma: 'Figma',\n github: 'GitHub',\n gitlab: 'GitLab',\n google: 'Google',\n kakao: 'Kakao',\n keycloak: 'Keycloak',\n linkedin: 'LinkedIn',\n microsoft: 'Microsoft',\n notion: 'Notion',\n slack: 'Slack',\n spotify: 'Spotify',\n twitch: 'Twitch',\n twitter: 'Twitter',\n workos: 'WorkOS',\n x: 'X',\n zoom: 'Zoom',\n} as const satisfies Record<string, string>;\n\nconst oauthProviderLabels: Partial<Record<string, string>> = DEFAULT_OAUTH_PROVIDER_LABELS;\n\nexport function resolveOAuthProviderIcon(providerId: string): OAuthProviderIconSpec | undefined {\n const normalizedProviderId = normalizeOAuthProviderId(providerId);\n\n return DEFAULT_OAUTH_PROVIDER_ICONS[\n normalizedProviderId as keyof typeof DEFAULT_OAUTH_PROVIDER_ICONS\n ];\n}\n\nexport function resolveOAuthProviderLabel(providerId: string): string {\n const normalizedProviderId = normalizeOAuthProviderId(providerId);\n const knownLabel = oauthProviderLabels[normalizedProviderId];\n\n return knownLabel ?? titleCaseProviderId(normalizedProviderId);\n}\n\nfunction normalizeOAuthProviderId(providerId: string): string {\n return providerId.trim().toLowerCase();\n}\n\nfunction titleCaseProviderId(providerId: string): string {\n const words = providerId\n .split(/[-_\\s]+/u)\n .map((word) => word.trim())\n .filter((word) => word.length > 0);\n\n if (words.length === 0) {\n return 'Provider';\n }\n\n return words.map((word) => `${word.charAt(0).toUpperCase()}${word.slice(1)}`).join(' ');\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import type React from 'react';
2
+ import type { ButtonProps } from '../../components/button';
2
3
  import type { FormFieldConfig, FormValues } from '../../components/form';
3
4
  import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
4
5
  export type AuthIdentifierKind = 'email' | 'phone' | 'username';
@@ -54,4 +55,41 @@ export interface OtpFormProps extends AuthFormBaseProps {
54
55
  onSubmit: (values: OtpFormValues) => void | Promise<void>;
55
56
  onResend?: () => void | Promise<void>;
56
57
  }
58
+ export interface OAuthProviderIconSpec {
59
+ name: string;
60
+ provider?: string;
61
+ size?: number | string;
62
+ color?: string;
63
+ }
64
+ export interface OAuthProviderItem {
65
+ id: string;
66
+ label?: React.ReactNode;
67
+ icon?: OAuthProviderIconSpec;
68
+ disabled?: boolean;
69
+ loading?: boolean;
70
+ }
71
+ export interface OAuthProviderButtonProps extends ZoraBaseProps {
72
+ providerId: string;
73
+ label?: React.ReactNode;
74
+ icon?: OAuthProviderIconSpec;
75
+ disabled?: boolean;
76
+ loading?: boolean;
77
+ fullWidth?: boolean;
78
+ size?: ButtonProps['size'];
79
+ variant?: ButtonProps['variant'];
80
+ color?: ButtonProps['color'];
81
+ onPress?: (providerId: string) => void | Promise<void>;
82
+ }
83
+ export type OAuthProviderListLayout = 'stack' | 'inline';
84
+ export interface OAuthProviderListProps extends ZoraBaseProps {
85
+ providers: readonly OAuthProviderItem[];
86
+ disabled?: boolean;
87
+ loading?: boolean;
88
+ fullWidth?: boolean;
89
+ layout?: OAuthProviderListLayout;
90
+ size?: ButtonProps['size'];
91
+ variant?: ButtonProps['variant'];
92
+ color?: ButtonProps['color'];
93
+ onProviderPress?: (providerId: string) => void | Promise<void>;
94
+ }
57
95
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/auth/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/auth/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/auth/types.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\n\nimport type { FormFieldConfig, FormValues } from '../../components/form';\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport type AuthIdentifierKind = 'email' | 'phone' | 'username';\n\nexport interface AuthFormBaseProps extends ZoraBaseProps {\n loading?: boolean;\n disabled?: boolean;\n error?: React.ReactNode;\n submitLabel?: React.ReactNode;\n}\n\nexport interface SignInFormValues {\n identifier: string;\n identifierKind: AuthIdentifierKind;\n secret: string;\n}\n\nexport interface SignInFormProps extends AuthFormBaseProps {\n identifiers?: readonly AuthIdentifierKind[];\n identifierLabel?: React.ReactNode;\n secretLabel?: React.ReactNode;\n forgotPasswordLabel?: React.ReactNode;\n signUpLabel?: React.ReactNode;\n onSubmit: (values: SignInFormValues) => void | Promise<void>;\n onForgotPassword?: () => void | Promise<void>;\n onSignUp?: () => void | Promise<void>;\n}\n\nexport type SignUpFormValues = FormValues;\nexport type SignUpFormField = FormFieldConfig;\n\nexport interface SignUpFormProps extends AuthFormBaseProps {\n fields?: readonly SignUpFormField[];\n signInLabel?: React.ReactNode;\n onSubmit: (values: SignUpFormValues) => void | Promise<void>;\n onSignIn?: () => void | Promise<void>;\n}\n\nexport interface ForgotPasswordFormValues {\n identifier: string;\n identifierKind: AuthIdentifierKind;\n}\n\nexport interface ForgotPasswordFormProps extends AuthFormBaseProps {\n identifiers?: readonly AuthIdentifierKind[];\n identifierLabel?: React.ReactNode;\n signInLabel?: React.ReactNode;\n onSubmit: (values: ForgotPasswordFormValues) => void | Promise<void>;\n onSignIn?: () => void | Promise<void>;\n}\n\nexport interface OtpFormValues {\n otp: string;\n}\n\nexport interface OtpFormProps extends AuthFormBaseProps {\n length?: number;\n otpLabel?: React.ReactNode;\n resendLabel?: React.ReactNode;\n resendDisabled?: boolean;\n resendLoading?: boolean;\n onSubmit: (values: OtpFormValues) => void | Promise<void>;\n onResend?: () => void | Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/auth/types.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\n\nimport type { ButtonProps } from '../../components/button';\nimport type { FormFieldConfig, FormValues } from '../../components/form';\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport type AuthIdentifierKind = 'email' | 'phone' | 'username';\n\nexport interface AuthFormBaseProps extends ZoraBaseProps {\n loading?: boolean;\n disabled?: boolean;\n error?: React.ReactNode;\n submitLabel?: React.ReactNode;\n}\n\nexport interface SignInFormValues {\n identifier: string;\n identifierKind: AuthIdentifierKind;\n secret: string;\n}\n\nexport interface SignInFormProps extends AuthFormBaseProps {\n identifiers?: readonly AuthIdentifierKind[];\n identifierLabel?: React.ReactNode;\n secretLabel?: React.ReactNode;\n forgotPasswordLabel?: React.ReactNode;\n signUpLabel?: React.ReactNode;\n onSubmit: (values: SignInFormValues) => void | Promise<void>;\n onForgotPassword?: () => void | Promise<void>;\n onSignUp?: () => void | Promise<void>;\n}\n\nexport type SignUpFormValues = FormValues;\nexport type SignUpFormField = FormFieldConfig;\n\nexport interface SignUpFormProps extends AuthFormBaseProps {\n fields?: readonly SignUpFormField[];\n signInLabel?: React.ReactNode;\n onSubmit: (values: SignUpFormValues) => void | Promise<void>;\n onSignIn?: () => void | Promise<void>;\n}\n\nexport interface ForgotPasswordFormValues {\n identifier: string;\n identifierKind: AuthIdentifierKind;\n}\n\nexport interface ForgotPasswordFormProps extends AuthFormBaseProps {\n identifiers?: readonly AuthIdentifierKind[];\n identifierLabel?: React.ReactNode;\n signInLabel?: React.ReactNode;\n onSubmit: (values: ForgotPasswordFormValues) => void | Promise<void>;\n onSignIn?: () => void | Promise<void>;\n}\n\nexport interface OtpFormValues {\n otp: string;\n}\n\nexport interface OtpFormProps extends AuthFormBaseProps {\n length?: number;\n otpLabel?: React.ReactNode;\n resendLabel?: React.ReactNode;\n resendDisabled?: boolean;\n resendLoading?: boolean;\n onSubmit: (values: OtpFormValues) => void | Promise<void>;\n onResend?: () => void | Promise<void>;\n}\n\nexport interface OAuthProviderIconSpec {\n name: string;\n provider?: string;\n size?: number | string;\n color?: string;\n}\n\nexport interface OAuthProviderItem {\n id: string;\n label?: React.ReactNode;\n icon?: OAuthProviderIconSpec;\n disabled?: boolean;\n loading?: boolean;\n}\n\nexport interface OAuthProviderButtonProps extends ZoraBaseProps {\n providerId: string;\n label?: React.ReactNode;\n icon?: OAuthProviderIconSpec;\n disabled?: boolean;\n loading?: boolean;\n fullWidth?: boolean;\n size?: ButtonProps['size'];\n variant?: ButtonProps['variant'];\n color?: ButtonProps['color'];\n onPress?: (providerId: string) => void | Promise<void>;\n}\n\nexport type OAuthProviderListLayout = 'stack' | 'inline';\n\nexport interface OAuthProviderListProps extends ZoraBaseProps {\n providers: readonly OAuthProviderItem[];\n disabled?: boolean;\n loading?: boolean;\n fullWidth?: boolean;\n layout?: OAuthProviderListLayout;\n size?: ButtonProps['size'];\n variant?: ButtonProps['variant'];\n color?: ButtonProps['color'];\n onProviderPress?: (providerId: string) => void | Promise<void>;\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/zora",
3
3
  "type": "module",
4
- "version": "2.5.5",
4
+ "version": "2.6.1",
5
5
  "description": "Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.",
6
6
  "homepage": "https://github.com/ankhorage/zora#readme",
7
7
  "bugs": {
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "@ankhorage/color-theory": "^0.0.7",
51
- "@ankhorage/contracts": "^1.13.0",
51
+ "@ankhorage/contracts": "^1.15.0",
52
52
  "@ankhorage/surface": "^2.0.2"
53
53
  },
54
54
  "files": [
@@ -1,10 +1,46 @@
1
+ import { ZORA_COLORS } from '../../internal/colorModel';
1
2
  import type { ZoraComponentMeta } from '../../metadata';
2
3
 
3
4
  export const progressMeta = {
4
5
  name: 'Progress',
5
6
  category: 'component',
6
- directManifestNode: false,
7
+ directManifestNode: true,
7
8
  allowedChildren: [],
8
- note: 'Feedback component; not represented as a manifest node in v1.',
9
- props: {},
9
+ blueprint: {
10
+ label: 'Progress',
11
+ defaultProps: {
12
+ value: 50,
13
+ max: 100,
14
+ color: 'primary',
15
+ size: 'm',
16
+ },
17
+ },
18
+ props: {
19
+ value: {
20
+ type: 'number',
21
+ category: 'State',
22
+ label: 'Value',
23
+ default: 50,
24
+ },
25
+ max: {
26
+ type: 'number',
27
+ category: 'State',
28
+ label: 'Max',
29
+ default: 100,
30
+ },
31
+ color: {
32
+ type: 'enum',
33
+ category: 'Style',
34
+ label: 'Color',
35
+ enum: [...ZORA_COLORS],
36
+ default: 'primary',
37
+ },
38
+ size: {
39
+ type: 'enum',
40
+ category: 'Style',
41
+ label: 'Size',
42
+ enum: ['s', 'm', 'l'],
43
+ default: 'm',
44
+ },
45
+ },
10
46
  } as const satisfies ZoraComponentMeta;
package/src/index.ts CHANGED
@@ -225,6 +225,11 @@ export type {
225
225
  AuthIdentifierKind,
226
226
  ForgotPasswordFormProps,
227
227
  ForgotPasswordFormValues,
228
+ OAuthProviderButtonProps,
229
+ OAuthProviderIconSpec,
230
+ OAuthProviderItem,
231
+ OAuthProviderListLayout,
232
+ OAuthProviderListProps,
228
233
  OtpFormProps,
229
234
  OtpFormValues,
230
235
  SignInFormProps,
@@ -233,7 +238,17 @@ export type {
233
238
  SignUpFormProps,
234
239
  SignUpFormValues,
235
240
  } from './patterns/auth';
236
- export { ForgotPasswordForm, OtpForm, SignInForm, SignUpForm } from './patterns/auth';
241
+ export {
242
+ DEFAULT_OAUTH_PROVIDER_ICONS,
243
+ ForgotPasswordForm,
244
+ OAuthProviderButton,
245
+ OAuthProviderList,
246
+ OtpForm,
247
+ resolveOAuthProviderIcon,
248
+ resolveOAuthProviderLabel,
249
+ SignInForm,
250
+ SignUpForm,
251
+ } from './patterns/auth';
237
252
  export type { ChatListAvatar, ChatListItemProps } from './patterns/chat-list-item';
238
253
  export { ChatListItem } from './patterns/chat-list-item';
239
254
  export type {
@@ -177,6 +177,7 @@ describe('ZORA_COMPONENT_META invariants', () => {
177
177
  'Heading',
178
178
  'Divider',
179
179
  'ChatListItem',
180
+ 'Progress',
180
181
  ]);
181
182
 
182
183
  const expectedContainerNodes = new Set([
@@ -217,6 +218,17 @@ describe('ZORA_COMPONENT_META invariants', () => {
217
218
  }
218
219
  });
219
220
 
221
+ test('Progress is a direct manifest leaf with serializable defaults', () => {
222
+ expect(ZORA_COMPONENT_META.Progress.directManifestNode).toBe(true);
223
+ expect(ZORA_COMPONENT_META.Progress.allowedChildren).toEqual([]);
224
+ expect(ZORA_COMPONENT_META.Progress.blueprint?.defaultProps).toEqual({
225
+ value: 50,
226
+ max: 100,
227
+ color: 'primary',
228
+ size: 'm',
229
+ });
230
+ });
231
+
220
232
  test('non-direct manifest nodes include an explicit note', () => {
221
233
  for (const [key, meta] of Object.entries(ZORA_COMPONENT_META)) {
222
234
  if (meta.directManifestNode) continue;
@@ -54,6 +54,8 @@ import { sidebarLayoutMeta } from '../layout/sidebar-layout/meta';
54
54
  import { topbarLayoutMeta } from '../layout/topbar-layout/meta';
55
55
  import {
56
56
  forgotPasswordFormMeta,
57
+ oauthProviderButtonMeta,
58
+ oauthProviderListMeta,
57
59
  otpFormMeta,
58
60
  signInFormMeta,
59
61
  signUpFormMeta,
@@ -149,6 +151,8 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = {
149
151
  SidebarLayout: sidebarLayoutMeta,
150
152
  TopbarLayout: topbarLayoutMeta,
151
153
  ForgotPasswordForm: forgotPasswordFormMeta,
154
+ OAuthProviderButton: oauthProviderButtonMeta,
155
+ OAuthProviderList: oauthProviderListMeta,
152
156
  OtpForm: otpFormMeta,
153
157
  SignInForm: signInFormMeta,
154
158
  SignUpForm: signUpFormMeta,
@@ -0,0 +1,51 @@
1
+ import React from 'react';
2
+
3
+ import { Button } from '../../components/button';
4
+ import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
5
+ import { resolveOAuthProviderIcon, resolveOAuthProviderLabel } from './oauthProviders';
6
+ import type { OAuthProviderButtonProps } from './types';
7
+
8
+ function OAuthProviderButtonInner({
9
+ themeId: _themeId,
10
+ mode: _mode,
11
+ providerId,
12
+ label,
13
+ icon,
14
+ disabled = false,
15
+ loading = false,
16
+ fullWidth = true,
17
+ size = 'l',
18
+ variant = 'outline',
19
+ color = 'neutral',
20
+ onPress,
21
+ testID,
22
+ }: OAuthProviderButtonProps) {
23
+ const resolvedIcon = icon ?? resolveOAuthProviderIcon(providerId);
24
+ const resolvedLabel = label ?? `Continue with ${resolveOAuthProviderLabel(providerId)}`;
25
+
26
+ return (
27
+ <Button
28
+ color={color}
29
+ disabled={disabled || loading || onPress === undefined}
30
+ fullWidth={fullWidth}
31
+ leadingIcon={resolvedIcon}
32
+ loading={loading}
33
+ onPress={() => {
34
+ void onPress?.(providerId);
35
+ }}
36
+ size={size}
37
+ testID={testID}
38
+ variant={variant}
39
+ >
40
+ {resolvedLabel}
41
+ </Button>
42
+ );
43
+ }
44
+
45
+ /***
46
+ * Renders a provider-branded OAuth action button without owning auth behavior.
47
+ *
48
+ * The component only renders UI and forwards the provider id through `onPress`.
49
+ * Adapters, redirects, and callback handling belong to app/runtime layers.
50
+ */
51
+ export const OAuthProviderButton = withZoraThemeScope(OAuthProviderButtonInner);
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+
3
+ import { Stack } from '../../foundation';
4
+ import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
5
+ import { OAuthProviderButton } from './OAuthProviderButton';
6
+ import type { OAuthProviderListProps } from './types';
7
+
8
+ function OAuthProviderListInner({
9
+ themeId: _themeId,
10
+ mode: _mode,
11
+ providers,
12
+ disabled = false,
13
+ loading = false,
14
+ fullWidth,
15
+ layout = 'stack',
16
+ size,
17
+ variant,
18
+ color,
19
+ onProviderPress,
20
+ testID,
21
+ }: OAuthProviderListProps) {
22
+ const direction = layout === 'inline' ? 'row' : 'column';
23
+ const resolvedFullWidth = fullWidth ?? layout === 'stack';
24
+
25
+ return (
26
+ <Stack
27
+ direction={direction}
28
+ gap="s"
29
+ testID={testID}
30
+ wrap={layout === 'inline' ? 'wrap' : undefined}
31
+ >
32
+ {providers.map((provider) => (
33
+ <OAuthProviderButton
34
+ color={color}
35
+ disabled={disabled || provider.disabled}
36
+ fullWidth={resolvedFullWidth}
37
+ icon={provider.icon}
38
+ key={provider.id}
39
+ label={provider.label}
40
+ loading={loading || provider.loading}
41
+ onPress={onProviderPress}
42
+ providerId={provider.id}
43
+ size={size}
44
+ variant={variant}
45
+ />
46
+ ))}
47
+ </Stack>
48
+ );
49
+ }
50
+
51
+ /***
52
+ * Renders a group of OAuth provider buttons for sign-in and auth settings flows.
53
+ */
54
+ export const OAuthProviderList = withZoraThemeScope(OAuthProviderListInner);
@@ -1,4 +1,11 @@
1
1
  export { ForgotPasswordForm } from './ForgotPasswordForm';
2
+ export { OAuthProviderButton } from './OAuthProviderButton';
3
+ export { OAuthProviderList } from './OAuthProviderList';
4
+ export {
5
+ DEFAULT_OAUTH_PROVIDER_ICONS,
6
+ resolveOAuthProviderIcon,
7
+ resolveOAuthProviderLabel,
8
+ } from './oauthProviders';
2
9
  export { OtpForm } from './OtpForm';
3
10
  export { SignInForm } from './SignInForm';
4
11
  export { SignUpForm } from './SignUpForm';
@@ -7,6 +14,11 @@ export type {
7
14
  AuthIdentifierKind,
8
15
  ForgotPasswordFormProps,
9
16
  ForgotPasswordFormValues,
17
+ OAuthProviderButtonProps,
18
+ OAuthProviderIconSpec,
19
+ OAuthProviderItem,
20
+ OAuthProviderListLayout,
21
+ OAuthProviderListProps,
10
22
  OtpFormProps,
11
23
  OtpFormValues,
12
24
  SignInFormProps,
@@ -11,6 +11,24 @@ export const forgotPasswordFormMeta = {
11
11
  props: {},
12
12
  } as const satisfies ZoraComponentMeta;
13
13
 
14
+ export const oauthProviderButtonMeta = {
15
+ name: 'OAuthProviderButton',
16
+ category: 'pattern',
17
+ directManifestNode: false,
18
+ allowedChildren: [],
19
+ note: AUTH_NOTE,
20
+ props: {},
21
+ } as const satisfies ZoraComponentMeta;
22
+
23
+ export const oauthProviderListMeta = {
24
+ name: 'OAuthProviderList',
25
+ category: 'pattern',
26
+ directManifestNode: false,
27
+ allowedChildren: [],
28
+ note: AUTH_NOTE,
29
+ props: {},
30
+ } as const satisfies ZoraComponentMeta;
31
+
14
32
  export const otpFormMeta = {
15
33
  name: 'OtpForm',
16
34
  category: 'pattern',
@@ -0,0 +1,31 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+
3
+ import {
4
+ DEFAULT_OAUTH_PROVIDER_ICONS,
5
+ resolveOAuthProviderIcon,
6
+ resolveOAuthProviderLabel,
7
+ } from './oauthProviders';
8
+
9
+ describe('OAuth provider UI helpers', () => {
10
+ it('resolves known provider labels', () => {
11
+ expect(resolveOAuthProviderLabel('google')).toBe('Google');
12
+ expect(resolveOAuthProviderLabel('github')).toBe('GitHub');
13
+ expect(resolveOAuthProviderLabel('linkedin')).toBe('LinkedIn');
14
+ });
15
+
16
+ it('formats custom provider labels', () => {
17
+ expect(resolveOAuthProviderLabel('custom-sso')).toBe('Custom Sso');
18
+ expect(resolveOAuthProviderLabel(' enterprise_idp ')).toBe('Enterprise Idp');
19
+ expect(resolveOAuthProviderLabel('')).toBe('Provider');
20
+ });
21
+
22
+ it('resolves known provider icons', () => {
23
+ expect(resolveOAuthProviderIcon('google')).toEqual({ provider: 'FontAwesome', name: 'google' });
24
+ expect(resolveOAuthProviderIcon('github')).toEqual({ provider: 'FontAwesome', name: 'github' });
25
+ expect(DEFAULT_OAUTH_PROVIDER_ICONS.apple).toEqual({ provider: 'FontAwesome', name: 'apple' });
26
+ });
27
+
28
+ it('returns undefined for custom provider icons', () => {
29
+ expect(resolveOAuthProviderIcon('custom-sso')).toBeUndefined();
30
+ });
31
+ });