@htmlbricks/hb-calendar-appointments 0.71.34 → 0.71.36

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.
Files changed (3) hide show
  1. package/README.md +128 -27
  2. package/manifest.json +34 -19
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,46 +1,147 @@
1
- ## `hb-calendar-appointments` — calendar-appointments
1
+ # `hb-calendar-appointments`
2
2
 
3
- **Category:** calendar | **Tags:** calendar, appointments
3
+ **Category:** calendar · **Tags:** calendar, appointments
4
4
 
5
- ### What it does
5
+ ## Summary
6
6
 
7
- Month agenda view: events for the current month are grouped by calendar day and listed chronologically with weekday, day number, time, and colored markers. Optional header with month navigation; changing month or selecting a day dispatches `changeCalendarDate`, `changeSelectedDate`, and clicking a row dispatches `calendarEventClick`. Uses Italian public holidays metadata; `events` is supplied as JSON.
7
+ A **month agenda** web component: it shows **only events in the visible month**, grouped **by calendar day**, with **per-day headings** and **clickable rows** for each appointment. An optional **header** switches the month and exposes slots for labels and navigation chrome.
8
8
 
9
- ### Custom element
9
+ ## What it does
10
10
 
11
- `hb-calendar-appointments`
11
+ - Filters `events` to the month implied by `date` (month + year).
12
+ - Sorts events by `date` when `events` is parsed from a string.
13
+ - Renders one block per day that has at least one event: weekday (long, locale from `navigator.languages[0]` or `en`), day-of-month number, then rows ordered as in the sorted list.
14
+ - Each row shows a Bootstrap Icons dot (`bi-dot`), time (`HH:mm`), and `label`; optional per-event `color` overrides the icon color via inline style.
15
+ - Month navigation (`disable_header` off) updates `date` and emits **`changeCalendarDate`**.
16
+ - Row click emits **`calendarEventClick`** with the event `id`.
12
17
 
13
- ### Attributes / props (snake_case)
18
+ The `date-holidays` package is imported and an `IT` instance is constructed in script, but **that object is not used** anywhere in the template or derived data (no holiday-based labels or filtering in the current implementation).
14
19
 
15
- | Property | Type | Notes |
16
- | --- | --- | --- |
17
- | `id` | string (optional) | Element identifier. |
18
- | `style` | string (optional) | Inline style string. |
19
- | `date` | Date (optional) | Current calendar month context; pass as ISO string / parsed JSON in HTML. |
20
- | `events` | array (optional) | JSON array of `{ date: Date; label: string; id: string; link?; icon?; color? }`. |
21
- | `selected` | Date (optional) | Selected day. |
22
- | `disable_header` | boolean (optional) | Hide the navigation header when true. |
20
+ ## UI / layout
23
21
 
24
- **Theme:** `--hb-calendar-selected`, `--hb-calendar-hover`, `--hb-calendar-today`. **Parts:** `calendar-header`, `calendar-current-time-header`, `cell`. **Slots:** `header_month_icon_prev`, `header_month_icon_next`, `header`, `calendar_month`.
22
+ | Region | Behavior |
23
+ |--------|------------|
24
+ | **Header** (optional) | Flex row: default title (month name + year via `Intl` + `dayjs`), prev/next controls. Wrapped in `part="calendar-header"`. Inner title span uses `part="calendar-current-time-header"`. Entire header hidden when `disable_header` is enabled (see logic below). |
25
+ | **Slots in header** | `header` wraps title + nav; `calendar_month` replaces default month/year text; `header_month_icon_prev` / `header_month_icon_next` replace default buttons (still wired to `changeMonth(-1)` / `changeMonth(1)` via outer `onclick`). |
26
+ | **Agenda list** | Under `#appointments_container`: for each day bucket, a bold day line (`events_day`) then `event_row` blocks (focusable `role="button"`). If the month has no events, the list area is empty (no placeholder). |
25
27
 
26
- ### Events (`CustomEvent` names)
28
+ Icons are loaded for the shadow tree via `styles/webcomponent.scss` (Bootstrap Icons font). A `<svelte:head>` stylesheet link is also present but does not apply inside shadow DOM by itself.
27
29
 
