diff --git a/resources/js/components/publish/CalendarPostChip.vue b/resources/js/components/publish/CalendarPostChip.vue index a99734a93..c6a022185 100644 --- a/resources/js/components/publish/CalendarPostChip.vue +++ b/resources/js/components/publish/CalendarPostChip.vue @@ -27,6 +27,7 @@ const props = withDefaults( post: CalendarPost; timezone: string; layout?: 'month' | 'week'; + compact?: boolean; }>(), { layout: 'month' }, ); @@ -137,72 +138,84 @@ const scheduleMode = computed(() => class="flex min-w-0 shrink-0 gap-1.5 rounded-lg border border-border-strong bg-card text-start transition-control hover:bg-secondary focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring data-[state=open]:bg-secondary" :class="[ STATUS_CLASSES[post.status] ?? '', - layout === 'week' - ? 'items-start p-1.5' - : 'h-7 items-center px-1', + compact + ? 'size-7 items-center justify-center' + : layout === 'week' + ? 'items-start p-1.5' + : 'h-7 items-center px-1', ]" :aria-label="`${channels} · ${time} · ${text || $t('calendar.no_content')}`" :data-testid="`calendar-post-${post.id}`" > - - - + + (), { layout: 'chip' }, ); @@ -80,7 +81,12 @@ const newPost = (): void => { v-else :is="canCreatePost ? 'button' : 'div'" :type="canCreatePost ? 'button' : undefined" - class="group/slot flex h-7 w-full min-w-0 shrink-0 items-center gap-1.5 rounded-lg border border-dashed border-border-strong px-1.5 text-xs font-medium text-muted-foreground transition-control enabled:hover:bg-secondary enabled:hover:text-foreground enabled:focus-visible:bg-secondary enabled:focus-visible:text-foreground" + class="group/slot flex shrink-0 items-center rounded-lg border border-dashed border-border-strong text-xs font-medium text-muted-foreground transition-control enabled:hover:bg-secondary enabled:hover:text-foreground enabled:focus-visible:bg-secondary enabled:focus-visible:text-foreground" + :class=" + compact + ? 'size-7 justify-center' + : 'h-7 w-full min-w-0 gap-1.5 px-1.5' + " :title="channel?.display_label" :aria-label=" channel @@ -97,22 +103,24 @@ const newPost = (): void => { - {{ time }} - + diff --git a/resources/js/components/publish/CalendarTimeGrid.vue b/resources/js/components/publish/CalendarTimeGrid.vue index 33968882d..bd1c08e77 100644 --- a/resources/js/components/publish/CalendarTimeGrid.vue +++ b/resources/js/components/publish/CalendarTimeGrid.vue @@ -71,6 +71,19 @@ const isStacked = ( hour: number, ): boolean => (column.byHour.get(hour)?.length ?? 0) > 1; +const iconOnly = computed(() => compact.value && props.days.length === 7); + +const chipClass = ( + column: { byHour: Map }, + hour: number, +): string => { + if (iconOnly.value) { + return ''; + } + + return isStacked(column, hour) ? 'w-full shrink-0' : 'flex-1'; +}; + const visibleItems = ( key: string, hour: number, @@ -201,11 +214,8 @@ watch( ? 'month' : 'week' " - :class=" - isStacked(column, hour) - ? 'w-full shrink-0' - : 'flex-1' - " + :compact="iconOnly" + :class="chipClass(column, hour)" /> + }) + " + :data-testid="`calendar-more-${dayKey(day)}`" + @click="toggleDay(dayKey(day))" + > + + + + diff --git a/tests/Browser/CalendarPageTest.php b/tests/Browser/CalendarPageTest.php index 49c346e3e..4cf4b38cf 100644 --- a/tests/Browser/CalendarPageTest.php +++ b/tests/Browser/CalendarPageTest.php @@ -551,6 +551,7 @@ function calendarChipSlot(mixed $page, Post $post): ?string $page->assertPresent("@calendar-post-{$first->id}") ->assertPresent("@calendar-post-{$second->id}") + ->assertScript("(() => { const box = document.querySelector('[data-testid=\"calendar-post-{$first->id}\"]').getBoundingClientRect(); return box.width === box.height; })()", true) ->assertScript('document.documentElement.scrollWidth <= window.innerWidth', true) ->assertNoJavaScriptErrors(); }); @@ -569,6 +570,7 @@ function calendarChipSlot(mixed $page, Post $post): ?string ->toBe(collect(range(0, 2))->map(fn (int $offset): string => "calendar-column-{$day->copy()->addDays($offset)->format('Y-m-d')}")->all()); $page->assertPresent("@calendar-post-{$post->id}") + ->assertSeeIn("@calendar-post-{$post->id}", '9:00') ->assertScript('document.documentElement.scrollWidth <= window.innerWidth', true); $page->resize(1280, 900); @@ -586,7 +588,7 @@ function calendarChipSlot(mixed $page, Post $post): ?string $page->assertMissing("@calendar-post-{$post->id}")->assertNoJavaScriptErrors(); }); -test('on a phone the month shows its weeks in columns with the posts of each day', function () { +test('on a phone the month shows its weeks in columns with the posts of each day as icon tiles', function () { [$user, $linkedin, $x] = calendarPageSetup(); $day = now('UTC')->addMonthNoOverflow()->startOfMonth()->addDays(12); $dayKey = $day->format('Y-m-d'); @@ -599,9 +601,15 @@ function calendarChipSlot(mixed $page, Post $post): ?string $page->assertPresent("@calendar-day-{$dayKey}") ->assertPresent("@calendar-post-{$posts[0]->id}") - ->assertPresent("@calendar-more-{$dayKey}") + ->assertSeeIn("@calendar-more-{$dayKey}", '+2') + ->assertDontSeeIn("@calendar-more-{$dayKey}", __('calendar.more', ['count' => 2])) + ->assertScript("(() => { const chip = document.querySelector('[data-testid=\"calendar-post-{$posts[0]->id}\"]'); const box = chip.getBoundingClientRect(); return box.width === box.height && chip.innerText.trim() === '' && !chip.querySelector('img, video'); })()", true) ->assertScript('document.documentElement.scrollWidth <= window.innerWidth', true) ->assertNoJavaScriptErrors(); + + $page->click("@calendar-more-{$dayKey}"); + waitForCalendarTestId($page, "calendar-post-{$posts[4]->id}"); + $page->assertAttribute("@calendar-more-{$dayKey}", 'aria-label', __('calendar.less')); }); test('on a phone, tapping a post in the month opens its details directly', function () {