@ankhorage/zora 1.4.6 → 1.4.8
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 +143 -0
- package/dist/components/card/meta.d.ts +1 -1
- package/dist/foundation/meta.d.ts +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/layout/auth-layout/meta.d.ts +1 -1
- package/dist/layout/page/meta.d.ts +1 -1
- package/dist/layout/page-section/meta.d.ts +1 -1
- package/dist/metadata/allowedChildren.d.ts +3 -3
- package/dist/metadata/allowedChildren.d.ts.map +1 -1
- package/dist/metadata/allowedChildren.js +1 -0
- package/dist/metadata/allowedChildren.js.map +1 -1
- package/dist/metadata/componentMeta.d.ts.map +1 -1
- package/dist/metadata/componentMeta.js +2 -0
- package/dist/metadata/componentMeta.js.map +1 -1
- package/dist/patterns/hero/Hero.d.ts.map +1 -1
- package/dist/patterns/hero/Hero.js +11 -15
- package/dist/patterns/hero/Hero.js.map +1 -1
- package/dist/patterns/notice/meta.d.ts +1 -1
- package/dist/patterns/panel/meta.d.ts +1 -1
- package/dist/patterns/post-card/PostCard.d.ts +4 -0
- package/dist/patterns/post-card/PostCard.d.ts.map +1 -0
- package/dist/patterns/post-card/PostCard.js +133 -0
- package/dist/patterns/post-card/PostCard.js.map +1 -0
- package/dist/patterns/post-card/index.d.ts +3 -0
- package/dist/patterns/post-card/index.d.ts.map +1 -0
- package/dist/patterns/post-card/index.js +2 -0
- package/dist/patterns/post-card/index.js.map +1 -0
- package/dist/patterns/post-card/meta.d.ts +64 -0
- package/dist/patterns/post-card/meta.d.ts.map +1 -0
- package/dist/patterns/post-card/meta.js +66 -0
- package/dist/patterns/post-card/meta.js.map +1 -0
- package/dist/patterns/post-card/types.d.ts +64 -0
- package/dist/patterns/post-card/types.d.ts.map +1 -0
- package/dist/patterns/post-card/types.js +2 -0
- package/dist/patterns/post-card/types.js.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +9 -0
- package/src/metadata/allowedChildren.ts +1 -0
- package/src/metadata/componentMeta.test.ts +1 -0
- package/src/metadata/componentMeta.ts +2 -0
- package/src/patterns/hero/Hero.tsx +18 -18
- package/src/patterns/post-card/PostCard.test.tsx +11 -0
- package/src/patterns/post-card/PostCard.tsx +234 -0
- package/src/patterns/post-card/index.ts +9 -0
- package/src/patterns/post-card/meta.ts +68 -0
- package/src/patterns/post-card/types.ts +71 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Hero.js","sourceRoot":"","sources":["../../../src/patterns/hero/Hero.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"Hero.js","sourceRoot":"","sources":["../../../src/patterns/hero/Hero.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport { Button } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { Heading } from '../../components/heading';\nimport { Text } from '../../components/text';\nimport { Box, Grid, Stack } from '../../foundation';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport type { HeroAction, HeroAlign, HeroProps } from './types';\n\nfunction HeroInner({\n themeId: _themeId,\n mode: _mode,\n title,\n description,\n eyebrow,\n primaryAction,\n secondaryAction,\n media,\n footer,\n align = 'start',\n layout = 'split',\n tone = 'subtle',\n compact = false,\n testID,\n}: HeroProps) {\n const hasActions = primaryAction !== undefined || secondaryAction !== undefined;\n const hasMedia = media !== undefined;\n const contentAlign = resolveContentAlign(align);\n const textAlign = align === 'center' ? 'center' : undefined;\n const mediaFirst = layout === 'mediaFirst';\n\n const content = (\n <Box width=\"100%\">\n <Stack align={contentAlign} gap={compact ? 's' : 'm'}>\n <Stack align={contentAlign} gap=\"xs\">\n {eyebrow !== undefined ? (\n <Text align={textAlign} tone=\"primary\" variant=\"eyebrow\">\n {eyebrow}\n </Text>\n ) : null}\n <Heading\n align={textAlign}\n level={1}\n size={{ base: 'h2', md: compact ? 'h2' : 'display' }}\n >\n {title}\n </Heading>\n {description !== undefined ? (\n <Text\n align={textAlign}\n tone=\"muted\"\n variant={{ base: 'body', md: compact ? 'body' : 'lead' }}\n >\n {description}\n </Text>\n ) : null}\n </Stack>\n\n {hasActions ? (\n <Stack\n align={contentAlign}\n direction={{ base: 'column', md: 'row' }}\n gap=\"s\"\n justify={align === 'center' ? 'center' : 'flex-start'}\n >\n {primaryAction !== undefined ? renderAction(primaryAction, 'primary') : null}\n {secondaryAction !== undefined ? renderAction(secondaryAction, 'secondary') : null}\n </Stack>\n ) : null}\n\n {footer}\n </Stack>\n </Box>\n );\n\n const mediaSlot = hasMedia ? <Box width=\"100%\">{media}</Box> : null;\n\n const body =\n hasMedia && layout !== 'stack' ? (\n <Grid cols={{ base: 1, md: 2 }} gap={compact ? 'm' : 'l'}>\n {mediaFirst ? mediaSlot : content}\n {mediaFirst ? content : mediaSlot}\n </Grid>\n ) : (\n <Stack align=\"center\" direction=\"column\" gap={compact ? 'm' : 'l'}>\n {mediaFirst ? mediaSlot : content}\n {mediaFirst ? content : mediaSlot}\n </Stack>\n );\n\n return (\n <Card compact={compact} testID={testID} tone={tone}>\n {body}\n </Card>\n );\n}\n\nfunction renderAction(action: HeroAction, role: 'primary' | 'secondary') {\n return (\n <Button\n disabled={action.disabled}\n emphasis={action.emphasis ?? (role === 'primary' ? 'solid' : 'soft')}\n onPress={action.onPress}\n tone={action.tone ?? (role === 'primary' ? 'primary' : 'neutral')}\n >\n {action.label}\n </Button>\n );\n}\n\nfunction resolveContentAlign(align: HeroAlign) {\n return align === 'center' ? 'center' : 'flex-start';\n}\n\nexport const Hero = withZoraThemeScope(HeroInner);\n"]}
|
|
@@ -2,7 +2,7 @@ export declare const noticeMeta: {
|
|
|
2
2
|
readonly name: "Notice";
|
|
3
3
|
readonly category: "pattern";
|
|
4
4
|
readonly directManifestNode: true;
|
|
5
|
-
readonly allowedChildren: readonly ["Box", "Stack", "Grid", "Container", "Divider", "Text", "Heading", "Button", "Input", "Textarea", "FormField", "Card", "Panel", "Notice", "EmptyState", "SectionHeader", "SettingsRow"];
|
|
5
|
+
readonly allowedChildren: readonly ["Box", "Stack", "Grid", "Container", "Divider", "Text", "Heading", "Button", "Input", "Textarea", "FormField", "Card", "Panel", "Notice", "EmptyState", "SectionHeader", "SettingsRow", "PostCard"];
|
|
6
6
|
readonly blueprint: {
|
|
7
7
|
readonly label: "Notice";
|
|
8
8
|
readonly defaultProps: {
|
|
@@ -2,7 +2,7 @@ export declare const panelMeta: {
|
|
|
2
2
|
readonly name: "Panel";
|
|
3
3
|
readonly category: "pattern";
|
|
4
4
|
readonly directManifestNode: true;
|
|
5
|
-
readonly allowedChildren: readonly ["Box", "Stack", "Grid", "Container", "Divider", "Text", "Heading", "Button", "Input", "Textarea", "FormField", "Card", "Panel", "Notice", "EmptyState", "SectionHeader", "SettingsRow"];
|
|
5
|
+
readonly allowedChildren: readonly ["Box", "Stack", "Grid", "Container", "Divider", "Text", "Heading", "Button", "Input", "Textarea", "FormField", "Card", "Panel", "Notice", "EmptyState", "SectionHeader", "SettingsRow", "PostCard"];
|
|
6
6
|
readonly blueprint: {
|
|
7
7
|
readonly label: "Panel";
|
|
8
8
|
readonly defaultProps: {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostCard.d.ts","sourceRoot":"","sources":["../../../src/patterns/post-card/PostCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,KAAK,EAIV,aAAa,EAEd,MAAM,SAAS,CAAC;AAyNjB,eAAO,MAAM,QAAQ,qDAAoC,CAAC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Image as ReactNativeImage } from 'react-native';
|
|
3
|
+
import { Avatar } from '../../components/avatar';
|
|
4
|
+
import { Button } from '../../components/button';
|
|
5
|
+
import { Card } from '../../components/card';
|
|
6
|
+
import { Text } from '../../components/text';
|
|
7
|
+
import { Box, Divider, Inline, Stack } from '../../foundation';
|
|
8
|
+
import { useZoraTheme } from '../../theme/useZoraTheme';
|
|
9
|
+
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
10
|
+
function resolveAuthorName(author) {
|
|
11
|
+
return typeof author.name === 'string' ? author.name : author.avatar?.name;
|
|
12
|
+
}
|
|
13
|
+
function resolveMediaAspectRatio(aspectRatio) {
|
|
14
|
+
if (aspectRatio === undefined || !Number.isFinite(aspectRatio) || aspectRatio <= 0) {
|
|
15
|
+
return 16 / 9;
|
|
16
|
+
}
|
|
17
|
+
return aspectRatio;
|
|
18
|
+
}
|
|
19
|
+
function isPostCardMediaList(media) {
|
|
20
|
+
return Array.isArray(media);
|
|
21
|
+
}
|
|
22
|
+
function normalizeMedia(media) {
|
|
23
|
+
if (!media) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
if (isPostCardMediaList(media)) {
|
|
27
|
+
return media;
|
|
28
|
+
}
|
|
29
|
+
return [media];
|
|
30
|
+
}
|
|
31
|
+
function PostCardAuthor({ author, compact = false }) {
|
|
32
|
+
const avatarName = resolveAuthorName(author);
|
|
33
|
+
const { avatar } = author;
|
|
34
|
+
return (<Inline align="center" gap="s" wrap="nowrap">
|
|
35
|
+
<Avatar initials={avatar?.initials} label={avatar?.label ?? avatarName} name={avatarName} shape={avatar?.shape} size={avatar?.size ?? (compact ? 's' : 'm')} source={avatar?.source} tone={avatar?.tone}/>
|
|
36
|
+
<Box flex={1}>
|
|
37
|
+
<Stack gap="xxs">
|
|
38
|
+
<Text variant="bodySmall" weight="semiBold">
|
|
39
|
+
{author.name}
|
|
40
|
+
</Text>
|
|
41
|
+
{author.subtitle ? (<Text tone="muted" variant="caption">
|
|
42
|
+
{author.subtitle}
|
|
43
|
+
</Text>) : null}
|
|
44
|
+
</Stack>
|
|
45
|
+
</Box>
|
|
46
|
+
</Inline>);
|
|
47
|
+
}
|
|
48
|
+
function PostCardMediaItem({ media }) {
|
|
49
|
+
const { theme } = useZoraTheme();
|
|
50
|
+
const aspectRatio = resolveMediaAspectRatio(media.aspectRatio);
|
|
51
|
+
if (!('source' in media)) {
|
|
52
|
+
return (<Box radius="m" style={{ overflow: 'hidden' }}>
|
|
53
|
+
{media.children}
|
|
54
|
+
</Box>);
|
|
55
|
+
}
|
|
56
|
+
return (<Box bg={theme.semantics.neutral.surface} radius="m" style={{ overflow: 'hidden' }}>
|
|
57
|
+
<Box style={{ aspectRatio, width: '100%' }}>
|
|
58
|
+
<ReactNativeImage accessibilityLabel={media.label} source={media.source} style={{ height: '100%', width: '100%' }}/>
|
|
59
|
+
</Box>
|
|
60
|
+
</Box>);
|
|
61
|
+
}
|
|
62
|
+
function PostActionLabel({ action }) {
|
|
63
|
+
if (!action.count) {
|
|
64
|
+
return <>{action.label}</>;
|
|
65
|
+
}
|
|
66
|
+
return (<>
|
|
67
|
+
{action.label} {action.count}
|
|
68
|
+
</>);
|
|
69
|
+
}
|
|
70
|
+
function PostCardActions({ actions }) {
|
|
71
|
+
if (actions.length === 0) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return (<Inline align="center" gap="s" wrap="wrap">
|
|
75
|
+
{actions.map((action) => (<Button key={action.id} disabled={action.disabled} emphasis={action.selected ? 'soft' : 'ghost'} leadingIcon={action.icon} onPress={action.onPress} size="s" tone={action.selected ? 'primary' : 'neutral'}>
|
|
76
|
+
<PostActionLabel action={action}/>
|
|
77
|
+
</Button>))}
|
|
78
|
+
</Inline>);
|
|
79
|
+
}
|
|
80
|
+
function PostCommentPreviewItem({ comment }) {
|
|
81
|
+
return (<Inline align="flex-start" gap="s" wrap="nowrap">
|
|
82
|
+
{comment.author ? <PostCardAuthor author={comment.author} compact/> : null}
|
|
83
|
+
<Box flex={1}>
|
|
84
|
+
<Stack gap="xxs">
|
|
85
|
+
<Text variant="bodySmall">{comment.text}</Text>
|
|
86
|
+
{comment.meta ? (<Text tone="subtle" variant="caption">
|
|
87
|
+
{comment.meta}
|
|
88
|
+
</Text>) : null}
|
|
89
|
+
{comment.action ? <Box>{comment.action}</Box> : null}
|
|
90
|
+
</Stack>
|
|
91
|
+
</Box>
|
|
92
|
+
</Inline>);
|
|
93
|
+
}
|
|
94
|
+
function PostCardComments({ comments }) {
|
|
95
|
+
if (comments.length === 0) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return (<Stack gap="s">
|
|
99
|
+
{comments.map((comment) => (<PostCommentPreviewItem key={comment.id} comment={comment}/>))}
|
|
100
|
+
</Stack>);
|
|
101
|
+
}
|
|
102
|
+
function PostCardInner({ themeId: _themeId, mode: _mode, testID, author, text, children, media, actions = [], comments = [], headerAction, footer, tone = 'default', compact = false, onPress, }) {
|
|
103
|
+
const mediaItems = normalizeMedia(media);
|
|
104
|
+
const gap = compact ? 's' : 'm';
|
|
105
|
+
const isInteractive = Boolean(onPress) && !headerAction;
|
|
106
|
+
const hasBody = text != null || children != null || mediaItems.length > 0;
|
|
107
|
+
const hasEngagement = actions.length > 0 || comments.length > 0;
|
|
108
|
+
return (<Card compact={compact} onPress={isInteractive ? onPress : undefined} testID={testID} tone={tone}>
|
|
109
|
+
<Stack gap={gap}>
|
|
110
|
+
<Inline align="center" gap="m" justify="space-between" wrap="nowrap">
|
|
111
|
+
<Box flex={1}>
|
|
112
|
+
<PostCardAuthor author={author} compact={compact}/>
|
|
113
|
+
</Box>
|
|
114
|
+
{headerAction ? <Box>{headerAction}</Box> : null}
|
|
115
|
+
</Inline>
|
|
116
|
+
|
|
117
|
+
{hasBody ? (<Stack gap={gap}>
|
|
118
|
+
{text ? <Text variant="body">{text}</Text> : null}
|
|
119
|
+
{children ? <Box>{children}</Box> : null}
|
|
120
|
+
{mediaItems.length > 0 ? (<Stack gap="s">
|
|
121
|
+
{mediaItems.map((item, index) => (<PostCardMediaItem key={`${index}`} media={item}/>))}
|
|
122
|
+
</Stack>) : null}
|
|
123
|
+
</Stack>) : null}
|
|
124
|
+
|
|
125
|
+
{hasEngagement ? <Divider /> : null}
|
|
126
|
+
<PostCardActions actions={actions}/>
|
|
127
|
+
<PostCardComments comments={comments}/>
|
|
128
|
+
{footer ? <Box pt="xs">{footer}</Box> : null}
|
|
129
|
+
</Stack>
|
|
130
|
+
</Card>);
|
|
131
|
+
}
|
|
132
|
+
export const PostCard = withZoraThemeScope(PostCardInner);
|
|
133
|
+
//# sourceMappingURL=PostCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostCard.js","sourceRoot":"","sources":["../../../src/patterns/post-card/PostCard.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Image as ReactNativeImage } from 'react-native';\n\nimport { Avatar } from '../../components/avatar';\nimport { Button } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { Text } from '../../components/text';\nimport { Box, Divider, Inline, Stack } from '../../foundation';\nimport { useZoraTheme } from '../../theme/useZoraTheme';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport type {\n PostAction,\n PostAuthor,\n PostCardMedia,\n PostCardProps,\n PostCommentPreview,\n} from './types';\n\nfunction resolveAuthorName(author: PostAuthor): string | undefined {\n return typeof author.name === 'string' ? author.name : author.avatar?.name;\n}\n\nfunction resolveMediaAspectRatio(aspectRatio: number | undefined): number {\n if (aspectRatio === undefined || !Number.isFinite(aspectRatio) || aspectRatio <= 0) {\n return 16 / 9;\n }\n\n return aspectRatio;\n}\n\nfunction isPostCardMediaList(\n media: NonNullable<PostCardProps['media']>,\n): media is readonly PostCardMedia[] {\n return Array.isArray(media);\n}\n\nfunction normalizeMedia(media: PostCardProps['media']): readonly PostCardMedia[] {\n if (!media) {\n return [];\n }\n\n if (isPostCardMediaList(media)) {\n return media;\n }\n\n return [media];\n}\n\nfunction PostCardAuthor({ author, compact = false }: { author: PostAuthor; compact?: boolean }) {\n const avatarName = resolveAuthorName(author);\n const { avatar } = author;\n\n return (\n <Inline align=\"center\" gap=\"s\" wrap=\"nowrap\">\n <Avatar\n initials={avatar?.initials}\n label={avatar?.label ?? avatarName}\n name={avatarName}\n shape={avatar?.shape}\n size={avatar?.size ?? (compact ? 's' : 'm')}\n source={avatar?.source}\n tone={avatar?.tone}\n />\n <Box flex={1}>\n <Stack gap=\"xxs\">\n <Text variant=\"bodySmall\" weight=\"semiBold\">\n {author.name}\n </Text>\n {author.subtitle ? (\n <Text tone=\"muted\" variant=\"caption\">\n {author.subtitle}\n </Text>\n ) : null}\n </Stack>\n </Box>\n </Inline>\n );\n}\n\nfunction PostCardMediaItem({ media }: { media: PostCardMedia }) {\n const { theme } = useZoraTheme();\n const aspectRatio = resolveMediaAspectRatio(media.aspectRatio);\n\n if (!('source' in media)) {\n return (\n <Box radius=\"m\" style={{ overflow: 'hidden' }}>\n {media.children}\n </Box>\n );\n }\n\n return (\n <Box bg={theme.semantics.neutral.surface} radius=\"m\" style={{ overflow: 'hidden' }}>\n <Box style={{ aspectRatio, width: '100%' }}>\n <ReactNativeImage\n accessibilityLabel={media.label}\n source={media.source}\n style={{ height: '100%', width: '100%' }}\n />\n </Box>\n </Box>\n );\n}\n\nfunction PostActionLabel({ action }: { action: PostAction }) {\n if (!action.count) {\n return <>{action.label}</>;\n }\n\n return (\n <>\n {action.label} {action.count}\n </>\n );\n}\n\nfunction PostCardActions({ actions }: { actions: readonly PostAction[] }) {\n if (actions.length === 0) {\n return null;\n }\n\n return (\n <Inline align=\"center\" gap=\"s\" wrap=\"wrap\">\n {actions.map((action) => (\n <Button\n key={action.id}\n disabled={action.disabled}\n emphasis={action.selected ? 'soft' : 'ghost'}\n leadingIcon={action.icon}\n onPress={action.onPress}\n size=\"s\"\n tone={action.selected ? 'primary' : 'neutral'}\n >\n <PostActionLabel action={action} />\n </Button>\n ))}\n </Inline>\n );\n}\n\nfunction PostCommentPreviewItem({ comment }: { comment: PostCommentPreview }) {\n return (\n <Inline align=\"flex-start\" gap=\"s\" wrap=\"nowrap\">\n {comment.author ? <PostCardAuthor author={comment.author} compact /> : null}\n <Box flex={1}>\n <Stack gap=\"xxs\">\n <Text variant=\"bodySmall\">{comment.text}</Text>\n {comment.meta ? (\n <Text tone=\"subtle\" variant=\"caption\">\n {comment.meta}\n </Text>\n ) : null}\n {comment.action ? <Box>{comment.action}</Box> : null}\n </Stack>\n </Box>\n </Inline>\n );\n}\n\nfunction PostCardComments({ comments }: { comments: readonly PostCommentPreview[] }) {\n if (comments.length === 0) {\n return null;\n }\n\n return (\n <Stack gap=\"s\">\n {comments.map((comment) => (\n <PostCommentPreviewItem key={comment.id} comment={comment} />\n ))}\n </Stack>\n );\n}\n\nfunction PostCardInner({\n themeId: _themeId,\n mode: _mode,\n testID,\n author,\n text,\n children,\n media,\n actions = [],\n comments = [],\n headerAction,\n footer,\n tone = 'default',\n compact = false,\n onPress,\n}: PostCardProps) {\n const mediaItems = normalizeMedia(media);\n const gap = compact ? 's' : 'm';\n const isInteractive = Boolean(onPress) && !headerAction;\n const hasBody = text != null || children != null || mediaItems.length > 0;\n const hasEngagement = actions.length > 0 || comments.length > 0;\n\n return (\n <Card\n compact={compact}\n onPress={isInteractive ? onPress : undefined}\n testID={testID}\n tone={tone}\n >\n <Stack gap={gap}>\n <Inline align=\"center\" gap=\"m\" justify=\"space-between\" wrap=\"nowrap\">\n <Box flex={1}>\n <PostCardAuthor author={author} compact={compact} />\n </Box>\n {headerAction ? <Box>{headerAction}</Box> : null}\n </Inline>\n\n {hasBody ? (\n <Stack gap={gap}>\n {text ? <Text variant=\"body\">{text}</Text> : null}\n {children ? <Box>{children}</Box> : null}\n {mediaItems.length > 0 ? (\n <Stack gap=\"s\">\n {mediaItems.map((item, index) => (\n <PostCardMediaItem key={`${index}`} media={item} />\n ))}\n </Stack>\n ) : null}\n </Stack>\n ) : null}\n\n {hasEngagement ? <Divider /> : null}\n <PostCardActions actions={actions} />\n <PostCardComments comments={comments} />\n {footer ? <Box pt=\"xs\">{footer}</Box> : null}\n </Stack>\n </Card>\n );\n}\n\nexport const PostCard = withZoraThemeScope(PostCardInner);\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/patterns/post-card/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EACV,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/patterns/post-card/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC","sourcesContent":["export { PostCard } from './PostCard';\nexport type {\n PostAction,\n PostAuthor,\n PostAuthorAvatar,\n PostCardMedia,\n PostCardProps,\n PostCommentPreview,\n} from './types';\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export declare const postCardMeta: {
|
|
2
|
+
readonly name: "PostCard";
|
|
3
|
+
readonly category: "pattern";
|
|
4
|
+
readonly description: "Social/content post card with author identity, body, media, actions, and comment previews.";
|
|
5
|
+
readonly directManifestNode: true;
|
|
6
|
+
readonly allowedChildren: readonly ["Box", "Stack", "Grid", "Container", "Divider", "Text", "Heading", "Button", "Input", "Textarea", "FormField", "Card", "Panel", "Notice", "EmptyState", "SectionHeader", "SettingsRow", "PostCard"];
|
|
7
|
+
readonly blueprint: {
|
|
8
|
+
readonly label: "Post card";
|
|
9
|
+
readonly icon: {
|
|
10
|
+
readonly name: "chatbubble-ellipses-outline";
|
|
11
|
+
};
|
|
12
|
+
readonly defaultProps: {
|
|
13
|
+
readonly author: {
|
|
14
|
+
readonly name: "Ada Lovelace";
|
|
15
|
+
readonly subtitle: "@ada · 2h";
|
|
16
|
+
readonly avatar: {
|
|
17
|
+
readonly name: "Ada Lovelace";
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
readonly text: "Share an update, image, or announcement with a reusable ZORA PostCard.";
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
readonly props: {
|
|
24
|
+
readonly author: {
|
|
25
|
+
readonly type: "array";
|
|
26
|
+
readonly category: "Content";
|
|
27
|
+
readonly label: "Author";
|
|
28
|
+
readonly itemSchema: readonly [{
|
|
29
|
+
readonly key: "name";
|
|
30
|
+
readonly schema: {
|
|
31
|
+
readonly type: "string";
|
|
32
|
+
readonly category: "Content";
|
|
33
|
+
readonly label: "Name";
|
|
34
|
+
};
|
|
35
|
+
}, {
|
|
36
|
+
readonly key: "subtitle";
|
|
37
|
+
readonly schema: {
|
|
38
|
+
readonly type: "string";
|
|
39
|
+
readonly category: "Content";
|
|
40
|
+
readonly label: "Subtitle";
|
|
41
|
+
};
|
|
42
|
+
}];
|
|
43
|
+
};
|
|
44
|
+
readonly text: {
|
|
45
|
+
readonly type: "string";
|
|
46
|
+
readonly category: "Content";
|
|
47
|
+
readonly label: "Text";
|
|
48
|
+
};
|
|
49
|
+
readonly compact: {
|
|
50
|
+
readonly type: "boolean";
|
|
51
|
+
readonly category: "Layout";
|
|
52
|
+
readonly label: "Compact";
|
|
53
|
+
readonly default: false;
|
|
54
|
+
};
|
|
55
|
+
readonly tone: {
|
|
56
|
+
readonly type: "enum";
|
|
57
|
+
readonly category: "Style";
|
|
58
|
+
readonly label: "Tone";
|
|
59
|
+
readonly enum: readonly ["default", "subtle", "outline"];
|
|
60
|
+
readonly default: "default";
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=meta.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/patterns/post-card/meta.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEa,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { CONTAINER_ALLOWED_CHILDREN } from '../../metadata/allowedChildren';
|
|
2
|
+
export const postCardMeta = {
|
|
3
|
+
name: 'PostCard',
|
|
4
|
+
category: 'pattern',
|
|
5
|
+
description: 'Social/content post card with author identity, body, media, actions, and comment previews.',
|
|
6
|
+
directManifestNode: true,
|
|
7
|
+
allowedChildren: [...CONTAINER_ALLOWED_CHILDREN],
|
|
8
|
+
blueprint: {
|
|
9
|
+
label: 'Post card',
|
|
10
|
+
icon: { name: 'chatbubble-ellipses-outline' },
|
|
11
|
+
defaultProps: {
|
|
12
|
+
author: {
|
|
13
|
+
name: 'Ada Lovelace',
|
|
14
|
+
subtitle: '@ada · 2h',
|
|
15
|
+
avatar: {
|
|
16
|
+
name: 'Ada Lovelace',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
text: 'Share an update, image, or announcement with a reusable ZORA PostCard.',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
props: {
|
|
23
|
+
author: {
|
|
24
|
+
type: 'array',
|
|
25
|
+
category: 'Content',
|
|
26
|
+
label: 'Author',
|
|
27
|
+
itemSchema: [
|
|
28
|
+
{
|
|
29
|
+
key: 'name',
|
|
30
|
+
schema: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
category: 'Content',
|
|
33
|
+
label: 'Name',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: 'subtitle',
|
|
38
|
+
schema: {
|
|
39
|
+
type: 'string',
|
|
40
|
+
category: 'Content',
|
|
41
|
+
label: 'Subtitle',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
text: {
|
|
47
|
+
type: 'string',
|
|
48
|
+
category: 'Content',
|
|
49
|
+
label: 'Text',
|
|
50
|
+
},
|
|
51
|
+
compact: {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
category: 'Layout',
|
|
54
|
+
label: 'Compact',
|
|
55
|
+
default: false,
|
|
56
|
+
},
|
|
57
|
+
tone: {
|
|
58
|
+
type: 'enum',
|
|
59
|
+
category: 'Style',
|
|
60
|
+
label: 'Tone',
|
|
61
|
+
enum: ['default', 'subtle', 'outline'],
|
|
62
|
+
default: 'default',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/patterns/post-card/meta.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAE5E,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,SAAS;IACnB,WAAW,EACT,4FAA4F;IAC9F,kBAAkB,EAAE,IAAI;IACxB,eAAe,EAAE,CAAC,GAAG,0BAA0B,CAAC;IAChD,SAAS,EAAE;QACT,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,EAAE,IAAI,EAAE,6BAA6B,EAAE;QAC7C,YAAY,EAAE;YACZ,MAAM,EAAE;gBACN,IAAI,EAAE,cAAc;gBACpB,QAAQ,EAAE,WAAW;gBACrB,MAAM,EAAE;oBACN,IAAI,EAAE,cAAc;iBACrB;aACF;YACD,IAAI,EAAE,wEAAwE;SAC/E;KACF;IACD,KAAK,EAAE;QACL,MAAM,EAAE;YACN,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,QAAQ;YACf,UAAU,EAAE;gBACV;oBACE,GAAG,EAAE,MAAM;oBACX,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,SAAS;wBACnB,KAAK,EAAE,MAAM;qBACd;iBACF;gBACD;oBACE,GAAG,EAAE,UAAU;oBACf,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,SAAS;wBACnB,KAAK,EAAE,UAAU;qBAClB;iBACF;aACF;SACF;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,MAAM;SACd;QACD,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,KAAK;SACf;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;YACtC,OAAO,EAAE,SAAS;SACnB;KACF;CACmC,CAAC","sourcesContent":["import type { ZoraComponentMeta } from '../../metadata';\nimport { CONTAINER_ALLOWED_CHILDREN } from '../../metadata/allowedChildren';\n\nexport const postCardMeta = {\n name: 'PostCard',\n category: 'pattern',\n description:\n 'Social/content post card with author identity, body, media, actions, and comment previews.',\n directManifestNode: true,\n allowedChildren: [...CONTAINER_ALLOWED_CHILDREN],\n blueprint: {\n label: 'Post card',\n icon: { name: 'chatbubble-ellipses-outline' },\n defaultProps: {\n author: {\n name: 'Ada Lovelace',\n subtitle: '@ada · 2h',\n avatar: {\n name: 'Ada Lovelace',\n },\n },\n text: 'Share an update, image, or announcement with a reusable ZORA PostCard.',\n },\n },\n props: {\n author: {\n type: 'array',\n category: 'Content',\n label: 'Author',\n itemSchema: [\n {\n key: 'name',\n schema: {\n type: 'string',\n category: 'Content',\n label: 'Name',\n },\n },\n {\n key: 'subtitle',\n schema: {\n type: 'string',\n category: 'Content',\n label: 'Subtitle',\n },\n },\n ],\n },\n text: {\n type: 'string',\n category: 'Content',\n label: 'Text',\n },\n compact: {\n type: 'boolean',\n category: 'Layout',\n label: 'Compact',\n default: false,\n },\n tone: {\n type: 'enum',\n category: 'Style',\n label: 'Tone',\n enum: ['default', 'subtle', 'outline'],\n default: 'default',\n },\n },\n} as const satisfies ZoraComponentMeta;\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ButtonIconSpec } from '@ankhorage/surface';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
import type { ImageSourcePropType } from 'react-native';
|
|
4
|
+
import type { AvatarShape, AvatarSize } from '../../components/avatar';
|
|
5
|
+
import type { ZoraCardTone, ZoraTone } from '../../internal/recipes';
|
|
6
|
+
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
7
|
+
export interface PostAuthorAvatar {
|
|
8
|
+
source?: ImageSourcePropType;
|
|
9
|
+
name?: string;
|
|
10
|
+
initials?: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
size?: AvatarSize;
|
|
13
|
+
shape?: AvatarShape;
|
|
14
|
+
tone?: ZoraTone;
|
|
15
|
+
}
|
|
16
|
+
export interface PostAuthor {
|
|
17
|
+
name: React.ReactNode;
|
|
18
|
+
subtitle?: React.ReactNode;
|
|
19
|
+
avatar?: PostAuthorAvatar;
|
|
20
|
+
}
|
|
21
|
+
interface PostCardSourceMedia {
|
|
22
|
+
source: ImageSourcePropType;
|
|
23
|
+
label: string;
|
|
24
|
+
aspectRatio?: number;
|
|
25
|
+
children?: never;
|
|
26
|
+
}
|
|
27
|
+
interface PostCardCustomMedia {
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
label?: string;
|
|
30
|
+
aspectRatio?: number;
|
|
31
|
+
source?: never;
|
|
32
|
+
}
|
|
33
|
+
export type PostCardMedia = PostCardSourceMedia | PostCardCustomMedia;
|
|
34
|
+
export interface PostAction {
|
|
35
|
+
id: string;
|
|
36
|
+
label: string;
|
|
37
|
+
icon?: ButtonIconSpec;
|
|
38
|
+
count?: React.ReactNode;
|
|
39
|
+
selected?: boolean;
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
onPress?: () => void;
|
|
42
|
+
}
|
|
43
|
+
export interface PostCommentPreview {
|
|
44
|
+
id: string;
|
|
45
|
+
author?: PostAuthor;
|
|
46
|
+
text: React.ReactNode;
|
|
47
|
+
meta?: React.ReactNode;
|
|
48
|
+
action?: React.ReactNode;
|
|
49
|
+
}
|
|
50
|
+
export interface PostCardProps extends ZoraBaseProps {
|
|
51
|
+
author: PostAuthor;
|
|
52
|
+
text?: React.ReactNode;
|
|
53
|
+
children?: React.ReactNode;
|
|
54
|
+
media?: PostCardMedia | readonly PostCardMedia[];
|
|
55
|
+
actions?: readonly PostAction[];
|
|
56
|
+
comments?: readonly PostCommentPreview[];
|
|
57
|
+
headerAction?: React.ReactNode;
|
|
58
|
+
footer?: React.ReactNode;
|
|
59
|
+
tone?: ZoraCardTone;
|
|
60
|
+
compact?: boolean;
|
|
61
|
+
onPress?: () => void;
|
|
62
|
+
}
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/post-card/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAED,UAAU,mBAAmB;IAC3B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB;AAED,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAEtE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,aAAa,EAAE,CAAC;IACjD,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACzC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/post-card/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ButtonIconSpec } from '@ankhorage/surface';\nimport type React from 'react';\nimport type { ImageSourcePropType } from 'react-native';\n\nimport type { AvatarShape, AvatarSize } from '../../components/avatar';\nimport type { ZoraCardTone, ZoraTone } from '../../internal/recipes';\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport interface PostAuthorAvatar {\n source?: ImageSourcePropType;\n name?: string;\n initials?: string;\n label?: string;\n size?: AvatarSize;\n shape?: AvatarShape;\n tone?: ZoraTone;\n}\n\nexport interface PostAuthor {\n name: React.ReactNode;\n subtitle?: React.ReactNode;\n avatar?: PostAuthorAvatar;\n}\n\ninterface PostCardSourceMedia {\n source: ImageSourcePropType;\n label: string;\n aspectRatio?: number;\n children?: never;\n}\n\ninterface PostCardCustomMedia {\n children: React.ReactNode;\n label?: string;\n aspectRatio?: number;\n source?: never;\n}\n\nexport type PostCardMedia = PostCardSourceMedia | PostCardCustomMedia;\n\nexport interface PostAction {\n id: string;\n label: string;\n icon?: ButtonIconSpec;\n count?: React.ReactNode;\n selected?: boolean;\n disabled?: boolean;\n onPress?: () => void;\n}\n\nexport interface PostCommentPreview {\n id: string;\n author?: PostAuthor;\n text: React.ReactNode;\n meta?: React.ReactNode;\n action?: React.ReactNode;\n}\n\nexport interface PostCardProps extends ZoraBaseProps {\n author: PostAuthor;\n text?: React.ReactNode;\n children?: React.ReactNode;\n media?: PostCardMedia | readonly PostCardMedia[];\n actions?: readonly PostAction[];\n comments?: readonly PostCommentPreview[];\n headerAction?: React.ReactNode;\n footer?: React.ReactNode;\n tone?: ZoraCardTone;\n compact?: boolean;\n onPress?: () => void;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.8",
|
|
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": {
|
package/src/index.ts
CHANGED
|
@@ -205,6 +205,15 @@ export type { NoticeProps } from './patterns/notice';
|
|
|
205
205
|
export { Notice } from './patterns/notice';
|
|
206
206
|
export type { PanelProps } from './patterns/panel';
|
|
207
207
|
export { Panel } from './patterns/panel';
|
|
208
|
+
export type {
|
|
209
|
+
PostAction,
|
|
210
|
+
PostAuthor,
|
|
211
|
+
PostAuthorAvatar,
|
|
212
|
+
PostCardMedia,
|
|
213
|
+
PostCardProps,
|
|
214
|
+
PostCommentPreview,
|
|
215
|
+
} from './patterns/post-card';
|
|
216
|
+
export { PostCard } from './patterns/post-card';
|
|
208
217
|
export type {
|
|
209
218
|
ResponsivePanelDesktopMode,
|
|
210
219
|
ResponsivePanelMobileMode,
|
|
@@ -55,6 +55,7 @@ import { inspectorFieldMeta } from '../patterns/inspector-field/meta';
|
|
|
55
55
|
import { listMeta, listRowMeta, listSectionMeta } from '../patterns/list/meta';
|
|
56
56
|
import { noticeMeta } from '../patterns/notice/meta';
|
|
57
57
|
import { panelMeta } from '../patterns/panel/meta';
|
|
58
|
+
import { postCardMeta } from '../patterns/post-card/meta';
|
|
58
59
|
import { responsivePanelMeta } from '../patterns/responsive-panel/meta';
|
|
59
60
|
import { sectionHeaderMeta } from '../patterns/section-header/meta';
|
|
60
61
|
import { selectableItemMeta, selectionProviderMeta } from '../patterns/selection/meta';
|
|
@@ -132,6 +133,7 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = {
|
|
|
132
133
|
ListSection: listSectionMeta,
|
|
133
134
|
Notice: noticeMeta,
|
|
134
135
|
Panel: panelMeta,
|
|
136
|
+
PostCard: postCardMeta,
|
|
135
137
|
ResponsivePanel: responsivePanelMeta,
|
|
136
138
|
SectionHeader: sectionHeaderMeta,
|
|
137
139
|
SelectableItem: selectableItemMeta,
|
|
@@ -4,9 +4,9 @@ import { Button } from '../../components/button';
|
|
|
4
4
|
import { Card } from '../../components/card';
|
|
5
5
|
import { Heading } from '../../components/heading';
|
|
6
6
|
import { Text } from '../../components/text';
|
|
7
|
-
import { Box, Stack } from '../../foundation';
|
|
7
|
+
import { Box, Grid, Stack } from '../../foundation';
|
|
8
8
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
9
|
-
import type { HeroAction, HeroAlign,
|
|
9
|
+
import type { HeroAction, HeroAlign, HeroProps } from './types';
|
|
10
10
|
|
|
11
11
|
function HeroInner({
|
|
12
12
|
themeId: _themeId,
|
|
@@ -26,13 +26,12 @@ function HeroInner({
|
|
|
26
26
|
}: HeroProps) {
|
|
27
27
|
const hasActions = primaryAction !== undefined || secondaryAction !== undefined;
|
|
28
28
|
const hasMedia = media !== undefined;
|
|
29
|
-
const direction = resolveDirection(layout, hasMedia);
|
|
30
29
|
const contentAlign = resolveContentAlign(align);
|
|
31
30
|
const textAlign = align === 'center' ? 'center' : undefined;
|
|
32
31
|
const mediaFirst = layout === 'mediaFirst';
|
|
33
32
|
|
|
34
33
|
const content = (
|
|
35
|
-
<Box
|
|
34
|
+
<Box width="100%">
|
|
36
35
|
<Stack align={contentAlign} gap={compact ? 's' : 'm'}>
|
|
37
36
|
<Stack align={contentAlign} gap="xs">
|
|
38
37
|
{eyebrow !== undefined ? (
|
|
@@ -49,8 +48,8 @@ function HeroInner({
|
|
|
49
48
|
</Heading>
|
|
50
49
|
{description !== undefined ? (
|
|
51
50
|
<Text
|
|
52
|
-
tone="muted"
|
|
53
51
|
align={textAlign}
|
|
52
|
+
tone="muted"
|
|
54
53
|
variant={{ base: 'body', md: compact ? 'body' : 'lead' }}
|
|
55
54
|
>
|
|
56
55
|
{description}
|
|
@@ -75,18 +74,24 @@ function HeroInner({
|
|
|
75
74
|
</Box>
|
|
76
75
|
);
|
|
77
76
|
|
|
78
|
-
const mediaSlot = hasMedia ?
|
|
79
|
-
<Box flex={{ md: 1 }} width={{ base: '100%', md: 'auto' }}>
|
|
80
|
-
{media}
|
|
81
|
-
</Box>
|
|
82
|
-
) : null;
|
|
77
|
+
const mediaSlot = hasMedia ? <Box width="100%">{media}</Box> : null;
|
|
83
78
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
<
|
|
79
|
+
const body =
|
|
80
|
+
hasMedia && layout !== 'stack' ? (
|
|
81
|
+
<Grid cols={{ base: 1, md: 2 }} gap={compact ? 'm' : 'l'}>
|
|
82
|
+
{mediaFirst ? mediaSlot : content}
|
|
83
|
+
{mediaFirst ? content : mediaSlot}
|
|
84
|
+
</Grid>
|
|
85
|
+
) : (
|
|
86
|
+
<Stack align="center" direction="column" gap={compact ? 'm' : 'l'}>
|
|
87
87
|
{mediaFirst ? mediaSlot : content}
|
|
88
88
|
{mediaFirst ? content : mediaSlot}
|
|
89
89
|
</Stack>
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<Card compact={compact} testID={testID} tone={tone}>
|
|
94
|
+
{body}
|
|
90
95
|
</Card>
|
|
91
96
|
);
|
|
92
97
|
}
|
|
@@ -108,9 +113,4 @@ function resolveContentAlign(align: HeroAlign) {
|
|
|
108
113
|
return align === 'center' ? 'center' : 'flex-start';
|
|
109
114
|
}
|
|
110
115
|
|
|
111
|
-
function resolveDirection(layout: HeroLayout, hasMedia: boolean) {
|
|
112
|
-
if (!hasMedia || layout === 'stack') return 'column' as const;
|
|
113
|
-
return { base: 'column', md: 'row' } as const;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
116
|
export const Hero = withZoraThemeScope(HeroInner);
|