{
	"$schema": "https://shadcn-svelte.com/schema/registry-item.json",
	"name": "date-strip",
	"title": "Date Strip",
	"type": "registry:ui",
	"description": "A horizontal strip of dates with optional navigation.",
	"dependencies": [
		"@lucide/svelte@^0.554.0"
	],
	"devDependencies": [
		"@lucide/svelte@^0.544.0",
		"@internationalized/date@^3.10.0"
	],
	"registryDependencies": [
		"button"
	],
	"files": [
		{
			"content": "<script lang=\"ts\">\r\n\timport { cn } from '$UTILS$';\r\n\timport { setDateStripContext } from './ctx';\r\n\timport { Button } from '$lib/components/ui/button';\r\n\timport { ChevronLeft, ChevronRight } from '@lucide/svelte';\r\n\timport type { Snippet } from 'svelte';\r\n\timport { type DateValue, getLocalTimeZone, today, startOfWeek } from '@internationalized/date';\r\n\r\n\tlet {\r\n\t\tvalue = $bindable(),\r\n\t\tclass: className,\r\n\t\tdaysToShow = 5,\r\n\t\tisDateDisabled = () => false,\r\n\t\tonDateChange,\r\n\t\tchildren\r\n\t}: {\r\n\t\tvalue?: DateValue | undefined;\r\n\t\tclass?: string;\r\n\t\tdaysToShow?: number;\r\n\t\tisDateDisabled?: (date: DateValue) => boolean;\r\n\t\tonDateChange?: (date: DateValue) => void;\r\n\t\tchildren: Snippet<[{ date: DateValue }]>;\r\n\t} = $props();\r\n\r\n\tlet startDate = $state(startOfWeek(today(getLocalTimeZone()), 'en-US'));\r\n\tlet slideDirection = $state<'start' | 'end'>('end');\r\n\r\n\tconst displayedDates = $derived(\r\n\t\tArray.from({ length: daysToShow }, (_, i) => startDate.add({ days: i }))\r\n\t);\r\n\r\n\tfunction handlePrev() {\r\n\t\tslideDirection = 'start';\r\n\t\tstartDate = startDate.add({ days: -daysToShow });\r\n\t}\r\n\r\n\tfunction handleNext() {\r\n\t\tslideDirection = 'end';\r\n\t\tstartDate = startDate.add({ days: daysToShow });\r\n\t}\r\n\r\n\tsetDateStripContext({\r\n\t\tselectedValue: () => value,\r\n\t\tonSelect: (d) => {\r\n\t\t\tvalue = d;\r\n\t\t\tonDateChange?.(d);\r\n\t\t},\r\n\t\tisDateDisabled,\r\n\t\tdirection: () => slideDirection\r\n\t});\r\n</script>\r\n\r\n<div class={cn('flex items-center gap-2 rounded-xl border bg-card p-1 shadow-sm', className)}>\r\n\t<Button variant=\"ghost\" size=\"icon\" class=\"h-7 w-7 shrink-0\" onclick={handlePrev}>\r\n\t\t<ChevronLeft class=\"h-4 w-4\" />\r\n\t</Button>\r\n\r\n\t<div class=\"flex flex-1 justify-between gap-1 overflow-hidden\">\r\n\t\t{#each displayedDates as date (date.toString())}\r\n\t\t\t{@render children({ date })}\r\n\t\t{/each}\r\n\t</div>\r\n\r\n\t<Button variant=\"ghost\" size=\"icon\" class=\"h-7 w-7 shrink-0\" onclick={handleNext}>\r\n\t\t<ChevronRight class=\"h-4 w-4\" />\r\n\t</Button>\r\n</div>\r\n",
			"type": "registry:ui",
			"target": "date-strip/date-strip.svelte"
		},
		{
			"content": "<script lang=\"ts\">\r\n\timport { cn } from '$UTILS$';\r\n\timport { getDateStripContext } from './ctx';\r\n\timport { type DateValue, getLocalTimeZone, isToday } from '@internationalized/date';\r\n\timport { DateFormatter } from '@internationalized/date';\r\n\timport { Button } from '$lib/components/ui/button';\r\n\r\n\tlet {\r\n\t\tdate,\r\n\t\tclass: className\r\n\t}: {\r\n\t\tdate: DateValue;\r\n\t\tclass?: string;\r\n\t} = $props();\r\n\r\n\tconst ctx = getDateStripContext();\r\n\tconst formatterMonth = new DateFormatter('en-US', { month: 'short' });\r\n\tconst formatterDay = new DateFormatter('en-US', { day: 'numeric' });\r\n\r\n\tlet isSelected = $derived(ctx.selectedValue()?.compare(date) === 0);\r\n\tlet isDisabled = $derived(ctx.isDateDisabled(date));\r\n    let direction = $derived(ctx.direction());\r\n\r\n\tfunction handleClick() {\r\n\t\tif (!isDisabled) {\r\n\t\t\tctx.onSelect(date);\r\n\t\t}\r\n\t}\r\n\r\n\tconst dateObj = $derived(date.toDate('UTC'));\r\n</script>\r\n\r\n<Button\r\n        variant=\"ghost\"\r\n        onclick={handleClick}\r\n        class={cn(\r\n        \"flex flex-col items-center justify-center -space-y-1 animate-in fade-in-5\",\r\n        \"w-12 h-12 shrink-0 rounded-lg\",\r\n        direction === \"end\" ? \"slide-in-from-right-12\" : \"slide-in-from-left-12\",\r\n        isToday(date, getLocalTimeZone()) && \"bg-accent\",\r\n        isSelected && \"bg-primary text-primary-foreground\",\r\n        className\r\n    )}\r\n        disabled={isDisabled}\r\n>\r\n    <span class=\"text-[8px] font-medium uppercase opacity-70\">\r\n        {formatterMonth.format(dateObj)}\r\n    </span>\r\n    <span class=\"text-base font-bold leading-none\">\r\n        {formatterDay.format(dateObj)}\r\n    </span>\r\n</Button>",
			"type": "registry:ui",
			"target": "date-strip/date-strip-item.svelte"
		},
		{
			"content": "import DateStrip from \"./date-strip.svelte\";\r\nimport DateStripItem from \"./date-strip-item.svelte\";\r\n\r\nexport {\r\n    DateStrip as Root,\r\n    DateStripItem as Item,\r\n};",
			"type": "registry:ui",
			"target": "date-strip/index.ts"
		},
		{
			"content": "import { getContext, setContext } from \"svelte\";\r\nimport type { DateValue } from \"@internationalized/date\";\r\n\r\nconst DATESTRIP_KEY = Symbol(\"datestrip\");\r\n\r\ntype DateStripContext = {\r\n    selectedValue: () => DateValue | undefined;\r\n    onSelect: (date: DateValue) => void;\r\n    isDateDisabled: (date: DateValue) => boolean;\r\n    direction: () => \"start\" | \"end\";\r\n};\r\n\r\nexport function setDateStripContext(props: DateStripContext) {\r\n    setContext(DATESTRIP_KEY, props);\r\n}\r\n\r\nexport function getDateStripContext() {\r\n    return getContext<DateStripContext>(DATESTRIP_KEY);\r\n}",
			"type": "registry:ui",
			"target": "date-strip/ctx.ts"
		}
	]
}