# Week strip

> A horizontal week of days: one accent pill slides between days and stretches toward the new one, weeks page with the finger 1:1, dots mark busy days, and a header shows the month with a Today button.

- Type: Component (navigation)
- Access: Free, open source (MIT)
- Page: https://goodui.dev/native/components/week-strip
- Markdown: https://goodui.dev/native/components/week-strip.md
- Registry item: https://goodui.dev/native/r/week-strip.json
- Dependencies: react-native-gesture-handler, react-native-reanimated, react-native-svg
- Keywords: react native week calendar strip, horizontal date picker, day selector, calendar strip expo, schedule day tabs, fitness week view, booking day picker

## When to use

- Switching the day shown below it: a schedule, workout plan, class timetable, bookings for a day.
- Picking a day close to today in a booking flow, above time-slots.

## When not to use

- Dates weeks or months away, or ranges: use date-picker.
- Switching between views that are not days: use segmented-control or tab-bar.

## Installation

With the shadcn CLI (needs a components.json in the Expo app), then `npx expo install --fix` so native dependencies match your Expo SDK. The foundation comes along the first time.

```bash
npx shadcn@latest add https://goodui.dev/native/r/week-strip.json
npx expo install --fix
```

The component lands in `components/goodui-native/week-strip/` and imports the foundation from `components/goodui-native/foundation/` with relative paths; it also installs button, icon-button, locale.

Built-in strings follow `<GooduiLocaleProvider>` (one [language pack](https://goodui.dev/native/r/locale-tr.json) translates the whole kit); the `labels` prop overrides them for one instance.

## Usage

```tsx
import { useState } from "react";
import { WeekStrip } from "@/components/goodui-native/week-strip/week-strip";

export function Schedule({ events }: { events: { day: string }[] }) {
  const [day, setDay] = useState(new Date());
  return (
    <WeekStrip
      value={day}
      onValueChange={setDay}
      min={new Date()}
      markedDates={(d) => events.filter((e) => e.day === d.toDateString()).length}
    />
  );
}
```

## Examples

### Follow the weekday while swiping, no header

```tsx
<WeekStrip showHeader={false} selectOnSwipe defaultValue={new Date()} onValueChange={loadWorkout} />
```

### French, Monday first, closed on Sundays

```tsx
<WeekStrip locale="fr-FR" todayLabel="Aujourd'hui" isDateDisabled={(d) => d.getDay() === 0} value={day} onValueChange={setDay} />
```

## API reference

### WeekStrip

`import { WeekStrip } from "@/components/goodui-native/week-strip/week-strip";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value` | `Date` | – | Selected day (controlled). |
| `defaultValue` | `Date` | – | Starting day when uncontrolled. Defaults to today. |
| `onValueChange` | `(date: Date) => void` | – | Called with the chosen day (midnight local). |
| `markedDates` | `(date: Date) => boolean \| number` | – | Dots under a day: `true` for one, a number for up to three (for example how many events). |
| `min` | `Date` | – | Earliest day. Earlier days are dimmed and the strip does not page before its week. |
| `max` | `Date` | – | Latest day. Later days are dimmed and the strip does not page past its week. |
| `isDateDisabled` | `(date: Date) => boolean` | – | Days that cannot be chosen, for example days the venue is closed. |
| `locale` | `string` | – | BCP 47 locale for weekday and month names, digits and the first day of the week. Defaults to the device locale. |
| `weekStartsOn` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6` | – | First column: 0 Sunday to 6 Saturday. Defaults to the locale's first day of the week. |
| `showHeader` | `boolean` | `true` | Month title, a Today button when today is not selected, and previous and next week arrows. Default `true`. |
| `todayLabel` | `string` | – | Label of the Today button. Same as `labels.today`. |
| `selectOnSwipe` | `boolean` | `false` | Swiping to another week also moves the selection to the same weekday there. Default `false`. |
| `onWeekChange` | `(weekStart: Date) => void` | – | Called with the first day of the week after paging. |
| `haptic` | `boolean` | `true` | `false` silences the select haptic on a day change. |
| `accessibilityLabel` | `string` | – | Names the strip for screen readers. Same as `labels.days`. |
| `labels` | `Partial<WeekStripLabels>` | – | Overrides for the built-in strings; a GooduiLocaleProvider pack sets them app-wide. |
| `style` | `StyleProp<ViewStyle>` | – | Style for the outer container. |
| `testID` | `string` | – | Identifier for end-to-end tests. |

## Accessibility

- The strip is a tablist named by accessibilityLabel (default "Days"); each day is a tab with selected and disabled in accessibilityState, and aria-selected on the web.
- A day's label starts with its visible weekday and number, then the full date and today, unavailable or the number of events.
- On the web the selected day is the one focusable tab: Left and Right move the selection across weeks, Home and End to the ends of the week, skipping unavailable days.
- The header has Previous week and Next week icon buttons, so paging never depends on a swipe, and a Today button while another day is selected.
- Weeks off screen are hidden from screen readers. The strip is 68 pt tall and each day a seventh of the width.

## Motion

- Selecting: the pill's edge facing the new day leads on the snappy spring and the trailing edge follows on smooth, so it stretches toward the day and settles. Each label and dot turns to the on-accent color by how much the pill covers it.
- Paging: weeks and the pill follow a horizontal drag 1:1, with resistance before min and past max; release pages one week by position and velocity on the smooth spring. The arrows and Today page on the same spring; a far jump lands one week short and pages in.
- Reduced motion: the pill and paging move with a short timing instead of springs.

## Haptics

- select when the selected day changes (tap, keys, Today, or a swipe with selectOnSwipe)
- haptic={false} silences it

## Performance

- Three weeks are mounted at a time. The pill, paging and label colors run on the UI thread; React renders when the week or the day changes.

## Notes for AI

- value is a Date; onValueChange gets a Date at local midnight. Compare days with toDateString().
- markedDates returns true for one dot or a number for up to three.
- Weekday and month names and digits come from Intl with locale; the first weekday follows the locale unless weekStartsOn is set.
- Paging alone does not change the selection unless selectOnSwipe is set; use onWeekChange to load a week's data.

## Related

- [Date picker](https://goodui.dev/native/components/date-picker.md): Inline month calendar: months slide with the finger, the selection circle travels from day to day and stretches toward the new one, a range sweeps its band in from the start day, and booked days are crossed out. A compact wheel variant picks day, month and year in the locale's order.
- [Time slots](https://goodui.dev/native/components/time-slots.md): A booking grid of time slots grouped into morning, afternoon and evening: the picked slot pops into the accent, taken slots are crossed out, low availability shows "2 left", and a summary with the end time and the confirm button rides under the grid or pinned to the bottom of the screen.
- [Segmented control](https://goodui.dev/native/components/segmented-control.md): Two to five views of the same thing with an elastic highlight that stretches toward the new segment, can be dragged, and ticks at every boundary. Includes a billing toggle.
- [Tab bar](https://goodui.dev/native/components/tab-bar.md): A bottom tab bar whose pill stretches toward the next tab and can be dragged to scrub between tabs; the selected icon bounces, badges pop, and it can hide while scrolling.

## Guidance for AI tools

Week strip: A horizontal week of days: one accent pill slides between days and stretches toward the new one, weeks page with the finger 1:1, dots mark busy days, and a header shows the month with a Today button. Use only the documented props. Keep accessibility, reduced motion and both color schemes intact when adapting it.

Full library index: https://goodui.dev/native/llms.txt