28
- - **`calendarEventClick`** — `{ eventId: string }`
29
- - **`changeCalendarDate`** — `{ date: Date }`
30
- - **`changeSelectedDate`** — `{ selectedDate: Date }`
30
+ ## Logic
31
31
 
32
- ### Usage notes
32
+ - **Visible month:** `month` / `year` derived from `date` (`dayjs`).
33
+ - **Filtering:** `monthsEvent` keeps events whose month and year match `date`.
34
+ - **Grouping:** `eventsOfThisMonthByDay` buckets by day-of-month (`D`); first occurrence of a day creates the bucket, further events append to that bucket’s array.
35
+ - **`disable_header`:** In `$effect`, string values are normalized: `true` / `yes` / `""` (empty) → header hidden; otherwise shown.
36
+ - **`events`:** If a string, `JSON.parse`; then sorted ascending by `new Date(a.date)` vs `new Date(b.date)`.
37
+ - **`selected`:** If a string, parsed with `dayjs(selected).toDate()` for in-component use. There is a **`selectDay`** helper that sets `selected` and would emit **`changeSelectedDate`**, but **nothing in the default markup calls `selectDay`**, so that event is **not** produced by the shipped UI (only the typed API / future wiring).
33
38
 
34
- - Bootstrap 5–oriented colors via CSS variables above.
35
- - Italian holiday data is built in; adjust expectations for non-IT locales.
36
- - Shadow DOM exposes named parts for deeper styling.
37
- - Pass `events` and dates as JSON strings from HTML attributes; runtime parsing depends on the web component bridge.
39
+ ## Custom element
38
40
 
39
- ### Minimal HTML example
41
+ ```text
42
+ hb-calendar-appointments
43
+ ```
44
+
45
+ ## Attributes / properties
46
+
47
+ HTML attributes are strings. Align with your bridge; the component’s `$effect` coerces some values.
48
+
49
+ | Name | Typing (`Component`) | Notes |
50
+ |------|----------------------|--------|
51
+ | `id` | `string` (optional) | Passed through like other props; host `id` if set as attribute. |
52
+ | `style` | `string` (optional) | Present in authoring types; not destructured in `component.wc.svelte` (host styling may still apply as a native attribute). |
53
+ | `date` | `Date` (optional) | Default: start of current month (`dayjs().startOf("month")`). Drives which month’s events are shown. From HTML, use an ISO-like string your runtime parses to `Date` / or set the property in JS. |
54
+ | `events` | `IEvent[]` (optional) | JSON array string from attributes; each item: `date`, `label`, `id` required for useful rows; `link`, `icon`, `color` optional (`link` / `icon` are **not read** by the template). |
55
+ | `selected` | `Date` (optional) | Parsed from string in `$effect`. No built-in control updates selection or emits `changeSelectedDate`. |
56
+ | `disable_header` | `boolean` (optional) | Default `false`. For attributes, this codebase often uses **`yes`** / **`no`**; the effect also treats string `"true"`, `"yes"`, and `""` as hide header. |
57
+
58
+ ### `IEvent` (from typings)
59
+
60
+ | Field | Type | Used in UI |
61
+ |-------|------|------------|
62
+ | `date` | `Date` | Filter, sort, time column, weekday/day grouping |
63
+ | `label` | `string` | Row text (`aria-label`, visible label) |
64
+ | `id` | `string` | `calendarEventClick` payload |
65
+ | `link` | optional `string` | No |
66
+ | `icon` | optional `string` | No |
67
+ | `color` | optional `string` | Icon color (inline `style`) |
68
+
69
+ ## Events (`CustomEvent`)
70
+
71
+ | Name | `detail` | When emitted (current implementation) |
72
+ |------|-----------|----------------------------------------|
73
+ | `calendarEventClick` | `{ eventId: string }` | User activates an `.event_row` (click path in template). |
74
+ | `changeCalendarDate` | `{ date: Date }` | Prev/next month navigation runs `changeMonth`. |
75
+ | `changeSelectedDate` | `{ selectedDate: Date }` | Only if something called `selectDay` — **not wired** in the default Svelte markup. |
76
+
77
+ ## Styling
78
+
79
+ ### CSS custom properties
80
+
81
+ Documented in `extra/docs.ts`; defaults from code (`styles/webcomponent.scss` + descriptions in docs):
82
+
83
+ | Variable | Kind | Default / source | Role |
84
+ |----------|------|-------------------|------|
85
+ | `--hb-calendar-event-button-color` | color | `var(--bulma-link, #485fc7)` on `:host` | Dot icon color when `event.color` is not set. |
86
+ | `--bulma-radius` | size | theme / `0.25rem` fallback in SCSS | `border-radius` on `.event_row`. |
87
+ | `--bulma-border` | color | theme / `hsl(0deg 0% 86%)` fallback | `outline` on `.event_row:hover`. |
88
+
89
+ ### CSS parts (`::part`)
90
+
91
+ | Part | Description |
92
+ |------|-------------|
93
+ | `calendar-header` | Outer header strip (month navigation + title area). |
94
+ | `calendar-current-time-header` | Inner title span (month slot + default month/year text). |
95
+
96
+ ## Slots
97
+
98
+ | Slot | Description |
99
+ |------|-------------|
100
+ | `header_month_icon_prev` | Replace default “previous month” control (e.g. icon button). |
101
+ | `header_month_icon_next` | Replace default “next month” control. |
102
+ | `header` | Wraps the whole header row (title + nav); default fills month + controls. |
103
+ | `calendar_month` | Replace/wrap visible month/year label in the header row. |
104
+
105
+ ## Typings
106
+
107
+ Authoring types live in `types/webcomponent.type.d.ts`:
108
+
109
+ - **`Component`** — `id`, `style`, `date`, `events`, `selected`, `disable_header`
110
+ - **`IEvent`** — event record shape
111
+ - **`Events`** — `calendarEventClick`, `changeCalendarDate`, `changeSelectedDate`
112
+
113
+ Built outputs (`types/html-elements.d.ts`, `types/svelte-elements.d.ts`) are regenerated with `npm run build:wc`.
114
+
115
+ ## Example HTML
40
116
 
