@rupe/v-datepicker 1.0.0-alpha.1 → 1.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # v-datepicker
2
+
3
+ A flexible and accessible Vue 3 datepicker component library.
4
+
5
+ ## Description
6
+
7
+ `v-datepicker` is a highly customizable datepicker package built for the Vue 3 ecosystem. It is primarily based on the robust implementation of [reka-ui](https://github.com/reka-ui/reka-ui) (formerly radix-vue) to ensure top-tier accessibility and performance.
8
+
9
+ This package is further enriched with advanced features like the **Month and Year Overlay**, inspired by the popular [vue-datepicker](https://github.com/Vuepic/vue-datepicker), providing a more intuitive navigation experience for users.
10
+
11
+ > **Note:** This is a **headless** library. No styling is included out of the box. You have full control over the look and feel, and are responsible for applying all styles (e.g., using Tailwind CSS).
12
+
13
+ ## Features
14
+
15
+ - **Headless & Accessible**: Built on top of Reka UI's accessible primitives.
16
+ - **Customizable**: Full control over the rendering of every part of the datepicker.
17
+ - **Tree-shakable**: Built using modern ES modules.
18
+ - **Month & Year Overlays**: Quick navigation inspired by Vue Datepicker.
19
+ - **TypeScript Ready**: Full type support for a better developer experience.
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ # pnpm
25
+ pnpm add @rupe/v-datepicker
26
+
27
+ # npm
28
+ npm install @rupe/v-datepicker
29
+
30
+ # yarn
31
+ yarn add @rupe/v-datepicker
32
+ ```
33
+
34
+ ## Basic Usage (Tailwind CSS)
35
+
36
+ Since the library is headless, you'll need to apply your own styles. Here's an example using Tailwind CSS:
37
+
38
+ ```vue
39
+ <script setup lang="ts">
40
+ import { DatePicker } from '@rupe/v-datepicker'
41
+ </script>
42
+
43
+ <template>
44
+ <DatePicker.Root class="relative">
45
+ <DatePicker.Field v-slot="{ segments }" class="flex items-center gap-1 border border-gray-300 rounded px-3 py-2 bg-white focus-within:ring-2 focus:ring-blue-500">
46
+ <div class="flex items-center">
47
+ <template v-for="item in segments" :key="item.part">
48
+ <DatePicker.Input
49
+ :part="item.part"
50
+ class="px-0.5 rounded focus:bg-blue-100 focus:outline-none data-[placeholder]:text-gray-400"
51
+ >
52
+ {{ item.value }}
53
+ </DatePicker.Input>
54
+ </template>
55
+ </div>
56
+ <DatePicker.Trigger class="ml-auto text-gray-500 hover:text-gray-700">
57
+ 📅
58
+ </DatePicker.Trigger>
59
+ </DatePicker.Field>
60
+
61
+ <DatePicker.Content class="absolute z-10 mt-2 bg-white border border-gray-200 rounded-lg shadow-xl p-4">
62
+ <DatePicker.Calendar v-slot="{ weekDays, grid }">
63
+ <DatePicker.Header class="flex items-center justify-between mb-4">
64
+ <DatePicker.Prev class="p-1 hover:bg-gray-100 rounded">⬅️</DatePicker.Prev>
65
+ <DatePicker.Heading class="font-bold flex gap-1">
66
+ <DatePicker.MonthHeading />
67
+ <DatePicker.YearHeading />
68
+ </DatePicker.Heading>
69
+ <DatePicker.Next class="p-1 hover:bg-gray-100 rounded">➡️</DatePicker.Next>
70
+ </DatePicker.Header>
71
+
72
+ <DatePicker.Grid v-for="month in grid" :key="month.value.toString()" class="w-full">
73
+ <DatePicker.GridHead>
74
+ <DatePicker.GridRow class="flex justify-between">
75
+ <DatePicker.HeadCell v-for="day in weekDays" :key="day" class="w-8 text-center text-xs text-gray-500 font-medium">
76
+ {{ day }}
77
+ </DatePicker.HeadCell>
78
+ </DatePicker.GridRow>
79
+ </DatePicker.GridHead>
80
+ <DatePicker.GridBody>
81
+ <DatePicker.GridRow v-for="(weekDates, index) in month.rows" :key="index" class="flex justify-between mt-1">
82
+ <DatePicker.Cell v-for="weekDate in weekDates" :key="weekDate.toString()" :date="weekDate">
83
+ <DatePicker.CellTrigger
84
+ :day="weekDate"
85
+ :month="month.value"
86
+ class="w-8 h-8 flex items-center justify-center rounded-full text-sm hover:bg-blue-50 data-[selected]:bg-blue-600 data-[selected]:text-white data-[outside-view]:text-gray-300"
87
+ />
88
+ </DatePicker.Cell>
89
+ </DatePicker.GridRow>
90
+ </DatePicker.GridBody>
91
+ </DatePicker.Grid>
92
+ </DatePicker.Calendar>
93
+ </DatePicker.Content>
94
+ </DatePicker.Root>
95
+ </template>
96
+ ```
97
+
98
+ ## Playground
99
+
100
+ The repository includes a playground project built with **Nuxt** and **Tailwind CSS** to test the library locally.
101
+
102
+ ### Running the Playground
103
+
104
+ 1. **Clone the repository**
105
+ 2. **Install dependencies**:
106
+ ```bash
107
+ pnpm install
108
+ ```
109
+ 3. **Start the playground**:
110
+ ```bash
111
+ pnpm dev
112
+ ```
113
+ This will start the Nuxt dev server for the `playground` folder. Any changes made in the `src/` directory will be reflected instantly via HMR.
114
+
115
+ ## Credits
116
+
117
+ Special thanks to the following projects that made this package possible:
118
+
119
+ - **[reka-ui](https://reka-ui.com/)**: For the incredible foundation of accessible headless components.
120
+ - **[vue-datepicker](https://vue3-datepicker.com/)**: For the inspiration behind the intuitive month and year overlay navigation.
121
+
122
+ ## License
123
+
124
+ MIT
package/dist/index.cjs CHANGED
@@ -4172,17 +4172,20 @@ const _sfc_main$q = /* @__PURE__ */ vue.defineComponent({
4172
4172
  const rootContext = injectCalendarRootContext();
4173
4173
  const months = vue.computed(() => rootContext.months.value);
4174
4174
  const years = vue.computed(() => rootContext.years.value);
4175
- const isOpen = vue.computed(() => rootContext.monthYearOverlayState.value === props.type);
4175
+ const isOpen = vue.computed(
4176
+ () => rootContext.monthYearOverlayState.value === props.type
4177
+ );
4176
4178
  function onEscapeKeyDown() {
4177
4179
  rootContext.monthYearOverlayState.value = false;
4178
4180
  }
4179
4181
  return (_ctx, _cache) => {
4180
- return vue.openBlock(), vue.createBlock(_sfc_main$O, {
4182
+ return isOpen.value ? (vue.openBlock(), vue.createBlock(_sfc_main$O, {
4183
+ key: 0,
4181
4184
  "as-child": "",
4182
4185
  onEscapeKeyDown
4183
4186
  }, {
4184
4187
  default: vue.withCtx(() => [
4185
- isOpen.value ? (vue.openBlock(), vue.createBlock(vue.unref(Primitive), vue.mergeProps({ key: 0 }, { ...props, ..._ctx.$attrs }, {
4188
+ vue.createVNode(vue.unref(Primitive), vue.mergeProps({ ...props, ..._ctx.$attrs }, {
4186
4189
  style: {
4187
4190
  position: "absolute",
4188
4191
  height: "100%",
@@ -4202,10 +4205,10 @@ const _sfc_main$q = /* @__PURE__ */ vue.defineComponent({
4202
4205
  })
4203
4206
  ]),
4204
4207
  _: 3
4205
- }, 16)) : vue.createCommentVNode("", true)
4208
+ }, 16)
4206
4209
  ]),
4207
4210
  _: 3
4208
- });
4211
+ })) : vue.createCommentVNode("", true);
4209
4212
  };
4210
4213
  }
4211
4214
  });