@ankhorage/zora 25.8.15 → 25.8.17
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 -1
- package/dist/capabilities/index.js +34 -59
- package/dist/capabilities/index.js.map +3 -3
- package/dist/features/date-picker/composition/DatePickerContent.d.ts.map +1 -1
- package/dist/features/date-picker/composition/DatePickerContent.js +1 -11
- package/dist/features/date-picker/composition/DatePickerContent.js.map +1 -1
- package/dist/features/date-picker/composition/DatePickerField.d.ts.map +1 -1
- package/dist/features/date-picker/composition/DatePickerField.js +2 -17
- package/dist/features/date-picker/composition/DatePickerField.js.map +1 -1
- package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.js +7 -19
- package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.js.map +1 -1
- package/dist/features/picker/composition/PickerField.d.ts +14 -0
- package/dist/features/picker/composition/PickerField.d.ts.map +1 -0
- package/dist/features/picker/composition/PickerField.js +21 -0
- package/dist/features/picker/composition/PickerField.js.map +1 -0
- package/dist/features/picker/composition/PickerHeader.d.ts +9 -0
- package/dist/features/picker/composition/PickerHeader.d.ts.map +1 -0
- package/dist/features/picker/composition/PickerHeader.js +14 -0
- package/dist/features/picker/composition/PickerHeader.js.map +1 -0
- package/dist/features/tabletop/meta.d.ts +46 -46
- package/dist/features/tabletop/meta.d.ts.map +1 -1
- package/dist/features/tabletop/meta.js +33 -58
- package/dist/features/tabletop/meta.js.map +1 -1
- package/dist/features/time-picker/composition/TimePickerContent.js +1 -12
- package/dist/features/time-picker/composition/TimePickerContent.js.map +1 -1
- package/dist/features/time-picker/composition/TimePickerField.d.ts.map +1 -1
- package/dist/features/time-picker/composition/TimePickerField.js +2 -17
- package/dist/features/time-picker/composition/TimePickerField.js.map +1 -1
- package/dist/features/typography/utils/headingThemeRecipeMeta.d.ts +5 -5
- package/dist/features/typography/utils/headingThemeRecipeMeta.d.ts.map +1 -1
- package/dist/features/typography/utils/headingThemeRecipeMeta.js +2 -19
- package/dist/features/typography/utils/headingThemeRecipeMeta.js.map +1 -1
- package/dist/features/typography/utils/resolveHeadingRecipe.d.ts.map +1 -1
- package/dist/features/typography/utils/resolveHeadingRecipe.js +11 -68
- package/dist/features/typography/utils/resolveHeadingRecipe.js.map +1 -1
- package/dist/features/typography/utils/resolveHeadingThemeRecipe.d.ts +4 -4
- package/dist/features/typography/utils/resolveHeadingThemeRecipe.d.ts.map +1 -1
- package/dist/features/typography/utils/resolveHeadingThemeRecipe.js +2 -33
- package/dist/features/typography/utils/resolveHeadingThemeRecipe.js.map +1 -1
- package/dist/features/typography/utils/resolveTextStyle.d.ts.map +1 -1
- package/dist/features/typography/utils/resolveTextStyle.js +11 -76
- package/dist/features/typography/utils/resolveTextStyle.js.map +1 -1
- package/dist/features/typography/utils/resolveTextThemeRecipe.d.ts +4 -4
- package/dist/features/typography/utils/resolveTextThemeRecipe.d.ts.map +1 -1
- package/dist/features/typography/utils/resolveTextThemeRecipe.js +2 -33
- package/dist/features/typography/utils/resolveTextThemeRecipe.js.map +1 -1
- package/dist/features/typography/utils/resolveTypographyStyleTokens.d.ts +21 -0
- package/dist/features/typography/utils/resolveTypographyStyleTokens.d.ts.map +1 -0
- package/dist/features/typography/utils/resolveTypographyStyleTokens.js +75 -0
- package/dist/features/typography/utils/resolveTypographyStyleTokens.js.map +1 -0
- package/dist/features/typography/utils/resolveTypographyThemeRecipeFields.d.ts +10 -0
- package/dist/features/typography/utils/resolveTypographyThemeRecipeFields.d.ts.map +1 -0
- package/dist/features/typography/utils/resolveTypographyThemeRecipeFields.js +19 -0
- package/dist/features/typography/utils/resolveTypographyThemeRecipeFields.js.map +1 -0
- package/dist/features/typography/utils/textThemeRecipeMeta.d.ts +6 -6
- package/dist/features/typography/utils/textThemeRecipeMeta.d.ts.map +1 -1
- package/dist/features/typography/utils/textThemeRecipeMeta.js +2 -19
- package/dist/features/typography/utils/textThemeRecipeMeta.js.map +1 -1
- package/dist/features/typography/utils/typographyThemeRecipeFields.d.ts +30 -0
- package/dist/features/typography/utils/typographyThemeRecipeFields.d.ts.map +1 -0
- package/dist/features/typography/utils/typographyThemeRecipeFields.js +23 -0
- package/dist/features/typography/utils/typographyThemeRecipeFields.js.map +1 -0
- package/dist/features/uploader/adapters/inbound/Uploader.d.ts.map +1 -1
- package/dist/features/uploader/adapters/inbound/Uploader.js +1 -16
- package/dist/features/uploader/adapters/inbound/Uploader.js.map +1 -1
- package/dist/features/uploader/application/use-cases/validateUploadAsset.d.ts.map +1 -1
- package/dist/features/uploader/application/use-cases/validateUploadAsset.js +1 -16
- package/dist/features/uploader/application/use-cases/validateUploadAsset.js.map +1 -1
- package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.d.ts.map +1 -1
- package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.js +3 -4
- package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.js.map +1 -1
- package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.d.ts +8 -0
- package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.d.ts.map +1 -0
- package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.js +10 -0
- package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.js.map +1 -0
- package/dist/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.d.ts.map +1 -1
- package/dist/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.js +4 -6
- package/dist/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.js.map +1 -1
- package/package.json +14 -14
- package/src/expo57Migration.test.ts +50 -0
- package/src/features/date-picker/composition/DatePickerContent.tsx +1 -22
- package/src/features/date-picker/composition/DatePickerField.tsx +2 -31
- package/src/features/matrix-grid/application/getMatrixGridNextFocusId.ts +11 -22
- package/src/features/picker/composition/PickerField.tsx +61 -0
- package/src/features/picker/composition/PickerHeader.tsx +25 -0
- package/src/features/tabletop/meta.ts +34 -58
- package/src/features/time-picker/composition/TimePickerContent.tsx +1 -23
- package/src/features/time-picker/composition/TimePickerField.tsx +2 -31
- package/src/features/typography/utils/headingThemeRecipeMeta.ts +2 -19
- package/src/features/typography/utils/resolveHeadingRecipe.ts +12 -88
- package/src/features/typography/utils/resolveHeadingThemeRecipe.ts +3 -39
- package/src/features/typography/utils/resolveTextStyle.ts +10 -98
- package/src/features/typography/utils/resolveTextThemeRecipe.ts +3 -39
- package/src/features/typography/utils/resolveTypographyStyleTokens.ts +113 -0
- package/src/features/typography/utils/resolveTypographyThemeRecipeFields.ts +27 -0
- package/src/features/typography/utils/textThemeRecipeMeta.ts +2 -19
- package/src/features/typography/utils/typographyThemeRecipeFields.ts +23 -0
- package/src/features/uploader/adapters/inbound/Uploader.tsx +1 -20
- package/src/features/uploader/application/use-cases/validateUploadAsset.test.ts +2 -2
- package/src/features/uploader/application/use-cases/validateUploadAsset.ts +2 -20
- package/src/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.ts +3 -6
- package/src/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.ts +18 -0
- package/src/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.ts +4 -8
- package/web-dist/chunks/{Accordion-rqr10gn4.js → Accordion-1495be5z.js} +2 -2
- package/web-dist/chunks/{Accordion-m2hcc8g4.js → Accordion-3qphhsb4.js} +1 -1
- package/web-dist/chunks/{Accordion-gn8ptzwb.js → Accordion-4x8gdqqs.js} +1 -1
- package/web-dist/chunks/{Accordion-9aczb0k2.js → Accordion-58bpmzdj.js} +2 -2
- package/web-dist/chunks/{Accordion-2jy53kzk.js → Accordion-69c4pfz2.js} +2 -2
- package/web-dist/chunks/{Accordion-rqhh2m5b.js → Accordion-7n93d7fa.js} +1 -1
- package/web-dist/chunks/{Accordion-m6mp8aea.js → Accordion-a42brn0p.js} +1 -1
- package/web-dist/chunks/{Accordion-g08740h4.js → Accordion-c912kzs0.js} +1 -1
- package/web-dist/chunks/{Accordion-tyh8jj9d.js → Accordion-cbbafww1.js} +1 -1
- package/web-dist/chunks/{Accordion-11ej93t5.js → Accordion-cjjg81ry.js} +2 -2
- package/web-dist/chunks/{Accordion-vkd002gw.js → Accordion-d0bebw9j.js} +3 -3
- package/web-dist/chunks/{Accordion-vjcd5kxc.js → Accordion-gntmfcmz.js} +1 -1
- package/web-dist/chunks/{Accordion-wqyrrptg.js → Accordion-jyemxzat.js} +1 -1
- package/web-dist/chunks/{Accordion-p7d5svfq.js → Accordion-kmwhjw1k.js} +1 -1
- package/web-dist/chunks/{Accordion-26prtnm7.js → Accordion-ptxa6trg.js} +1 -1
- package/web-dist/chunks/{Accordion-4yq92mxp.js → Accordion-ve81xazy.js} +1 -1
- package/web-dist/chunks/Accordion-vnb3vntm.js +79 -0
- package/web-dist/chunks/{Accordion-9rnsg9pk.js → Accordion-vqx3exsq.js} +129 -243
- package/web-dist/chunks/{Accordion-1hbt9k69.js → Accordion-w95t2pr3.js} +1 -1
- package/web-dist/chunks/{Accordion-g2aqhct0.js → Accordion-z5dpzw3g.js} +2 -2
- package/web-dist/chunks/{Accordion-a4pz3vjj.js → Accordion-zf1g5422.js} +1 -1
- package/web-dist/components/accordion/Accordion.js +2 -2
- package/web-dist/components/accordion-item/AccordionItem.js +2 -2
- package/web-dist/components/app-bar/AppBar.js +2 -2
- package/web-dist/components/app-header/AppHeader.js +2 -2
- package/web-dist/components/auth-screen/AuthScreen.js +4 -4
- package/web-dist/components/avatar/Avatar.js +2 -2
- package/web-dist/components/avatar-group/AvatarGroup.js +2 -2
- package/web-dist/components/barcode-scanner-view/BarcodeScannerView.js +4 -4
- package/web-dist/components/breadcrumbs/Breadcrumbs.js +1 -1
- package/web-dist/components/camera-permission-view/CameraPermissionView.js +4 -4
- package/web-dist/components/card/Card.js +3 -3
- package/web-dist/components/chat-list-item/ChatListItem.js +3 -3
- package/web-dist/components/checkbox/Checkbox.js +2 -2
- package/web-dist/components/checkbox-group/CheckboxGroup.js +2 -2
- package/web-dist/components/chip/Chip.js +2 -2
- package/web-dist/components/chip-group/ChipGroup.js +2 -2
- package/web-dist/components/collection-editor/CollectionEditor.js +3 -3
- package/web-dist/components/content-rail/ContentRail.js +1 -1
- package/web-dist/components/data-table/DataTable.js +7 -7
- package/web-dist/components/date-picker/DatePicker.js +12 -49
- package/web-dist/components/dialog/Dialog.js +2 -2
- package/web-dist/components/empty-state/EmptyState.js +4 -4
- package/web-dist/components/explorer/Explorer.js +2 -2
- package/web-dist/components/field/Field.js +2 -2
- package/web-dist/components/file-explorer/FileExplorer.js +2 -2
- package/web-dist/components/flat-list/FlatList.js +3 -3
- package/web-dist/components/forgot-password-form/ForgotPasswordForm.js +4 -4
- package/web-dist/components/form/Form.js +3 -3
- package/web-dist/components/form-actions/FormActions.js +3 -3
- package/web-dist/components/form-error/FormError.js +3 -3
- package/web-dist/components/heading/Heading.js +1 -1
- package/web-dist/components/hero/Hero.js +3 -3
- package/web-dist/components/list/List.js +3 -3
- package/web-dist/components/list-item/ListItem.js +3 -3
- package/web-dist/components/list-section/ListSection.js +3 -3
- package/web-dist/components/matrix-grid/MatrixGrid.js +5 -17
- package/web-dist/components/media-card/MediaCard.js +3 -3
- package/web-dist/components/media-explorer/MediaExplorer.js +2 -2
- package/web-dist/components/message-bubble/MessageBubble.js +3 -3
- package/web-dist/components/metric-card/MetricCard.js +3 -3
- package/web-dist/components/missing-element/MissingElement.js +1 -1
- package/web-dist/components/o-auth-provider-button/OAuthProviderButton.js +4 -4
- package/web-dist/components/o-auth-provider-list/OAuthProviderList.js +4 -4
- package/web-dist/components/otp-form/OtpForm.js +4 -4
- package/web-dist/components/pagination/Pagination.js +1 -1
- package/web-dist/components/palette-item/PaletteItem.js +3 -3
- package/web-dist/components/post-card/PostCard.js +3 -3
- package/web-dist/components/product-card/ProductCard.js +3 -3
- package/web-dist/components/progress/Progress.js +2 -2
- package/web-dist/components/progress-ring/ProgressRing.js +2 -2
- package/web-dist/components/radio/Radio.js +2 -2
- package/web-dist/components/radio-group/RadioGroup.js +2 -2
- package/web-dist/components/reader/Reader.js +4 -4
- package/web-dist/components/scan-overlay/ScanOverlay.js +4 -4
- package/web-dist/components/screen-section/ScreenSection.js +2 -2
- package/web-dist/components/section-header/SectionHeader.js +2 -2
- package/web-dist/components/section-list/SectionList.js +3 -3
- package/web-dist/components/sign-in-form/SignInForm.js +4 -4
- package/web-dist/components/sign-up-form/SignUpForm.js +4 -4
- package/web-dist/components/skeleton/Skeleton.js +6 -6
- package/web-dist/components/skeleton-card/SkeletonCard.js +6 -6
- package/web-dist/components/skeleton-list/SkeletonList.js +6 -6
- package/web-dist/components/skeleton-text/SkeletonText.js +6 -6
- package/web-dist/components/text/Text.js +1 -1
- package/web-dist/components/time-picker/TimePicker.js +12 -51
- package/web-dist/components/timeline/Timeline.js +1 -1
- package/web-dist/components/toolbar/Toolbar.js +3 -3
- package/web-dist/components/tree-item/TreeItem.js +3 -3
- package/web-dist/components/uploader/Uploader.js +21 -37
- package/web-dist/manifest.json +204 -202
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatBytes } from '@ankhorage/utility/number';
|
|
1
2
|
/*** Validates a picked upload asset against MIME, extension, size, and caller rules. */
|
|
2
3
|
export function validateUploadAsset({ asset, accept, maxSizeBytes, validate, }) {
|
|
3
4
|
if (!isAccepted(asset.contentType, asset.fileName, accept)) {
|
|
@@ -58,20 +59,4 @@ function parseAccept(accept) {
|
|
|
58
59
|
.map((token) => token.trim())
|
|
59
60
|
.filter((token) => token.length > 0);
|
|
60
61
|
}
|
|
61
|
-
/*** Formats a byte count for concise upload validation feedback. */
|
|
62
|
-
function formatBytes(value) {
|
|
63
|
-
if (!Number.isFinite(value) || value <= 0) {
|
|
64
|
-
return '0 B';
|
|
65
|
-
}
|
|
66
|
-
const units = ['B', 'KB', 'MB', 'GB'];
|
|
67
|
-
let size = value;
|
|
68
|
-
let unitIndex = 0;
|
|
69
|
-
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
70
|
-
size /= 1024;
|
|
71
|
-
unitIndex += 1;
|
|
72
|
-
}
|
|
73
|
-
const unit = units.at(unitIndex) ?? 'B';
|
|
74
|
-
const rounded = unitIndex === 0 ? Math.round(size) : Math.round(size * 10) / 10;
|
|
75
|
-
return `${rounded} ${unit}`;
|
|
76
|
-
}
|
|
77
62
|
//# sourceMappingURL=validateUploadAsset.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateUploadAsset.js","sourceRoot":"","sources":["../../../../../src/features/uploader/application/use-cases/validateUploadAsset.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validateUploadAsset.js","sourceRoot":"","sources":["../../../../../src/features/uploader/application/use-cases/validateUploadAsset.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatBytes } from '@ankhorage/utility/number';\n\nimport type { ValidateUploadAssetInput } from '../../../../types/upload';\n\n/*** Validates a picked upload asset against MIME, extension, size, and caller rules. */\nexport function validateUploadAsset({\n asset,\n accept,\n maxSizeBytes,\n validate,\n}: ValidateUploadAssetInput): string | undefined {\n if (!isAccepted(asset.contentType, asset.fileName, accept)) {\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 asset.sizeBytes !== undefined &&\n Number.isFinite(asset.sizeBytes) &&\n asset.sizeBytes > maxSizeBytes\n ) {\n return `File is too large (${formatBytes(asset.sizeBytes)}). Max ${formatBytes(maxSizeBytes)}.`;\n }\n\n return validate?.(asset);\n}\n\n/*** Returns whether available file metadata satisfies at least one accept token. */\nfunction isAccepted(\n contentType: string | undefined,\n fileName: string | undefined,\n accept: string | undefined,\n): boolean {\n const tokens = parseAccept(accept);\n if (tokens.length === 0) {\n return true;\n }\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) {\n return true;\n }\n }\n\n return !hadSignal;\n}\n\n/*** Matches one MIME or extension accept token against available file metadata. */\nfunction matchesAcceptToken(\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 return normalizedFileName ? normalizedFileName.endsWith(normalizedToken) : null;\n }\n\n if (normalizedToken.endsWith('/*')) {\n if (!normalizedContentType) {\n return null;\n }\n\n return normalizedContentType.startsWith(normalizedToken.slice(0, -1));\n }\n\n return normalizedContentType ? normalizedContentType === normalizedToken : null;\n}\n\n/*** Parses a browser-style accept string into normalized non-empty tokens. */\nfunction parseAccept(accept: string | undefined): readonly string[] {\n if (!accept) {\n return [];\n }\n\n return accept\n .split(',')\n .map((token) => token.trim())\n .filter((token) => token.length > 0);\n}\n"]}
|
package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createWebDesiredStateWithNodeAsync.d.ts","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.ts"],"names":[],"mappings":"AAQA,iFAAiF;AACjF,wBAAsB,kCAAkC,CAAC,KAAK,EAAE;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,
|
|
1
|
+
{"version":3,"file":"createWebDesiredStateWithNodeAsync.d.ts","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.ts"],"names":[],"mappings":"AAQA,iFAAiF;AACjF,wBAAsB,kCAAkC,CAAC,KAAK,EAAE;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,4HA+BA"}
|
package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { dirname, join, resolve } from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
4
|
import { readWebDesiredStateWithNodeAsync } from '../adapters/outbound/node/readWebDesiredStateWithNodeAsync';
|
|
5
|
+
import { readWebComponentPackageMetadataAsync } from './readWebComponentPackageMetadataAsync';
|
|
6
6
|
import { synchronizeWebComponentArtifactsWithNodeAsync } from './synchronizeWebComponentArtifactsWithNodeAsync';
|
|
7
7
|
/*** Add one requested web component and regenerate the complete declared set. */
|
|
8
8
|
export async function createWebDesiredStateWithNodeAsync(input) {
|
|
9
9
|
const desired = await readWebDesiredStateWithNodeAsync(input.projectRoot, true);
|
|
10
10
|
const components = [...new Set([...desired.components, input.component])].sort();
|
|
11
|
-
const packageRoot =
|
|
12
|
-
const packageJson = JSON.parse(await readFile(resolve(packageRoot, 'package.json'), 'utf8'));
|
|
11
|
+
const { packageRoot, packageVersion } = await readWebComponentPackageMetadataAsync();
|
|
13
12
|
const desiredPath = resolve(input.projectRoot, 'zora.web.json');
|
|
14
13
|
const previous = await readFile(desiredPath, 'utf8').catch((error) => {
|
|
15
14
|
if (isMissingFile(error))
|
|
@@ -24,7 +23,7 @@ export async function createWebDesiredStateWithNodeAsync(input) {
|
|
|
24
23
|
components,
|
|
25
24
|
outputDirectory: resolve(input.projectRoot, '.ankh', 'zora', 'web'),
|
|
26
25
|
packageRoot,
|
|
27
|
-
packageVersion
|
|
26
|
+
packageVersion,
|
|
28
27
|
});
|
|
29
28
|
}
|
|
30
29
|
catch (error) {
|
package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createWebDesiredStateWithNodeAsync.js","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"createWebDesiredStateWithNodeAsync.js","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\n\nimport { readWebDesiredStateWithNodeAsync } from '../adapters/outbound/node/readWebDesiredStateWithNodeAsync';\nimport { readWebComponentPackageMetadataAsync } from './readWebComponentPackageMetadataAsync';\nimport { synchronizeWebComponentArtifactsWithNodeAsync } from './synchronizeWebComponentArtifactsWithNodeAsync';\n\n/*** Add one requested web component and regenerate the complete declared set. */\nexport async function createWebDesiredStateWithNodeAsync(input: {\n readonly component: string;\n readonly projectRoot: string;\n}) {\n const desired = await readWebDesiredStateWithNodeAsync(input.projectRoot, true);\n const components = [...new Set([...desired.components, input.component])].sort();\n const { packageRoot, packageVersion } = await readWebComponentPackageMetadataAsync();\n const desiredPath = resolve(input.projectRoot, 'zora.web.json');\n const previous = await readFile(desiredPath, 'utf8').catch((error: unknown) => {\n if (isMissingFile(error)) return undefined;\n throw error;\n });\n const next = `${JSON.stringify({ schemaVersion: 1, components }, null, 2)}\\n`;\n if (next !== previous) await replaceDesiredStateAsync(desiredPath, next);\n try {\n return await synchronizeWebComponentArtifactsWithNodeAsync({\n components,\n outputDirectory: resolve(input.projectRoot, '.ankh', 'zora', 'web'),\n packageRoot,\n packageVersion,\n });\n } catch (error) {\n if (next !== previous) {\n try {\n if (previous === undefined) await rm(desiredPath);\n else await replaceDesiredStateAsync(desiredPath, previous);\n } catch (rollbackError) {\n throw new AggregateError([error, rollbackError], 'ZORA create and rollback failed.', {\n cause: rollbackError,\n });\n }\n }\n throw error;\n }\n}\n\n/*** Replace the authoritative project declaration only after its complete contents are staged. */\nasync function replaceDesiredStateAsync(path: string, content: string): Promise<void> {\n const temporaryPath = join(dirname(path), `.zora-web-${randomUUID()}.tmp`);\n try {\n await writeFile(temporaryPath, content, 'utf8');\n await rename(temporaryPath, path);\n } finally {\n await rm(temporaryPath, { force: true });\n }\n}\n\n/*** Recognize only absent desired state, not unrelated filesystem failures. */\nfunction isMissingFile(error: unknown): boolean {\n return error instanceof Error && 'code' in error && error.code === 'ENOENT';\n}\n"]}
|
package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/*** Reads the active ZORA package location and version for generated web artifacts. */
|
|
2
|
+
export declare function readWebComponentPackageMetadataAsync(): Promise<WebComponentPackageMetadata>;
|
|
3
|
+
interface WebComponentPackageMetadata {
|
|
4
|
+
readonly packageRoot: string;
|
|
5
|
+
readonly packageVersion: string;
|
|
6
|
+
}
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=readWebComponentPackageMetadataAsync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readWebComponentPackageMetadataAsync.d.ts","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.ts"],"names":[],"mappings":"AAIA,uFAAuF;AACvF,wBAAsB,oCAAoC,IAAI,OAAO,CAAC,2BAA2B,CAAC,CAOjG;AAED,UAAU,2BAA2B;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC"}
|
package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
/*** Reads the active ZORA package location and version for generated web artifacts. */
|
|
5
|
+
export async function readWebComponentPackageMetadataAsync() {
|
|
6
|
+
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');
|
|
7
|
+
const packageJson = JSON.parse(await readFile(resolve(packageRoot, 'package.json'), 'utf8'));
|
|
8
|
+
return { packageRoot, packageVersion: packageJson.version };
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=readWebComponentPackageMetadataAsync.js.map
|
package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readWebComponentPackageMetadataAsync.js","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,oCAAoC;IACxD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IACpF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAE1F,CAAC;IAEF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;AAC9D,CAAC","sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/*** Reads the active ZORA package location and version for generated web artifacts. */\nexport async function readWebComponentPackageMetadataAsync(): Promise<WebComponentPackageMetadata> {\n const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');\n const packageJson = JSON.parse(await readFile(resolve(packageRoot, 'package.json'), 'utf8')) as {\n readonly version: string;\n };\n\n return { packageRoot, packageVersion: packageJson.version };\n}\n\ninterface WebComponentPackageMetadata {\n readonly packageRoot: string;\n readonly packageVersion: string;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synchronizeDeclaredWebComponentsWithNodeAsync.d.ts","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"synchronizeDeclaredWebComponentsWithNodeAsync.d.ts","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.ts"],"names":[],"mappings":"AAMA,oFAAoF;AACpF,wBAAsB,6CAA6C,CAAC,WAAW,EAAE,MAAM,4HAStF"}
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dirname, resolve } from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
1
|
+
import { resolve } from 'node:path';
|
|
4
2
|
import { readWebDesiredStateWithNodeAsync } from '../adapters/outbound/node/readWebDesiredStateWithNodeAsync';
|
|
3
|
+
import { readWebComponentPackageMetadataAsync } from './readWebComponentPackageMetadataAsync';
|
|
5
4
|
import { synchronizeWebComponentArtifactsWithNodeAsync } from './synchronizeWebComponentArtifactsWithNodeAsync';
|
|
6
5
|
/*** Load project desired state and sync it from the active ZORA package release. */
|
|
7
6
|
export async function synchronizeDeclaredWebComponentsWithNodeAsync(projectRoot) {
|
|
8
7
|
const desired = await readWebDesiredStateWithNodeAsync(projectRoot, false);
|
|
9
|
-
const packageRoot =
|
|
10
|
-
const packageJson = JSON.parse(await readFile(resolve(packageRoot, 'package.json'), 'utf8'));
|
|
8
|
+
const { packageRoot, packageVersion } = await readWebComponentPackageMetadataAsync();
|
|
11
9
|
return await synchronizeWebComponentArtifactsWithNodeAsync({
|
|
12
10
|
components: desired.components,
|
|
13
11
|
outputDirectory: resolve(projectRoot, '.ankh', 'zora', 'web'),
|
|
14
12
|
packageRoot,
|
|
15
|
-
packageVersion
|
|
13
|
+
packageVersion,
|
|
16
14
|
});
|
|
17
15
|
}
|
|
18
16
|
//# sourceMappingURL=synchronizeDeclaredWebComponentsWithNodeAsync.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synchronizeDeclaredWebComponentsWithNodeAsync.js","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"synchronizeDeclaredWebComponentsWithNodeAsync.js","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,gCAAgC,EAAE,MAAM,4DAA4D,CAAC;AAC9G,OAAO,EAAE,oCAAoC,EAAE,MAAM,wCAAwC,CAAC;AAC9F,OAAO,EAAE,6CAA6C,EAAE,MAAM,iDAAiD,CAAC;AAEhH,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,6CAA6C,CAAC,WAAmB;IACrF,MAAM,OAAO,GAAG,MAAM,gCAAgC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC3E,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,MAAM,oCAAoC,EAAE,CAAC;IACrF,OAAO,MAAM,6CAA6C,CAAC;QACzD,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,eAAe,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;QAC7D,WAAW;QACX,cAAc;KACf,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { resolve } from 'node:path';\n\nimport { readWebDesiredStateWithNodeAsync } from '../adapters/outbound/node/readWebDesiredStateWithNodeAsync';\nimport { readWebComponentPackageMetadataAsync } from './readWebComponentPackageMetadataAsync';\nimport { synchronizeWebComponentArtifactsWithNodeAsync } from './synchronizeWebComponentArtifactsWithNodeAsync';\n\n/*** Load project desired state and sync it from the active ZORA package release. */\nexport async function synchronizeDeclaredWebComponentsWithNodeAsync(projectRoot: string) {\n const desired = await readWebDesiredStateWithNodeAsync(projectRoot, false);\n const { packageRoot, packageVersion } = await readWebComponentPackageMetadataAsync();\n return await synchronizeWebComponentArtifactsWithNodeAsync({\n components: desired.components,\n outputDirectory: resolve(projectRoot, '.ankh', 'zora', 'web'),\n packageRoot,\n packageVersion,\n });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "25.8.
|
|
4
|
+
"version": "25.8.17",
|
|
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": {
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
"ui-kit"
|
|
27
27
|
],
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"@react-native-vector-icons/fontawesome": "^13.1.3",
|
|
30
|
-
"@react-native-vector-icons/fontawesome5": "^13.1.3",
|
|
31
|
-
"@react-native-vector-icons/fontawesome6": "^13.1.4",
|
|
32
|
-
"@react-native-vector-icons/ionicons": "^13.1.3",
|
|
33
|
-
"@react-native-vector-icons/material-design-icons": "^13.1.3",
|
|
29
|
+
"@react-native-vector-icons/fontawesome": "^13.1.3 || ^14.0.0",
|
|
30
|
+
"@react-native-vector-icons/fontawesome5": "^13.1.3 || ^14.0.0",
|
|
31
|
+
"@react-native-vector-icons/fontawesome6": "^13.1.4 || ^14.0.0",
|
|
32
|
+
"@react-native-vector-icons/ionicons": "^13.1.3 || ^14.0.0",
|
|
33
|
+
"@react-native-vector-icons/material-design-icons": "^13.1.3 || ^14.0.0",
|
|
34
34
|
"react": "19.2.3",
|
|
35
35
|
"react-native": "0.86.x",
|
|
36
36
|
"react-native-gesture-handler": "~2.32.0",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@ankhorage/reader": "^0.1.1",
|
|
51
51
|
"@ankhorage/runtime": "^5.0.3",
|
|
52
52
|
"@ankhorage/surface": "^9.4.6",
|
|
53
|
-
"@ankhorage/utility": "^1.9.
|
|
53
|
+
"@ankhorage/utility": "^1.9.86",
|
|
54
54
|
"chess.js": "^1.4.0",
|
|
55
55
|
"expo-document-picker": "~57.0.3",
|
|
56
56
|
"expo-image-picker": "~57.0.20"
|
|
@@ -149,13 +149,13 @@
|
|
|
149
149
|
"version-packages": "ankhorage-changeset version"
|
|
150
150
|
},
|
|
151
151
|
"devDependencies": {
|
|
152
|
-
"@ankhorage/devtools": "^2.3.
|
|
152
|
+
"@ankhorage/devtools": "^2.3.21",
|
|
153
153
|
"@ankhorage/paradox": "^0.3.5",
|
|
154
|
-
"@react-native-vector-icons/fontawesome": "^
|
|
155
|
-
"@react-native-vector-icons/fontawesome5": "^
|
|
156
|
-
"@react-native-vector-icons/fontawesome6": "^
|
|
157
|
-
"@react-native-vector-icons/ionicons": "^
|
|
158
|
-
"@react-native-vector-icons/material-design-icons": "^
|
|
154
|
+
"@react-native-vector-icons/fontawesome": "^14.0.0",
|
|
155
|
+
"@react-native-vector-icons/fontawesome5": "^14.0.0",
|
|
156
|
+
"@react-native-vector-icons/fontawesome6": "^14.0.0",
|
|
157
|
+
"@react-native-vector-icons/ionicons": "^14.0.0",
|
|
158
|
+
"@react-native-vector-icons/material-design-icons": "^14.0.0",
|
|
159
159
|
"@types/bun": "^1.4.2",
|
|
160
160
|
"@types/node": "^26.6.5",
|
|
161
161
|
"@types/react": "^19.3.0",
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
"@types/react-native-web": "^0.19.3",
|
|
164
164
|
"cytoscape": "^3.34.4",
|
|
165
165
|
"cytoscape-elk": "^2.3.0",
|
|
166
|
-
"happy-dom": "^21.0.
|
|
166
|
+
"happy-dom": "^21.0.4",
|
|
167
167
|
"react": "19.2.3",
|
|
168
168
|
"react-dom": "19.2.3",
|
|
169
169
|
"react-native": "0.86.3",
|
|
@@ -29,6 +29,26 @@ const RNVI_PLUGINS = [
|
|
|
29
29
|
'@react-native-vector-icons/fontawesome6',
|
|
30
30
|
'@react-native-vector-icons/ionicons',
|
|
31
31
|
] as const;
|
|
32
|
+
const EXPO_57_GRID_WORKSPACES_CONTRACT = {
|
|
33
|
+
expo: '~57.0.30',
|
|
34
|
+
metroConfig: '0.86.3',
|
|
35
|
+
typesReact: '~19.2.18',
|
|
36
|
+
zora: '25.8.15',
|
|
37
|
+
} as const;
|
|
38
|
+
const GRID_WORKSPACES_MANIFEST = 'examples/grid-workspaces/package.json';
|
|
39
|
+
|
|
40
|
+
function readRenovatePackageRule(packageName: string): string {
|
|
41
|
+
const renovateSource = readFileSync(join(ROOT, 'renovate.json5'), 'utf8');
|
|
42
|
+
const packageMatcher = `matchPackageNames: ['${packageName}'],`;
|
|
43
|
+
const ruleStart = renovateSource.lastIndexOf(' {', renovateSource.indexOf(packageMatcher));
|
|
44
|
+
const ruleEnd = renovateSource.indexOf('\n },', renovateSource.indexOf(packageMatcher));
|
|
45
|
+
|
|
46
|
+
if (ruleStart === -1 || ruleEnd === -1) {
|
|
47
|
+
throw new Error(`Expected a Renovate rule for ${packageName}.`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return renovateSource.slice(ruleStart, ruleEnd);
|
|
51
|
+
}
|
|
32
52
|
|
|
33
53
|
function readJson(path: string): Record<string, unknown> {
|
|
34
54
|
const value: unknown = JSON.parse(readFileSync(path, 'utf8'));
|
|
@@ -137,6 +157,36 @@ describe('Expo 57 example boundary', () => {
|
|
|
137
157
|
expect(scaffoldSource).not.toContain('ZoraTabBar');
|
|
138
158
|
});
|
|
139
159
|
|
|
160
|
+
test('pins Grid Workspaces native tooling to the Expo 57 React Native contract', () => {
|
|
161
|
+
const packageJson = readExamplePackage('examples/grid-workspaces');
|
|
162
|
+
const dependencies = readRecord(packageJson, 'dependencies');
|
|
163
|
+
const development = readRecord(packageJson, 'devDependencies');
|
|
164
|
+
|
|
165
|
+
expect(dependencies.expo).toBe(EXPO_57_GRID_WORKSPACES_CONTRACT.expo);
|
|
166
|
+
expect(dependencies['@ankhorage/zora']).toBe(EXPO_57_GRID_WORKSPACES_CONTRACT.zora);
|
|
167
|
+
expect(dependencies['@react-native/metro-config']).toBe(
|
|
168
|
+
EXPO_57_GRID_WORKSPACES_CONTRACT.metroConfig,
|
|
169
|
+
);
|
|
170
|
+
expect(development['@types/react']).toBe(EXPO_57_GRID_WORKSPACES_CONTRACT.typesReact);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('limits Grid Workspaces native-tooling Renovate constraints to its manifest', () => {
|
|
174
|
+
const packageJson = readJson(join(ROOT, 'package.json'));
|
|
175
|
+
const development = readRecord(packageJson, 'devDependencies');
|
|
176
|
+
|
|
177
|
+
for (const [packageName, allowedVersion] of [
|
|
178
|
+
['@react-native/metro-config', EXPO_57_GRID_WORKSPACES_CONTRACT.metroConfig],
|
|
179
|
+
['@types/react', EXPO_57_GRID_WORKSPACES_CONTRACT.typesReact],
|
|
180
|
+
]) {
|
|
181
|
+
const renovateRule = readRenovatePackageRule(packageName);
|
|
182
|
+
|
|
183
|
+
expect(renovateRule).toContain(`matchFileNames: ['${GRID_WORKSPACES_MANIFEST}'],`);
|
|
184
|
+
expect(renovateRule).toContain(`allowedVersions: '${allowedVersion}',`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
expect(development['@types/react']).not.toBe(EXPO_57_GRID_WORKSPACES_CONTRACT.typesReact);
|
|
188
|
+
});
|
|
189
|
+
|
|
140
190
|
test('uses Navigator native tabs in every router example', () => {
|
|
141
191
|
for (const directory of ROUTER_EXAMPLE_DIRS) {
|
|
142
192
|
const packageJson = readExamplePackage(directory);
|
|
@@ -3,6 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import type { DatePickerProps } from '../../../types/date-picker';
|
|
4
4
|
import { Button } from '../../button/public';
|
|
5
5
|
import { View } from '../../layout/public';
|
|
6
|
+
import { PickerHeader } from '../../picker/composition/PickerHeader';
|
|
6
7
|
import { Text } from '../../typography/public';
|
|
7
8
|
import { formatLocalDate, parseLocalDate } from '../utils/localDate';
|
|
8
9
|
|
|
@@ -61,28 +62,6 @@ interface DatePickerContentProps extends Pick<
|
|
|
61
62
|
onSelect: (value: Date) => void;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
/*** Renders the shared title block used by picker overlays. */
|
|
65
|
-
function PickerHeader({
|
|
66
|
-
description,
|
|
67
|
-
title,
|
|
68
|
-
}: {
|
|
69
|
-
description: React.ReactNode | undefined;
|
|
70
|
-
title: React.ReactNode;
|
|
71
|
-
}) {
|
|
72
|
-
return (
|
|
73
|
-
<View gap="xxs">
|
|
74
|
-
<Text align="center" variant="label" weight="semiBold">
|
|
75
|
-
{title}
|
|
76
|
-
</Text>
|
|
77
|
-
{description ? (
|
|
78
|
-
<Text align="center" emphasis="muted" variant="bodySmall">
|
|
79
|
-
{description}
|
|
80
|
-
</Text>
|
|
81
|
-
) : null}
|
|
82
|
-
</View>
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
65
|
/*** Renders previous and next month controls for the calendar. */
|
|
87
66
|
function DatePickerMonthNavigation({
|
|
88
67
|
displayMonth,
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { Field } from '@ankhorage/surface';
|
|
2
1
|
import type React from 'react';
|
|
3
2
|
|
|
4
3
|
import type { DatePickerProps } from '../../../types/date-picker';
|
|
5
|
-
import {
|
|
6
|
-
import { Text } from '../../typography/public';
|
|
4
|
+
import { PickerField } from '../../picker/composition/PickerField';
|
|
7
5
|
|
|
8
6
|
/*** Renders the shared DatePicker field frame around a platform-specific trigger. */
|
|
9
7
|
export function DatePickerField({
|
|
@@ -15,18 +13,7 @@ export function DatePickerField({
|
|
|
15
13
|
required,
|
|
16
14
|
testID,
|
|
17
15
|
}: DatePickerFieldProps) {
|
|
18
|
-
return
|
|
19
|
-
<Field
|
|
20
|
-
disabled={disabled}
|
|
21
|
-
errorText={error}
|
|
22
|
-
invalid={Boolean(error)}
|
|
23
|
-
label={label ? renderLabel(label, description) : undefined}
|
|
24
|
-
required={required}
|
|
25
|
-
testID={testID}
|
|
26
|
-
>
|
|
27
|
-
{children}
|
|
28
|
-
</Field>
|
|
29
|
-
);
|
|
16
|
+
return <PickerField {...{ children, description, disabled, error, label, required, testID }} />;
|
|
30
17
|
}
|
|
31
18
|
|
|
32
19
|
interface DatePickerFieldProps extends Pick<
|
|
@@ -35,19 +22,3 @@ interface DatePickerFieldProps extends Pick<
|
|
|
35
22
|
> {
|
|
36
23
|
children: React.ReactNode;
|
|
37
24
|
}
|
|
38
|
-
|
|
39
|
-
/*** Renders the picker label and optional supporting description. */
|
|
40
|
-
function renderLabel(label: React.ReactNode, description: React.ReactNode | undefined) {
|
|
41
|
-
return (
|
|
42
|
-
<View gap="xs">
|
|
43
|
-
<Text variant="label" weight="semiBold">
|
|
44
|
-
{label}
|
|
45
|
-
</Text>
|
|
46
|
-
{description ? (
|
|
47
|
-
<Text emphasis="muted" variant="bodySmall">
|
|
48
|
-
{description}
|
|
49
|
-
</Text>
|
|
50
|
-
) : null}
|
|
51
|
-
</View>
|
|
52
|
-
);
|
|
53
|
-
}
|
|
@@ -64,40 +64,29 @@ function findDirectionalNeighbour(
|
|
|
64
64
|
): MatrixGridSparseIndexEntry | undefined {
|
|
65
65
|
if (!entries) return undefined;
|
|
66
66
|
const coordinate = getAxisCoordinate(current, axis);
|
|
67
|
-
const insertionIndex =
|
|
67
|
+
const insertionIndex = findFirstAtOrAfter(entries, coordinate, axis, false);
|
|
68
68
|
if (direction === -1) return insertionIndex === 0 ? undefined : entries[insertionIndex - 1];
|
|
69
|
-
return entries[
|
|
69
|
+
return entries[findFirstAtOrAfter(entries, coordinate, axis, true)];
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
/***
|
|
73
|
-
function
|
|
72
|
+
/*** Locates the first entry at or after a matrix coordinate in a sorted sparse axis. */
|
|
73
|
+
function findFirstAtOrAfter(
|
|
74
74
|
entries: readonly MatrixGridSparseIndexEntry[],
|
|
75
75
|
coordinate: number,
|
|
76
76
|
axis: 'columnIndex' | 'rowIndex',
|
|
77
|
+
strictlyAfter: boolean,
|
|
77
78
|
): number {
|
|
78
79
|
let lower = 0;
|
|
79
80
|
let upper = entries.length;
|
|
80
81
|
while (lower < upper) {
|
|
81
82
|
const middle = Math.floor((lower + upper) / 2);
|
|
82
83
|
const entry = entries.at(middle);
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
/*** Locate the first index at or after a matrix coordinate in a sorted sparse axis. */
|
|
90
|
-
function findFirstGreaterOrEqual(
|
|
91
|
-
entries: readonly MatrixGridSparseIndexEntry[],
|
|
92
|
-
coordinate: number,
|
|
93
|
-
axis: 'columnIndex' | 'rowIndex',
|
|
94
|
-
): number {
|
|
95
|
-
let lower = 0;
|
|
96
|
-
let upper = entries.length;
|
|
97
|
-
while (lower < upper) {
|
|
98
|
-
const middle = Math.floor((lower + upper) / 2);
|
|
99
|
-
const entry = entries.at(middle);
|
|
100
|
-
if (entry && getAxisCoordinate(entry, axis) < coordinate) lower = middle + 1;
|
|
84
|
+
const entryCoordinate = entry ? getAxisCoordinate(entry, axis) : undefined;
|
|
85
|
+
if (
|
|
86
|
+
entryCoordinate !== undefined &&
|
|
87
|
+
(strictlyAfter ? entryCoordinate <= coordinate : entryCoordinate < coordinate)
|
|
88
|
+
)
|
|
89
|
+
lower = middle + 1;
|
|
101
90
|
else upper = middle;
|
|
102
91
|
}
|
|
103
92
|
return lower;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Field } from '@ankhorage/surface';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
|
|
4
|
+
import { View } from '../../layout/public';
|
|
5
|
+
import { Text } from '../../typography/public';
|
|
6
|
+
|
|
7
|
+
/*** Renders the common field frame and label treatment for picker controls. */
|
|
8
|
+
export function PickerField({
|
|
9
|
+
children,
|
|
10
|
+
description,
|
|
11
|
+
disabled,
|
|
12
|
+
error,
|
|
13
|
+
label,
|
|
14
|
+
required,
|
|
15
|
+
testID,
|
|
16
|
+
}: PickerFieldProps) {
|
|
17
|
+
return (
|
|
18
|
+
<Field
|
|
19
|
+
disabled={disabled}
|
|
20
|
+
errorText={error}
|
|
21
|
+
invalid={Boolean(error)}
|
|
22
|
+
label={label ? <PickerFieldLabel description={description} label={label} /> : undefined}
|
|
23
|
+
required={required}
|
|
24
|
+
testID={testID}
|
|
25
|
+
>
|
|
26
|
+
{children}
|
|
27
|
+
</Field>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface PickerFieldProps {
|
|
32
|
+
readonly children: React.ReactNode;
|
|
33
|
+
readonly description: React.ReactNode | undefined;
|
|
34
|
+
readonly disabled: boolean | undefined;
|
|
35
|
+
readonly error: React.ReactNode | undefined;
|
|
36
|
+
readonly label: React.ReactNode | undefined;
|
|
37
|
+
readonly required: boolean | undefined;
|
|
38
|
+
readonly testID: string | undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/*** Renders a picker field label and its optional supporting description. */
|
|
42
|
+
function PickerFieldLabel({
|
|
43
|
+
description,
|
|
44
|
+
label,
|
|
45
|
+
}: {
|
|
46
|
+
readonly description: React.ReactNode | undefined;
|
|
47
|
+
readonly label: React.ReactNode;
|
|
48
|
+
}) {
|
|
49
|
+
return (
|
|
50
|
+
<View gap="xs">
|
|
51
|
+
<Text variant="label" weight="semiBold">
|
|
52
|
+
{label}
|
|
53
|
+
</Text>
|
|
54
|
+
{description ? (
|
|
55
|
+
<Text emphasis="muted" variant="bodySmall">
|
|
56
|
+
{description}
|
|
57
|
+
</Text>
|
|
58
|
+
) : null}
|
|
59
|
+
</View>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
|
|
3
|
+
import { View } from '../../layout/public';
|
|
4
|
+
import { Text } from '../../typography/public';
|
|
5
|
+
|
|
6
|
+
/*** Renders the title block shared by picker overlay content. */
|
|
7
|
+
export function PickerHeader({ description, title }: PickerHeaderProps) {
|
|
8
|
+
return (
|
|
9
|
+
<View gap="xxs">
|
|
10
|
+
<Text align="center" variant="label" weight="semiBold">
|
|
11
|
+
{title}
|
|
12
|
+
</Text>
|
|
13
|
+
{description ? (
|
|
14
|
+
<Text align="center" emphasis="muted" variant="bodySmall">
|
|
15
|
+
{description}
|
|
16
|
+
</Text>
|
|
17
|
+
) : null}
|
|
18
|
+
</View>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface PickerHeaderProps {
|
|
23
|
+
readonly description: React.ReactNode | undefined;
|
|
24
|
+
readonly title: React.ReactNode;
|
|
25
|
+
}
|