41
117
  ```html
42
118
  <hb-calendar-appointments
43
- disable_header="false"
119
+ id="agenda-1"
120
+ disable_header="no"
121
+ date="2026-04-01T00:00:00.000Z"
122
+ events='[
123
+ {"id":"a1","label":"Stand-up","date":"2026-04-17T09:00:00.000Z"},
124
+ {"id":"a2","label":"Review","date":"2026-04-17T15:30:00.000Z","color":"#b86bff"}
125
+ ]'
126
+ ></hb-calendar-appointments>
127
+ ```
128
+
129
+ With hidden header:
130
+
131
+ ```html
132
+ <hb-calendar-appointments
133
+ disable_header="yes"
44
134
  events='[{"id":"1","label":"Meeting","date":"2026-03-15T10:00:00.000Z"}]'
45
135
  ></hb-calendar-appointments>
46
136
  ```
137
+
138
+ Listen in JavaScript, for example:
139
+
140
+ ```js
141
+ document.querySelector("hb-calendar-appointments")?.addEventListener("calendarEventClick", (e) => {
142
+ console.log(e.detail.eventId);
143
+ });
144
+ document.querySelector("hb-calendar-appointments")?.addEventListener("changeCalendarDate", (e) => {
145
+ console.log(e.detail.date);
146
+ });
147
+ ```
package/manifest.json CHANGED
@@ -158,35 +158,50 @@
158
158
  {
159
159
  "name": "--hb-calendar-event-button-color",
160
160
  "valueType": "color",
161
- "defaultValue": "",
162
- "description": "Default dot color for events; falls back to `--bulma-link` when unset."
161
+ "defaultValue": "(from `--bulma-link`)",
162
+ "description": "Color for the event marker icon (Bootstrap Icon) in each row; host default on `:host` maps to `--bulma-link`."
163
+ },
164
+ {
165
+ "name": "--bulma-radius",
166
+ "valueType": "number",
167
+ "defaultValue": "0.375rem",
168
+ "description": "Corner radius for interactive event rows on hover."
169
+ },
170
+ {
171
+ "name": "--bulma-border",
172
+ "valueType": "color",
173
+ "defaultValue": "(theme)",
174
+ "description": "Outline color for hovered event rows."
163
175
  }
