Skip to content

Commit f56d9da

Browse files
committed
improvement(scheduled-tasks): extract shared CalendarDayCell for the weekday picker
Pull the calendar's day pill into one CalendarDayCell component (the single source of the day-pill chrome: primary fill when selected, the border ring on today, fixed 30px square or full-width). The calendar grid and the weekly "Repeat on" toggles now both render it, so the call sites are props-only (no re-derived chipVariants classes) and the two surfaces stay visually identical by construction.
1 parent 8d74e35 commit f56d9da

4 files changed

Lines changed: 77 additions & 27 deletions

File tree

apps/sim/app/workspace/[workspaceId]/scheduled-tasks/components/task-modal/recurrence-section.tsx

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
import { useRef } from 'react'
44
import { format } from 'date-fns'
55
import {
6+
CalendarDayCell,
67
ChipDatePicker,
78
ChipModalField,
89
ChipModalSeparator,
9-
chipVariants,
1010
Switch,
1111
} from '@/components/emcn'
12-
import { cn } from '@/lib/core/utils/cn'
1312
import type {
1413
MonthlyMode,
1514
Recurrence,
@@ -226,28 +225,24 @@ export function RecurrenceSection({ recurrence, onChange, launchDate }: Recurren
226225

227226
{recurrence.frequency === 'weekly' && (
228227
<ChipModalField type='custom' title='Repeat on'>
229-
{/* A one-row extract of the calendar: seven equal day cells that
230-
reuse its exact day-cell grammar (`primary` fill when on, bare
231-
`--text-body` when off) so the weekday toggles read as a sibling
232-
of the date picker rather than a separate segmented bar. */}
228+
{/* A one-row extract of the calendar: seven equal day cells built
229+
from the same {@link CalendarDayCell} the date picker uses, so
230+
the weekday toggles read as a sibling of the calendar rather than
231+
a separate segmented bar. */}
233232
<div className='grid grid-cols-7 gap-1'>
234233
{WEEKDAYS.map((weekday) => {
235234
const selected = selectedWeekdays.includes(weekday.value)
236235
return (
237-
<button
236+
<CalendarDayCell
238237
key={weekday.value}
239-
type='button'
238+
selected={selected}
239+
fullWidth
240240
aria-pressed={selected}
241241
aria-label={weekday.name}
242242
onClick={() => handleWeekdayToggle(weekday.value)}
243-
className={cn(
244-
chipVariants({ variant: selected ? 'primary' : undefined, flush: true }),
245-
'h-[30px] w-full justify-center p-0',
246-
!selected && 'text-[var(--text-body)]'
247-
)}
248243
>
249244
{weekday.short}
250-
</button>
245+
</CalendarDayCell>
251246
)
252247
})}
253248
</div>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use client'
2+
3+
import { type ButtonHTMLAttributes, forwardRef, type ReactNode } from 'react'
4+
import { chipVariants } from '@/components/emcn/components/chip/chip'
5+
import { cn } from '@/lib/core/utils/cn'
6+
7+
export interface CalendarDayCellProps
8+
extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
9+
/** Strong `primary` fill — the selected calendar day or an active weekday toggle. */
10+
selected?: boolean
11+
/** The `border` shadow-ring marking today. Ignored while `selected`. */
12+
today?: boolean
13+
/**
14+
* Fills the container width (the weekday-toggle row) instead of the fixed
15+
* 30px square used by the calendar's month grid.
16+
*/
17+
fullWidth?: boolean
18+
children: ReactNode
19+
}
20+
21+
/**
22+
* The single day pill shared by the {@link Calendar} month grid and any
23+
* chip-aligned day toggle (e.g. the scheduled-task weekly "Repeat on" row).
24+
* Built from `chipVariants` so the chrome — height, radius, centered glyph,
25+
* `primary` selected fill, `border` today ring — lives in one place and the
26+
* row of weekday toggles reads as a sibling of the date picker rather than a
27+
* separate control.
28+
*
29+
* @example
30+
* <CalendarDayCell selected={isSelected} today={isToday} onClick={pick}>{day}</CalendarDayCell>
31+
*
32+
* @example
33+
* // Weekday toggle: fill the column, drive selection with `aria-pressed`.
34+
* <CalendarDayCell selected={on} fullWidth aria-pressed={on} aria-label='Monday' onClick={toggle}>M</CalendarDayCell>
35+
*/
36+
export const CalendarDayCell = forwardRef<HTMLButtonElement, CalendarDayCellProps>(
37+
function CalendarDayCell(
38+
{ selected = false, today = false, fullWidth = false, className, children, type, ...props },
39+
ref
40+
) {
41+
return (
42+
<button
43+
ref={ref}
44+
type={type ?? 'button'}
45+
className={cn(
46+
chipVariants({
47+
variant: selected ? 'primary' : today ? 'border' : undefined,
48+
flush: true,
49+
}),
50+
'justify-center p-0',
51+
fullWidth ? 'h-[30px] w-full' : 'size-[30px]',
52+
!selected && 'text-[var(--text-body)]',
53+
className
54+
)}
55+
{...props}
56+
>
57+
{children}
58+
</button>
59+
)
60+
}
61+
)

apps/sim/components/emcn/components/calendar/calendar.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { useEffect, useMemo, useState } from 'react'
44
import { ChevronLeft, ChevronRight } from 'lucide-react'
5+
import { CalendarDayCell } from '@/components/emcn/components/calendar/calendar-day-cell'
56
import { Chip, chipVariants } from '@/components/emcn/components/chip/chip'
67
import { chipContentLabelClass } from '@/components/emcn/components/chip/chip-chrome'
78
import { cn } from '@/lib/core/utils/cn'
@@ -172,20 +173,9 @@ export function Calendar({ value, onChange, className }: CalendarProps) {
172173

173174
return (
174175
<div key={day} className='flex h-[34px] items-center justify-center'>
175-
<button
176-
type='button'
177-
onClick={() => selectDay(day)}
178-
className={cn(
179-
chipVariants({
180-
variant: isSelected ? 'primary' : isToday ? 'border' : undefined,
181-
flush: true,
182-
}),
183-
'size-[30px] justify-center p-0',
184-
!isSelected && 'text-[var(--text-body)]'
185-
)}
186-
>
176+
<CalendarDayCell selected={isSelected} today={isToday} onClick={() => selectDay(day)}>
187177
{day}
188-
</button>
178+
</CalendarDayCell>
189179
</div>
190180
)
191181
})}

apps/sim/components/emcn/components/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ export { Badge } from './badge/badge'
33
export { Banner } from './banner/banner'
44
export { Button, buttonVariants } from './button/button'
55
export { ButtonGroup, ButtonGroupItem } from './button-group/button-group'
6+
export {
7+
CalendarDayCell,
8+
type CalendarDayCellProps,
9+
} from './calendar/calendar-day-cell'
610
export { Checkbox } from './checkbox/checkbox'
711
export { Chip, ChipLink, chipVariants } from './chip/chip'
812
export { ChipChevronDown } from './chip/chip-chevron'

0 commit comments

Comments
 (0)