@yuafox/easepick2-kbd-plugin 2.0.0

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/LICENSE.md ADDED
@@ -0,0 +1,5 @@
1
+ # Software License Agreement
2
+
3
+ Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
4
+
5
+ Copyright © 2021-2022, [Rinat G.](https://github.com/wakirin)
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # @easepick/kbd-plugin
2
+
3
+ [![npm version](https://badge.fury.io/js/@easepick%2Fkbd-plugin.svg)](https://www.npmjs.com/package/@easepick/kbd-plugin)
4
+
5
+ > This package does not need to be installed if you are using [@easepick/bundle](https://easepick.com/packages/bundle).
6
+
7
+ Adds keyboard navigation.
8
+
9
+ ## Documentation
10
+
11
+ [https://easepick.com/packages/kbd-plugin](https://easepick.com/packages/kbd-plugin)
12
+
13
+
14
+ ## Options
15
+
16
+ | Name | Type | Default | Description
17
+ | --- | :---: | :---: | ---
18
+ | unitIndex | number | 1 | `tabIndex` for elements except days elements.
19
+ | dayIndex | number | 2 | `tabIndex` for days elements.
package/dist/index.css ADDED
File without changes
@@ -0,0 +1,81 @@
1
+ import { BasePlugin, IPlugin } from '@yuafox/easepick2-base-plugin';
2
+ import { RangePlugin } from '@yuafox/easepick2-range-plugin';
3
+ import { IKbdPlugin } from './interface';
4
+ import './index.scss';
5
+ export declare class KbdPlugin extends BasePlugin implements IPlugin {
6
+ docElement: HTMLElement;
7
+ rangePlugin: RangePlugin;
8
+ binds: {
9
+ onView: any;
10
+ onKeydown: any;
11
+ };
12
+ options: IKbdPlugin;
13
+ /**
14
+ * Returns plugin name
15
+ *
16
+ * @returns String
17
+ */
18
+ getName(): string;
19
+ /**
20
+ * - Called automatically via BasePlugin.attach() -
21
+ * The function execute on initialize the picker
22
+ */
23
+ onAttach(): void;
24
+ /**
25
+ * - Called automatically via BasePlugin.detach() -
26
+ */
27
+ onDetach(): void;
28
+ /**
29
+ * Function `view` event
30
+ * Adds `tabIndex` to the picker elements
31
+ *
32
+ * @param event
33
+ */
34
+ private onView;
35
+ /**
36
+ * Function for `keydown` event
37
+ * Handle keys when the picker has focus
38
+ *
39
+ * @param event
40
+ */
41
+ private onKeydown;
42
+ /**
43
+ * Find closest day elements
44
+ *
45
+ * @param layout
46
+ * @param target
47
+ * @param isAllow
48
+ * @returns Boolean
49
+ */
50
+ private findAllowableDaySibling;
51
+ /**
52
+ * Switch month via buttons (previous month, next month)
53
+ *
54
+ * @param evt
55
+ */
56
+ private changeMonth;
57
+ /**
58
+ * Handle ArrowUp and ArrowDown keys
59
+ *
60
+ * @param evt
61
+ */
62
+ private verticalMove;
63
+ /**
64
+ * Handle ArrowLeft and ArrowRight keys
65
+ *
66
+ * @param evt
67
+ */
68
+ private horizontalMove;
69
+ /**
70
+ * Handle Enter and Space keys
71
+ *
72
+ * @param evt
73
+ */
74
+ private handleEnter;
75
+ /**
76
+ * Manually fire `mouseenter` event to display date range correctly
77
+ *
78
+ * @param evt
79
+ */
80
+ private onMouseEnter;
81
+ }
@@ -0,0 +1 @@
1
+ import{BasePlugin as e}from"@yuafox/easepick2-base-plugin";class t extends e{docElement=null;rangePlugin;binds={onView:this.onView.bind(this),onKeydown:this.onKeydown.bind(this)};options={unitIndex:1,dayIndex:2};getName(){return"KbdPlugin"}onAttach(){const e=this.picker.options.element,t=e.getBoundingClientRect();if(this.docElement=document.createElement("span"),this.docElement.style.position="absolute",this.docElement.style.top=`${e.offsetTop}px`,this.docElement.style.left=e.offsetLeft+t.width-25+"px",this.docElement.attachShadow({mode:"open"}),this.options.html)this.docElement.shadowRoot.innerHTML=this.options.html;else{const e=`\n <style>\n button {\n border: none;\n background: transparent;\n font-size: ${window.getComputedStyle(this.picker.options.element).fontSize};\n }\n </style>\n\n <button>&#128197;</button>\n `;this.docElement.shadowRoot.innerHTML=e}const n=this.docElement.shadowRoot.querySelector("button");n&&(n.addEventListener("click",(e=>{e.preventDefault(),this.picker.show({target:this.picker.options.element})}),{capture:!0}),n.addEventListener("keydown",(e=>{"Escape"===e.code&&this.picker.hide()}),{capture:!0})),this.picker.options.element.after(this.docElement),this.picker.on("view",this.binds.onView),this.picker.on("keydown",this.binds.onKeydown)}onDetach(){this.docElement&&this.docElement.isConnected&&this.docElement.remove(),this.picker.off("view",this.binds.onView),this.picker.off("keydown",this.binds.onKeydown)}onView(e){const{view:t,target:n}=e.detail;if(n&&"querySelector"in n)if("CalendarDay"!==t||["locked","not-available"].some((e=>n.classList.contains(e)))){[...n.querySelectorAll(".unit:not(.day)")].forEach((e=>e.tabIndex=this.options.unitIndex))}else n.tabIndex=this.options.dayIndex}onKeydown(e){switch(this.onMouseEnter(e),e.code){case"ArrowUp":case"ArrowDown":this.verticalMove(e);break;case"ArrowLeft":case"ArrowRight":this.horizontalMove(e);break;case"Enter":case"Space":this.handleEnter(e);break;case"Escape":this.picker.hide()}}findAllowableDaySibling(e,t,n){const i=Array.from(e.querySelectorAll(`.day[tabindex="${this.options.dayIndex}"]`)),o=i.indexOf(t);return i.filter(((e,t)=>n(t,o)&&e.tabIndex===this.options.dayIndex))[0]}changeMonth(e){const t={ArrowLeft:"previous",ArrowRight:"next"},n=this.picker.ui.container.querySelector(`.${t[e.code]}-button[tabindex="${this.options.unitIndex}"]`);n&&!n.parentElement.classList.contains(`no-${t[e.code]}-month`)&&(n.dispatchEvent(new Event("click",{bubbles:!0})),setTimeout((()=>{let t=null;switch(e.code){case"ArrowLeft":const e=this.picker.ui.container.querySelectorAll(`.day[tabindex="${this.options.dayIndex}"]`);t=e[e.length-1];break;case"ArrowRight":t=this.picker.ui.container.querySelector(`.day[tabindex="${this.options.dayIndex}"]`)}t&&t.focus()})))}verticalMove(e){const t=e.target;if(t.classList.contains("day")){e.preventDefault();const n=this.findAllowableDaySibling(this.picker.ui.container,t,((t,n)=>t===(n="ArrowUp"===e.code?n-7:n+7)));n&&n.focus()}}horizontalMove(e){const t=e.target;if(t.classList.contains("day")){e.preventDefault();const n=this.findAllowableDaySibling(this.picker.ui.container,t,((t,n)=>t===(n="ArrowLeft"===e.code?n-1:n+1)));n?n.focus():this.changeMonth(e)}}handleEnter(e){const t=e.target;t.classList.contains("day")&&(e.preventDefault(),t.dispatchEvent(new Event("click",{bubbles:!0})),setTimeout((()=>{if(this.rangePlugin=this.picker.PluginManager.getInstance("RangePlugin"),this.rangePlugin||!this.picker.options.autoApply){const e=this.picker.ui.container.querySelector(".day.selected");e&&setTimeout((()=>{e.focus()}))}})))}onMouseEnter(e){e.target.classList.contains("day")&&setTimeout((()=>{const e=this.picker.ui.shadowRoot.activeElement;e&&e.dispatchEvent(new Event("mouseenter",{bubbles:!0}))}))}}export{t as KbdPlugin};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @license
3
+ * Package: @yuafox/easepick2-kbd-plugin
4
+ * Version: 2.0.0
5
+ * https://github.com/YuaFox/easepick2
6
+ * Copyright 2026 YuaFox
7
+ *
8
+ * Licensed under the terms of GNU General Public License Version 2 or later. (http://www.gnu.org/licenses/gpl.html)
9
+ */
10
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@yuafox/easepick2-base-plugin")):"function"==typeof define&&define.amd?define(["exports","@yuafox/easepick2-base-plugin"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).easepick=e.easepick||{},e.easepick)}(this,(function(e,t){"use strict";class n extends t.BasePlugin{docElement=null;rangePlugin;binds={onView:this.onView.bind(this),onKeydown:this.onKeydown.bind(this)};options={unitIndex:1,dayIndex:2};getName(){return"KbdPlugin"}onAttach(){const e=this.picker.options.element,t=e.getBoundingClientRect();if(this.docElement=document.createElement("span"),this.docElement.style.position="absolute",this.docElement.style.top=`${e.offsetTop}px`,this.docElement.style.left=e.offsetLeft+t.width-25+"px",this.docElement.attachShadow({mode:"open"}),this.options.html)this.docElement.shadowRoot.innerHTML=this.options.html;else{const e=`\n <style>\n button {\n border: none;\n background: transparent;\n font-size: ${window.getComputedStyle(this.picker.options.element).fontSize};\n }\n </style>\n\n <button>&#128197;</button>\n `;this.docElement.shadowRoot.innerHTML=e}const n=this.docElement.shadowRoot.querySelector("button");n&&(n.addEventListener("click",(e=>{e.preventDefault(),this.picker.show({target:this.picker.options.element})}),{capture:!0}),n.addEventListener("keydown",(e=>{"Escape"===e.code&&this.picker.hide()}),{capture:!0})),this.picker.options.element.after(this.docElement),this.picker.on("view",this.binds.onView),this.picker.on("keydown",this.binds.onKeydown)}onDetach(){this.docElement&&this.docElement.isConnected&&this.docElement.remove(),this.picker.off("view",this.binds.onView),this.picker.off("keydown",this.binds.onKeydown)}onView(e){const{view:t,target:n}=e.detail;if(n&&"querySelector"in n)if("CalendarDay"!==t||["locked","not-available"].some((e=>n.classList.contains(e)))){[...n.querySelectorAll(".unit:not(.day)")].forEach((e=>e.tabIndex=this.options.unitIndex))}else n.tabIndex=this.options.dayIndex}onKeydown(e){switch(this.onMouseEnter(e),e.code){case"ArrowUp":case"ArrowDown":this.verticalMove(e);break;case"ArrowLeft":case"ArrowRight":this.horizontalMove(e);break;case"Enter":case"Space":this.handleEnter(e);break;case"Escape":this.picker.hide()}}findAllowableDaySibling(e,t,n){const i=Array.from(e.querySelectorAll(`.day[tabindex="${this.options.dayIndex}"]`)),o=i.indexOf(t);return i.filter(((e,t)=>n(t,o)&&e.tabIndex===this.options.dayIndex))[0]}changeMonth(e){const t={ArrowLeft:"previous",ArrowRight:"next"},n=this.picker.ui.container.querySelector(`.${t[e.code]}-button[tabindex="${this.options.unitIndex}"]`);n&&!n.parentElement.classList.contains(`no-${t[e.code]}-month`)&&(n.dispatchEvent(new Event("click",{bubbles:!0})),setTimeout((()=>{let t=null;switch(e.code){case"ArrowLeft":const e=this.picker.ui.container.querySelectorAll(`.day[tabindex="${this.options.dayIndex}"]`);t=e[e.length-1];break;case"ArrowRight":t=this.picker.ui.container.querySelector(`.day[tabindex="${this.options.dayIndex}"]`)}t&&t.focus()})))}verticalMove(e){const t=e.target;if(t.classList.contains("day")){e.preventDefault();const n=this.findAllowableDaySibling(this.picker.ui.container,t,((t,n)=>t===(n="ArrowUp"===e.code?n-7:n+7)));n&&n.focus()}}horizontalMove(e){const t=e.target;if(t.classList.contains("day")){e.preventDefault();const n=this.findAllowableDaySibling(this.picker.ui.container,t,((t,n)=>t===(n="ArrowLeft"===e.code?n-1:n+1)));n?n.focus():this.changeMonth(e)}}handleEnter(e){const t=e.target;t.classList.contains("day")&&(e.preventDefault(),t.dispatchEvent(new Event("click",{bubbles:!0})),setTimeout((()=>{if(this.rangePlugin=this.picker.PluginManager.getInstance("RangePlugin"),this.rangePlugin||!this.picker.options.autoApply){const e=this.picker.ui.container.querySelector(".day.selected");e&&setTimeout((()=>{e.focus()}))}})))}onMouseEnter(e){e.target.classList.contains("day")&&setTimeout((()=>{const e=this.picker.ui.shadowRoot.activeElement;e&&e.dispatchEvent(new Event("mouseenter",{bubbles:!0}))}))}}e.KbdPlugin=n,Object.defineProperty(e,"__esModule",{value:!0})}));
@@ -0,0 +1,11 @@
1
+ import { IBaseConfig } from '@yuafox/easepick2-base-plugin';
2
+ export interface IKbdPlugin extends IBaseConfig {
3
+ unitIndex?: number;
4
+ dayIndex?: number;
5
+ html?: string;
6
+ }
7
+ declare module '@yuafox/easepick2-core/dist/types' {
8
+ interface IKbdPlugin {
9
+ KbdPlugin?: IKbdPlugin;
10
+ }
11
+ }
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@yuafox/easepick2-kbd-plugin",
3
+ "description": "Keyboard plugin for easepick2.",
4
+ "version": "2.0.0",
5
+ "main": "dist/index.umd.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "dependencies": {
9
+ "@yuafox/easepick2-base-plugin": "^2.0.0"
10
+ },
11
+ "author": {
12
+ "name": "YuaFox"
13
+ },
14
+ "license": "GPL-2.0-or-later",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/YuaFox/easepick2.git",
18
+ "directory": "packages/kbd-plugin"
19
+ },
20
+ "homepage": "https://github.com/YuaFox/easepick2",
21
+ "bugs": {
22
+ "url": "https://github.com/YuaFox/easepick2/issues"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ]
27
+ }