164
176
  ],
165
177
  "parts": [
166
178
  {
167
- "name": "calendar-header"
168
- },
169
- {
170
- "name": "calendar-current-time-header"
179
+ "name": "calendar-header",
180
+ "description": "Outer header strip (month navigation and title); style layout and chrome of the top bar."
171
181
  },
172
182
  {
173
- "name": "cell"
183
+ "name": "calendar-current-time-header",
184
+ "description": "Inner header row showing the current month label and controls next to the navigation slots."
174
185
  }
175
186
  ]
176
187
  },
177
188
  "contributors": [],
178
189
  "htmlSlots": [
179
190
  {
180
- "name": "header_month_icon_prev"
191
+ "name": "header_month_icon_prev",
192
+ "description": "Previous-month control inside the header (e.g. custom chevron or icon button)."
181
193
  },
182
194
  {
183
- "name": "header_month_icon_next"
195
+ "name": "header_month_icon_next",
196
+ "description": "Next-month control inside the header (e.g. custom chevron or icon button)."
184
197
  },
185
198
  {
186
- "name": "header"
199
+ "name": "header",
200
+ "description": "Optional content above the month line; wraps the default title when empty."
187
201
  },
188
202
  {
189
- "name": "calendar_month"
203
+ "name": "calendar_month",
204
+ "description": "Replace or wrap the visible month / year label in the header row."
190
205
  }
191
206
  ],
192
207
  "i18n": [],
@@ -197,12 +212,12 @@
197
212
  "data": {
198
213
  "events": [
199
214
  {
200
- "date": "2026-04-16T23:11:50.599Z",
215
+ "date": "2026-04-17T00:13:29.971Z",
201
216
  "id": "test",
202
217
  "label": "thetest"
203
218
  },
204
219
  {
205
- "date": "2026-03-30T23:11:50.599Z",
220
+ "date": "2026-03-31T00:13:29.971Z",
206
221
  "id": "test2",
207
222
  "label": "thetest start",
208
223
  "color": "red"
@@ -223,12 +238,12 @@
223
238
  "data": {
224
239
  "events": [
225
240
  {
226
- "date": "2026-04-16T23:11:50.599Z",
241
+ "date": "2026-04-17T00:13:29.971Z",
227
242
  "id": "test",
228
243
  "label": "thetest"
229
244
  },
230
245
  {
231
- "date": "2026-03-30T23:11:50.599Z",
246
+ "date": "2026-03-31T00:13:29.971Z",
232
247
  "id": "test2",
233
248
  "label": "thetest start",
234
249
  "color": "red"
@@ -243,18 +258,18 @@
243
258
  "data": {
244
259
  "events": [
245
260
  {
246
- "date": "2026-04-16T23:11:50.599Z",
261
+ "date": "2026-04-17T00:13:29.971Z",
247
262
  "id": "test",
248
263
  "label": "thetest"
249
264
  },
250
265
  {
251
- "date": "2026-03-30T23:11:50.599Z",
266
+ "date": "2026-03-31T00:13:29.971Z",
252
267
  "id": "test2",
253
268
  "label": "thetest start",
254
269
  "color": "red"
255
270
  }
256
271
  ],
257
- "selected": "2026-04-16T23:11:50.599Z"
272
+ "selected": "2026-04-17T00:13:29.971Z"
258
273
  }
259
274
  }
260
275
  ],
@@ -279,5 +294,5 @@
279
294
  "size": {},
280
295
  "iifePath": "main.iife.js",
281
296
  "repoName": "@htmlbricks/hb-calendar-appointments",
282
- "version": "0.71.34"
297
+ "version": "0.71.36"
283
298
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@htmlbricks/hb-calendar-appointments",
3
- "version": "0.71.34",
3
+ "version": "0.71.36",
4
4
  "contributors": [],
5
5
  "description": "Month agenda view: events for the current month are grouped by calendar day and listed chronologically with weekday, day number, time, and colored markers. Optional header with month navigation; changing month or selecting a day dispatches `changeCalendarDate`, `changeSelectedDate`, and clicking a row dispatches `calendarEventClick`. Uses Italian public holidays metadata and accepts `events` as JSON.",
6
6
  "licenses": [