kalendly 0.3.3 → 0.3.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 +136 -11
- package/dist/styles/calendar.css +21 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -497,28 +497,73 @@ Clicking a day opens a popup with a grid of slots. Each shows only "Booked" or "
|
|
|
497
497
|
|
|
498
498
|
The grid renders `1440 / slot-duration` slots, and `cal-availability-select` emits times on that granularity — half-hour slots produce half-hour selections.
|
|
499
499
|
|
|
500
|
-
Precision below `slot-duration` is not representable: a booking from 17:30 on a 60-minute grid marks 17:00–18:00 booked, because that hour cannot be sold. A
|
|
500
|
+
Precision below `slot-duration` is not representable: a booking from 17:30 on a 60-minute grid marks 17:00–18:00 booked, because that hour cannot be sold. A schedule kept in half-hours sets `slot-duration="30"` rather than expecting the grid to subdivide itself.
|
|
501
501
|
|
|
502
502
|
### Colouring the navigation arrows
|
|
503
503
|
|
|
504
504
|
The `‹` and `›` arrows take their hover fill from `--calendar-primary-color` by
|
|
505
505
|
default, so changing `primary` moves them along with the selected-day fill and
|
|
506
|
-
today outline.
|
|
506
|
+
today outline. Five tokens colour them on their own:
|
|
507
|
+
|
|
508
|
+
| Token | Theme key | Default |
|
|
509
|
+
| ------------------------------- | ----------------- | -------------------------- |
|
|
510
|
+
| `--calendar-nav-arrow-fg` | `navArrowFg` | `--calendar-text-color` |
|
|
511
|
+
| `--calendar-nav-arrow-bg` | `navArrowBg` | `--calendar-background` |
|
|
512
|
+
| `--calendar-nav-arrow-border` | `navArrowBorder` | `--calendar-border-color` |
|
|
513
|
+
| `--calendar-nav-arrow-hover-fg` | `navArrowHoverFg` | `--calendar-on-accent` |
|
|
514
|
+
| `--calendar-nav-arrow-hover-bg` | `navArrowHoverBg` | `--calendar-primary-color` |
|
|
515
|
+
|
|
516
|
+
Each defaults to the value it replaces, so setting none of them changes nothing.
|
|
517
|
+
|
|
518
|
+
**Set them straight on the element.** This is the only way that scopes to one
|
|
519
|
+
calendar:
|
|
520
|
+
|
|
521
|
+
```html
|
|
522
|
+
<kal-calendar
|
|
523
|
+
style="
|
|
524
|
+
--calendar-nav-arrow-fg: #0f766e;
|
|
525
|
+
--calendar-nav-arrow-border: #0f766e;
|
|
526
|
+
--calendar-nav-arrow-hover-bg: #0f766e;
|
|
527
|
+
--calendar-nav-arrow-hover-fg: #fff;
|
|
528
|
+
"
|
|
529
|
+
></kal-calendar>
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
Or from a stylesheet, which is usually tidier. There is no shadow DOM, so your
|
|
533
|
+
CSS reaches the component:
|
|
534
|
+
|
|
535
|
+
```css
|
|
536
|
+
#booking-calendar {
|
|
537
|
+
--calendar-nav-arrow-fg: #0f766e;
|
|
538
|
+
--calendar-nav-arrow-border: #0f766e;
|
|
539
|
+
--calendar-nav-arrow-hover-bg: #0f766e;
|
|
540
|
+
--calendar-nav-arrow-hover-fg: #fff;
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
The same works in every framework, since it is just an attribute or a class:
|
|
545
|
+
|
|
546
|
+
```jsx
|
|
547
|
+
<kal-calendar style={{ '--calendar-nav-arrow-hover-bg': '#0f766e' }} />
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
**Or use the `theme` property** — but note it is page-wide:
|
|
507
551
|
|
|
508
552
|
```js
|
|
509
|
-
cal.theme = {
|
|
510
|
-
navArrowFg: '#0f766e',
|
|
511
|
-
navArrowBorder: '#0f766e',
|
|
512
|
-
navArrowHoverBg: '#0f766e',
|
|
513
|
-
navArrowHoverFg: '#ffffff',
|
|
514
|
-
};
|
|
553
|
+
cal.theme = { navArrowFg: '#0f766e', navArrowHoverBg: '#0f766e' };
|
|
515
554
|
```
|
|
516
555
|
|
|
517
|
-
|
|
556
|
+
> `theme` writes its values to `:root`, so it colours **every** `<kal-calendar>`
|
|
557
|
+
> on the page, not the element you set it on. With one calendar that is
|
|
558
|
+
> harmless. With two, the last assignment wins for both — use the CSS custom
|
|
559
|
+
> properties above to theme them separately.
|
|
560
|
+
|
|
561
|
+
Every other token works the same way: anything in the theming table can be set
|
|
562
|
+
per element as a CSS variable, or page-wide through `theme`.
|
|
518
563
|
|
|
519
564
|
### Booking constraints
|
|
520
565
|
|
|
521
|
-
Four optional attributes describe when
|
|
566
|
+
Four optional attributes describe when bookings are accepted. Omit them all and nothing is constrained.
|
|
522
567
|
|
|
523
568
|
```html
|
|
524
569
|
<kal-calendar
|
|
@@ -544,7 +589,7 @@ None substitutes for another. A horizon cannot say "weekdays only", a weekday li
|
|
|
544
589
|
|
|
545
590
|
`available-hours` takes a comma-separated list because a working day is not always contiguous: `"09:00-12:00,13:00-17:00"` closes for lunch, and `"09:00-17:00,17:30-22:00"` runs meetings then an evening class. Each range is half-open, `[start, end)` — `"09:00-17:00"` on an hourly grid makes 16:00–17:00 the last bookable slot, the same convention events use.
|
|
546
591
|
|
|
547
|
-
Excluded **days** are not click targets at all: no hover response, and neither `cal-date-select` nor `cal-availability-select` fires. Excluded **hours** render greyed and marked `Closed`, and emit no `cal-slot-select`. They are shown rather than hidden so a booking that falls outside the window is still visible
|
|
592
|
+
Excluded **days** are not click targets at all: no hover response, and neither `cal-date-select` nor `cal-availability-select` fires. Excluded **hours** render greyed and marked `Closed`, and emit no `cal-slot-select`. They are shown rather than hidden so a booking that falls outside the window is still visible.
|
|
548
593
|
|
|
549
594
|
Style either with `--calendar-out-of-range-bg` and `--calendar-out-of-range-fg`, or the `outOfRangeBg` / `outOfRangeFg` theme keys.
|
|
550
595
|
|
|
@@ -842,10 +887,90 @@ Type, radius, elevation and spacing scales are exposed the same way —
|
|
|
842
887
|
`--calendar-font-*`, `--calendar-radius-*`, `--calendar-shadow-*` and
|
|
843
888
|
`--calendar-space-*`. See `dist/styles/calendar.css` for the full set.
|
|
844
889
|
|
|
890
|
+
### Where you set a token decides what it colours
|
|
891
|
+
|
|
892
|
+
The same token means different things depending on where you declare it.
|
|
893
|
+
|
|
894
|
+
| Set on | Colours |
|
|
895
|
+
| ---------------------------- | ----------------------------------------- |
|
|
896
|
+
| `:root` or a stylesheet | every `<kal-calendar>` on the page |
|
|
897
|
+
| the `<kal-calendar>` element | that calendar only |
|
|
898
|
+
| the `theme` property | **every** calendar — it writes to `:root` |
|
|
899
|
+
|
|
900
|
+
To theme one calendar, set the custom properties on the element. There is no
|
|
901
|
+
shadow DOM, so they inherit straight through:
|
|
902
|
+
|
|
903
|
+
```html
|
|
904
|
+
<kal-calendar
|
|
905
|
+
style="
|
|
906
|
+
--calendar-primary-color: #4f46e5;
|
|
907
|
+
--calendar-primary-color-rgb: 79, 70, 229;
|
|
908
|
+
--calendar-on-accent: #fff;
|
|
909
|
+
"
|
|
910
|
+
></kal-calendar>
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
Or from your own stylesheet, which is usually tidier:
|
|
914
|
+
|
|
915
|
+
```css
|
|
916
|
+
#booking-calendar {
|
|
917
|
+
--calendar-primary-color: #4f46e5;
|
|
918
|
+
--calendar-primary-color-rgb: 79, 70, 229;
|
|
919
|
+
--calendar-on-accent: #fff;
|
|
920
|
+
}
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
It is only an attribute, so every framework does it its own way:
|
|
924
|
+
|
|
925
|
+
```jsx
|
|
926
|
+
/* React — cast because CSS custom properties are not in CSSProperties */
|
|
927
|
+
<kal-calendar
|
|
928
|
+
style={{
|
|
929
|
+
'--calendar-primary-color': 'var(--primary)',
|
|
930
|
+
'--calendar-primary-color-rgb': 'var(--primary-rgb)',
|
|
931
|
+
'--calendar-on-accent': 'var(--primary-foreground)',
|
|
932
|
+
} as React.CSSProperties}
|
|
933
|
+
/>
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
```vue
|
|
937
|
+
<kal-calendar :style="{ '--calendar-primary-color': brand }" />
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
```svelte
|
|
941
|
+
<kal-calendar style="--calendar-primary-color: {brand}" />
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
```html
|
|
945
|
+
<!-- Angular -->
|
|
946
|
+
<kal-calendar [style.--calendar-primary-color]="brand"></kal-calendar>
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
Pointing a token at one of your own design-system variables works, since it
|
|
950
|
+
resolves in the element's scope:
|
|
951
|
+
|
|
952
|
+
```html
|
|
953
|
+
<kal-calendar style="--calendar-primary-color: var(--primary)"></kal-calendar>
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
> **Set `--calendar-primary-color-rgb` alongside `--calendar-primary-color`.**
|
|
957
|
+
> Translucent fills — cell hover, the picker shadow — are built as
|
|
958
|
+
> `rgba(var(--calendar-primary-color-rgb), …)`, because CSS cannot take the
|
|
959
|
+
> channels out of a hex colour. Change the colour without the channels and
|
|
960
|
+
> those fills keep the old hue. The value is three bare numbers, no `rgb()`.
|
|
961
|
+
|
|
962
|
+
Every demo under `docs/examples/` has a **Brand Colour** control that does
|
|
963
|
+
exactly this, so you can see which parts of the calendar follow the base token.
|
|
964
|
+
|
|
845
965
|
### JS theme property (full reference)
|
|
846
966
|
|
|
847
967
|
Every `--calendar-*` colour token has a matching camelCase theme key.
|
|
848
968
|
|
|
969
|
+
> `theme` writes its values to `:root`, so it colours **every** `<kal-calendar>`
|
|
970
|
+
> on the page, not the element you assign it to. With one calendar that is
|
|
971
|
+
> harmless; with two, the last assignment wins for both. Use the element-scoped
|
|
972
|
+
> custom properties above to theme them separately.
|
|
973
|
+
|
|
849
974
|
```js
|
|
850
975
|
cal.theme = {
|
|
851
976
|
primary: '#3b82f6',
|
package/dist/styles/calendar.css
CHANGED
|
@@ -56,12 +56,6 @@
|
|
|
56
56
|
--calendar-event-indicator: var(--kal-blue-500);
|
|
57
57
|
--calendar-input-invalid: var(--kal-red-500);
|
|
58
58
|
--calendar-input-invalid-rgb: 239, 68, 68;
|
|
59
|
-
--calendar-input-invalid-bg: rgba(var(--calendar-input-invalid-rgb), 0.1);
|
|
60
|
-
--calendar-nav-arrow-fg: var(--calendar-text-color);
|
|
61
|
-
--calendar-nav-arrow-bg: var(--calendar-background);
|
|
62
|
-
--calendar-nav-arrow-border: var(--calendar-border-color);
|
|
63
|
-
--calendar-nav-arrow-hover-fg: var(--calendar-on-accent);
|
|
64
|
-
--calendar-nav-arrow-hover-bg: var(--calendar-primary-color);
|
|
65
59
|
--calendar-popup-header-fg: var(--kal-white);
|
|
66
60
|
--calendar-popup-close-fg: var(--kal-white);
|
|
67
61
|
--calendar-popup-close-bg: rgba(255, 255, 255, 0.2);
|
|
@@ -135,8 +129,6 @@
|
|
|
135
129
|
--calendar-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
136
130
|
--calendar-shadow-md: 0 2px 6px rgba(0, 0, 0, 0.12);
|
|
137
131
|
--calendar-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
138
|
-
--calendar-shadow-primary: 0 2px 8px
|
|
139
|
-
rgba(var(--calendar-primary-color-rgb), 0.2);
|
|
140
132
|
/* Spacing scale — rem so padding tracks the type scale */
|
|
141
133
|
--calendar-space-0-5: 0.125rem;
|
|
142
134
|
--calendar-space-1: 0.25rem;
|
|
@@ -212,20 +204,27 @@
|
|
|
212
204
|
justify-content: center;
|
|
213
205
|
width: 36px;
|
|
214
206
|
height: 36px;
|
|
215
|
-
border: 1px solid
|
|
207
|
+
border: 1px solid
|
|
208
|
+
var(--calendar-nav-arrow-border, var(--calendar-border-color));
|
|
216
209
|
border-radius: var(--calendar-radius-md);
|
|
217
|
-
background: var(--calendar-nav-arrow-bg);
|
|
210
|
+
background: var(--calendar-nav-arrow-bg, var(--calendar-background));
|
|
218
211
|
cursor: pointer;
|
|
219
212
|
font-size: var(--calendar-font-lg);
|
|
220
|
-
color: var(--calendar-nav-arrow-fg);
|
|
213
|
+
color: var(--calendar-nav-arrow-fg, var(--calendar-text-color));
|
|
221
214
|
transition: all 0.2s ease;
|
|
222
215
|
flex-shrink: 0;
|
|
223
216
|
}
|
|
224
217
|
|
|
225
218
|
.calendar-nav-arrow:hover {
|
|
226
|
-
background-color: var(
|
|
227
|
-
|
|
228
|
-
|
|
219
|
+
background-color: var(
|
|
220
|
+
--calendar-nav-arrow-hover-bg,
|
|
221
|
+
var(--calendar-primary-color)
|
|
222
|
+
);
|
|
223
|
+
border-color: var(
|
|
224
|
+
--calendar-nav-arrow-hover-bg,
|
|
225
|
+
var(--calendar-primary-color)
|
|
226
|
+
);
|
|
227
|
+
color: var(--calendar-nav-arrow-hover-fg, var(--calendar-on-accent));
|
|
229
228
|
}
|
|
230
229
|
|
|
231
230
|
.calendar-picker-container {
|
|
@@ -258,7 +257,10 @@
|
|
|
258
257
|
|
|
259
258
|
.calendar-picker-btn[aria-expanded='true'] {
|
|
260
259
|
border-color: var(--calendar-primary-color);
|
|
261
|
-
box-shadow: var(
|
|
260
|
+
box-shadow: var(
|
|
261
|
+
--calendar-shadow-primary,
|
|
262
|
+
0 2px 8px rgba(var(--calendar-primary-color-rgb), 0.2)
|
|
263
|
+
);
|
|
262
264
|
}
|
|
263
265
|
|
|
264
266
|
.calendar-picker-chevron {
|
|
@@ -370,7 +372,10 @@
|
|
|
370
372
|
|
|
371
373
|
.calendar-picker-year-input.invalid {
|
|
372
374
|
border-color: var(--calendar-input-invalid);
|
|
373
|
-
background-color: var(
|
|
375
|
+
background-color: var(
|
|
376
|
+
--calendar-input-invalid-bg,
|
|
377
|
+
rgba(var(--calendar-input-invalid-rgb), 0.1)
|
|
378
|
+
);
|
|
374
379
|
}
|
|
375
380
|
|
|
376
381
|
.calendar-picker-months {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kalendly",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "A universal calendar web component — works in React, Vue, Angular, Svelte, Solid.js, and plain HTML with no framework dependency",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|