Add ActorLabel
This commit is contained in:
@@ -0,0 +1,54 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {AtUri} from '@atproto/api'
|
||||||
|
import {z} from 'zod'
|
||||||
|
|
||||||
|
import {useProfileQuery} from '#/state/queries/profile'
|
||||||
|
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
|
||||||
|
import {color} from './common'
|
||||||
|
import {Label} from './Label'
|
||||||
|
|
||||||
|
const actorLabelProps = z.object({
|
||||||
|
uri: z.string(),
|
||||||
|
field: z.enum(['handle', 'displayName', 'description']),
|
||||||
|
color,
|
||||||
|
size: z
|
||||||
|
.number()
|
||||||
|
.positive()
|
||||||
|
.default(16)
|
||||||
|
.transform(v => ({fontSize: v})),
|
||||||
|
lineHeight: z
|
||||||
|
.number()
|
||||||
|
.positive()
|
||||||
|
.default(1)
|
||||||
|
.transform(v => ({lineHeight: v})),
|
||||||
|
weight: z
|
||||||
|
.enum(['normal', 'semibold', 'bold'])
|
||||||
|
.default('normal')
|
||||||
|
.transform(v => ({fontWeight: v})),
|
||||||
|
})
|
||||||
|
|
||||||
|
export type ActorLabelProps = z.infer<typeof actorLabelProps>
|
||||||
|
|
||||||
|
export function ActorLabel(props: React.PropsWithChildren<ActorLabelProps>) {
|
||||||
|
const propsParsed = actorLabelProps.parse(props)
|
||||||
|
const urip = new AtUri(propsParsed.uri)
|
||||||
|
|
||||||
|
const {data: did} = useResolveDidQuery(urip.host)
|
||||||
|
const {data: profile} = useProfileQuery({did})
|
||||||
|
|
||||||
|
let text = ''
|
||||||
|
if (profile) {
|
||||||
|
if (props.field === 'handle') {
|
||||||
|
text = profile.handle
|
||||||
|
}
|
||||||
|
if (props.field === 'displayName') {
|
||||||
|
text = profile.displayName || profile.handle
|
||||||
|
}
|
||||||
|
if (props.field === 'description') {
|
||||||
|
text = profile.description || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO loading, error
|
||||||
|
return <Label {...props} text={text} />
|
||||||
|
}
|
||||||
@@ -2,20 +2,12 @@ import React from 'react'
|
|||||||
import {z} from 'zod'
|
import {z} from 'zod'
|
||||||
|
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
import {color} from './common'
|
||||||
import {useFontColor} from './hooks'
|
import {useFontColor} from './hooks'
|
||||||
|
|
||||||
const labelProps = z.object({
|
export const labelProps = z.object({
|
||||||
text: z.string(),
|
text: z.string(),
|
||||||
color: z
|
color,
|
||||||
.enum([
|
|
||||||
'default',
|
|
||||||
'primary',
|
|
||||||
'secondary',
|
|
||||||
'positive',
|
|
||||||
'negative',
|
|
||||||
'inverted',
|
|
||||||
])
|
|
||||||
.default('default'),
|
|
||||||
size: z
|
size: z
|
||||||
.number()
|
.number()
|
||||||
.positive()
|
.positive()
|
||||||
|
|||||||
@@ -30,3 +30,7 @@ export const pad = z
|
|||||||
})),
|
})),
|
||||||
])
|
])
|
||||||
.optional()
|
.optional()
|
||||||
|
|
||||||
|
export const color = z
|
||||||
|
.enum(['default', 'primary', 'secondary', 'positive', 'negative', 'inverted'])
|
||||||
|
.default('default')
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {ZodError} from 'zod'
|
|||||||
|
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import type {AppComNode} from '../types'
|
import type {AppComNode} from '../types'
|
||||||
|
import {ActorLabel} from './ActorLabel'
|
||||||
import {Avatar} from './Avatar'
|
import {Avatar} from './Avatar'
|
||||||
import {Box} from './Box'
|
import {Box} from './Box'
|
||||||
import {Embed} from './Embed'
|
import {Embed} from './Embed'
|
||||||
@@ -14,6 +15,7 @@ import {Stack} from './Stack'
|
|||||||
import {Tabs} from './Tabs'
|
import {Tabs} from './Tabs'
|
||||||
|
|
||||||
export const VOCAB: Record<string, React.ComponentType<any>> = {
|
export const VOCAB: Record<string, React.ComponentType<any>> = {
|
||||||
|
ActorLabel,
|
||||||
Avatar,
|
Avatar,
|
||||||
Box,
|
Box,
|
||||||
Embed,
|
Embed,
|
||||||
|
|||||||
@@ -85,6 +85,25 @@ const DEFAULT_AC = h('Stack', {gap: 10}, [
|
|||||||
h('Avatar', {uri: 'at://pfrazee.com/'}),
|
h('Avatar', {uri: 'at://pfrazee.com/'}),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
|
h('Box', {pad: {x: 10}}, [
|
||||||
|
h('Label', {text: 'ActorLabel', size: 10, weight: 'bold'}),
|
||||||
|
]),
|
||||||
|
h('Box', {border: 'secondary', corner: 8, pad: {x: 16, y: 12}}, [
|
||||||
|
h('Stack', {gap: 10}, [
|
||||||
|
h('Stack', {direction: 'row', gap: 8}, [
|
||||||
|
h('Label', {weight: 'bold', text: 'Display Name:'}),
|
||||||
|
h('ActorLabel', {uri: 'bsky.app', field: 'displayName'}),
|
||||||
|
]),
|
||||||
|
h('Stack', {direction: 'row', gap: 8}, [
|
||||||
|
h('Label', {weight: 'bold', text: 'Handle:'}),
|
||||||
|
h('ActorLabel', {uri: 'bsky.app', field: 'handle'}),
|
||||||
|
]),
|
||||||
|
h('Stack', {direction: 'row', gap: 8}, [
|
||||||
|
h('Label', {weight: 'bold', text: 'Description:'}),
|
||||||
|
h('ActorLabel', {uri: 'bsky.app', field: 'description'}),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
h('Box', {pad: {x: 10}}, [
|
h('Box', {pad: {x: 10}}, [
|
||||||
h('Label', {text: 'Embed (Actor)', size: 10, weight: 'bold'}),
|
h('Label', {text: 'Embed (Actor)', size: 10, weight: 'bold'}),
|
||||||
]),
|
]),
|
||||||
|
|||||||
Reference in New Issue
Block a user