@bloc-ui/date-picker 0.0.2 → 0.0.4

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 CHANGED
@@ -1,10 +1,10 @@
1
1
  # @bloc-ui/date-picker
2
2
 
3
- > **Latest:** v0.0.2
3
+ > **Latest:** v0.0.4
4
4
 
5
- Date picker component with calendar dropdown for Angular — part of the [Bloc UI](https://github.com/debasish1996/BLOC-UI) component library. Supports template-driven and reactive forms, min/max date enforcement, and customisable display format.
5
+ Directive-based date picker for Angular — part of the [Bloc UI](https://github.com/debasish1996/BLOC-UI) component library. Apply the trigger directive to any element (input, button, etc.) to attach a calendar dropdown. Supports **single date** and **date range** selection, template-driven and reactive forms, min/max constraints, month/year drill-down navigation, and a customisable display format.
6
6
 
7
- **[Live Documentation & Demos](https://debasish1996.github.io/BLOC-UI/)**
7
+ **[Live Documentation & Demos](https://bloc-verse.com/date-picker)**
8
8
 
9
9
  > **Tip:** You can also install [`@bloc-ui/kit`](https://www.npmjs.com/package/@bloc-ui/kit) to get this package along with every other Bloc UI component in a single import.
10
10
 
@@ -20,95 +20,241 @@ npm install @bloc-ui/date-picker
20
20
 
21
21
  ---
22
22
 
23
- ## Usage
23
+ ## Directives
24
+
25
+ | Directive | Selector | Exports as |
26
+ | ------------------------------------- | ------------------------------ | ---------------------------- |
27
+ | `BlocDatePickerTriggerDirective` | `[blocDatePickerTrigger]` | `blocDatePickerTrigger` |
28
+ | `BlocDateRangePickerTriggerDirective` | `[blocDateRangePickerTrigger]` | `blocDateRangePickerTrigger` |
24
29
 
25
30
  ```ts
26
- import { BlocDatePickerComponent, BlocDatePickerModule } from '@bloc-ui/date-picker';
31
+ import {
32
+ BlocDatePickerTriggerDirective,
33
+ BlocDateRangePickerTriggerDirective,
34
+ BlocDatePickerModule,
35
+ } from '@bloc-ui/date-picker';
27
36
  ```
28
37
 
38
+ ---
39
+
40
+ ## Single date picker
41
+
42
+ Apply `blocDatePickerTrigger` to any element. Use the `displayValue` signal via a template reference to render the formatted date.
43
+
29
44
  ### Basic
30
45
 
31
46
  ```html
32
- <bloc-date-picker /> <bloc-date-picker placeholder="Pick a date" />
47
+ <input
48
+ blocDatePickerTrigger
49
+ #dp="blocDatePickerTrigger"
50
+ [value]="dp.displayValue()"
51
+ readonly
52
+ placeholder="Select date"
53
+ />
33
54
  ```
34
55
 
35
56
  ### With ngModel
36
57
 
37
58
  ```html
38
- <bloc-date-picker [(ngModel)]="selectedDate" />
59
+ <input
60
+ blocDatePickerTrigger
61
+ #dp="blocDatePickerTrigger"
62
+ [(ngModel)]="selectedDate"
63
+ [value]="dp.displayValue()"
64
+ readonly
65
+ />
39
66
  ```
40
67
 
41
68
  ### With Reactive Forms
42
69
 
43
70
  ```html
44
- <bloc-date-picker [formControl]="dateCtrl" />
71
+ <input
72
+ blocDatePickerTrigger
73
+ #dp="blocDatePickerTrigger"
74
+ [formControl]="dateCtrl"
75
+ [value]="dp.displayValue()"
76
+ readonly
77
+ />
45
78
  ```
46
79
 
47
- ### Sizes
80
+ ### Min / Max
48
81
 
49
82
  ```html
50
- <bloc-date-picker size="sm" /> <bloc-date-picker size="lg" />
83
+ <input
84
+ blocDatePickerTrigger
85
+ #dp="blocDatePickerTrigger"
86
+ [minDate]="minDate"
87
+ [maxDate]="maxDate"
88
+ [value]="dp.displayValue()"
89
+ readonly
90
+ />
51
91
  ```
52
92
 
53
- ### Min / Max
93
+ ### Custom format
94
+
95
+ ```html
96
+ <input
97
+ blocDatePickerTrigger
98
+ #dp="blocDatePickerTrigger"
99
+ format="dd/MM/yyyy"
100
+ [value]="dp.displayValue()"
101
+ readonly
102
+ />
103
+ ```
104
+
105
+ ---
106
+
107
+ ## `BlocDatePickerTriggerDirective` inputs
108
+
109
+ | Input | Type | Default | Description |
110
+ | ---------- | -------------- | -------------- | ----------------------- |
111
+ | `minDate` | `Date \| null` | `null` | Minimum selectable date |
112
+ | `maxDate` | `Date \| null` | `null` | Maximum selectable date |
113
+ | `format` | `string` | `'yyyy-MM-dd'` | Display format |
114
+ | `disabled` | `boolean` | `false` | Disable the picker |
115
+
116
+ ## `BlocDatePickerTriggerDirective` exported state
117
+
118
+ | Signal | Type | Description |
119
+ | ---------------- | --------- | ----------------------------------- |
120
+ | `displayValue()` | `string` | Formatted selected date for display |
121
+ | `isOpen()` | `boolean` | Whether the calendar panel is open |
122
+
123
+ ---
124
+
125
+ ## Date range picker
126
+
127
+ Apply `blocDateRangePickerTrigger` to any element. The **first click** sets the start date; the **second click** completes the range. A hover preview highlights days between the anchor and the cursor.
128
+
129
+ The control value and `ngModel` type is `DateRange`:
130
+
131
+ ```ts
132
+ interface DateRange {
133
+ from: Date | null;
134
+ to: Date | null;
135
+ }
136
+ ```
137
+
138
+ ### With ngModel
139
+
140
+ ```html
141
+ <input
142
+ blocDateRangePickerTrigger
143
+ #rp="blocDateRangePickerTrigger"
144
+ [(ngModel)]="dateRange"
145
+ [value]="rp.displayValue()"
146
+ readonly
147
+ placeholder="Select range"
148
+ />
149
+ ```
150
+
151
+ ### With Reactive Forms
152
+
153
+ ```html
154
+ <input
155
+ blocDateRangePickerTrigger
156
+ #rp="blocDateRangePickerTrigger"
157
+ [formControl]="rangeCtrl"
158
+ [value]="rp.displayValue()"
159
+ readonly
160
+ />
161
+ ```
162
+
163
+ ### With separate from / to inputs
164
+
165
+ Use `displayValueFrom` and `displayValueTo` to populate two separate fields. Supply a `FormGroup` via `rangeFormGroup` to have `from` and `to` controls patched automatically:
54
166
 
55
167
  ```html
56
- <bloc-date-picker [minDate]="minDate" [maxDate]="maxDate" />
168
+ <input
169
+ blocDateRangePickerTrigger
170
+ #rp="blocDateRangePickerTrigger"
171
+ [rangeFormGroup]="rangeFg"
172
+ [value]="rp.displayValueFrom()"
173
+ placeholder="From"
174
+ readonly
175
+ />
176
+
177
+ <input [value]="rp.displayValueTo()" placeholder="To" readonly />
57
178
  ```
58
179
 
59
180
  ---
60
181
 
61
- ## `BlocDatePickerComponent` inputs
182
+ ## `BlocDateRangePickerTriggerDirective` inputs
183
+
184
+ | Input | Type | Default | Description |
185
+ | ---------------- | ------------------- | -------------- | ----------------------------------------------------------------------- |
186
+ | `minDate` | `Date \| null` | `null` | Minimum selectable date |
187
+ | `maxDate` | `Date \| null` | `null` | Maximum selectable date |
188
+ | `format` | `string` | `'yyyy-MM-dd'` | Display format |
189
+ | `disabled` | `boolean` | `false` | Disable the picker |
190
+ | `rangeFormGroup` | `FormGroup \| null` | `null` | FormGroup with `from` / `to` controls to patch directly on range commit |
191
+
192
+ ## `BlocDateRangePickerTriggerDirective` exported state
193
+
194
+ | Signal | Type | Description |
195
+ | -------------------- | --------- | ---------------------------------- |
196
+ | `displayValue()` | `string` | `"from → to"` or partial |
197
+ | `displayValueFrom()` | `string` | Formatted start date |
198
+ | `displayValueTo()` | `string` | Formatted end date |
199
+ | `isOpen()` | `boolean` | Whether the calendar panel is open |
200
+
201
+ ---
202
+
203
+ ## Calendar navigation
204
+
205
+ The calendar supports three views:
206
+
207
+ | View | How to reach |
208
+ | --------- | ------------------------------------------ |
209
+ | **Day** | Default view |
210
+ | **Month** | Click the month/year label in the header |
211
+ | **Year** | Click the year label inside the month view |
62
212
 
63
- | Input | Type | Default | Description |
64
- | ------------- | ---------------------- | --------------- | ----------------------- |
65
- | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Density preset |
66
- | `placeholder` | `string` | `'Select date'` | Input placeholder text |
67
- | `format` | `string` | `'yyyy-MM-dd'` | Display format |
68
- | `disabled` | `boolean` | `false` | Disable the picker |
69
- | `minDate` | `Date \| null` | `null` | Minimum selectable date |
70
- | `maxDate` | `Date \| null` | `null` | Maximum selectable date |
213
+ Clicking a year navigates to the month view; clicking a month navigates back to the day view.
71
214
 
72
215
  ---
73
216
 
74
217
  ## CSS tokens
75
218
 
76
- | Token | Fallback | Description |
77
- | ------------------------------------ | ------------------------------ | ------------------------ |
78
- | `--bloc-date-picker-padding` | `8px 36px 8px 12px` | Input padding |
79
- | `--bloc-date-picker-font-size` | `0.875rem` | Input font size |
80
- | `--bloc-date-picker-radius` | `6px` | Input border radius |
81
- | `--bloc-date-picker-color` | `#374151` | Input text colour |
82
- | `--bloc-date-picker-bg` | `#ffffff` | Input background |
83
- | `--bloc-date-picker-border` | `var(--bloc-border, #d1d5db)` | Input border colour |
84
- | `--bloc-date-picker-focus-border` | `var(--bloc-primary, #6b7280)` | Focus border colour |
85
- | `--bloc-date-picker-focus-ring` | `rgba(107,114,128,0.2)` | Focus ring colour |
86
- | `--bloc-date-picker-placeholder` | `#9ca3af` | Placeholder colour |
87
- | `--bloc-date-picker-icon-color` | `#9ca3af` | Calendar icon colour |
88
- | `--bloc-date-picker-z-index` | `100` | Dropdown z-index |
89
- | `--bloc-date-picker-dropdown-bg` | `#ffffff` | Dropdown background |
90
- | `--bloc-date-picker-dropdown-border` | `var(--bloc-border, #d1d5db)` | Dropdown border |
91
- | `--bloc-date-picker-dropdown-shadow` | `0 4px 16px rgba(0,0,0,0.1)` | Dropdown shadow |
92
- | `--bloc-date-picker-day-color` | `#374151` | Day text colour |
93
- | `--bloc-date-picker-day-hover-bg` | `#f3f4f6` | Day hover background |
94
- | `--bloc-date-picker-today-border` | `var(--bloc-primary, #6b7280)` | Today border colour |
95
- | `--bloc-date-picker-selected-bg` | `var(--bloc-primary, #6b7280)` | Selected day background |
96
- | `--bloc-date-picker-selected-color` | `#ffffff` | Selected day text colour |
219
+ | Token | Fallback | Description |
220
+ | -------------------------------------- | ------------------------------ | ----------------------------- |
221
+ | `--bloc-date-picker-z-index` | `100` | Dropdown z-index |
222
+ | `--bloc-date-picker-dropdown-bg` | `#ffffff` | Dropdown background |
223
+ | `--bloc-date-picker-dropdown-border` | `var(--bloc-border, #d1d5db)` | Dropdown border colour |
224
+ | `--bloc-date-picker-dropdown-radius` | `8px` | Dropdown border radius |
225
+ | `--bloc-date-picker-dropdown-shadow` | `0 4px 16px rgba(0,0,0,0.1)` | Dropdown shadow |
226
+ | `--bloc-date-picker-header-color` | `#374151` | Header month/year text colour |
227
+ | `--bloc-date-picker-nav-color` | `#6b7280` | Navigation arrow colour |
228
+ | `--bloc-date-picker-nav-hover-bg` | `#f3f4f6` | Navigation arrow hover bg |
229
+ | `--bloc-date-picker-weekday-color` | `#9ca3af` | Weekday label colour |
230
+ | `--bloc-date-picker-day-color` | `#374151` | Day number text colour |
231
+ | `--bloc-date-picker-day-radius` | `6px` | Day button border radius |
232
+ | `--bloc-date-picker-day-hover-bg` | `#f3f4f6` | Day hover background |
233
+ | `--bloc-date-picker-today-border` | `var(--bloc-primary, #6b7280)` | Today outline colour |
234
+ | `--bloc-date-picker-selected-bg` | `var(--bloc-primary, #6b7280)` | Selected / range-end bg |
235
+ | `--bloc-date-picker-selected-color` | `#ffffff` | Selected day text colour |
236
+ | `--bloc-date-picker-range-bg` | `#f3f4f6` | In-range highlight background |
237
+ | `--bloc-date-picker-footer-border` | `var(--bloc-border, #d1d5db)` | Footer divider colour |
238
+ | `--bloc-date-picker-action-color` | `var(--bloc-primary, #6b7280)` | Today / action button colour |
239
+ | `--bloc-date-picker-action-hover-bg` | `#f3f4f6` | Action button hover bg |
240
+ | `--bloc-date-picker-clear-color` | `#9ca3af` | Clear button colour |
241
+ | `--bloc-date-picker-clear-hover-color` | `#374151` | Clear button hover colour |
97
242
 
98
243
  ---
99
244
 
100
245
  ## Accessibility
101
246
 
102
- - Input sets `aria-expanded` and `aria-haspopup="dialog"` for the calendar dropdown.
103
- - Dropdown uses `role="dialog"` with `aria-label="Date picker"`.
247
+ - Trigger element sets `aria-expanded` and `aria-haspopup="dialog"`.
248
+ - Dropdown uses `role="dialog"` with `aria-label="Date picker"` (or `"Date range picker"`).
249
+ - Navigation buttons carry descriptive `aria-label` attributes.
250
+ - Disabled days have the `disabled` attribute on the button element.
104
251
  - Closes on <kbd>Escape</kbd> key and outside click.
105
- - Calendar includes a "Today" button for quick navigation.
106
252
 
107
253
  ---
108
254
 
109
255
  ## Theming
110
256
 
111
- All visual tokens (`--bloc-primary`, `--bloc-surface`, colour scales, dark-mode) are provided by the optional [`@bloc-ui/theme`](https://www.npmjs.com/package/@bloc-ui/theme) package. The date picker works without it — neutral fallbacks are applied automatically.
257
+ All visual tokens (`--bloc-primary`, `--bloc-border`, colour scales, dark-mode) are provided by the optional [`@bloc-ui/theme`](https://www.npmjs.com/package/@bloc-ui/theme) package. The date picker works without it — neutral fallbacks are applied automatically.
112
258
 
113
259
  ---
114
260