@ankhorage/zora 2.8.3 → 2.8.5
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/CHANGELOG.md +12 -0
- package/README.md +1 -2
- package/dist/components/avatar/Avatar.d.ts.map +1 -1
- package/dist/components/avatar/Avatar.js +16 -8
- package/dist/components/avatar/Avatar.js.map +1 -1
- package/dist/components/date-picker/DatePicker.d.ts.map +1 -1
- package/dist/components/date-picker/DatePicker.js +16 -7
- package/dist/components/date-picker/DatePicker.js.map +1 -1
- package/dist/components/form/useFormController.d.ts.map +1 -1
- package/dist/components/form/useFormController.js +4 -4
- package/dist/components/form/useFormController.js.map +1 -1
- package/dist/components/heading/resolveHeadingRecipe.d.ts.map +1 -1
- package/dist/components/heading/resolveHeadingRecipe.js +18 -2
- package/dist/components/heading/resolveHeadingRecipe.js.map +1 -1
- package/dist/components/text/resolveTextRecipe.d.ts.map +1 -1
- package/dist/components/text/resolveTextRecipe.js +18 -2
- package/dist/components/text/resolveTextRecipe.js.map +1 -1
- package/dist/patterns/auth/oauthProviders.d.ts.map +1 -1
- package/dist/patterns/auth/oauthProviders.js +4 -4
- package/dist/patterns/auth/oauthProviders.js.map +1 -1
- package/dist/patterns/auth/utils.d.ts.map +1 -1
- package/dist/patterns/auth/utils.js +13 -7
- package/dist/patterns/auth/utils.js.map +1 -1
- package/dist/patterns/image-upload-field/uploadFlow.js +1 -1
- package/dist/patterns/image-upload-field/uploadFlow.js.map +1 -1
- package/dist/patterns/selection/resolveSelectionNextIds.js +1 -1
- package/dist/patterns/selection/resolveSelectionNextIds.js.map +1 -1
- package/dist/patterns/theme-composer/ThemeComposer.d.ts +1 -1
- package/dist/patterns/theme-composer/ThemeComposer.d.ts.map +1 -1
- package/dist/patterns/theme-composer/ThemeComposer.js +37 -40
- package/dist/patterns/theme-composer/ThemeComposer.js.map +1 -1
- package/dist/theme/useZoraTheme.d.ts +1 -1
- package/package.json +3 -3
- package/src/components/avatar/Avatar.tsx +16 -8
- package/src/components/date-picker/DatePicker.tsx +18 -7
- package/src/components/form/useFormController.ts +6 -4
- package/src/components/heading/resolveHeadingRecipe.ts +20 -2
- package/src/components/text/resolveTextRecipe.test.ts +20 -2
- package/src/components/text/resolveTextRecipe.ts +20 -2
- package/src/metadata/componentMeta.test.ts +5 -3
- package/src/nativePeerContract.test.ts +11 -1
- package/src/patterns/auth/oauthProviders.ts +6 -7
- package/src/patterns/auth/utils.ts +13 -7
- package/src/patterns/image-upload-field/uploadFlow.ts +1 -1
- package/src/patterns/selection/resolveSelectionNextIds.ts +1 -1
- package/src/patterns/theme-composer/ThemeComposer.tsx +48 -41
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/patterns/auth/utils.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAO,CAAkD,CAAC;AAE7F,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/patterns/auth/utils.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAO,CAAkD,CAAC;AAE7F,SAAS,0BAA0B,CAAC,UAA8B;IAChE,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB,KAAK,OAAO,CAAC;QACb;YACE,OAAO,OAAO,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CACzB,WAA0C,EAC1C,UAA8B;IAE9B,OAAO,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,WAA0C;IAC/E,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,0BAA0B,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,WAAW,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,WAA0C;IAE1C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC;IAEjC,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,WAA0C;IAE1C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QAC3D,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,UAAkB,EAClB,WAA0C;IAE1C,MAAM,oBAAoB,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;IAE/C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;IACnC,CAAC;IAED,IAAI,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,oBAAoB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC5F,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,kBAAkB,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC;QAChD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;AACnC,CAAC","sourcesContent":["import type { FormFieldConfig, ValidationRule } from '../../components/form';\nimport type { AuthIdentifierKind } from './types';\n\nexport const defaultIdentifiers = ['email'] as const satisfies readonly AuthIdentifierKind[];\n\nfunction resolveIdentifierKindLabel(identifier: AuthIdentifierKind): string {\n switch (identifier) {\n case 'phone':\n return 'Phone';\n case 'username':\n return 'Username';\n case 'email':\n default:\n return 'Email';\n }\n}\n\nfunction includesIdentifier(\n identifiers: readonly AuthIdentifierKind[],\n identifier: AuthIdentifierKind,\n): boolean {\n return identifiers.includes(identifier);\n}\n\nexport function resolveIdentifierLabel(identifiers: readonly AuthIdentifierKind[]): string {\n if (identifiers.length === 1) {\n return resolveIdentifierKindLabel(identifiers[0] ?? 'email');\n }\n\n return identifiers.map(resolveIdentifierKindLabel).join(', or ');\n}\n\nexport function resolveIdentifierType(\n identifiers: readonly AuthIdentifierKind[],\n): FormFieldConfig['type'] {\n if (identifiers.length !== 1) {\n return 'text';\n }\n\n const [identifier] = identifiers;\n\n if (identifier === 'email') {\n return 'email';\n }\n\n if (identifier === 'phone') {\n return 'tel';\n }\n\n return 'text';\n}\n\nexport function resolveIdentifierRules(\n identifiers: readonly AuthIdentifierKind[],\n): readonly ValidationRule[] {\n if (identifiers.length === 1 && identifiers[0] === 'email') {\n return [{ kind: 'required' }, { kind: 'email' }];\n }\n\n return [{ kind: 'required' }];\n}\n\nexport function normalizeIdentifierKind(\n identifier: string,\n identifiers: readonly AuthIdentifierKind[],\n): AuthIdentifierKind {\n const normalizedIdentifier = identifier.trim();\n\n if (identifiers.length === 1) {\n return identifiers[0] ?? 'email';\n }\n\n if (includesIdentifier(identifiers, 'email') && normalizedIdentifier.includes('@')) {\n return 'email';\n }\n\n if (includesIdentifier(identifiers, 'phone') && /^[+()\\d\\s.-]+$/.test(normalizedIdentifier)) {\n return 'phone';\n }\n\n if (includesIdentifier(identifiers, 'username')) {\n return 'username';\n }\n\n return identifiers[0] ?? 'email';\n}\n"]}
|
|
@@ -52,7 +52,7 @@ function formatBytes(value) {
|
|
|
52
52
|
size /= 1024;
|
|
53
53
|
unitIndex += 1;
|
|
54
54
|
}
|
|
55
|
-
const unit = units
|
|
55
|
+
const unit = units.at(unitIndex) ?? 'B';
|
|
56
56
|
const rounded = unitIndex === 0 ? Math.round(size) : Math.round(size * 10) / 10;
|
|
57
57
|
return `${rounded} ${unit}`;
|
|
58
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadFlow.js","sourceRoot":"","sources":["../../../src/patterns/image-upload-field/uploadFlow.ts"],"names":[],"mappings":"AAGA,SAAS,WAAW,CAAC,MAA0B;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAEvB,OAAO,MAAM;SACV,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,kBAAkB,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,QAAQ,GAKT;IACC,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,qBAAqB,GAAG,WAAW,EAAE,WAAW,EAAE,CAAC;IACzD,MAAM,kBAAkB,GAAG,QAAQ,EAAE,WAAW,EAAE,CAAC;IAEnD,IAAI,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,kBAAkB;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,kBAAkB,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,qBAAqB;YAAE,OAAO,IAAI,CAAC;QACxC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACjF,OAAO,qBAAqB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,CAAC,qBAAqB;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,qBAAqB,KAAK,eAAe,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EACzB,MAAM,EACN,WAAW,EACX,QAAQ,GAKT;IACC,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,kBAAkB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrE,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QAED,SAAS,GAAG,IAAI,CAAC;QACjB,IAAI,OAAO;YAAE,OAAO,IAAI,CAAC;IAC3B,CAAC;IAED,+DAA+D;IAC/D,OAAO,CAAC,SAAS,CAAC;AACpB,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAExD,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;IAC/C,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,OAAO,IAAI,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,IAAI,IAAI,IAAI,CAAC;QACb,SAAS,IAAI,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"uploadFlow.js","sourceRoot":"","sources":["../../../src/patterns/image-upload-field/uploadFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ZoraImageAsset } from '../image-preview';\nimport type { ZoraPickedImage } from './types';\n\nfunction parseAccept(accept: string | undefined): readonly string[] {\n if (!accept) return [];\n\n return accept\n .split(',')\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n}\n\nfunction matchesAcceptToken({\n token,\n contentType,\n fileName,\n}: {\n token: string;\n contentType: string | undefined;\n fileName: string | undefined;\n}): boolean | null {\n const normalizedToken = token.toLowerCase();\n const normalizedContentType = contentType?.toLowerCase();\n const normalizedFileName = fileName?.toLowerCase();\n\n if (normalizedToken.startsWith('.')) {\n if (!normalizedFileName) return null;\n return normalizedFileName.endsWith(normalizedToken);\n }\n\n if (normalizedToken.endsWith('/*')) {\n if (!normalizedContentType) return null;\n const prefix = normalizedToken.slice(0, Math.max(0, normalizedToken.length - 1));\n return normalizedContentType.startsWith(prefix);\n }\n\n if (!normalizedContentType) return null;\n return normalizedContentType === normalizedToken;\n}\n\nexport function isAccepted({\n accept,\n contentType,\n fileName,\n}: {\n accept: string | undefined;\n contentType: string | undefined;\n fileName: string | undefined;\n}): boolean {\n const tokens = parseAccept(accept);\n if (tokens.length === 0) return true;\n\n let hadSignal = false;\n\n for (const token of tokens) {\n const matches = matchesAcceptToken({ token, contentType, fileName });\n if (matches === null) {\n continue;\n }\n\n hadSignal = true;\n if (matches) return true;\n }\n\n // If we cannot validate due to missing metadata, do not block.\n return !hadSignal;\n}\n\nfunction formatBytes(value: number): string {\n if (!Number.isFinite(value) || value <= 0) return '0 B';\n\n const units = ['B', 'KB', 'MB', 'GB'] as const;\n let size = value;\n let unitIndex = 0;\n\n while (size >= 1024 && unitIndex < units.length - 1) {\n size /= 1024;\n unitIndex += 1;\n }\n\n const unit = units.at(unitIndex) ?? 'B';\n const rounded = unitIndex === 0 ? Math.round(size) : Math.round(size * 10) / 10;\n return `${rounded} ${unit}`;\n}\n\nexport function formatAcceptHint(accept: string | undefined): string | null {\n const tokens = parseAccept(accept);\n if (tokens.length === 0) return null;\n return `Accepted: ${tokens.join(', ')}`;\n}\n\nexport function formatMaxSizeHint(maxSizeBytes: number | undefined): string | null {\n if (maxSizeBytes === undefined) return null;\n if (!Number.isFinite(maxSizeBytes) || maxSizeBytes <= 0) return null;\n return `Max size: ${formatBytes(maxSizeBytes)}`;\n}\n\nexport function createOptimisticAssetFromPicked(picked: ZoraPickedImage): ZoraImageAsset {\n return {\n kind: 'url',\n url: picked.uri,\n width: picked.width,\n height: picked.height,\n contentType: picked.contentType,\n metadata: {\n fileName: picked.fileName,\n sizeBytes: picked.sizeBytes,\n },\n };\n}\n\nexport function resolveRenderableUrl(asset: ZoraImageAsset | null): string | null {\n if (!asset) return null;\n if (asset.kind === 'url') return asset.url;\n return asset.publicUrl ?? null;\n}\n\nexport function validatePickedImage({\n picked,\n accept,\n maxSizeBytes,\n validatePicked,\n}: {\n picked: ZoraPickedImage;\n accept: string | undefined;\n maxSizeBytes: number | undefined;\n validatePicked: ((picked: ZoraPickedImage) => string | undefined) | undefined;\n}): string | undefined {\n if (!isAccepted({ accept, contentType: picked.contentType, fileName: picked.fileName })) {\n return accept ? `File type not accepted. Expected ${accept}.` : 'File type not accepted.';\n }\n\n if (\n maxSizeBytes !== undefined &&\n Number.isFinite(maxSizeBytes) &&\n maxSizeBytes > 0 &&\n picked.sizeBytes !== undefined &&\n Number.isFinite(picked.sizeBytes) &&\n picked.sizeBytes > maxSizeBytes\n ) {\n return `File is too large (${formatBytes(picked.sizeBytes)}). Max ${formatBytes(maxSizeBytes)}.`;\n }\n\n return validatePicked?.(picked);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveSelectionNextIds.js","sourceRoot":"","sources":["../../../src/patterns/selection/resolveSelectionNextIds.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAC1B,GAAkC,EAClC,IAAmB;IAEnB,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAS;QAC3B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,IAAI,IAAI,KAAK,QAAQ;YAAE,MAAM;IAC/B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAoB,EAAE,CAAoB;IACpE,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"resolveSelectionNextIds.js","sourceRoot":"","sources":["../../../src/patterns/selection/resolveSelectionNextIds.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAC1B,GAAkC,EAClC,IAAmB;IAEnB,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAS;QAC3B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,IAAI,IAAI,KAAK,QAAQ;YAAE,MAAM;IAC/B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAoB,EAAE,CAAoB;IACpE,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IAChD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EACvB,IAAI,EACJ,GAAG,EACH,EAAE,GAKH;IACC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACrB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO,CAAC,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EACvB,IAAI,EACJ,GAAG,EACH,EAAE,GAKH;IACC,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACrB,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IAED,OAAO,CAAC,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;AACtB,CAAC","sourcesContent":["import type { SelectionMode } from './types';\n\nexport function normalizeIds(\n ids: readonly string[] | undefined,\n mode: SelectionMode,\n): readonly string[] {\n const uniqueIds: string[] = [];\n const seen = new Set<string>();\n\n for (const id of ids ?? []) {\n if (seen.has(id)) continue;\n seen.add(id);\n uniqueIds.push(id);\n if (mode === 'single') break;\n }\n\n return uniqueIds;\n}\n\nexport function areIdsEqual(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) return false;\n for (let index = 0; index < a.length; index += 1) {\n if (a.at(index) !== b.at(index)) return false;\n }\n\n return true;\n}\n\nexport function clearIds(): readonly string[] {\n return [];\n}\n\nexport function selectId({\n mode,\n ids,\n id,\n}: {\n mode: SelectionMode;\n ids: readonly string[];\n id: string;\n}): readonly string[] {\n if (mode === 'single') {\n return [id];\n }\n\n if (ids.includes(id)) {\n return ids;\n }\n\n return [...ids, id];\n}\n\nexport function toggleId({\n mode,\n ids,\n id,\n}: {\n mode: SelectionMode;\n ids: readonly string[];\n id: string;\n}): readonly string[] {\n if (ids.includes(id)) {\n return ids.filter((existingId) => existingId !== id);\n }\n\n if (mode === 'single') {\n return [id];\n }\n\n return [...ids, id];\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import type { ThemeComposerProps } from './types';
|
|
|
3
3
|
/***
|
|
4
4
|
* UI for composing and applying a theme via structured controls.
|
|
5
5
|
*
|
|
6
|
-
|
|
6
|
+
*
|
|
7
7
|
*/
|
|
8
8
|
export declare const ThemeComposer: (props: ThemeComposerProps) => React.ReactElement | null;
|
|
9
9
|
//# sourceMappingURL=ThemeComposer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeComposer.d.ts","sourceRoot":"","sources":["../../../src/patterns/theme-composer/ThemeComposer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAc1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"ThemeComposer.d.ts","sourceRoot":"","sources":["../../../src/patterns/theme-composer/ThemeComposer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAc1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA2SlD;;;;GAIG;AACH,eAAO,MAAM,aAAa,0DAAyC,CAAC"}
|
|
@@ -15,6 +15,9 @@ import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
|
15
15
|
const HEX_ERROR_MESSAGE = 'Enter a valid 6-digit hex color.';
|
|
16
16
|
const HEX_INPUT_PLACEHOLDER = 'Enter hex color';
|
|
17
17
|
const NAME_ERROR_MESSAGE = 'Theme name cannot be empty.';
|
|
18
|
+
function createInputDraft(sourceValue) {
|
|
19
|
+
return { inputValue: sourceValue, error: undefined };
|
|
20
|
+
}
|
|
18
21
|
function isValidHex(value) {
|
|
19
22
|
try {
|
|
20
23
|
parseHexColorOrThrow(value);
|
|
@@ -37,57 +40,49 @@ const MODE_TABS = [
|
|
|
37
40
|
];
|
|
38
41
|
function ThemeComposerInner({ themeId: _themeId, value, onChange, mode, onModeChange, onSubmit, appCategories, testID, }) {
|
|
39
42
|
const { theme } = useZoraTheme();
|
|
40
|
-
const [
|
|
41
|
-
const [
|
|
42
|
-
const [
|
|
43
|
-
const [
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}, [value.name]);
|
|
43
|
+
const [hexDraft, setHexDraft] = React.useState(() => createInputDraft(value.primaryColor));
|
|
44
|
+
const [nameDraft, setNameDraft] = React.useState(() => createInputDraft(value.name));
|
|
45
|
+
const [previousPrimaryColor, setPreviousPrimaryColor] = React.useState(value.primaryColor);
|
|
46
|
+
const [previousName, setPreviousName] = React.useState(value.name);
|
|
47
|
+
if (previousPrimaryColor !== value.primaryColor) {
|
|
48
|
+
setPreviousPrimaryColor(value.primaryColor);
|
|
49
|
+
setHexDraft(createInputDraft(value.primaryColor));
|
|
50
|
+
}
|
|
51
|
+
if (previousName !== value.name) {
|
|
52
|
+
setPreviousName(value.name);
|
|
53
|
+
setNameDraft(createInputDraft(value.name));
|
|
54
|
+
}
|
|
53
55
|
function handleNameChange(text) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
setNameError(undefined);
|
|
56
|
+
const error = text.trim().length === 0 ? NAME_ERROR_MESSAGE : undefined;
|
|
57
|
+
setNameDraft({ inputValue: text, error });
|
|
58
|
+
if (!error) {
|
|
60
59
|
onChange({ ...value, name: text });
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
function handleHexChange(text) {
|
|
64
|
-
// Ensure leading hash
|
|
65
63
|
const normalized = text.startsWith('#') ? text : `#${text}`;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
const error = isValidHex(normalized) ? undefined : HEX_ERROR_MESSAGE;
|
|
65
|
+
setHexDraft({ inputValue: normalized, error });
|
|
66
|
+
if (!error) {
|
|
69
67
|
onChange({ ...value, primaryColor: normalized });
|
|
70
68
|
}
|
|
71
|
-
else {
|
|
72
|
-
setHexError(HEX_ERROR_MESSAGE);
|
|
73
|
-
}
|
|
74
69
|
}
|
|
75
70
|
function handleSubmit() {
|
|
76
|
-
const hasValidName =
|
|
77
|
-
const hasValidHex = isValidHex(
|
|
71
|
+
const hasValidName = nameDraft.inputValue.trim().length > 0;
|
|
72
|
+
const hasValidHex = isValidHex(hexDraft.inputValue);
|
|
78
73
|
if (!hasValidName) {
|
|
79
|
-
|
|
74
|
+
setNameDraft((current) => ({ ...current, error: NAME_ERROR_MESSAGE }));
|
|
80
75
|
}
|
|
81
76
|
if (!hasValidHex) {
|
|
82
|
-
|
|
77
|
+
setHexDraft((current) => ({ ...current, error: HEX_ERROR_MESSAGE }));
|
|
83
78
|
}
|
|
84
79
|
if (!hasValidName || !hasValidHex) {
|
|
85
80
|
return;
|
|
86
81
|
}
|
|
87
82
|
onSubmit?.({
|
|
88
83
|
...value,
|
|
89
|
-
name:
|
|
90
|
-
primaryColor:
|
|
84
|
+
name: nameDraft.inputValue,
|
|
85
|
+
primaryColor: hexDraft.inputValue,
|
|
91
86
|
});
|
|
92
87
|
}
|
|
93
88
|
const activeMode = mode ?? 'light';
|
|
@@ -101,9 +96,9 @@ function ThemeComposerInner({ themeId: _themeId, value, onChange, mode, onModeCh
|
|
|
101
96
|
<Stack gap="m">
|
|
102
97
|
<Stack gap="xs">
|
|
103
98
|
<Text variant="label">Name</Text>
|
|
104
|
-
<Input value={
|
|
105
|
-
{
|
|
106
|
-
{
|
|
99
|
+
<Input value={nameDraft.inputValue} onChangeText={handleNameChange} placeholder="My theme" autoCorrect={false} invalid={nameDraft.error !== undefined} testID={testID ? `${testID}-name-input` : undefined}/>
|
|
100
|
+
{nameDraft.error ? (<Text color="danger" variant="bodySmall">
|
|
101
|
+
{nameDraft.error}
|
|
107
102
|
</Text>) : null}
|
|
108
103
|
</Stack>
|
|
109
104
|
<Stack gap="xs">
|
|
@@ -125,17 +120,19 @@ function ThemeComposerInner({ themeId: _themeId, value, onChange, mode, onModeCh
|
|
|
125
120
|
<Stack gap="m">
|
|
126
121
|
<Stack direction="row" gap="m" align="center">
|
|
127
122
|
<Box flex={1}>
|
|
128
|
-
<Input value={
|
|
123
|
+
<Input value={hexDraft.inputValue} onChangeText={handleHexChange} placeholder={HEX_INPUT_PLACEHOLDER} autoCapitalize="none" autoCorrect={false} maxLength={7} invalid={hexDraft.error !== undefined} testID={testID ? `${testID}-hex-input` : undefined}/>
|
|
129
124
|
</Box>
|
|
130
125
|
{/* Color preview chip */}
|
|
131
126
|
<Box width={36} height={36} radius="m" style={{
|
|
132
|
-
backgroundColor: isValidHex(
|
|
127
|
+
backgroundColor: isValidHex(hexDraft.inputValue)
|
|
128
|
+
? hexDraft.inputValue
|
|
129
|
+
: theme.colors.border,
|
|
133
130
|
borderWidth: 1,
|
|
134
131
|
borderColor: theme.colors.border,
|
|
135
132
|
}}/>
|
|
136
133
|
</Stack>
|
|
137
|
-
{
|
|
138
|
-
{
|
|
134
|
+
{hexDraft.error ? (<Text color="danger" variant="bodySmall">
|
|
135
|
+
{hexDraft.error}
|
|
139
136
|
</Text>) : null}
|
|
140
137
|
</Stack>
|
|
141
138
|
</Card>
|
|
@@ -214,7 +211,7 @@ function ThemeComposerInner({ themeId: _themeId, value, onChange, mode, onModeCh
|
|
|
214
211
|
/***
|
|
215
212
|
* UI for composing and applying a theme via structured controls.
|
|
216
213
|
*
|
|
217
|
-
|
|
214
|
+
*
|
|
218
215
|
*/
|
|
219
216
|
export const ThemeComposer = withZoraThemeScope(ThemeComposerInner);
|
|
220
217
|
//# sourceMappingURL=ThemeComposer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeComposer.js","sourceRoot":"","sources":["../../../src/patterns/theme-composer/ThemeComposer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { COLOR_HARMONIES, parseHexColorOrThrow } from '@ankhorage/color-theory';\nimport type { AppCategory } from '@ankhorage/contracts';\nimport { APP_CATEGORIES } from '@ankhorage/contracts';\nimport React from 'react';\n\nimport { Badge } from '../../components/badge';\nimport { Button } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { Heading } from '../../components/heading';\nimport { Input } from '../../components/input';\nimport { Select } from '../../components/select';\nimport { Tabs } from '../../components/tabs';\nimport { Text } from '../../components/text';\nimport { Box, Stack } from '../../foundation';\nimport type { ZoraThemeMode } from '../../theme/types';\nimport { useZoraTheme } from '../../theme/useZoraTheme';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport type { ThemeComposerProps } from './types';\n\nconst HEX_ERROR_MESSAGE = 'Enter a valid 6-digit hex color.';\nconst HEX_INPUT_PLACEHOLDER = 'Enter hex color';\nconst NAME_ERROR_MESSAGE = 'Theme name cannot be empty.';\n\nfunction isValidHex(value: string): boolean {\n try {\n parseHexColorOrThrow(value);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction formatAppCategoryLabel(category: AppCategory): string {\n return category\n .split('_')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n}\n\nconst HARMONY_OPTIONS = COLOR_HARMONIES.map((h) => ({ value: h, label: h }));\n\nconst MODE_TABS = [\n { value: 'light' as ZoraThemeMode, label: 'Light' },\n { value: 'dark' as ZoraThemeMode, label: 'Dark' },\n];\n\nfunction ThemeComposerInner({\n themeId: _themeId,\n value,\n onChange,\n mode,\n onModeChange,\n onSubmit,\n appCategories,\n testID,\n}: ThemeComposerProps) {\n const { theme } = useZoraTheme();\n\n const [hexInput, setHexInput] = React.useState<string>(value.primaryColor);\n const [hexError, setHexError] = React.useState<string | undefined>(undefined);\n\n const [nameInput, setNameInput] = React.useState<string>(value.name);\n const [nameError, setNameError] = React.useState<string | undefined>(undefined);\n\n // Keep local inputs in sync when value changes externally\n React.useEffect(() => {\n setHexInput(value.primaryColor);\n setHexError(undefined);\n }, [value.primaryColor]);\n\n React.useEffect(() => {\n setNameInput(value.name);\n setNameError(undefined);\n }, [value.name]);\n\n function handleNameChange(text: string) {\n setNameInput(text);\n if (text.trim().length === 0) {\n setNameError(NAME_ERROR_MESSAGE);\n } else {\n setNameError(undefined);\n onChange({ ...value, name: text });\n }\n }\n\n function handleHexChange(text: string) {\n // Ensure leading hash\n const normalized = text.startsWith('#') ? text : `#${text}`;\n setHexInput(normalized);\n\n if (isValidHex(normalized)) {\n setHexError(undefined);\n onChange({ ...value, primaryColor: normalized });\n } else {\n setHexError(HEX_ERROR_MESSAGE);\n }\n }\n\n function handleSubmit() {\n const hasValidName = nameInput.trim().length > 0;\n const hasValidHex = isValidHex(hexInput);\n\n if (!hasValidName) {\n setNameError(NAME_ERROR_MESSAGE);\n }\n\n if (!hasValidHex) {\n setHexError(HEX_ERROR_MESSAGE);\n }\n\n if (!hasValidName || !hasValidHex) {\n return;\n }\n\n onSubmit?.({\n ...value,\n name: nameInput,\n primaryColor: hexInput,\n });\n }\n\n const activeMode = mode ?? 'light';\n const categoryOptions = (appCategories ?? APP_CATEGORIES).map((c) => ({\n value: c,\n label: formatAppCategoryLabel(c),\n }));\n\n return (\n <Stack gap=\"l\" testID={testID}>\n {/* Section: Theme identity */}\n <Card\n title=\"Theme identity\"\n description=\"Name your theme. The ID is assigned automatically and shown for reference.\"\n >\n <Stack gap=\"m\">\n <Stack gap=\"xs\">\n <Text variant=\"label\">Name</Text>\n <Input\n value={nameInput}\n onChangeText={handleNameChange}\n placeholder=\"My theme\"\n autoCorrect={false}\n invalid={nameError !== undefined}\n testID={testID ? `${testID}-name-input` : undefined}\n />\n {nameError ? (\n <Text color=\"danger\" variant=\"bodySmall\">\n {nameError}\n </Text>\n ) : null}\n </Stack>\n <Stack gap=\"xs\">\n <Text variant=\"label\">ID</Text>\n <Text\n emphasis=\"muted\"\n variant=\"bodySmall\"\n testID={testID ? `${testID}-id-display` : undefined}\n >\n {value.id}\n </Text>\n </Stack>\n </Stack>\n </Card>\n\n {/* Section: App category */}\n <Card title=\"App category\" description=\"Choose the category that best describes this app.\">\n <Select\n value={value.appCategory}\n options={categoryOptions}\n onValueChange={(c) => onChange({ ...value, appCategory: c })}\n testID={testID ? `${testID}-category-select` : undefined}\n />\n </Card>\n\n {/* Section: Primary Color */}\n <Card title=\"Primary color\" description=\"Set the seed color for your theme palette.\">\n <Stack gap=\"m\">\n <Stack direction=\"row\" gap=\"m\" align=\"center\">\n <Box flex={1}>\n <Input\n value={hexInput}\n onChangeText={handleHexChange}\n placeholder={HEX_INPUT_PLACEHOLDER}\n autoCapitalize=\"none\"\n autoCorrect={false}\n maxLength={7}\n invalid={hexError !== undefined}\n testID={testID ? `${testID}-hex-input` : undefined}\n />\n </Box>\n {/* Color preview chip */}\n <Box\n width={36}\n height={36}\n radius=\"m\"\n style={{\n backgroundColor: isValidHex(hexInput) ? hexInput : theme.colors.border,\n borderWidth: 1,\n borderColor: theme.colors.border,\n }}\n />\n </Stack>\n {hexError ? (\n <Text color=\"danger\" variant=\"bodySmall\">\n {hexError}\n </Text>\n ) : null}\n </Stack>\n </Card>\n\n {/* Section: Harmony */}\n <Card\n title=\"Harmony\"\n description=\"Choose how accent hues are generated from your primary color.\"\n >\n <Select\n value={value.harmony}\n options={HARMONY_OPTIONS}\n onValueChange={(h) => onChange({ ...value, harmony: h })}\n testID={testID ? `${testID}-harmony-select` : undefined}\n />\n </Card>\n\n {/* Section: Mode */}\n <Card title=\"Mode\" description=\"Switch between light and dark presentation.\">\n <Tabs\n value={activeMode}\n items={MODE_TABS}\n onValueChange={(m) => onModeChange?.(m)}\n variant=\"segmented\"\n testID={testID ? `${testID}-mode-tabs` : undefined}\n />\n </Card>\n\n {/* Section: Preview */}\n <Card title=\"Preview\" description=\"A quick look at how your theme renders common controls.\">\n <Stack gap=\"m\">\n <Stack gap=\"xs\">\n <Text variant=\"label\">Name</Text>\n <Text>{value.name}</Text>\n </Stack>\n <Stack gap=\"xs\">\n <Text variant=\"label\">Category</Text>\n <Text>{formatAppCategoryLabel(value.appCategory)}</Text>\n </Stack>\n <Stack gap=\"xs\">\n <Text variant=\"label\">Primary color</Text>\n <Text emphasis=\"muted\" variant=\"bodySmall\">\n {value.primaryColor}\n </Text>\n </Stack>\n <Stack gap=\"xs\">\n <Text variant=\"label\">Harmony</Text>\n <Text emphasis=\"muted\" variant=\"bodySmall\">\n {value.harmony}\n </Text>\n </Stack>\n <Heading level={4}>Heading</Heading>\n <Text>Body text — this shows default text color and weight.</Text>\n <Text emphasis=\"muted\" variant=\"bodySmall\">\n Muted caption text.\n </Text>\n <Stack direction=\"row\" gap=\"s\" align=\"center\">\n <Button color=\"primary\" variant=\"solid\" size=\"m\">\n Primary\n </Button>\n <Button color=\"neutral\" variant=\"soft\" size=\"m\">\n Neutral\n </Button>\n <Button color=\"danger\" variant=\"ghost\" size=\"m\">\n Danger\n </Button>\n </Stack>\n <Stack direction=\"row\" gap=\"s\" align=\"center\">\n <Badge color=\"primary\">Primary</Badge>\n <Badge color=\"success\" variant=\"soft\">\n Success\n </Badge>\n <Badge color=\"warning\" variant=\"soft\">\n Warning\n </Badge>\n <Badge color=\"danger\" variant=\"soft\">\n Danger\n </Badge>\n </Stack>\n <Card\n tone=\"subtle\"\n title=\"Nested card\"\n description=\"Subtle tone inside the preview.\"\n compact\n />\n </Stack>\n </Card>\n\n {/* Submit */}\n {onSubmit ? (\n <Button\n color=\"primary\"\n variant=\"solid\"\n onPress={handleSubmit}\n testID={testID ? `${testID}-submit` : undefined}\n >\n Apply theme\n </Button>\n ) : null}\n </Stack>\n );\n}\n\n/***\n * UI for composing and applying a theme via structured controls.\n *\n \n */\nexport const ThemeComposer = withZoraThemeScope(ThemeComposerInner);\n"]}
|
|
1
|
+
{"version":3,"file":"ThemeComposer.js","sourceRoot":"","sources":["../../../src/patterns/theme-composer/ThemeComposer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { COLOR_HARMONIES, parseHexColorOrThrow } from '@ankhorage/color-theory';\nimport type { AppCategory } from '@ankhorage/contracts';\nimport { APP_CATEGORIES } from '@ankhorage/contracts';\nimport React from 'react';\n\nimport { Badge } from '../../components/badge';\nimport { Button } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { Heading } from '../../components/heading';\nimport { Input } from '../../components/input';\nimport { Select } from '../../components/select';\nimport { Tabs } from '../../components/tabs';\nimport { Text } from '../../components/text';\nimport { Box, Stack } from '../../foundation';\nimport type { ZoraThemeMode } from '../../theme/types';\nimport { useZoraTheme } from '../../theme/useZoraTheme';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport type { ThemeComposerProps } from './types';\n\nconst HEX_ERROR_MESSAGE = 'Enter a valid 6-digit hex color.';\nconst HEX_INPUT_PLACEHOLDER = 'Enter hex color';\nconst NAME_ERROR_MESSAGE = 'Theme name cannot be empty.';\n\ninterface InputDraft {\n inputValue: string;\n error: string | undefined;\n}\n\nfunction createInputDraft(sourceValue: string): InputDraft {\n return { inputValue: sourceValue, error: undefined };\n}\n\nfunction isValidHex(value: string): boolean {\n try {\n parseHexColorOrThrow(value);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction formatAppCategoryLabel(category: AppCategory): string {\n return category\n .split('_')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n}\n\nconst HARMONY_OPTIONS = COLOR_HARMONIES.map((h) => ({ value: h, label: h }));\n\nconst MODE_TABS = [\n { value: 'light' as ZoraThemeMode, label: 'Light' },\n { value: 'dark' as ZoraThemeMode, label: 'Dark' },\n];\n\nfunction ThemeComposerInner({\n themeId: _themeId,\n value,\n onChange,\n mode,\n onModeChange,\n onSubmit,\n appCategories,\n testID,\n}: ThemeComposerProps) {\n const { theme } = useZoraTheme();\n\n const [hexDraft, setHexDraft] = React.useState<InputDraft>(() =>\n createInputDraft(value.primaryColor),\n );\n const [nameDraft, setNameDraft] = React.useState<InputDraft>(() => createInputDraft(value.name));\n const [previousPrimaryColor, setPreviousPrimaryColor] = React.useState(value.primaryColor);\n const [previousName, setPreviousName] = React.useState(value.name);\n\n if (previousPrimaryColor !== value.primaryColor) {\n setPreviousPrimaryColor(value.primaryColor);\n setHexDraft(createInputDraft(value.primaryColor));\n }\n\n if (previousName !== value.name) {\n setPreviousName(value.name);\n setNameDraft(createInputDraft(value.name));\n }\n\n function handleNameChange(text: string) {\n const error = text.trim().length === 0 ? NAME_ERROR_MESSAGE : undefined;\n setNameDraft({ inputValue: text, error });\n\n if (!error) {\n onChange({ ...value, name: text });\n }\n }\n\n function handleHexChange(text: string) {\n const normalized = text.startsWith('#') ? text : `#${text}`;\n const error = isValidHex(normalized) ? undefined : HEX_ERROR_MESSAGE;\n setHexDraft({ inputValue: normalized, error });\n\n if (!error) {\n onChange({ ...value, primaryColor: normalized });\n }\n }\n\n function handleSubmit() {\n const hasValidName = nameDraft.inputValue.trim().length > 0;\n const hasValidHex = isValidHex(hexDraft.inputValue);\n\n if (!hasValidName) {\n setNameDraft((current) => ({ ...current, error: NAME_ERROR_MESSAGE }));\n }\n\n if (!hasValidHex) {\n setHexDraft((current) => ({ ...current, error: HEX_ERROR_MESSAGE }));\n }\n\n if (!hasValidName || !hasValidHex) {\n return;\n }\n\n onSubmit?.({\n ...value,\n name: nameDraft.inputValue,\n primaryColor: hexDraft.inputValue,\n });\n }\n\n const activeMode = mode ?? 'light';\n const categoryOptions = (appCategories ?? APP_CATEGORIES).map((c) => ({\n value: c,\n label: formatAppCategoryLabel(c),\n }));\n\n return (\n <Stack gap=\"l\" testID={testID}>\n {/* Section: Theme identity */}\n <Card\n title=\"Theme identity\"\n description=\"Name your theme. The ID is assigned automatically and shown for reference.\"\n >\n <Stack gap=\"m\">\n <Stack gap=\"xs\">\n <Text variant=\"label\">Name</Text>\n <Input\n value={nameDraft.inputValue}\n onChangeText={handleNameChange}\n placeholder=\"My theme\"\n autoCorrect={false}\n invalid={nameDraft.error !== undefined}\n testID={testID ? `${testID}-name-input` : undefined}\n />\n {nameDraft.error ? (\n <Text color=\"danger\" variant=\"bodySmall\">\n {nameDraft.error}\n </Text>\n ) : null}\n </Stack>\n <Stack gap=\"xs\">\n <Text variant=\"label\">ID</Text>\n <Text\n emphasis=\"muted\"\n variant=\"bodySmall\"\n testID={testID ? `${testID}-id-display` : undefined}\n >\n {value.id}\n </Text>\n </Stack>\n </Stack>\n </Card>\n\n {/* Section: App category */}\n <Card title=\"App category\" description=\"Choose the category that best describes this app.\">\n <Select\n value={value.appCategory}\n options={categoryOptions}\n onValueChange={(c) => onChange({ ...value, appCategory: c })}\n testID={testID ? `${testID}-category-select` : undefined}\n />\n </Card>\n\n {/* Section: Primary Color */}\n <Card title=\"Primary color\" description=\"Set the seed color for your theme palette.\">\n <Stack gap=\"m\">\n <Stack direction=\"row\" gap=\"m\" align=\"center\">\n <Box flex={1}>\n <Input\n value={hexDraft.inputValue}\n onChangeText={handleHexChange}\n placeholder={HEX_INPUT_PLACEHOLDER}\n autoCapitalize=\"none\"\n autoCorrect={false}\n maxLength={7}\n invalid={hexDraft.error !== undefined}\n testID={testID ? `${testID}-hex-input` : undefined}\n />\n </Box>\n {/* Color preview chip */}\n <Box\n width={36}\n height={36}\n radius=\"m\"\n style={{\n backgroundColor: isValidHex(hexDraft.inputValue)\n ? hexDraft.inputValue\n : theme.colors.border,\n borderWidth: 1,\n borderColor: theme.colors.border,\n }}\n />\n </Stack>\n {hexDraft.error ? (\n <Text color=\"danger\" variant=\"bodySmall\">\n {hexDraft.error}\n </Text>\n ) : null}\n </Stack>\n </Card>\n\n {/* Section: Harmony */}\n <Card\n title=\"Harmony\"\n description=\"Choose how accent hues are generated from your primary color.\"\n >\n <Select\n value={value.harmony}\n options={HARMONY_OPTIONS}\n onValueChange={(h) => onChange({ ...value, harmony: h })}\n testID={testID ? `${testID}-harmony-select` : undefined}\n />\n </Card>\n\n {/* Section: Mode */}\n <Card title=\"Mode\" description=\"Switch between light and dark presentation.\">\n <Tabs\n value={activeMode}\n items={MODE_TABS}\n onValueChange={(m) => onModeChange?.(m)}\n variant=\"segmented\"\n testID={testID ? `${testID}-mode-tabs` : undefined}\n />\n </Card>\n\n {/* Section: Preview */}\n <Card title=\"Preview\" description=\"A quick look at how your theme renders common controls.\">\n <Stack gap=\"m\">\n <Stack gap=\"xs\">\n <Text variant=\"label\">Name</Text>\n <Text>{value.name}</Text>\n </Stack>\n <Stack gap=\"xs\">\n <Text variant=\"label\">Category</Text>\n <Text>{formatAppCategoryLabel(value.appCategory)}</Text>\n </Stack>\n <Stack gap=\"xs\">\n <Text variant=\"label\">Primary color</Text>\n <Text emphasis=\"muted\" variant=\"bodySmall\">\n {value.primaryColor}\n </Text>\n </Stack>\n <Stack gap=\"xs\">\n <Text variant=\"label\">Harmony</Text>\n <Text emphasis=\"muted\" variant=\"bodySmall\">\n {value.harmony}\n </Text>\n </Stack>\n <Heading level={4}>Heading</Heading>\n <Text>Body text — this shows default text color and weight.</Text>\n <Text emphasis=\"muted\" variant=\"bodySmall\">\n Muted caption text.\n </Text>\n <Stack direction=\"row\" gap=\"s\" align=\"center\">\n <Button color=\"primary\" variant=\"solid\" size=\"m\">\n Primary\n </Button>\n <Button color=\"neutral\" variant=\"soft\" size=\"m\">\n Neutral\n </Button>\n <Button color=\"danger\" variant=\"ghost\" size=\"m\">\n Danger\n </Button>\n </Stack>\n <Stack direction=\"row\" gap=\"s\" align=\"center\">\n <Badge color=\"primary\">Primary</Badge>\n <Badge color=\"success\" variant=\"soft\">\n Success\n </Badge>\n <Badge color=\"warning\" variant=\"soft\">\n Warning\n </Badge>\n <Badge color=\"danger\" variant=\"soft\">\n Danger\n </Badge>\n </Stack>\n <Card\n tone=\"subtle\"\n title=\"Nested card\"\n description=\"Subtle tone inside the preview.\"\n compact\n />\n </Stack>\n </Card>\n\n {/* Submit */}\n {onSubmit ? (\n <Button\n color=\"primary\"\n variant=\"solid\"\n onPress={handleSubmit}\n testID={testID ? `${testID}-submit` : undefined}\n >\n Apply theme\n </Button>\n ) : null}\n </Stack>\n );\n}\n\n/***\n * UI for composing and applying a theme via structured controls.\n *\n *\n */\nexport const ThemeComposer = withZoraThemeScope(ThemeComposerInner);\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare function useZoraTheme(): {
|
|
2
2
|
theme: import("@ankhorage/surface").SurfaceTheme;
|
|
3
3
|
mode: "light" | "dark";
|
|
4
|
-
setThemeConfig: (config: Partial<import("@ankhorage/
|
|
4
|
+
setThemeConfig: (config: Partial<import("@ankhorage/contracts").ThemeConfig>) => void;
|
|
5
5
|
setMode: (mode: "light" | "dark") => void;
|
|
6
6
|
_hasProvider?: boolean;
|
|
7
7
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.8.
|
|
4
|
+
"version": "2.8.5",
|
|
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": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@ankhorage/color-theory": "^0.0.7",
|
|
45
45
|
"@ankhorage/contracts": "^2.1.0",
|
|
46
|
-
"@ankhorage/surface": "^2.0.
|
|
46
|
+
"@ankhorage/surface": "^2.0.3"
|
|
47
47
|
},
|
|
48
48
|
"files": [
|
|
49
49
|
"dist",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"version-packages": "changeset version"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
|
-
"@ankhorage/devtools": "^1.3.
|
|
92
|
+
"@ankhorage/devtools": "^1.3.4",
|
|
93
93
|
"@ankhorage/paradox": "^0.1.10",
|
|
94
94
|
"@changesets/cli": "^2.31.0",
|
|
95
95
|
"@expo/vector-icons": "^15.1.1",
|
|
@@ -11,13 +11,21 @@ import { Text, type TextVariant } from '../text';
|
|
|
11
11
|
import { resolveAvatarInitials } from './resolveAvatarInitials';
|
|
12
12
|
import type { AvatarProps, AvatarShape, AvatarSize } from './types';
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
function resolveAvatarSize(size: AvatarSize): number {
|
|
15
|
+
switch (size) {
|
|
16
|
+
case 'xs':
|
|
17
|
+
return 24;
|
|
18
|
+
case 's':
|
|
19
|
+
return 32;
|
|
20
|
+
case 'l':
|
|
21
|
+
return 48;
|
|
22
|
+
case 'xl':
|
|
23
|
+
return 64;
|
|
24
|
+
case 'm':
|
|
25
|
+
default:
|
|
26
|
+
return 40;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
21
29
|
|
|
22
30
|
function resolveRoleSemantics(theme: SurfaceTheme, color: ZoraColor): RoleSemantics {
|
|
23
31
|
switch (color) {
|
|
@@ -82,7 +90,7 @@ function AvatarInner({
|
|
|
82
90
|
color = 'neutral',
|
|
83
91
|
}: AvatarProps) {
|
|
84
92
|
const { theme } = useZoraTheme();
|
|
85
|
-
const resolvedSize =
|
|
93
|
+
const resolvedSize = resolveAvatarSize(size);
|
|
86
94
|
const resolvedInitials = initials ?? resolveAvatarInitials(name);
|
|
87
95
|
const role = resolveRoleSemantics(theme, color);
|
|
88
96
|
const backgroundColor = color === 'neutral' ? theme.semantics.neutral.surface : role.softBg;
|
|
@@ -131,7 +131,15 @@ function DatePickerInner({
|
|
|
131
131
|
testID,
|
|
132
132
|
}: DatePickerProps) {
|
|
133
133
|
const [visible, setVisible] = React.useState(false);
|
|
134
|
-
const [
|
|
134
|
+
const [fallbackMonth] = React.useState(() => resolveInitialMonth(null, undefined));
|
|
135
|
+
const initialMonth = value || minDate ? resolveInitialMonth(value, minDate) : fallbackMonth;
|
|
136
|
+
const initialMonthKey = initialMonth.getTime();
|
|
137
|
+
const [displayMonthState, setDisplayMonthState] = React.useState(() => ({
|
|
138
|
+
sourceMonthKey: initialMonthKey,
|
|
139
|
+
month: initialMonth,
|
|
140
|
+
}));
|
|
141
|
+
const displayMonth =
|
|
142
|
+
displayMonthState.sourceMonthKey === initialMonthKey ? displayMonthState.month : initialMonth;
|
|
135
143
|
const monthDays = React.useMemo(() => createMonthDays(displayMonth), [displayMonth]);
|
|
136
144
|
const previousMonth = new Date(displayMonth.getFullYear(), displayMonth.getMonth() - 1, 1);
|
|
137
145
|
const nextMonth = new Date(displayMonth.getFullYear(), displayMonth.getMonth() + 1, 1);
|
|
@@ -141,11 +149,14 @@ function DatePickerInner({
|
|
|
141
149
|
: formatDefaultDate(value)
|
|
142
150
|
: placeholder;
|
|
143
151
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
152
|
+
function setDisplayMonth(month: Date) {
|
|
153
|
+
setDisplayMonthState({ sourceMonthKey: initialMonthKey, month });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function openPicker() {
|
|
157
|
+
setDisplayMonthState({ sourceMonthKey: initialMonthKey, month: initialMonth });
|
|
158
|
+
setVisible(true);
|
|
159
|
+
}
|
|
149
160
|
|
|
150
161
|
return (
|
|
151
162
|
<Field
|
|
@@ -158,7 +169,7 @@ function DatePickerInner({
|
|
|
158
169
|
>
|
|
159
170
|
<Button
|
|
160
171
|
disabled={disabled}
|
|
161
|
-
onPress={
|
|
172
|
+
onPress={openPicker}
|
|
162
173
|
testID={testID ? `${testID}-trigger` : undefined}
|
|
163
174
|
trailingIcon={{ name: 'calendar-outline' }}
|
|
164
175
|
variant="outline"
|
|
@@ -30,9 +30,11 @@ export function useFormController<TName extends string = string>({
|
|
|
30
30
|
onSubmit,
|
|
31
31
|
validateOnChange = false,
|
|
32
32
|
}: UseFormControllerOptions<TName>): UseFormControllerResult<TName> {
|
|
33
|
-
const
|
|
33
|
+
const [initialFormValues] = React.useState<FormValues<TName>>(() =>
|
|
34
|
+
createInitialValues(fields, initialValues),
|
|
35
|
+
);
|
|
34
36
|
const [internalValues, setInternalValues] = React.useState<FormValues<TName>>(
|
|
35
|
-
|
|
37
|
+
() => initialFormValues,
|
|
36
38
|
);
|
|
37
39
|
const [validationErrors, setValidationErrors] = React.useState<FormErrors<TName>>({});
|
|
38
40
|
|
|
@@ -91,8 +93,8 @@ export function useFormController<TName extends string = string>({
|
|
|
91
93
|
|
|
92
94
|
const reset = React.useCallback(() => {
|
|
93
95
|
setValidationErrors({});
|
|
94
|
-
setValues(
|
|
95
|
-
}, [setValues]);
|
|
96
|
+
setValues(initialFormValues);
|
|
97
|
+
}, [initialFormValues, setValues]);
|
|
96
98
|
|
|
97
99
|
return {
|
|
98
100
|
values,
|
|
@@ -130,7 +130,17 @@ function resolveHeadingColor(
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
function resolveWeight(theme: SurfaceTheme, weight: HeadingWeight): FontWeight {
|
|
133
|
-
|
|
133
|
+
switch (weight) {
|
|
134
|
+
case 'medium':
|
|
135
|
+
return theme.typography.weights.medium;
|
|
136
|
+
case 'semiBold':
|
|
137
|
+
return theme.typography.weights.semiBold;
|
|
138
|
+
case 'bold':
|
|
139
|
+
return theme.typography.weights.bold;
|
|
140
|
+
case 'regular':
|
|
141
|
+
default:
|
|
142
|
+
return theme.typography.weights.regular;
|
|
143
|
+
}
|
|
134
144
|
}
|
|
135
145
|
|
|
136
146
|
function resolveFontFamily({
|
|
@@ -142,7 +152,15 @@ function resolveFontFamily({
|
|
|
142
152
|
weight: FontWeight;
|
|
143
153
|
italic: boolean;
|
|
144
154
|
}): string | undefined {
|
|
145
|
-
|
|
155
|
+
const fonts = italic ? theme.typography.fonts.italic : theme.typography.fonts.normal;
|
|
156
|
+
|
|
157
|
+
for (const [fontWeight, fontFamily] of Object.entries(fonts)) {
|
|
158
|
+
if (fontWeight === weight) {
|
|
159
|
+
return fontFamily;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return undefined;
|
|
146
164
|
}
|
|
147
165
|
|
|
148
166
|
export function resolveHeadingRecipe(
|
|
@@ -13,6 +13,24 @@ function isResponsiveRecord<T>(value: Responsive<T>): value is Partial<Record<Br
|
|
|
13
13
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
function readResponsiveValue<T>(
|
|
17
|
+
value: Partial<Record<Breakpoint, T>>,
|
|
18
|
+
breakpoint: Breakpoint,
|
|
19
|
+
): T | undefined {
|
|
20
|
+
switch (breakpoint) {
|
|
21
|
+
case 'base':
|
|
22
|
+
return value.base;
|
|
23
|
+
case 'sm':
|
|
24
|
+
return value.sm;
|
|
25
|
+
case 'md':
|
|
26
|
+
return value.md;
|
|
27
|
+
case 'lg':
|
|
28
|
+
return value.lg;
|
|
29
|
+
case 'xl':
|
|
30
|
+
return value.xl;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
16
34
|
function resolveResponsiveMock<T>(
|
|
17
35
|
value: Responsive<T> | undefined,
|
|
18
36
|
breakpoint: Breakpoint,
|
|
@@ -22,9 +40,9 @@ function resolveResponsiveMock<T>(
|
|
|
22
40
|
|
|
23
41
|
const activeIndex = breakpointOrder.indexOf(breakpoint);
|
|
24
42
|
for (let i = activeIndex; i >= 0; i -= 1) {
|
|
25
|
-
const key = breakpointOrder
|
|
43
|
+
const key = breakpointOrder.at(i);
|
|
26
44
|
if (!key) continue;
|
|
27
|
-
const candidate = value
|
|
45
|
+
const candidate = readResponsiveValue(value, key);
|
|
28
46
|
if (candidate !== undefined) return candidate;
|
|
29
47
|
}
|
|
30
48
|
|
|
@@ -34,7 +34,17 @@ function isMediumBreakpointOrLarger(breakpoint: Breakpoint): boolean {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
function resolveWeight(theme: SurfaceTheme, weight: TextWeight): FontWeight {
|
|
37
|
-
|
|
37
|
+
switch (weight) {
|
|
38
|
+
case 'medium':
|
|
39
|
+
return theme.typography.weights.medium;
|
|
40
|
+
case 'semiBold':
|
|
41
|
+
return theme.typography.weights.semiBold;
|
|
42
|
+
case 'bold':
|
|
43
|
+
return theme.typography.weights.bold;
|
|
44
|
+
case 'regular':
|
|
45
|
+
default:
|
|
46
|
+
return theme.typography.weights.regular;
|
|
47
|
+
}
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
function resolveFontFamily({
|
|
@@ -52,7 +62,15 @@ function resolveFontFamily({
|
|
|
52
62
|
return 'monospace';
|
|
53
63
|
}
|
|
54
64
|
|
|
55
|
-
|
|
65
|
+
const fonts = italic ? theme.typography.fonts.italic : theme.typography.fonts.normal;
|
|
66
|
+
|
|
67
|
+
for (const [fontWeight, fontFamily] of Object.entries(fonts)) {
|
|
68
|
+
if (fontWeight === weight) {
|
|
69
|
+
return fontFamily;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return undefined;
|
|
56
74
|
}
|
|
57
75
|
|
|
58
76
|
function resolveVariantRecipe(
|