@ankhorage/zora 1.4.7 → 1.4.9
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 +262 -0
- package/dist/components/card/meta.d.ts +1 -1
- package/dist/foundation/meta.d.ts +4 -4
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -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 +2 -0
- package/dist/metadata/allowedChildren.js.map +1 -1
- package/dist/metadata/componentMeta.d.ts.map +1 -1
- package/dist/metadata/componentMeta.js +4 -0
- package/dist/metadata/componentMeta.js.map +1 -1
- package/dist/patterns/chat-list-item/ChatListItem.d.ts +4 -0
- package/dist/patterns/chat-list-item/ChatListItem.d.ts.map +1 -0
- package/dist/patterns/chat-list-item/ChatListItem.js +110 -0
- package/dist/patterns/chat-list-item/ChatListItem.js.map +1 -0
- package/dist/patterns/chat-list-item/index.d.ts +3 -0
- package/dist/patterns/chat-list-item/index.d.ts.map +1 -0
- package/dist/patterns/chat-list-item/index.js +2 -0
- package/dist/patterns/chat-list-item/index.js.map +1 -0
- package/dist/patterns/chat-list-item/meta.d.ts +74 -0
- package/dist/patterns/chat-list-item/meta.d.ts.map +1 -0
- package/dist/patterns/chat-list-item/meta.js +72 -0
- package/dist/patterns/chat-list-item/meta.js.map +1 -0
- package/dist/patterns/chat-list-item/types.d.ts +31 -0
- package/dist/patterns/chat-list-item/types.d.ts.map +1 -0
- package/dist/patterns/chat-list-item/types.js +2 -0
- package/dist/patterns/chat-list-item/types.js.map +1 -0
- 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 +11 -0
- package/src/metadata/allowedChildren.ts +2 -0
- package/src/metadata/componentMeta.test.ts +2 -0
- package/src/metadata/componentMeta.ts +4 -0
- package/src/patterns/chat-list-item/ChatListItem.test.tsx +11 -0
- package/src/patterns/chat-list-item/ChatListItem.tsx +219 -0
- package/src/patterns/chat-list-item/index.ts +2 -0
- package/src/patterns/chat-list-item/meta.ts +74 -0
- package/src/patterns/chat-list-item/types.ts +33 -0
- 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
|
@@ -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", "ChatListItem"];
|
|
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.9",
|
|
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
|
@@ -163,6 +163,8 @@ export type {
|
|
|
163
163
|
SignUpFormValues,
|
|
164
164
|
} from './patterns/auth';
|
|
165
165
|
export { ForgotPasswordForm, OtpForm, SignInForm, SignUpForm } from './patterns/auth';
|
|
166
|
+
export type { ChatListAvatar, ChatListItemProps } from './patterns/chat-list-item';
|
|
167
|
+
export { ChatListItem } from './patterns/chat-list-item';
|
|
166
168
|
export type {
|
|
167
169
|
CollectionEditorProps,
|
|
168
170
|
CollectionEditorRenderItemProps,
|
|
@@ -205,6 +207,15 @@ export type { NoticeProps } from './patterns/notice';
|
|
|
205
207
|
export { Notice } from './patterns/notice';
|
|
206
208
|
export type { PanelProps } from './patterns/panel';
|
|
207
209
|
export { Panel } from './patterns/panel';
|
|
210
|
+
export type {
|
|
211
|
+
PostAction,
|
|
212
|
+
PostAuthor,
|
|
213
|
+
PostAuthorAvatar,
|
|
214
|
+
PostCardMedia,
|
|
215
|
+
PostCardProps,
|
|
216
|
+
PostCommentPreview,
|
|
217
|
+
} from './patterns/post-card';
|
|
218
|
+
export { PostCard } from './patterns/post-card';
|
|
208
219
|
export type {
|
|
209
220
|
ResponsivePanelDesktopMode,
|
|
210
221
|
ResponsivePanelMobileMode,
|
|
@@ -141,6 +141,7 @@ describe('ZORA_COMPONENT_META invariants', () => {
|
|
|
141
141
|
'Text',
|
|
142
142
|
'Heading',
|
|
143
143
|
'Divider',
|
|
144
|
+
'ChatListItem',
|
|
144
145
|
]);
|
|
145
146
|
|
|
146
147
|
const expectedContainerNodes = new Set([
|
|
@@ -151,6 +152,7 @@ describe('ZORA_COMPONENT_META invariants', () => {
|
|
|
151
152
|
'Card',
|
|
152
153
|
'Panel',
|
|
153
154
|
'Notice',
|
|
155
|
+
'PostCard',
|
|
154
156
|
'Box',
|
|
155
157
|
'Stack',
|
|
156
158
|
'Grid',
|
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
signInFormMeta,
|
|
44
44
|
signUpFormMeta,
|
|
45
45
|
} from '../patterns/auth/meta';
|
|
46
|
+
import { chatListItemMeta } from '../patterns/chat-list-item/meta';
|
|
46
47
|
import { collectionEditorMeta } from '../patterns/collection-editor/meta';
|
|
47
48
|
import { confirmDialogMeta } from '../patterns/confirm-dialog/meta';
|
|
48
49
|
import { disclosureSectionMeta } from '../patterns/disclosure-section/meta';
|
|
@@ -55,6 +56,7 @@ import { inspectorFieldMeta } from '../patterns/inspector-field/meta';
|
|
|
55
56
|
import { listMeta, listRowMeta, listSectionMeta } from '../patterns/list/meta';
|
|
56
57
|
import { noticeMeta } from '../patterns/notice/meta';
|
|
57
58
|
import { panelMeta } from '../patterns/panel/meta';
|
|
59
|
+
import { postCardMeta } from '../patterns/post-card/meta';
|
|
58
60
|
import { responsivePanelMeta } from '../patterns/responsive-panel/meta';
|
|
59
61
|
import { sectionHeaderMeta } from '../patterns/section-header/meta';
|
|
60
62
|
import { selectableItemMeta, selectionProviderMeta } from '../patterns/selection/meta';
|
|
@@ -118,6 +120,7 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = {
|
|
|
118
120
|
OtpForm: otpFormMeta,
|
|
119
121
|
SignInForm: signInFormMeta,
|
|
120
122
|
SignUpForm: signUpFormMeta,
|
|
123
|
+
ChatListItem: chatListItemMeta,
|
|
121
124
|
CollectionEditor: collectionEditorMeta,
|
|
122
125
|
ConfirmDialog: confirmDialogMeta,
|
|
123
126
|
DisclosureSection: disclosureSectionMeta,
|
|
@@ -132,6 +135,7 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = {
|
|
|
132
135
|
ListSection: listSectionMeta,
|
|
133
136
|
Notice: noticeMeta,
|
|
134
137
|
Panel: panelMeta,
|
|
138
|
+
PostCard: postCardMeta,
|
|
135
139
|
ResponsivePanel: responsivePanelMeta,
|
|
136
140
|
SectionHeader: sectionHeaderMeta,
|
|
137
141
|
SelectableItem: selectableItemMeta,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { ZORA_COMPONENT_META } from '../../metadata';
|
|
4
|
+
|
|
5
|
+
describe('ChatListItem', () => {
|
|
6
|
+
test('is registered as a public ZORA pattern', () => {
|
|
7
|
+
expect(ZORA_COMPONENT_META.ChatListItem?.name).toBe('ChatListItem');
|
|
8
|
+
expect(ZORA_COMPONENT_META.ChatListItem?.category).toBe('pattern');
|
|
9
|
+
expect(ZORA_COMPONENT_META.ChatListItem?.directManifestNode).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { ButtonBase } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { Avatar } from '../../components/avatar';
|
|
5
|
+
import { Badge } from '../../components/badge';
|
|
6
|
+
import { Text } from '../../components/text';
|
|
7
|
+
import { Box, Inline, Stack } from '../../foundation';
|
|
8
|
+
import { useZoraTheme } from '../../theme/useZoraTheme';
|
|
9
|
+
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
10
|
+
import type { ChatListAvatar, ChatListItemProps } from './types';
|
|
11
|
+
|
|
12
|
+
function resolveAvatarName({
|
|
13
|
+
avatar,
|
|
14
|
+
title,
|
|
15
|
+
}: {
|
|
16
|
+
avatar: ChatListAvatar | undefined;
|
|
17
|
+
title: React.ReactNode;
|
|
18
|
+
}): string | undefined {
|
|
19
|
+
if (avatar?.name) {
|
|
20
|
+
return avatar.name;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return typeof title === 'string' ? title : undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function resolvePadding(compact: boolean) {
|
|
27
|
+
return compact ? { px: 'm' as const, py: 's' as const } : { px: 'm' as const, py: 'm' as const };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function resolveContainerStyles({
|
|
31
|
+
theme,
|
|
32
|
+
selected,
|
|
33
|
+
pressed,
|
|
34
|
+
hovered,
|
|
35
|
+
disabled,
|
|
36
|
+
}: {
|
|
37
|
+
theme: ReturnType<typeof useZoraTheme>['theme'];
|
|
38
|
+
selected: boolean;
|
|
39
|
+
pressed: boolean;
|
|
40
|
+
hovered: boolean;
|
|
41
|
+
disabled: boolean;
|
|
42
|
+
}) {
|
|
43
|
+
const borderColor = selected ? theme.semantics.border.focus : 'transparent';
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
bg: pressed
|
|
47
|
+
? theme.semantics.neutral.surfaceActive
|
|
48
|
+
: hovered
|
|
49
|
+
? theme.semantics.neutral.surfaceHover
|
|
50
|
+
: selected
|
|
51
|
+
? theme.semantics.neutral.surface
|
|
52
|
+
: 'transparent',
|
|
53
|
+
borderColor,
|
|
54
|
+
borderWidth: selected ? 1 : 0,
|
|
55
|
+
opacity: disabled ? 0.72 : 1,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function renderUnreadCount(unreadCount: React.ReactNode) {
|
|
60
|
+
if (unreadCount == null) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Badge size="s" tone="primary">
|
|
66
|
+
{unreadCount}
|
|
67
|
+
</Badge>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function ChatListItemInner({
|
|
72
|
+
themeId: _themeId,
|
|
73
|
+
mode: _mode,
|
|
74
|
+
testID,
|
|
75
|
+
title,
|
|
76
|
+
preview,
|
|
77
|
+
meta,
|
|
78
|
+
timestamp,
|
|
79
|
+
avatar,
|
|
80
|
+
leading,
|
|
81
|
+
trailing,
|
|
82
|
+
unread = false,
|
|
83
|
+
unreadCount,
|
|
84
|
+
selected = false,
|
|
85
|
+
disabled = false,
|
|
86
|
+
compact = false,
|
|
87
|
+
accessibilityLabel,
|
|
88
|
+
onPress,
|
|
89
|
+
}: ChatListItemProps) {
|
|
90
|
+
const { theme } = useZoraTheme();
|
|
91
|
+
const padding = resolvePadding(compact);
|
|
92
|
+
const avatarName = resolveAvatarName({ avatar, title });
|
|
93
|
+
const isInteractive = Boolean(onPress);
|
|
94
|
+
const hasTimestamp = timestamp != null;
|
|
95
|
+
const hasPreview = preview != null;
|
|
96
|
+
const hasMeta = meta != null;
|
|
97
|
+
const hasTrailing = trailing != null;
|
|
98
|
+
const hasUnreadCount = unreadCount != null;
|
|
99
|
+
const hasSecondaryRow = hasPreview || hasMeta || hasUnreadCount || hasTrailing;
|
|
100
|
+
|
|
101
|
+
const content = ({ pressed, hovered }: { pressed: boolean; hovered: boolean }) => {
|
|
102
|
+
const styles = resolveContainerStyles({
|
|
103
|
+
theme,
|
|
104
|
+
selected,
|
|
105
|
+
pressed,
|
|
106
|
+
hovered,
|
|
107
|
+
disabled,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<Box
|
|
112
|
+
bg={styles.bg}
|
|
113
|
+
borderColor={styles.borderColor}
|
|
114
|
+
borderWidth={styles.borderWidth}
|
|
115
|
+
px={padding.px}
|
|
116
|
+
py={padding.py}
|
|
117
|
+
radius="m"
|
|
118
|
+
style={{ opacity: styles.opacity }}
|
|
119
|
+
>
|
|
120
|
+
<Inline align="center" gap="m" wrap="nowrap">
|
|
121
|
+
{leading ?? (
|
|
122
|
+
<Avatar
|
|
123
|
+
initials={avatar?.initials}
|
|
124
|
+
label={avatar?.label ?? avatarName}
|
|
125
|
+
name={avatarName}
|
|
126
|
+
shape={avatar?.shape}
|
|
127
|
+
size={avatar?.size ?? (compact ? 's' : 'm')}
|
|
128
|
+
source={avatar?.source}
|
|
129
|
+
tone={avatar?.tone}
|
|
130
|
+
/>
|
|
131
|
+
)}
|
|
132
|
+
|
|
133
|
+
<Box flex={1}>
|
|
134
|
+
<Stack gap="xxs">
|
|
135
|
+
<Inline align="center" gap="s" justify="space-between" wrap="nowrap">
|
|
136
|
+
<Box flex={1}>
|
|
137
|
+
<Text
|
|
138
|
+
numberOfLines={1}
|
|
139
|
+
tone={disabled ? 'muted' : 'default'}
|
|
140
|
+
variant="bodySmall"
|
|
141
|
+
weight={unread || selected ? 'semiBold' : 'medium'}
|
|
142
|
+
>
|
|
143
|
+
{title}
|
|
144
|
+
</Text>
|
|
145
|
+
</Box>
|
|
146
|
+
{hasTimestamp ? (
|
|
147
|
+
<Text
|
|
148
|
+
numberOfLines={1}
|
|
149
|
+
tone={unread ? 'primary' : 'subtle'}
|
|
150
|
+
variant="caption"
|
|
151
|
+
weight={unread ? 'semiBold' : 'regular'}
|
|
152
|
+
>
|
|
153
|
+
{timestamp}
|
|
154
|
+
</Text>
|
|
155
|
+
) : null}
|
|
156
|
+
</Inline>
|
|
157
|
+
|
|
158
|
+
{hasSecondaryRow ? (
|
|
159
|
+
<Inline align="center" gap="s" justify="space-between" wrap="nowrap">
|
|
160
|
+
<Box flex={1}>
|
|
161
|
+
<Stack gap="xxs">
|
|
162
|
+
{hasPreview ? (
|
|
163
|
+
<Text
|
|
164
|
+
numberOfLines={1}
|
|
165
|
+
tone={unread ? 'default' : 'muted'}
|
|
166
|
+
variant="bodySmall"
|
|
167
|
+
weight={unread ? 'medium' : 'regular'}
|
|
168
|
+
>
|
|
169
|
+
{preview}
|
|
170
|
+
</Text>
|
|
171
|
+
) : null}
|
|
172
|
+
{hasMeta ? (
|
|
173
|
+
<Text numberOfLines={1} tone="subtle" variant="caption">
|
|
174
|
+
{meta}
|
|
175
|
+
</Text>
|
|
176
|
+
) : null}
|
|
177
|
+
</Stack>
|
|
178
|
+
</Box>
|
|
179
|
+
|
|
180
|
+
{hasUnreadCount || hasTrailing ? (
|
|
181
|
+
<Inline align="center" gap="s" wrap="nowrap">
|
|
182
|
+
{renderUnreadCount(unreadCount)}
|
|
183
|
+
{trailing}
|
|
184
|
+
</Inline>
|
|
185
|
+
) : null}
|
|
186
|
+
</Inline>
|
|
187
|
+
) : null}
|
|
188
|
+
</Stack>
|
|
189
|
+
</Box>
|
|
190
|
+
</Inline>
|
|
191
|
+
</Box>
|
|
192
|
+
);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
if (!isInteractive) {
|
|
196
|
+
return <Box testID={testID}>{content({ pressed: false, hovered: false })}</Box>;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return (
|
|
200
|
+
<ButtonBase
|
|
201
|
+
accessibilityLabel={accessibilityLabel}
|
|
202
|
+
accessibilityRole="button"
|
|
203
|
+
accessibilityState={{ disabled, selected }}
|
|
204
|
+
disabled={disabled}
|
|
205
|
+
onPress={onPress}
|
|
206
|
+
radius="m"
|
|
207
|
+
testID={testID}
|
|
208
|
+
>
|
|
209
|
+
{(state) =>
|
|
210
|
+
content({
|
|
211
|
+
pressed: state.pressed,
|
|
212
|
+
hovered: state.hovered,
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
</ButtonBase>
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export const ChatListItem = withZoraThemeScope(ChatListItemInner);
|