Skip to content

Commit

Permalink
feat(structure): update TimelineItem to match new UI, prepare for chu…
Browse files Browse the repository at this point in the history
…nks (#7449)

* feat(structure): update TimelineItem to match new UI, prepare for chunks

* chore(core): export getCalendarLabels to support DateTimeInput reusability
  • Loading branch information
pedrobonamin committed Nov 18, 2024
1 parent ae2ac88 commit a009dbc
Show file tree
Hide file tree
Showing 10 changed files with 268 additions and 161 deletions.
1 change: 1 addition & 0 deletions packages/sanity/src/core/form/inputs/DateInputs/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export {DateInput, type DateInputProps} from './DateInput'
export {DateTimeInput, type DateTimeInputProps} from './DateTimeInput'
export {getCalendarLabels} from './utils'
3 changes: 3 additions & 0 deletions packages/sanity/src/core/form/inputs/DateInputs/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ export function isValidDate(date: Date): boolean {
return date instanceof Date && !isNaN(date.valueOf())
}

/**
* @internal
*/
export function getCalendarLabels(
t: (key: string, values?: Record<string, unknown>) => string,
): CalendarLabels {
Expand Down
7 changes: 7 additions & 0 deletions packages/sanity/src/structure/i18n/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,13 @@ const structureLocaleStrings = defineLocalesResources('structure', {
'structure-error.reload-button.text': 'Reload',
/** Labels the structure path of the structure error screen */
'structure-error.structure-path.label': 'Structure path',

/** The aria label for the menu button in the timeline item */
'timeline-item.menu-button.aria-label': 'Open action menu',
/** The text for the tooltip in menu button the timeline item */
'timeline-item.menu-button.tooltip': 'Actions',
/** The text for the expand action in the timeline item menu */
'timeline-item.menu.action-expand': 'Expand',
})

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import {Box, Card, Container, Stack, Text} from '@sanity/ui'
import {useMemo, useState} from 'react'
import {type ChunkType, getCalendarLabels, useDateTimeFormat, useTranslation} from 'sanity'

import {DateTimeInput} from '../../../../../ui-components/inputs/DateInputs/DateTimeInput'
import {TIMELINE_ITEM_I18N_KEY_MAPPING} from '../timelineI18n'
import {TimelineItem} from '../timelineItem'

const CHUNK_TYPES = Object.keys(TIMELINE_ITEM_I18N_KEY_MAPPING).reverse() as ChunkType[]

export default function TimelineItemStory() {
const {t: coreT} = useTranslation()
const [date, setDate] = useState<Date>(() => new Date())
const [selected, setSelected] = useState<string | null>(null)
const dateFormatter = useDateTimeFormat({dateStyle: 'medium', timeStyle: 'short'})
const calendarLabels = useMemo(() => getCalendarLabels(coreT), [coreT])

const inputValue = date ? dateFormatter.format(new Date(date)) : ''
const handleDatechange = (newDate: Date | null) => {
if (newDate) {
setDate(newDate)
} else {
console.error('No date selected')
}
}

return (
<Box margin={3}>
<Container width={0} margin={4}>
<Box paddingY={3}>
<Text as="h2" size={2} weight="semibold">
Timeline Item
</Text>
</Box>
<Stack space={2} marginTop={3}>
<Text weight="medium" as="label" htmlFor="date" size={1}>
Select date:
</Text>
<DateTimeInput
id="date"
selectTime
onChange={handleDatechange}
calendarLabels={calendarLabels}
value={date ? new Date(date) : undefined}
inputValue={inputValue}
constrainSize={false}
/>
<Text size={0} muted>
Update the selected date to see how the component behaves with relative dates.
</Text>
</Stack>

<Card border padding={2} marginTop={3} radius={2}>
<Stack space={1}>
{CHUNK_TYPES.map((key, index) => (
<TimelineItem
key={key}
onSelect={() => setSelected((p) => (p === key ? null : key))}
isSelected={selected === key}
type={key}
timestamp={date.toString()}
chunk={{
index,
id: key,
type: key,
start: -13,
end: -13,
startTimestamp: date.toString(),
endTimestamp: date.toString(),
authors: new Set(['p8xDvUMxC']),
draftState: 'unknown',
publishedState: 'present',
}}
squashedChunks={
key === 'publish'
? [
{
index: 0,
id: '123',
type: 'editDraft',
start: 0,
end: 0,
startTimestamp: date.toString(),
endTimestamp: date.toString(),
authors: new Set(['pP5s3g90N']),
draftState: 'present',
publishedState: 'present',
},
{
index: 1,
id: '345',
type: 'editDraft',
start: 1,
end: 1,
startTimestamp: date.toString(),
endTimestamp: date.toString(),
authors: new Set(['pJ61yWhkD']),
draftState: 'present',
publishedState: 'present',
},
{
index: 2,
id: '345',
type: 'editDraft',
start: 2,
end: 2,
startTimestamp: date.toString(),
endTimestamp: date.toString(),
authors: new Set(['pJ61yWhkD']),
draftState: 'present',
publishedState: 'present',
},
]
: undefined
}
/>
))}
</Stack>
</Card>
</Container>
</Box>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,10 @@ export default defineScope({
title: 'Default',
component: lazy(() => import('./DefaultStory')),
},
{
name: 'timelineItem',
title: 'Timeline Item',
component: lazy(() => import('./TimelineItemStory')),
},
],
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
AddCircleIcon,
AddIcon,
CloseIcon,
EditIcon,
type IconComponent,
Expand All @@ -9,10 +9,10 @@ import {
} from '@sanity/icons'

export const TIMELINE_ICON_COMPONENTS: {[key: string]: IconComponent | undefined} = {
create: AddCircleIcon,
create: AddIcon,
delete: TrashIcon,
discardDraft: CloseIcon,
initial: AddCircleIcon,
initial: AddIcon,
editDraft: EditIcon,
editLive: EditIcon,
publish: PublishIcon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,10 @@ export const Timeline = ({
const renderItem = useCallback<CommandListRenderItemCallback<Chunk>>(
(chunk, {activeIndex}) => {
const isFirst = activeIndex === 0
const isLast = (filteredChunks && activeIndex === filteredChunks.length - 1) || false
return (
<Box paddingBottom={isLast ? 1 : 0} paddingTop={isFirst ? 1 : 0} paddingX={1}>
<Box paddingBottom={1} paddingTop={isFirst ? 1 : 0} paddingX={1}>
<TimelineItem
chunk={chunk}
isFirst={isFirst}
isLast={isLast}
isLatest={activeIndex === 0 && !disabledBeforeFirstChunk}
isSelected={activeIndex === selectedIndex}
onSelect={onSelect}
timestamp={chunk.endTimestamp}
Expand All @@ -72,7 +68,7 @@ export const Timeline = ({
</Box>
)
},
[disabledBeforeFirstChunk, filteredChunks, hasMoreChunks, onSelect, selectedIndex],
[filteredChunks, hasMoreChunks, onSelect, selectedIndex],
)

useEffect(() => setMounted(true), [])
Expand Down

This file was deleted.

Loading

0 comments on commit a009dbc

Please sign in to comment.