@tetherto/dev-websites-core 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -9
- package/dist/cms/index.d.mts +3 -0
- package/dist/cms/index.mjs +3 -0
- package/dist/cms.mjs +1419 -0
- package/dist/cms.mjs.map +1 -0
- package/dist/i18n/index.d.mts +2 -0
- package/dist/i18n/index.mjs +2 -0
- package/dist/i18n.mjs +10 -0
- package/dist/i18n.mjs.map +1 -0
- package/dist/index.d.mts +214 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +7 -0
- package/dist/index2.d.mts +8 -0
- package/dist/index2.d.mts.map +1 -0
- package/dist/index3.d.mts +63 -0
- package/dist/index3.d.mts.map +1 -0
- package/dist/index4.d.mts +23 -0
- package/dist/index4.d.mts.map +1 -0
- package/dist/index5.d.mts +6 -0
- package/dist/logger.mjs +44 -0
- package/dist/logger.mjs.map +1 -0
- package/dist/readMediaBuffer.d.mts +15 -0
- package/dist/readMediaBuffer.d.mts.map +1 -0
- package/dist/readMediaBuffer.mjs +62 -0
- package/dist/readMediaBuffer.mjs.map +1 -0
- package/dist/seo/index.d.mts +2 -0
- package/dist/seo/index.mjs +2 -0
- package/dist/seo.mjs +124 -0
- package/dist/seo.mjs.map +1 -0
- package/dist/ui/a11y/focus.d.mts +6 -0
- package/dist/ui/a11y/focus.d.mts.map +1 -0
- package/dist/ui/a11y/focus.mjs +7 -0
- package/dist/ui/a11y/focus.mjs.map +1 -0
- package/dist/ui/a11y/index.d.mts +4 -0
- package/dist/ui/a11y/index.mjs +4 -0
- package/dist/ui/carousel/index.d.mts +3 -0
- package/dist/ui/carousel/index.mjs +3 -0
- package/dist/ui/components/Accordion/Accordion.d.mts +16 -0
- package/dist/ui/components/Accordion/Accordion.d.mts.map +1 -0
- package/dist/ui/components/Accordion/Accordion.mjs +51 -0
- package/dist/ui/components/Accordion/Accordion.mjs.map +1 -0
- package/dist/ui/components/Accordion/index.d.mts +2 -0
- package/dist/ui/components/Accordion/index.mjs +2 -0
- package/dist/ui/components/Avatar/Avatar.d.mts +9 -0
- package/dist/ui/components/Avatar/Avatar.d.mts.map +1 -0
- package/dist/ui/components/Avatar/Avatar.mjs +15 -0
- package/dist/ui/components/Avatar/Avatar.mjs.map +1 -0
- package/dist/ui/components/Avatar/index.d.mts +2 -0
- package/dist/ui/components/Avatar/index.mjs +2 -0
- package/dist/ui/components/Badge/Badge.d.mts +14 -0
- package/dist/ui/components/Badge/Badge.d.mts.map +1 -0
- package/dist/ui/components/Badge/Badge.mjs +30 -0
- package/dist/ui/components/Badge/Badge.mjs.map +1 -0
- package/dist/ui/components/Badge/index.d.mts +2 -0
- package/dist/ui/components/Badge/index.mjs +2 -0
- package/dist/ui/components/BadgeVersion/BadgeVersion.d.mts +24 -0
- package/dist/ui/components/BadgeVersion/BadgeVersion.d.mts.map +1 -0
- package/dist/ui/components/BadgeVersion/BadgeVersion.mjs +66 -0
- package/dist/ui/components/BadgeVersion/BadgeVersion.mjs.map +1 -0
- package/dist/ui/components/BadgeVersion/index.d.mts +2 -0
- package/dist/ui/components/BadgeVersion/index.mjs +2 -0
- package/dist/ui/components/Button/Button.d.mts +14 -0
- package/dist/ui/components/Button/Button.d.mts.map +1 -0
- package/dist/ui/components/Button/Button.mjs +48 -0
- package/dist/ui/components/Button/Button.mjs.map +1 -0
- package/dist/ui/components/Button/index.d.mts +2 -0
- package/dist/ui/components/Button/index.mjs +2 -0
- package/dist/ui/components/Card/Card.d.mts +14 -0
- package/dist/ui/components/Card/Card.d.mts.map +1 -0
- package/dist/ui/components/Card/Card.mjs +40 -0
- package/dist/ui/components/Card/Card.mjs.map +1 -0
- package/dist/ui/components/Card/index.d.mts +2 -0
- package/dist/ui/components/Card/index.mjs +2 -0
- package/dist/ui/components/Carousel/Carousel.d.mts +42 -0
- package/dist/ui/components/Carousel/Carousel.d.mts.map +1 -0
- package/dist/ui/components/Carousel/Carousel.mjs +164 -0
- package/dist/ui/components/Carousel/Carousel.mjs.map +1 -0
- package/dist/ui/components/Carousel/index.d.mts +2 -0
- package/dist/ui/components/Carousel/index.mjs +2 -0
- package/dist/ui/components/Checkbox/Checkbox.d.mts +8 -0
- package/dist/ui/components/Checkbox/Checkbox.d.mts.map +1 -0
- package/dist/ui/components/Checkbox/Checkbox.mjs +39 -0
- package/dist/ui/components/Checkbox/Checkbox.mjs.map +1 -0
- package/dist/ui/components/Checkbox/index.d.mts +2 -0
- package/dist/ui/components/Checkbox/index.mjs +2 -0
- package/dist/ui/components/CodeBlock/CodeBlock.d.mts +22 -0
- package/dist/ui/components/CodeBlock/CodeBlock.d.mts.map +1 -0
- package/dist/ui/components/CodeBlock/CodeBlock.mjs +66 -0
- package/dist/ui/components/CodeBlock/CodeBlock.mjs.map +1 -0
- package/dist/ui/components/CodeBlock/index.d.mts +2 -0
- package/dist/ui/components/CodeBlock/index.mjs +2 -0
- package/dist/ui/components/CodeBlockTabs/CodeBlockTabs.d.mts +19 -0
- package/dist/ui/components/CodeBlockTabs/CodeBlockTabs.d.mts.map +1 -0
- package/dist/ui/components/CodeBlockTabs/CodeBlockTabs.mjs +59 -0
- package/dist/ui/components/CodeBlockTabs/CodeBlockTabs.mjs.map +1 -0
- package/dist/ui/components/CodeBlockTabs/index.d.mts +2 -0
- package/dist/ui/components/CodeBlockTabs/index.mjs +2 -0
- package/dist/ui/components/CollapsibleSection/CollapsibleSection.d.mts +13 -0
- package/dist/ui/components/CollapsibleSection/CollapsibleSection.d.mts.map +1 -0
- package/dist/ui/components/CollapsibleSection/CollapsibleSection.mjs +55 -0
- package/dist/ui/components/CollapsibleSection/CollapsibleSection.mjs.map +1 -0
- package/dist/ui/components/CollapsibleSection/index.d.mts +2 -0
- package/dist/ui/components/CollapsibleSection/index.mjs +2 -0
- package/dist/ui/components/CopyButton/CopyButton.d.mts +12 -0
- package/dist/ui/components/CopyButton/CopyButton.d.mts.map +1 -0
- package/dist/ui/components/CopyButton/CopyButton.mjs +45 -0
- package/dist/ui/components/CopyButton/CopyButton.mjs.map +1 -0
- package/dist/ui/components/CopyButton/index.d.mts +2 -0
- package/dist/ui/components/CopyButton/index.mjs +2 -0
- package/dist/ui/components/Dialog/Dialog.d.mts +26 -0
- package/dist/ui/components/Dialog/Dialog.d.mts.map +1 -0
- package/dist/ui/components/Dialog/Dialog.mjs +79 -0
- package/dist/ui/components/Dialog/Dialog.mjs.map +1 -0
- package/dist/ui/components/Dialog/index.d.mts +2 -0
- package/dist/ui/components/Dialog/index.mjs +2 -0
- package/dist/ui/components/EmptyState/EmptyState.d.mts +18 -0
- package/dist/ui/components/EmptyState/EmptyState.d.mts.map +1 -0
- package/dist/ui/components/EmptyState/EmptyState.mjs +36 -0
- package/dist/ui/components/EmptyState/EmptyState.mjs.map +1 -0
- package/dist/ui/components/EmptyState/index.d.mts +2 -0
- package/dist/ui/components/EmptyState/index.mjs +2 -0
- package/dist/ui/components/FieldError/FieldError.d.mts +14 -0
- package/dist/ui/components/FieldError/FieldError.d.mts.map +1 -0
- package/dist/ui/components/FieldError/FieldError.mjs +19 -0
- package/dist/ui/components/FieldError/FieldError.mjs.map +1 -0
- package/dist/ui/components/FieldError/index.d.mts +2 -0
- package/dist/ui/components/FieldError/index.mjs +2 -0
- package/dist/ui/components/FormattedDate/FormattedDate.d.mts +15 -0
- package/dist/ui/components/FormattedDate/FormattedDate.d.mts.map +1 -0
- package/dist/ui/components/FormattedDate/FormattedDate.mjs +23 -0
- package/dist/ui/components/FormattedDate/FormattedDate.mjs.map +1 -0
- package/dist/ui/components/FormattedDate/index.d.mts +2 -0
- package/dist/ui/components/FormattedDate/index.mjs +2 -0
- package/dist/ui/components/IconButton/IconButton.d.mts +10 -0
- package/dist/ui/components/IconButton/IconButton.d.mts.map +1 -0
- package/dist/ui/components/IconButton/IconButton.mjs +19 -0
- package/dist/ui/components/IconButton/IconButton.mjs.map +1 -0
- package/dist/ui/components/IconButton/index.d.mts +2 -0
- package/dist/ui/components/IconButton/index.mjs +2 -0
- package/dist/ui/components/Input/Input.d.mts +12 -0
- package/dist/ui/components/Input/Input.d.mts.map +1 -0
- package/dist/ui/components/Input/Input.mjs +43 -0
- package/dist/ui/components/Input/Input.mjs.map +1 -0
- package/dist/ui/components/Input/index.d.mts +2 -0
- package/dist/ui/components/Input/index.mjs +2 -0
- package/dist/ui/components/Label/Label.d.mts +11 -0
- package/dist/ui/components/Label/Label.d.mts.map +1 -0
- package/dist/ui/components/Label/Label.mjs +18 -0
- package/dist/ui/components/Label/Label.mjs.map +1 -0
- package/dist/ui/components/Label/index.d.mts +2 -0
- package/dist/ui/components/Label/index.mjs +2 -0
- package/dist/ui/components/LazyVideo/LazyVideo.d.mts +23 -0
- package/dist/ui/components/LazyVideo/LazyVideo.d.mts.map +1 -0
- package/dist/ui/components/LazyVideo/LazyVideo.mjs +57 -0
- package/dist/ui/components/LazyVideo/LazyVideo.mjs.map +1 -0
- package/dist/ui/components/LazyVideo/index.d.mts +2 -0
- package/dist/ui/components/LazyVideo/index.mjs +2 -0
- package/dist/ui/components/Pagination/Pagination.d.mts +38 -0
- package/dist/ui/components/Pagination/Pagination.d.mts.map +1 -0
- package/dist/ui/components/Pagination/Pagination.mjs +110 -0
- package/dist/ui/components/Pagination/Pagination.mjs.map +1 -0
- package/dist/ui/components/Pagination/index.d.mts +2 -0
- package/dist/ui/components/Pagination/index.mjs +2 -0
- package/dist/ui/components/PaginationItem/PaginationItem.d.mts +15 -0
- package/dist/ui/components/PaginationItem/PaginationItem.d.mts.map +1 -0
- package/dist/ui/components/PaginationItem/PaginationItem.mjs +34 -0
- package/dist/ui/components/PaginationItem/PaginationItem.mjs.map +1 -0
- package/dist/ui/components/PaginationItem/index.d.mts +2 -0
- package/dist/ui/components/PaginationItem/index.mjs +2 -0
- package/dist/ui/components/PasswordInput/PasswordInput.d.mts +10 -0
- package/dist/ui/components/PasswordInput/PasswordInput.d.mts.map +1 -0
- package/dist/ui/components/PasswordInput/PasswordInput.mjs +39 -0
- package/dist/ui/components/PasswordInput/PasswordInput.mjs.map +1 -0
- package/dist/ui/components/PasswordInput/index.d.mts +2 -0
- package/dist/ui/components/PasswordInput/index.mjs +2 -0
- package/dist/ui/components/ProgressStepper/ProgressStepper.d.mts +20 -0
- package/dist/ui/components/ProgressStepper/ProgressStepper.d.mts.map +1 -0
- package/dist/ui/components/ProgressStepper/ProgressStepper.mjs +39 -0
- package/dist/ui/components/ProgressStepper/ProgressStepper.mjs.map +1 -0
- package/dist/ui/components/ProgressStepper/index.d.mts +2 -0
- package/dist/ui/components/ProgressStepper/index.mjs +2 -0
- package/dist/ui/components/Prose/Prose.d.mts +10 -0
- package/dist/ui/components/Prose/Prose.d.mts.map +1 -0
- package/dist/ui/components/Prose/Prose.mjs +19 -0
- package/dist/ui/components/Prose/Prose.mjs.map +1 -0
- package/dist/ui/components/Prose/index.d.mts +2 -0
- package/dist/ui/components/Prose/index.mjs +2 -0
- package/dist/ui/components/Radio/Radio.d.mts +8 -0
- package/dist/ui/components/Radio/Radio.d.mts.map +1 -0
- package/dist/ui/components/Radio/Radio.mjs +25 -0
- package/dist/ui/components/Radio/Radio.mjs.map +1 -0
- package/dist/ui/components/Radio/index.d.mts +2 -0
- package/dist/ui/components/Radio/index.mjs +2 -0
- package/dist/ui/components/Reveal/Reveal.d.mts +10 -0
- package/dist/ui/components/Reveal/Reveal.d.mts.map +1 -0
- package/dist/ui/components/Reveal/Reveal.mjs +18 -0
- package/dist/ui/components/Reveal/Reveal.mjs.map +1 -0
- package/dist/ui/components/Reveal/index.d.mts +2 -0
- package/dist/ui/components/Reveal/index.mjs +2 -0
- package/dist/ui/components/SearchInput/SearchInput.d.mts +15 -0
- package/dist/ui/components/SearchInput/SearchInput.d.mts.map +1 -0
- package/dist/ui/components/SearchInput/SearchInput.mjs +28 -0
- package/dist/ui/components/SearchInput/SearchInput.mjs.map +1 -0
- package/dist/ui/components/SearchInput/index.d.mts +2 -0
- package/dist/ui/components/SearchInput/index.mjs +2 -0
- package/dist/ui/components/Select/Select.d.mts +34 -0
- package/dist/ui/components/Select/Select.d.mts.map +1 -0
- package/dist/ui/components/Select/Select.mjs +167 -0
- package/dist/ui/components/Select/Select.mjs.map +1 -0
- package/dist/ui/components/Select/index.d.mts +2 -0
- package/dist/ui/components/Select/index.mjs +2 -0
- package/dist/ui/components/Sheet/Sheet.d.mts +19 -0
- package/dist/ui/components/Sheet/Sheet.d.mts.map +1 -0
- package/dist/ui/components/Sheet/Sheet.mjs +59 -0
- package/dist/ui/components/Sheet/Sheet.mjs.map +1 -0
- package/dist/ui/components/Sheet/index.d.mts +2 -0
- package/dist/ui/components/Sheet/index.mjs +2 -0
- package/dist/ui/components/StaggerReveal/StaggerReveal.d.mts +10 -0
- package/dist/ui/components/StaggerReveal/StaggerReveal.d.mts.map +1 -0
- package/dist/ui/components/StaggerReveal/StaggerReveal.mjs +31 -0
- package/dist/ui/components/StaggerReveal/StaggerReveal.mjs.map +1 -0
- package/dist/ui/components/StaggerReveal/index.d.mts +2 -0
- package/dist/ui/components/StaggerReveal/index.mjs +2 -0
- package/dist/ui/components/Stepper/Stepper.d.mts +15 -0
- package/dist/ui/components/Stepper/Stepper.d.mts.map +1 -0
- package/dist/ui/components/Stepper/Stepper.mjs +38 -0
- package/dist/ui/components/Stepper/Stepper.mjs.map +1 -0
- package/dist/ui/components/Stepper/index.d.mts +2 -0
- package/dist/ui/components/Stepper/index.mjs +2 -0
- package/dist/ui/components/Switch/Switch.d.mts +12 -0
- package/dist/ui/components/Switch/Switch.d.mts.map +1 -0
- package/dist/ui/components/Switch/Switch.mjs +34 -0
- package/dist/ui/components/Switch/Switch.mjs.map +1 -0
- package/dist/ui/components/Switch/index.d.mts +2 -0
- package/dist/ui/components/Switch/index.mjs +2 -0
- package/dist/ui/components/TextButton/TextButton.d.mts +9 -0
- package/dist/ui/components/TextButton/TextButton.d.mts.map +1 -0
- package/dist/ui/components/TextButton/TextButton.mjs +16 -0
- package/dist/ui/components/TextButton/TextButton.mjs.map +1 -0
- package/dist/ui/components/TextButton/index.d.mts +2 -0
- package/dist/ui/components/TextButton/index.mjs +2 -0
- package/dist/ui/components/Textarea/Textarea.d.mts +9 -0
- package/dist/ui/components/Textarea/Textarea.d.mts.map +1 -0
- package/dist/ui/components/Textarea/Textarea.mjs +27 -0
- package/dist/ui/components/Textarea/Textarea.mjs.map +1 -0
- package/dist/ui/components/Textarea/index.d.mts +2 -0
- package/dist/ui/components/Textarea/index.mjs +2 -0
- package/dist/ui/components/Toast/Toast.d.mts +20 -0
- package/dist/ui/components/Toast/Toast.d.mts.map +1 -0
- package/dist/ui/components/Toast/Toast.mjs +128 -0
- package/dist/ui/components/Toast/Toast.mjs.map +1 -0
- package/dist/ui/components/Toast/index.d.mts +2 -0
- package/dist/ui/components/Toast/index.mjs +2 -0
- package/dist/ui/components/Tooltip/Tooltip.d.mts +11 -0
- package/dist/ui/components/Tooltip/Tooltip.d.mts.map +1 -0
- package/dist/ui/components/Tooltip/Tooltip.mjs +20 -0
- package/dist/ui/components/Tooltip/Tooltip.mjs.map +1 -0
- package/dist/ui/components/Tooltip/index.d.mts +2 -0
- package/dist/ui/components/Tooltip/index.mjs +2 -0
- package/dist/ui/components/VisuallyHidden/VisuallyHidden.d.mts +7 -0
- package/dist/ui/components/VisuallyHidden/VisuallyHidden.d.mts.map +1 -0
- package/dist/ui/components/VisuallyHidden/VisuallyHidden.mjs +13 -0
- package/dist/ui/components/VisuallyHidden/VisuallyHidden.mjs.map +1 -0
- package/dist/ui/components/VisuallyHidden/index.d.mts +2 -0
- package/dist/ui/components/VisuallyHidden/index.mjs +2 -0
- package/dist/ui/hooks/index.d.mts +2 -0
- package/dist/ui/hooks/index.mjs +2 -0
- package/dist/ui/hooks/useInView.d.mts +13 -0
- package/dist/ui/hooks/useInView.d.mts.map +1 -0
- package/dist/ui/hooks/useInView.mjs +37 -0
- package/dist/ui/hooks/useInView.mjs.map +1 -0
- package/dist/ui/index.d.mts +81 -0
- package/dist/ui/index.mjs +40 -0
- package/dist/ui/theme/preset.d.mts +170 -0
- package/dist/ui/theme/preset.d.mts.map +1 -0
- package/dist/ui/theme/preset.mjs +143 -0
- package/dist/ui/theme/preset.mjs.map +1 -0
- package/dist/ui/utils/cn.d.mts +6 -0
- package/dist/ui/utils/cn.d.mts.map +1 -0
- package/dist/ui/utils/cn.mjs +42 -0
- package/dist/ui/utils/cn.mjs.map +1 -0
- package/dist/ui/utils/index.d.mts +2 -0
- package/dist/ui/utils/index.mjs +2 -0
- package/dist/utils/index.d.mts +2 -0
- package/dist/utils/index.mjs +3 -0
- package/dist/utils.mjs +18 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +66 -7
- package/src/ui/theme/preset.css +53 -0
- package/src/ui/theme/preset.ts +131 -0
- package/src/ui/theme/theme.css +12 -0
- package/src/ui/theme/tokens.css +57 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { t as createLogger } from "./logger.mjs";
|
|
2
|
+
import { readFile } from "fs/promises";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
|
5
|
+
//#region src/cms/payload/readMediaBuffer.ts
|
|
6
|
+
/**
|
|
7
|
+
* Read a Payload-managed Media file's raw bytes, bypassing the public HTTP
|
|
8
|
+
* surface. Uses S3 when `AWS_S3_BUCKET` is set; otherwise reads from
|
|
9
|
+
* `<cwd>/media/<filename>` (Payload's default upload staticDir for `media`).
|
|
10
|
+
*/
|
|
11
|
+
const log = createLogger("readPayloadMedia");
|
|
12
|
+
let cachedS3Client = null;
|
|
13
|
+
function isS3Enabled() {
|
|
14
|
+
return Boolean(process.env.AWS_S3_BUCKET);
|
|
15
|
+
}
|
|
16
|
+
function getS3Client() {
|
|
17
|
+
if (cachedS3Client) return cachedS3Client;
|
|
18
|
+
const endpoint = process.env.AWS_S3_ENDPOINT?.trim();
|
|
19
|
+
const clientConfig = {
|
|
20
|
+
region: process.env.AWS_S3_REGION ?? "us-east-1",
|
|
21
|
+
...endpoint ? { endpoint } : {},
|
|
22
|
+
...process.env.AWS_S3_FORCE_PATH_STYLE === "true" ? { forcePathStyle: true } : {}
|
|
23
|
+
};
|
|
24
|
+
const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
|
|
25
|
+
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
|
|
26
|
+
if (accessKeyId && secretAccessKey) clientConfig.credentials = {
|
|
27
|
+
accessKeyId,
|
|
28
|
+
secretAccessKey
|
|
29
|
+
};
|
|
30
|
+
cachedS3Client = new S3Client(clientConfig);
|
|
31
|
+
return cachedS3Client;
|
|
32
|
+
}
|
|
33
|
+
async function readFromS3(filename) {
|
|
34
|
+
const bucket = process.env.AWS_S3_BUCKET;
|
|
35
|
+
if (!bucket) throw new Error("AWS_S3_BUCKET is not set — cannot read media from S3");
|
|
36
|
+
const response = await getS3Client().send(new GetObjectCommand({
|
|
37
|
+
Bucket: bucket,
|
|
38
|
+
Key: filename
|
|
39
|
+
}));
|
|
40
|
+
if (!response.Body) throw new Error(`S3 returned an empty body for media file: ${filename}`);
|
|
41
|
+
const bytes = await response.Body.transformToByteArray();
|
|
42
|
+
return Buffer.from(bytes);
|
|
43
|
+
}
|
|
44
|
+
async function readFromDisk(filename) {
|
|
45
|
+
const filePath = join(process.cwd(), "media", filename);
|
|
46
|
+
return readFile(filePath);
|
|
47
|
+
}
|
|
48
|
+
async function readPayloadMediaBuffer(media) {
|
|
49
|
+
const filename = media.filename?.trim();
|
|
50
|
+
if (!filename) throw new Error("Media document has no filename");
|
|
51
|
+
const source = isS3Enabled() ? "s3" : "disk";
|
|
52
|
+
log.debug(`reading media filename=${filename} source=${source}`);
|
|
53
|
+
return source === "s3" ? readFromS3(filename) : readFromDisk(filename);
|
|
54
|
+
}
|
|
55
|
+
async function readPayloadMediaAsDataUrl(media) {
|
|
56
|
+
const buffer = await readPayloadMediaBuffer(media);
|
|
57
|
+
return `data:${media.mimeType?.trim() || "image/jpeg"};base64,${buffer.toString("base64")}`;
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { readPayloadMediaBuffer as n, readPayloadMediaAsDataUrl as t };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=readMediaBuffer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readMediaBuffer.mjs","names":[],"sources":["../src/cms/payload/readMediaBuffer.ts"],"sourcesContent":["/**\n * Read a Payload-managed Media file's raw bytes, bypassing the public HTTP\n * surface. Uses S3 when `AWS_S3_BUCKET` is set; otherwise reads from\n * `<cwd>/media/<filename>` (Payload's default upload staticDir for `media`).\n */\n\nimport { readFile } from 'fs/promises'\nimport { join } from 'path'\n\nimport { GetObjectCommand, S3Client, type S3ClientConfig } from '@aws-sdk/client-s3'\n\nimport { createLogger } from '../../utils/logger/logger.js'\n\nconst log = createLogger('readPayloadMedia')\n\nexport type PayloadMedia = {\n filename?: string | null\n mimeType?: string | null\n}\n\nlet cachedS3Client: S3Client | null = null\n\nfunction isS3Enabled(): boolean {\n return Boolean(process.env.AWS_S3_BUCKET)\n}\n\nfunction getS3Client(): S3Client {\n if (cachedS3Client) return cachedS3Client\n const endpoint = process.env.AWS_S3_ENDPOINT?.trim()\n const clientConfig: S3ClientConfig = {\n region: process.env.AWS_S3_REGION ?? 'us-east-1',\n ...(endpoint ? { endpoint } : {}),\n ...(process.env.AWS_S3_FORCE_PATH_STYLE === 'true' ? { forcePathStyle: true } : {}),\n }\n const accessKeyId = process.env.AWS_ACCESS_KEY_ID\n const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY\n if (accessKeyId && secretAccessKey) {\n clientConfig.credentials = { accessKeyId, secretAccessKey }\n }\n cachedS3Client = new S3Client(clientConfig)\n return cachedS3Client\n}\n\nasync function readFromS3(filename: string): Promise<Buffer> {\n const bucket = process.env.AWS_S3_BUCKET\n if (!bucket) {\n throw new Error('AWS_S3_BUCKET is not set — cannot read media from S3')\n }\n const client = getS3Client()\n const response = await client.send(new GetObjectCommand({ Bucket: bucket, Key: filename }))\n if (!response.Body) {\n throw new Error(`S3 returned an empty body for media file: ${filename}`)\n }\n\n const bytes = await response.Body.transformToByteArray()\n return Buffer.from(bytes)\n}\n\nasync function readFromDisk(filename: string): Promise<Buffer> {\n const filePath = join(process.cwd(), 'media', filename)\n return readFile(filePath)\n}\n\nexport async function readPayloadMediaBuffer(media: PayloadMedia): Promise<Buffer> {\n const filename = media.filename?.trim()\n if (!filename) {\n throw new Error('Media document has no filename')\n }\n const source = isS3Enabled() ? 's3' : 'disk'\n log.debug(`reading media filename=${filename} source=${source}`)\n return source === 's3' ? readFromS3(filename) : readFromDisk(filename)\n}\n\nexport async function readPayloadMediaAsDataUrl(media: PayloadMedia): Promise<string> {\n const buffer = await readPayloadMediaBuffer(media)\n const mimeType = media.mimeType?.trim() || 'image/jpeg'\n return `data:${mimeType};base64,${buffer.toString('base64')}`\n}\n"],"mappings":";;;;;;;;;;AAaA,MAAM,MAAM,aAAa,kBAAkB;AAO3C,IAAI,iBAAkC;AAEtC,SAAS,cAAuB;CAC9B,OAAO,QAAQ,QAAQ,IAAI,aAAa;AAC1C;AAEA,SAAS,cAAwB;CAC/B,IAAI,gBAAgB,OAAO;CAC3B,MAAM,WAAW,QAAQ,IAAI,iBAAiB,KAAK;CACnD,MAAM,eAA+B;EACnC,QAAQ,QAAQ,IAAI,iBAAiB;EACrC,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EAC/B,GAAI,QAAQ,IAAI,4BAA4B,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACnF;CACA,MAAM,cAAc,QAAQ,IAAI;CAChC,MAAM,kBAAkB,QAAQ,IAAI;CACpC,IAAI,eAAe,iBACjB,aAAa,cAAc;EAAE;EAAa;CAAgB;CAE5D,iBAAiB,IAAI,SAAS,YAAY;CAC1C,OAAO;AACT;AAEA,eAAe,WAAW,UAAmC;CAC3D,MAAM,SAAS,QAAQ,IAAI;CAC3B,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,sDAAsD;CAGxE,MAAM,WAAW,MADF,YACa,CAAC,CAAC,KAAK,IAAI,iBAAiB;EAAE,QAAQ;EAAQ,KAAK;CAAS,CAAC,CAAC;CAC1F,IAAI,CAAC,SAAS,MACZ,MAAM,IAAI,MAAM,6CAA6C,UAAU;CAGzE,MAAM,QAAQ,MAAM,SAAS,KAAK,qBAAqB;CACvD,OAAO,OAAO,KAAK,KAAK;AAC1B;AAEA,eAAe,aAAa,UAAmC;CAC7D,MAAM,WAAW,KAAK,QAAQ,IAAI,GAAG,SAAS,QAAQ;CACtD,OAAO,SAAS,QAAQ;AAC1B;AAEA,eAAsB,uBAAuB,OAAsC;CACjF,MAAM,WAAW,MAAM,UAAU,KAAK;CACtC,IAAI,CAAC,UACH,MAAM,IAAI,MAAM,gCAAgC;CAElD,MAAM,SAAS,YAAY,IAAI,OAAO;CACtC,IAAI,MAAM,0BAA0B,SAAS,UAAU,QAAQ;CAC/D,OAAO,WAAW,OAAO,WAAW,QAAQ,IAAI,aAAa,QAAQ;AACvE;AAEA,eAAsB,0BAA0B,OAAsC;CACpF,MAAM,SAAS,MAAM,uBAAuB,KAAK;CAEjD,OAAO,QADU,MAAM,UAAU,KAAK,KAAK,aACnB,UAAU,OAAO,SAAS,QAAQ;AAC5D"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as createMetadataFactory, i as OgImage, n as CreateMetadataFactoryOptions, o as GetSiteUrlOptions, r as CreateMetadataInput, s as getSiteUrl, t as getOgBackgroundDataUrl } from "../index3.mjs";
|
|
2
|
+
export { type CreateMetadataFactoryOptions, type CreateMetadataInput, type GetSiteUrlOptions, type OgImage, createMetadataFactory, getOgBackgroundDataUrl, getSiteUrl };
|
package/dist/seo.mjs
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { t as createLogger } from "./logger.mjs";
|
|
2
|
+
import { t as readPayloadMediaAsDataUrl } from "./readMediaBuffer.mjs";
|
|
3
|
+
//#region src/seo/site-url.ts
|
|
4
|
+
const log$1 = createLogger("siteUrl");
|
|
5
|
+
/** Resolve the public site origin from env (`NEXT_PUBLIC_SITE_URL` / `VERCEL_URL`). */
|
|
6
|
+
function getSiteUrl(options = {}) {
|
|
7
|
+
const fallback = options.fallback ?? "http://localhost:3000";
|
|
8
|
+
const fromEnv = process.env.NEXT_PUBLIC_SITE_URL;
|
|
9
|
+
if (fromEnv) return fromEnv.replace(/\/$/, "");
|
|
10
|
+
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`.replace(/\/$/, "");
|
|
11
|
+
if (process.env.NODE_ENV === "production") log$1.warn(`NEXT_PUBLIC_SITE_URL and VERCEL_URL are unset — falling back to ${fallback}. Canonical and Open Graph URLs will be incorrect.`);
|
|
12
|
+
return fallback.replace(/\/$/, "");
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/seo/metadata.ts
|
|
16
|
+
const ABSOLUTE_URL_RE = /^https?:\/\//i;
|
|
17
|
+
function toAbsolute(value, base) {
|
|
18
|
+
if (ABSOLUTE_URL_RE.test(value)) return value;
|
|
19
|
+
return new URL(value, base).toString();
|
|
20
|
+
}
|
|
21
|
+
function createMetadataFactory(options) {
|
|
22
|
+
const localePrefix = options.localePrefix ?? "as-needed";
|
|
23
|
+
const resolveSiteUrl = options.getSiteUrl ?? (() => getSiteUrl());
|
|
24
|
+
function createMetadata(input) {
|
|
25
|
+
const siteName = input.siteName ?? options.siteName;
|
|
26
|
+
const defaultDescription = input.defaultDescription ?? options.defaultDescription;
|
|
27
|
+
const description = input.description?.trim() || defaultDescription;
|
|
28
|
+
const pathname = input.pathname ?? "/";
|
|
29
|
+
const base = resolveSiteUrl();
|
|
30
|
+
const canonical = input.canonicalUrl ? toAbsolute(input.canonicalUrl, base) : new URL(pathname, base).toString();
|
|
31
|
+
const locale = input.locale ?? options.defaultLocale;
|
|
32
|
+
const ogLocale = options.getOpenGraphLocale(locale);
|
|
33
|
+
const languages = {};
|
|
34
|
+
for (const l of options.locales) {
|
|
35
|
+
const isDefault = l === options.defaultLocale;
|
|
36
|
+
const localizedPath = localePrefix === "as-needed" && isDefault ? pathname : `/${l}${pathname}`;
|
|
37
|
+
languages[l] = new URL(localizedPath, base).toString();
|
|
38
|
+
}
|
|
39
|
+
languages["x-default"] = new URL(pathname, base).toString();
|
|
40
|
+
const images = input.images?.map((img) => ({
|
|
41
|
+
...img,
|
|
42
|
+
url: toAbsolute(img.url, base)
|
|
43
|
+
}));
|
|
44
|
+
const ogType = input.ogType ?? "website";
|
|
45
|
+
const robots = input.noIndex || input.noFollow ? {
|
|
46
|
+
index: !input.noIndex,
|
|
47
|
+
follow: !input.noFollow
|
|
48
|
+
} : void 0;
|
|
49
|
+
return {
|
|
50
|
+
title: input.title,
|
|
51
|
+
description,
|
|
52
|
+
alternates: {
|
|
53
|
+
canonical,
|
|
54
|
+
languages
|
|
55
|
+
},
|
|
56
|
+
openGraph: {
|
|
57
|
+
type: ogType,
|
|
58
|
+
title: input.title,
|
|
59
|
+
description,
|
|
60
|
+
url: canonical,
|
|
61
|
+
siteName,
|
|
62
|
+
locale: ogLocale,
|
|
63
|
+
...images ? { images } : {},
|
|
64
|
+
...ogType === "article" && input.article ? {
|
|
65
|
+
publishedTime: input.article.publishedTime,
|
|
66
|
+
modifiedTime: input.article.modifiedTime,
|
|
67
|
+
expirationTime: input.article.expirationTime,
|
|
68
|
+
section: input.article.section,
|
|
69
|
+
tags: input.article.tags,
|
|
70
|
+
authors: input.article.authors
|
|
71
|
+
} : {}
|
|
72
|
+
},
|
|
73
|
+
twitter: {
|
|
74
|
+
card: "summary_large_image",
|
|
75
|
+
title: input.title,
|
|
76
|
+
description,
|
|
77
|
+
...images ? { images: images.map((i) => i.url) } : {},
|
|
78
|
+
...input.twitterCreator ? { creator: input.twitterCreator } : {}
|
|
79
|
+
},
|
|
80
|
+
...robots ? { robots } : {}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function createRootMetadata(overrides) {
|
|
84
|
+
const base = resolveSiteUrl();
|
|
85
|
+
const siteName = overrides?.siteName ?? options.siteName;
|
|
86
|
+
const description = overrides?.defaultDescription ?? options.defaultDescription;
|
|
87
|
+
return {
|
|
88
|
+
metadataBase: new URL(base),
|
|
89
|
+
title: {
|
|
90
|
+
default: siteName,
|
|
91
|
+
template: `%s | ${siteName}`
|
|
92
|
+
},
|
|
93
|
+
description
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
createMetadata,
|
|
98
|
+
createRootMetadata
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/seo/og-background.ts
|
|
103
|
+
/**
|
|
104
|
+
* Resolves a Payload Media document into a base64 data URL for Satori OG images.
|
|
105
|
+
* Server-only — reads via disk/S3, not the public HTTP media URL.
|
|
106
|
+
*/
|
|
107
|
+
const log = createLogger("ogBackground");
|
|
108
|
+
async function getOgBackgroundDataUrl(media) {
|
|
109
|
+
if (!media || !media.filename) return void 0;
|
|
110
|
+
try {
|
|
111
|
+
return await readPayloadMediaAsDataUrl({
|
|
112
|
+
filename: media.filename,
|
|
113
|
+
mimeType: media.mimeType
|
|
114
|
+
});
|
|
115
|
+
} catch (error) {
|
|
116
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
117
|
+
log.warn(`Failed to load OG background for media ${media.filename}: ${reason}`);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
export { createMetadataFactory as n, getSiteUrl as r, getOgBackgroundDataUrl as t };
|
|
123
|
+
|
|
124
|
+
//# sourceMappingURL=seo.mjs.map
|
package/dist/seo.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seo.mjs","names":["log"],"sources":["../src/seo/site-url.ts","../src/seo/metadata.ts","../src/seo/og-background.ts"],"sourcesContent":["import { createLogger } from '../utils/logger/logger.js'\n\nconst log = createLogger('siteUrl')\n\nexport type GetSiteUrlOptions = {\n /** Fallback when no env URL is set. Defaults to `http://localhost:3000`. */\n fallback?: string\n}\n\n/** Resolve the public site origin from env (`NEXT_PUBLIC_SITE_URL` / `VERCEL_URL`). */\nexport function getSiteUrl(options: GetSiteUrlOptions = {}): string {\n const fallback = options.fallback ?? 'http://localhost:3000'\n const fromEnv = process.env.NEXT_PUBLIC_SITE_URL\n if (fromEnv) return fromEnv.replace(/\\/$/, '')\n if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`.replace(/\\/$/, '')\n // A localhost origin in production means canonical/OG URLs will be wrong — surface it loudly.\n if (process.env.NODE_ENV === 'production') {\n log.warn(\n `NEXT_PUBLIC_SITE_URL and VERCEL_URL are unset — falling back to ${fallback}. Canonical and Open Graph URLs will be incorrect.`\n )\n }\n return fallback.replace(/\\/$/, '')\n}\n","import { getSiteUrl } from './site-url.js'\n\nimport type { Metadata } from 'next'\n\nexport type OgImage = {\n url: string\n width?: number\n height?: number\n alt?: string\n}\n\nexport type CreateMetadataInput = {\n title: string\n description?: string\n pathname?: string\n canonicalUrl?: string\n noIndex?: boolean\n noFollow?: boolean\n locale?: string\n images?: OgImage[]\n ogType?: 'website' | 'article'\n article?: {\n publishedTime?: string\n modifiedTime?: string\n expirationTime?: string\n section?: string\n tags?: string[]\n authors?: string[]\n }\n twitterCreator?: string\n /** Per-call overrides (e.g. localized site name). */\n siteName?: string\n defaultDescription?: string\n}\n\nexport type CreateMetadataFactoryOptions = {\n siteName: string\n defaultDescription: string\n locales: readonly string[]\n defaultLocale: string\n /** Maps locale → Open Graph locale tag (e.g. `en` → `en_US`). */\n getOpenGraphLocale: (locale: string) => string\n localePrefix?: 'always' | 'as-needed' | 'never'\n getSiteUrl?: () => string\n}\n\nconst ABSOLUTE_URL_RE = /^https?:\\/\\//i\n\nfunction toAbsolute(value: string, base: string): string {\n if (ABSOLUTE_URL_RE.test(value)) return value\n return new URL(value, base).toString()\n}\n\nexport function createMetadataFactory(options: CreateMetadataFactoryOptions) {\n const localePrefix = options.localePrefix ?? 'as-needed'\n const resolveSiteUrl = options.getSiteUrl ?? (() => getSiteUrl())\n\n function createMetadata(input: CreateMetadataInput): Metadata {\n const siteName = input.siteName ?? options.siteName\n const defaultDescription = input.defaultDescription ?? options.defaultDescription\n const description = input.description?.trim() || defaultDescription\n const pathname = input.pathname ?? '/'\n const base = resolveSiteUrl()\n const canonical = input.canonicalUrl\n ? toAbsolute(input.canonicalUrl, base)\n : new URL(pathname, base).toString()\n\n const locale = input.locale ?? options.defaultLocale\n const ogLocale = options.getOpenGraphLocale(locale)\n\n const languages: Record<string, string> = {}\n for (const l of options.locales) {\n const isDefault = l === options.defaultLocale\n const localizedPath =\n localePrefix === 'as-needed' && isDefault ? pathname : `/${l}${pathname}`\n languages[l] = new URL(localizedPath, base).toString()\n }\n languages['x-default'] = new URL(pathname, base).toString()\n\n const images: OgImage[] | undefined = input.images?.map((img) => ({\n ...img,\n url: toAbsolute(img.url, base),\n }))\n\n const ogType = input.ogType ?? 'website'\n\n const robots =\n input.noIndex || input.noFollow\n ? {\n index: !input.noIndex,\n follow: !input.noFollow,\n }\n : undefined\n\n return {\n title: input.title,\n description,\n alternates: {\n canonical,\n languages,\n },\n openGraph: {\n type: ogType,\n title: input.title,\n description,\n url: canonical,\n siteName,\n locale: ogLocale,\n ...(images ? { images } : {}),\n ...(ogType === 'article' && input.article\n ? {\n publishedTime: input.article.publishedTime,\n modifiedTime: input.article.modifiedTime,\n expirationTime: input.article.expirationTime,\n section: input.article.section,\n tags: input.article.tags,\n authors: input.article.authors,\n }\n : {}),\n },\n twitter: {\n card: 'summary_large_image',\n title: input.title,\n description,\n ...(images ? { images: images.map((i) => i.url) } : {}),\n ...(input.twitterCreator ? { creator: input.twitterCreator } : {}),\n },\n ...(robots ? { robots } : {}),\n }\n }\n\n function createRootMetadata(overrides?: {\n siteName?: string\n defaultDescription?: string\n }): Metadata {\n const base = resolveSiteUrl()\n const siteName = overrides?.siteName ?? options.siteName\n const description = overrides?.defaultDescription ?? options.defaultDescription\n return {\n metadataBase: new URL(base),\n title: {\n default: siteName,\n template: `%s | ${siteName}`,\n },\n description,\n }\n }\n\n return { createMetadata, createRootMetadata }\n}\n","/**\n * Resolves a Payload Media document into a base64 data URL for Satori OG images.\n * Server-only — reads via disk/S3, not the public HTTP media URL.\n */\n\nimport { createLogger } from '../utils/logger/logger.js'\nimport { readPayloadMediaAsDataUrl } from '../cms/payload/readMediaBuffer.js'\n\nimport type { PayloadMedia } from '../cms/payload/readMediaBuffer.js'\n\nconst log = createLogger('ogBackground')\n\nexport async function getOgBackgroundDataUrl(\n media: PayloadMedia | null | undefined\n): Promise<string | undefined> {\n if (!media || !media.filename) return undefined\n try {\n return await readPayloadMediaAsDataUrl({\n filename: media.filename,\n mimeType: media.mimeType,\n })\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error)\n log.warn(`Failed to load OG background for media ${media.filename}: ${reason}`)\n return undefined\n }\n}\n"],"mappings":";;;AAEA,MAAMA,QAAM,aAAa,SAAS;;AAQlC,SAAgB,WAAW,UAA6B,CAAC,GAAW;CAClE,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,UAAU,QAAQ,IAAI;CAC5B,IAAI,SAAS,OAAO,QAAQ,QAAQ,OAAO,EAAE;CAC7C,IAAI,QAAQ,IAAI,YAAY,OAAO,WAAW,QAAQ,IAAI,aAAa,QAAQ,OAAO,EAAE;CAExF,IAAI,QAAQ,IAAI,aAAa,cAC3B,MAAI,KACF,mEAAmE,SAAS,mDAC9E;CAEF,OAAO,SAAS,QAAQ,OAAO,EAAE;AACnC;;;ACwBA,MAAM,kBAAkB;AAExB,SAAS,WAAW,OAAe,MAAsB;CACvD,IAAI,gBAAgB,KAAK,KAAK,GAAG,OAAO;CACxC,OAAO,IAAI,IAAI,OAAO,IAAI,CAAC,CAAC,SAAS;AACvC;AAEA,SAAgB,sBAAsB,SAAuC;CAC3E,MAAM,eAAe,QAAQ,gBAAgB;CAC7C,MAAM,iBAAiB,QAAQ,qBAAqB,WAAW;CAE/D,SAAS,eAAe,OAAsC;EAC5D,MAAM,WAAW,MAAM,YAAY,QAAQ;EAC3C,MAAM,qBAAqB,MAAM,sBAAsB,QAAQ;EAC/D,MAAM,cAAc,MAAM,aAAa,KAAK,KAAK;EACjD,MAAM,WAAW,MAAM,YAAY;EACnC,MAAM,OAAO,eAAe;EAC5B,MAAM,YAAY,MAAM,eACpB,WAAW,MAAM,cAAc,IAAI,IACnC,IAAI,IAAI,UAAU,IAAI,CAAC,CAAC,SAAS;EAErC,MAAM,SAAS,MAAM,UAAU,QAAQ;EACvC,MAAM,WAAW,QAAQ,mBAAmB,MAAM;EAElD,MAAM,YAAoC,CAAC;EAC3C,KAAK,MAAM,KAAK,QAAQ,SAAS;GAC/B,MAAM,YAAY,MAAM,QAAQ;GAChC,MAAM,gBACJ,iBAAiB,eAAe,YAAY,WAAW,IAAI,IAAI;GACjE,UAAU,KAAK,IAAI,IAAI,eAAe,IAAI,CAAC,CAAC,SAAS;EACvD;EACA,UAAU,eAAe,IAAI,IAAI,UAAU,IAAI,CAAC,CAAC,SAAS;EAE1D,MAAM,SAAgC,MAAM,QAAQ,KAAK,SAAS;GAChE,GAAG;GACH,KAAK,WAAW,IAAI,KAAK,IAAI;EAC/B,EAAE;EAEF,MAAM,SAAS,MAAM,UAAU;EAE/B,MAAM,SACJ,MAAM,WAAW,MAAM,WACnB;GACE,OAAO,CAAC,MAAM;GACd,QAAQ,CAAC,MAAM;EACjB,IACA,KAAA;EAEN,OAAO;GACL,OAAO,MAAM;GACb;GACA,YAAY;IACV;IACA;GACF;GACA,WAAW;IACT,MAAM;IACN,OAAO,MAAM;IACb;IACA,KAAK;IACL;IACA,QAAQ;IACR,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;IAC3B,GAAI,WAAW,aAAa,MAAM,UAC9B;KACE,eAAe,MAAM,QAAQ;KAC7B,cAAc,MAAM,QAAQ;KAC5B,gBAAgB,MAAM,QAAQ;KAC9B,SAAS,MAAM,QAAQ;KACvB,MAAM,MAAM,QAAQ;KACpB,SAAS,MAAM,QAAQ;IACzB,IACA,CAAC;GACP;GACA,SAAS;IACP,MAAM;IACN,OAAO,MAAM;IACb;IACA,GAAI,SAAS,EAAE,QAAQ,OAAO,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC;IACrD,GAAI,MAAM,iBAAiB,EAAE,SAAS,MAAM,eAAe,IAAI,CAAC;GAClE;GACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAC7B;CACF;CAEA,SAAS,mBAAmB,WAGf;EACX,MAAM,OAAO,eAAe;EAC5B,MAAM,WAAW,WAAW,YAAY,QAAQ;EAChD,MAAM,cAAc,WAAW,sBAAsB,QAAQ;EAC7D,OAAO;GACL,cAAc,IAAI,IAAI,IAAI;GAC1B,OAAO;IACL,SAAS;IACT,UAAU,QAAQ;GACpB;GACA;EACF;CACF;CAEA,OAAO;EAAE;EAAgB;CAAmB;AAC9C;;;;;;;AC3IA,MAAM,MAAM,aAAa,cAAc;AAEvC,eAAsB,uBACpB,OAC6B;CAC7B,IAAI,CAAC,SAAS,CAAC,MAAM,UAAU,OAAO,KAAA;CACtC,IAAI;EACF,OAAO,MAAM,0BAA0B;GACrC,UAAU,MAAM;GAChB,UAAU,MAAM;EAClB,CAAC;CACH,SAAS,OAAO;EACd,MAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACpE,IAAI,KAAK,0CAA0C,MAAM,SAAS,IAAI,QAAQ;EAC9E;CACF;AACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/ui/a11y/focus.d.ts
|
|
2
|
+
/** Shared focus-ring utility for interactive controls. */
|
|
3
|
+
declare const focusRingClassName = "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background";
|
|
4
|
+
//#endregion
|
|
5
|
+
export { focusRingClassName };
|
|
6
|
+
//# sourceMappingURL=focus.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus.d.mts","names":[],"sources":["../../../src/ui/a11y/focus.ts"],"mappings":";;cACa"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/ui/a11y/focus.ts
|
|
2
|
+
/** Shared focus-ring utility for interactive controls. */
|
|
3
|
+
const focusRingClassName = "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background";
|
|
4
|
+
//#endregion
|
|
5
|
+
export { focusRingClassName };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=focus.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus.mjs","names":[],"sources":["../../../src/ui/a11y/focus.ts"],"sourcesContent":["/** Shared focus-ring utility for interactive controls. */\nexport const focusRingClassName =\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background'\n"],"mappings":";;AACA,MAAa,qBACX"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { focusRingClassName } from "./focus.mjs";
|
|
2
|
+
import { VisuallyHidden, VisuallyHiddenProps } from "../components/VisuallyHidden/VisuallyHidden.mjs";
|
|
3
|
+
import "../components/VisuallyHidden/index.mjs";
|
|
4
|
+
export { VisuallyHidden, type VisuallyHiddenProps, focusRingClassName };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Carousel, CarouselApi, CarouselContainer, CarouselControls, CarouselControlsProps, CarouselPagination, CarouselPaginationProps, CarouselProps, CarouselSlide, CarouselViewport, useCarousel } from "../components/Carousel/Carousel.mjs";
|
|
2
|
+
import "../components/Carousel/index.mjs";
|
|
3
|
+
export { Carousel, type CarouselApi, CarouselContainer, CarouselControls, type CarouselControlsProps, CarouselPagination, type CarouselPaginationProps, type CarouselProps, CarouselSlide, CarouselViewport, useCarousel };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Carousel, CarouselContainer, CarouselControls, CarouselPagination, CarouselSlide, CarouselViewport, useCarousel } from "../components/Carousel/Carousel.mjs";
|
|
2
|
+
import "../components/Carousel/index.mjs";
|
|
3
|
+
export { Carousel, CarouselContainer, CarouselControls, CarouselPagination, CarouselSlide, CarouselViewport, useCarousel };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/ui/components/Accordion/Accordion.d.ts
|
|
3
|
+
type AccordionItem = {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
defaultOpen?: boolean;
|
|
7
|
+
content: ReactNode;
|
|
8
|
+
};
|
|
9
|
+
type AccordionProps = {
|
|
10
|
+
items: AccordionItem[];
|
|
11
|
+
className?: string;
|
|
12
|
+
};
|
|
13
|
+
declare function Accordion({ items, className }: AccordionProps): import("react").JSX.Element;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { Accordion, AccordionItem, AccordionProps };
|
|
16
|
+
//# sourceMappingURL=Accordion.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Accordion.d.mts","names":[],"sources":["../../../../src/ui/components/Accordion/Accordion.tsx"],"mappings":";;KAMY;EACV;EACA;EACA;EACA,SAAS;;KAGC;EACV,OAAO;EACP;;iBA+CO,YAAY,OAAO,aAAa,iCAAc,IAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../utils/cn.mjs";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
//#region src/ui/components/Accordion/Accordion.tsx
|
|
6
|
+
function ChevronIcon({ className }) {
|
|
7
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
8
|
+
"aria-hidden": "true",
|
|
9
|
+
viewBox: "0 0 24 24",
|
|
10
|
+
width: "24",
|
|
11
|
+
height: "24",
|
|
12
|
+
fill: "none",
|
|
13
|
+
className,
|
|
14
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
15
|
+
d: "M6 9l6 6 6-6",
|
|
16
|
+
stroke: "currentColor",
|
|
17
|
+
strokeWidth: "1.75",
|
|
18
|
+
strokeLinecap: "round",
|
|
19
|
+
strokeLinejoin: "round"
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function AccordionRow({ item }) {
|
|
24
|
+
const [open, setOpen] = useState(Boolean(item.defaultOpen));
|
|
25
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
26
|
+
className: "border-b border-border",
|
|
27
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
28
|
+
type: "button",
|
|
29
|
+
"aria-expanded": open,
|
|
30
|
+
onClick: () => setOpen((v) => !v),
|
|
31
|
+
className: "flex w-full cursor-pointer items-center justify-between gap-4 py-5 text-left",
|
|
32
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
33
|
+
className: "text-xl font-bold text-foreground",
|
|
34
|
+
children: item.title
|
|
35
|
+
}), /* @__PURE__ */ jsx(ChevronIcon, { className: cn("shrink-0 text-foreground transition-transform", open && "rotate-180") })]
|
|
36
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
37
|
+
className: cn("pb-6 text-base text-secondary", open ? "block" : "hidden"),
|
|
38
|
+
children: item.content
|
|
39
|
+
})]
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function Accordion({ items, className }) {
|
|
43
|
+
return /* @__PURE__ */ jsx("div", {
|
|
44
|
+
className: cn("flex w-full flex-col", className),
|
|
45
|
+
children: items.map((item) => /* @__PURE__ */ jsx(AccordionRow, { item }, item.id))
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { Accordion };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=Accordion.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Accordion.mjs","names":[],"sources":["../../../../src/ui/components/Accordion/Accordion.tsx"],"sourcesContent":["'use client'\n\nimport { useState, type ReactNode } from 'react'\n\nimport { cn } from '../../utils/cn.js'\n\nexport type AccordionItem = {\n id: string\n title: string\n defaultOpen?: boolean\n content: ReactNode\n}\n\nexport type AccordionProps = {\n items: AccordionItem[]\n className?: string\n}\n\nfunction ChevronIcon({ className }: { className?: string }) {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n fill=\"none\"\n className={className}\n >\n <path\n d=\"M6 9l6 6 6-6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nfunction AccordionRow({ item }: { item: AccordionItem }) {\n const [open, setOpen] = useState(Boolean(item.defaultOpen))\n\n return (\n <div className=\"border-b border-border\">\n <button\n type=\"button\"\n aria-expanded={open}\n onClick={() => setOpen((v) => !v)}\n className=\"flex w-full cursor-pointer items-center justify-between gap-4 py-5 text-left\"\n >\n <h2 className=\"text-xl font-bold text-foreground\">{item.title}</h2>\n <ChevronIcon\n className={cn('shrink-0 text-foreground transition-transform', open && 'rotate-180')}\n />\n </button>\n <div className={cn('pb-6 text-base text-secondary', open ? 'block' : 'hidden')}>\n {item.content}\n </div>\n </div>\n )\n}\n\nfunction Accordion({ items, className }: AccordionProps) {\n return (\n <div className={cn('flex w-full flex-col', className)}>\n {items.map((item) => (\n <AccordionRow key={item.id} item={item} />\n ))}\n </div>\n )\n}\n\nexport { Accordion }\n"],"mappings":";;;;;AAkBA,SAAS,YAAY,EAAE,aAAqC;CAC1D,OACE,oBAAC,OAAD;EACE,eAAY;EACZ,SAAQ;EACR,OAAM;EACN,QAAO;EACP,MAAK;EACM;EAEX,UAAA,oBAAC,QAAD;GACE,GAAE;GACF,QAAO;GACP,aAAY;GACZ,eAAc;GACd,gBAAe;EAChB,CAAA;CACE,CAAA;AAET;AAEA,SAAS,aAAa,EAAE,QAAiC;CACvD,MAAM,CAAC,MAAM,WAAW,SAAS,QAAQ,KAAK,WAAW,CAAC;CAE1D,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,qBAAC,UAAD;GACE,MAAK;GACL,iBAAe;GACf,eAAe,SAAS,MAAM,CAAC,CAAC;GAChC,WAAU;GAJZ,UAAA,CAME,oBAAC,MAAD;IAAI,WAAU;IAAqC,UAAA,KAAK;GAAU,CAAA,GAClE,oBAAC,aAAD,EACE,WAAW,GAAG,iDAAiD,QAAQ,YAAY,EACpF,CAAA,CACK;EACR,CAAA,GAAA,oBAAC,OAAD;GAAK,WAAW,GAAG,iCAAiC,OAAO,UAAU,QAAQ;GAC1E,UAAA,KAAK;EACH,CAAA,CACF;;AAET;AAEA,SAAS,UAAU,EAAE,OAAO,aAA6B;CACvD,OACE,oBAAC,OAAD;EAAK,WAAW,GAAG,wBAAwB,SAAS;EACjD,UAAA,MAAM,KAAK,SACV,oBAAC,cAAD,EAAkC,KAAO,GAAtB,KAAK,EAAiB,CAC1C;CACE,CAAA;AAET"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ComponentProps } from "react";
|
|
2
|
+
//#region src/ui/components/Avatar/Avatar.d.ts
|
|
3
|
+
type AvatarProps = ComponentProps<'div'> & {
|
|
4
|
+
initials?: string;
|
|
5
|
+
};
|
|
6
|
+
declare function Avatar({ className, initials, children, ...props }: AvatarProps): import("react").JSX.Element;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { Avatar, AvatarProps };
|
|
9
|
+
//# sourceMappingURL=Avatar.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Avatar.d.mts","names":[],"sources":["../../../../src/ui/components/Avatar/Avatar.tsx"],"mappings":";;KAIY,cAAc;EACxB;;iBAGO,SAAS,WAAW,UAAU,aAAa,SAAS,8BAAW,IAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { cn } from "../../utils/cn.mjs";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
//#region src/ui/components/Avatar/Avatar.tsx
|
|
4
|
+
function Avatar({ className, initials, children, ...props }) {
|
|
5
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6
|
+
"data-slot": "avatar",
|
|
7
|
+
className: cn("inline-flex size-9 shrink-0 items-center justify-center rounded-full border border-foreground/10 bg-surface text-btn font-semibold text-secondary", className),
|
|
8
|
+
...props,
|
|
9
|
+
children: children ?? initials
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Avatar };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=Avatar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Avatar.mjs","names":[],"sources":["../../../../src/ui/components/Avatar/Avatar.tsx"],"sourcesContent":["import { cn } from '../../utils/cn.js'\n\nimport type { ComponentProps } from 'react'\n\nexport type AvatarProps = ComponentProps<'div'> & {\n initials?: string\n}\n\nfunction Avatar({ className, initials, children, ...props }: AvatarProps) {\n return (\n <div\n data-slot=\"avatar\"\n className={cn(\n 'inline-flex size-9 shrink-0 items-center justify-center rounded-full border border-foreground/10 bg-surface text-btn font-semibold text-secondary',\n className\n )}\n {...props}\n >\n {children ?? initials}\n </div>\n )\n}\n\nexport { Avatar }\n"],"mappings":";;;AAQA,SAAS,OAAO,EAAE,WAAW,UAAU,UAAU,GAAG,SAAsB;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,qJACA,SACF;EACA,GAAI;EAEH,UAAA,YAAY;CACV,CAAA;AAET"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HTMLAttributes } from "react";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
//#region src/ui/components/Badge/Badge.d.ts
|
|
4
|
+
declare const badgeVariants: (props?: ({
|
|
5
|
+
variant?: "status" | "active" | "inactive" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
type BadgeProps = HTMLAttributes<HTMLSpanElement> & VariantProps<typeof badgeVariants> & {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
dot?: boolean;
|
|
10
|
+
};
|
|
11
|
+
declare function Badge({ className, variant, asChild, dot, children, ...props }: BadgeProps): import("react").JSX.Element;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Badge, BadgeProps, badgeVariants };
|
|
14
|
+
//# sourceMappingURL=Badge.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Badge.d.mts","names":[],"sources":["../../../../src/ui/components/Badge/Badge.tsx"],"mappings":";;;cASM,gBAAa;;6CAgBlB;KAEW,aAAa,eAAe,mBACtC,oBAAoB;EAClB;EACA;;iBAGK,QACP,WACA,SACA,SACA,KACA,aACG,SACF,6BAAU,IAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../utils/cn.mjs";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { Slot, Slottable } from "@radix-ui/react-slot";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
//#region src/ui/components/Badge/Badge.tsx
|
|
7
|
+
const badgeVariants = cva("inline-flex items-center font-semibold whitespace-nowrap transition-colors", {
|
|
8
|
+
variants: { variant: {
|
|
9
|
+
active: "cursor-pointer rounded-full bg-accent px-4 py-2 text-sm text-accent-foreground",
|
|
10
|
+
inactive: "cursor-pointer rounded-full border border-border bg-card px-4 py-2 text-sm text-secondary hover:text-foreground",
|
|
11
|
+
status: "h-[18px] shrink-0 gap-1.5 rounded-full bg-success/12 px-2 text-xs leading-none text-success uppercase"
|
|
12
|
+
} },
|
|
13
|
+
defaultVariants: { variant: "inactive" }
|
|
14
|
+
});
|
|
15
|
+
function Badge({ className, variant, asChild = false, dot = false, children, ...props }) {
|
|
16
|
+
return /* @__PURE__ */ jsxs(asChild ? Slot : "span", {
|
|
17
|
+
"data-slot": "badge",
|
|
18
|
+
"data-variant": variant,
|
|
19
|
+
className: cn(badgeVariants({ variant }), className),
|
|
20
|
+
...props,
|
|
21
|
+
children: [dot ? /* @__PURE__ */ jsx("span", {
|
|
22
|
+
"aria-hidden": true,
|
|
23
|
+
className: "size-[5px] shrink-0 rounded-[2.5px] bg-success"
|
|
24
|
+
}) : null, /* @__PURE__ */ jsx(Slottable, { children })]
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { Badge, badgeVariants };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=Badge.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Badge.mjs","names":[],"sources":["../../../../src/ui/components/Badge/Badge.tsx"],"sourcesContent":["'use client'\n\nimport { Slot, Slottable } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nimport { cn } from '../../utils/cn.js'\n\nimport type { HTMLAttributes } from 'react'\n\nconst badgeVariants = cva(\n 'inline-flex items-center font-semibold whitespace-nowrap transition-colors',\n {\n variants: {\n variant: {\n active: 'cursor-pointer rounded-full bg-accent px-4 py-2 text-sm text-accent-foreground',\n inactive:\n 'cursor-pointer rounded-full border border-border bg-card px-4 py-2 text-sm text-secondary hover:text-foreground',\n status:\n 'h-[18px] shrink-0 gap-1.5 rounded-full bg-success/12 px-2 text-xs leading-none text-success uppercase',\n },\n },\n defaultVariants: {\n variant: 'inactive',\n },\n }\n)\n\nexport type BadgeProps = HTMLAttributes<HTMLSpanElement> &\n VariantProps<typeof badgeVariants> & {\n asChild?: boolean\n dot?: boolean\n }\n\nfunction Badge({\n className,\n variant,\n asChild = false,\n dot = false,\n children,\n ...props\n}: BadgeProps) {\n const Comp = asChild ? Slot : 'span'\n\n return (\n <Comp\n data-slot=\"badge\"\n data-variant={variant}\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n >\n {dot ? <span aria-hidden className=\"size-[5px] shrink-0 rounded-[2.5px] bg-success\" /> : null}\n <Slottable>{children}</Slottable>\n </Comp>\n )\n}\n\nexport { Badge, badgeVariants }\n"],"mappings":";;;;;;AASA,MAAM,gBAAgB,IACpB,8EACA;CACE,UAAU,EACR,SAAS;EACP,QAAQ;EACR,UACE;EACF,QACE;CACJ,EACF;CACA,iBAAiB,EACf,SAAS,WACX;AACF,CACF;AAQA,SAAS,MAAM,EACb,WACA,SACA,UAAU,OACV,MAAM,OACN,UACA,GAAG,SACU;CAGb,OACE,qBAHW,UAAU,OAAO,QAG5B;EACE,aAAU;EACV,gBAAc;EACd,WAAW,GAAG,cAAc,EAAE,QAAQ,CAAC,GAAG,SAAS;EACnD,GAAI;EAJN,UAAA,CAMG,MAAM,oBAAC,QAAD;GAAM,eAAA;GAAY,WAAU;EAAkD,CAAA,IAAI,MACzF,oBAAC,WAAD,EAAY,SAAoB,CAAA,CAC5B;;AAEV"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ComponentType, HTMLAttributes, SVGProps } from "react";
|
|
2
|
+
//#region src/ui/components/BadgeVersion/BadgeVersion.d.ts
|
|
3
|
+
type ReleaseType = 'major' | 'minor' | 'patch';
|
|
4
|
+
type ReleaseTypeStyle = {
|
|
5
|
+
badgeClassName: string;
|
|
6
|
+
textClassName: string;
|
|
7
|
+
Icon: ComponentType<SVGProps<SVGSVGElement> & {
|
|
8
|
+
size?: number;
|
|
9
|
+
}>;
|
|
10
|
+
};
|
|
11
|
+
declare function coerceBadgeReleaseType(raw: unknown): ReleaseType;
|
|
12
|
+
declare const BADGE_VERSION_RELEASE_TYPE_STYLES: Record<ReleaseType, ReleaseTypeStyle>;
|
|
13
|
+
type BadgeVersionProps = Omit<HTMLAttributes<HTMLSpanElement>, 'children'> & {
|
|
14
|
+
version: string;
|
|
15
|
+
type?: ReleaseType | string | null;
|
|
16
|
+
showReleaseType?: boolean;
|
|
17
|
+
/** Apps own i18n — required when `showReleaseType` is true. */
|
|
18
|
+
releaseTypeLabel?: string;
|
|
19
|
+
wrapperClassName?: string;
|
|
20
|
+
};
|
|
21
|
+
declare function BadgeVersion({ version, type, showReleaseType, releaseTypeLabel, className, wrapperClassName, 'aria-label': ariaLabelProp, ...rest }: BadgeVersionProps): import("react").JSX.Element;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { BADGE_VERSION_RELEASE_TYPE_STYLES, BadgeVersion, BadgeVersionProps, ReleaseType, coerceBadgeReleaseType };
|
|
24
|
+
//# sourceMappingURL=BadgeVersion.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BadgeVersion.d.mts","names":[],"sources":["../../../../src/ui/components/BadgeVersion/BadgeVersion.tsx"],"mappings":";;KAMY;KAEP;EACH;EACA;EACA,MAAM,cAAc,SAAS;IAAmB;;;iBAKlC,uBAAuB,eAAe;cAOzC,mCAAmC,OAAO,aAAa;KAkBxD,oBAAoB,KAAK,eAAe;EAClD;EACA,OAAO;EACP;;EAEA;EACA;;iBAGO,eACP,SACA,MACA,iBACA,kBACA,WACA,gCACc,kBACX,QACF,oCAAiB,IAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { cn } from "../../utils/cn.mjs";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { MdAddCircleOutline, MdCheck, MdWarning } from "react-icons/md";
|
|
4
|
+
//#region src/ui/components/BadgeVersion/BadgeVersion.tsx
|
|
5
|
+
const RELEASE_TYPES = /* @__PURE__ */ new Set([
|
|
6
|
+
"major",
|
|
7
|
+
"minor",
|
|
8
|
+
"patch"
|
|
9
|
+
]);
|
|
10
|
+
function coerceBadgeReleaseType(raw) {
|
|
11
|
+
if (typeof raw === "string" && RELEASE_TYPES.has(raw)) return raw;
|
|
12
|
+
return "patch";
|
|
13
|
+
}
|
|
14
|
+
const BADGE_VERSION_RELEASE_TYPE_STYLES = {
|
|
15
|
+
major: {
|
|
16
|
+
badgeClassName: "bg-destructive/20 text-destructive",
|
|
17
|
+
textClassName: "text-destructive",
|
|
18
|
+
Icon: MdWarning
|
|
19
|
+
},
|
|
20
|
+
minor: {
|
|
21
|
+
badgeClassName: "bg-accent/20 text-accent",
|
|
22
|
+
textClassName: "text-accent",
|
|
23
|
+
Icon: MdAddCircleOutline
|
|
24
|
+
},
|
|
25
|
+
patch: {
|
|
26
|
+
badgeClassName: "bg-warning/20 text-warning",
|
|
27
|
+
textClassName: "text-warning",
|
|
28
|
+
Icon: MdCheck
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
function BadgeVersion({ version, type, showReleaseType = false, releaseTypeLabel, className, wrapperClassName, "aria-label": ariaLabelProp, ...rest }) {
|
|
32
|
+
const releaseType = coerceBadgeReleaseType(type);
|
|
33
|
+
const styles = BADGE_VERSION_RELEASE_TYPE_STYLES[releaseType];
|
|
34
|
+
const typeLabel = showReleaseType ? releaseTypeLabel : null;
|
|
35
|
+
const defaultGroupAriaLabel = showReleaseType && typeLabel && !ariaLabelProp ? `${version} ${typeLabel}` : void 0;
|
|
36
|
+
if (!showReleaseType) return /* @__PURE__ */ jsx("span", {
|
|
37
|
+
"data-slot": "badge-version",
|
|
38
|
+
"data-release-type": releaseType,
|
|
39
|
+
className: cn("inline-flex items-center rounded-btn px-2 py-[3px] text-body-xs font-bold", styles.badgeClassName, className),
|
|
40
|
+
"aria-label": ariaLabelProp,
|
|
41
|
+
...rest,
|
|
42
|
+
children: version
|
|
43
|
+
});
|
|
44
|
+
const Icon = styles.Icon;
|
|
45
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
46
|
+
className: cn("inline-flex flex-wrap items-center gap-2", wrapperClassName),
|
|
47
|
+
"aria-label": ariaLabelProp ?? defaultGroupAriaLabel,
|
|
48
|
+
...rest,
|
|
49
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
50
|
+
"data-slot": "badge-version",
|
|
51
|
+
"data-release-type": releaseType,
|
|
52
|
+
className: cn("inline-flex items-center rounded-btn px-2 py-[3px] text-body-xs font-bold", styles.badgeClassName, className),
|
|
53
|
+
children: version
|
|
54
|
+
}), typeLabel ? /* @__PURE__ */ jsxs("span", {
|
|
55
|
+
className: cn("inline-flex items-center gap-1 text-btn font-semibold", styles.textClassName),
|
|
56
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
57
|
+
size: 14,
|
|
58
|
+
"aria-hidden": true
|
|
59
|
+
}), typeLabel]
|
|
60
|
+
}) : null]
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { BADGE_VERSION_RELEASE_TYPE_STYLES, BadgeVersion, coerceBadgeReleaseType };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=BadgeVersion.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BadgeVersion.mjs","names":[],"sources":["../../../../src/ui/components/BadgeVersion/BadgeVersion.tsx"],"sourcesContent":["import { MdAddCircleOutline, MdCheck, MdWarning } from 'react-icons/md'\n\nimport { cn } from '../../utils/cn.js'\n\nimport type { ComponentType, HTMLAttributes, SVGProps } from 'react'\n\nexport type ReleaseType = 'major' | 'minor' | 'patch'\n\ntype ReleaseTypeStyle = {\n badgeClassName: string\n textClassName: string\n Icon: ComponentType<SVGProps<SVGSVGElement> & { size?: number }>\n}\n\nconst RELEASE_TYPES = new Set<ReleaseType>(['major', 'minor', 'patch'])\n\nexport function coerceBadgeReleaseType(raw: unknown): ReleaseType {\n if (typeof raw === 'string' && RELEASE_TYPES.has(raw as ReleaseType)) {\n return raw as ReleaseType\n }\n return 'patch'\n}\n\nexport const BADGE_VERSION_RELEASE_TYPE_STYLES: Record<ReleaseType, ReleaseTypeStyle> = {\n major: {\n badgeClassName: 'bg-destructive/20 text-destructive',\n textClassName: 'text-destructive',\n Icon: MdWarning,\n },\n minor: {\n badgeClassName: 'bg-accent/20 text-accent',\n textClassName: 'text-accent',\n Icon: MdAddCircleOutline,\n },\n patch: {\n badgeClassName: 'bg-warning/20 text-warning',\n textClassName: 'text-warning',\n Icon: MdCheck,\n },\n}\n\nexport type BadgeVersionProps = Omit<HTMLAttributes<HTMLSpanElement>, 'children'> & {\n version: string\n type?: ReleaseType | string | null\n showReleaseType?: boolean\n /** Apps own i18n — required when `showReleaseType` is true. */\n releaseTypeLabel?: string\n wrapperClassName?: string\n}\n\nfunction BadgeVersion({\n version,\n type,\n showReleaseType = false,\n releaseTypeLabel,\n className,\n wrapperClassName,\n 'aria-label': ariaLabelProp,\n ...rest\n}: BadgeVersionProps) {\n const releaseType = coerceBadgeReleaseType(type)\n const styles = BADGE_VERSION_RELEASE_TYPE_STYLES[releaseType]\n const typeLabel = showReleaseType ? releaseTypeLabel : null\n const defaultGroupAriaLabel =\n showReleaseType && typeLabel && !ariaLabelProp ? `${version} ${typeLabel}` : undefined\n\n if (!showReleaseType) {\n return (\n <span\n data-slot=\"badge-version\"\n data-release-type={releaseType}\n className={cn(\n 'inline-flex items-center rounded-btn px-2 py-[3px] text-body-xs font-bold',\n styles.badgeClassName,\n className\n )}\n aria-label={ariaLabelProp}\n {...rest}\n >\n {version}\n </span>\n )\n }\n\n const Icon = styles.Icon\n\n return (\n <span\n className={cn('inline-flex flex-wrap items-center gap-2', wrapperClassName)}\n aria-label={ariaLabelProp ?? defaultGroupAriaLabel}\n {...rest}\n >\n <span\n data-slot=\"badge-version\"\n data-release-type={releaseType}\n className={cn(\n 'inline-flex items-center rounded-btn px-2 py-[3px] text-body-xs font-bold',\n styles.badgeClassName,\n className\n )}\n >\n {version}\n </span>\n {typeLabel ? (\n <span\n className={cn(\n 'inline-flex items-center gap-1 text-btn font-semibold',\n styles.textClassName\n )}\n >\n <Icon size={14} aria-hidden />\n {typeLabel}\n </span>\n ) : null}\n </span>\n )\n}\n\nexport { BadgeVersion }\n"],"mappings":";;;;AAcA,MAAM,gCAAgB,IAAI,IAAiB;CAAC;CAAS;CAAS;AAAO,CAAC;AAEtE,SAAgB,uBAAuB,KAA2B;CAChE,IAAI,OAAO,QAAQ,YAAY,cAAc,IAAI,GAAkB,GACjE,OAAO;CAET,OAAO;AACT;AAEA,MAAa,oCAA2E;CACtF,OAAO;EACL,gBAAgB;EAChB,eAAe;EACf,MAAM;CACR;CACA,OAAO;EACL,gBAAgB;EAChB,eAAe;EACf,MAAM;CACR;CACA,OAAO;EACL,gBAAgB;EAChB,eAAe;EACf,MAAM;CACR;AACF;AAWA,SAAS,aAAa,EACpB,SACA,MACA,kBAAkB,OAClB,kBACA,WACA,kBACA,cAAc,eACd,GAAG,QACiB;CACpB,MAAM,cAAc,uBAAuB,IAAI;CAC/C,MAAM,SAAS,kCAAkC;CACjD,MAAM,YAAY,kBAAkB,mBAAmB;CACvD,MAAM,wBACJ,mBAAmB,aAAa,CAAC,gBAAgB,GAAG,QAAQ,GAAG,cAAc;CAE/E,IAAI,CAAC,iBACH,OACE,oBAAC,QAAD;EACE,aAAU;EACV,qBAAmB;EACnB,WAAW,GACT,6EACA,OAAO,gBACP,SACF;EACA,cAAY;EACZ,GAAI;EAEH,UAAA;CACG,CAAA;CAIV,MAAM,OAAO,OAAO;CAEpB,OACE,qBAAC,QAAD;EACE,WAAW,GAAG,4CAA4C,gBAAgB;EAC1E,cAAY,iBAAiB;EAC7B,GAAI;EAHN,UAAA,CAKE,oBAAC,QAAD;GACE,aAAU;GACV,qBAAmB;GACnB,WAAW,GACT,6EACA,OAAO,gBACP,SACF;GAEC,UAAA;EACG,CAAA,GACL,YACC,qBAAC,QAAD;GACE,WAAW,GACT,yDACA,OAAO,aACT;GAJF,UAAA,CAME,oBAAC,MAAD;IAAM,MAAM;IAAI,eAAA;GAAa,CAAA,GAC5B,SACG;EACJ,CAAA,IAAA,IACA;;AAEV"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ComponentProps } from "react";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
//#region src/ui/components/Button/Button.d.ts
|
|
4
|
+
declare const buttonVariants: (props?: ({
|
|
5
|
+
variant?: "solid" | "outline" | "ghost" | "secondary" | "social" | "action" | "elevated-outline" | "link" | null | undefined;
|
|
6
|
+
size?: "social" | "default" | "sm" | "cta" | "icon" | null | undefined;
|
|
7
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
|
+
type ButtonProps = ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
|
|
9
|
+
asChild?: boolean;
|
|
10
|
+
};
|
|
11
|
+
declare function Button({ className, variant, size, asChild, ...props }: ButtonProps): import("react").JSX.Element;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Button, ButtonProps, buttonVariants };
|
|
14
|
+
//# sourceMappingURL=Button.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.d.mts","names":[],"sources":["../../../../src/ui/components/Button/Button.tsx"],"mappings":";;;cAUM,iBAAc;;;6CAmCnB;KAEW,cAAc,2BACxB,oBAAoB;EAClB;;iBAGK,SACP,WACA,SACA,MACA,YACG,SACF,8BAAW,IAAA"}
|