@nuralyui/input 0.0.6 → 0.0.8
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/input.component.d.ts +29 -11
- package/input.component.d.ts.map +1 -1
- package/input.component.js +181 -89
- package/input.component.js.map +1 -1
- package/input.style.d.ts.map +1 -1
- package/input.style.js +128 -11
- package/input.style.js.map +1 -1
- package/input.style.variable.d.ts.map +1 -1
- package/input.style.variable.js +53 -0
- package/input.style.variable.js.map +1 -1
- package/input.types.d.ts +20 -0
- package/input.types.d.ts.map +1 -1
- package/input.types.js.map +1 -1
- package/mixins/focus-mixin.d.ts +60 -0
- package/mixins/focus-mixin.d.ts.map +1 -0
- package/mixins/focus-mixin.js +65 -0
- package/mixins/focus-mixin.js.map +1 -0
- package/mixins/index.d.ts +9 -0
- package/mixins/index.d.ts.map +1 -0
- package/mixins/index.js +9 -0
- package/mixins/index.js.map +1 -0
- package/mixins/number-mixin.d.ts +51 -0
- package/mixins/number-mixin.d.ts.map +1 -0
- package/mixins/number-mixin.js +131 -0
- package/mixins/number-mixin.js.map +1 -0
- package/mixins/selection-mixin.d.ts +57 -0
- package/mixins/selection-mixin.d.ts.map +1 -0
- package/mixins/selection-mixin.js +80 -0
- package/mixins/selection-mixin.js.map +1 -0
- package/package.json +1 -1
- package/utils/input-renderers.d.ts +4 -0
- package/utils/input-renderers.d.ts.map +1 -1
- package/utils/input-renderers.js +17 -0
- package/utils/input-renderers.js.map +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import { LitElement } from 'lit';
|
|
7
|
+
declare type Constructor<T = {}> = new (...args: any[]) => T;
|
|
8
|
+
/**
|
|
9
|
+
* Interface for components that support number operations
|
|
10
|
+
*/
|
|
11
|
+
export interface NumberCapable {
|
|
12
|
+
/**
|
|
13
|
+
* Increment the number value
|
|
14
|
+
*/
|
|
15
|
+
increment(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Decrement the number value
|
|
18
|
+
*/
|
|
19
|
+
decrement(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Set the step attribute for number inputs
|
|
22
|
+
* @param step - The step value
|
|
23
|
+
*/
|
|
24
|
+
setStep(step: string | undefined): void;
|
|
25
|
+
/**
|
|
26
|
+
* Validate if a step value is valid
|
|
27
|
+
* @param step - The step value to validate
|
|
28
|
+
* @returns True if valid
|
|
29
|
+
*/
|
|
30
|
+
isValidStep(step: string | undefined): boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Mixin that provides number input capabilities to input components
|
|
34
|
+
*
|
|
35
|
+
* @param superClass - The base class to extend
|
|
36
|
+
* @returns Enhanced class with number capabilities
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* export class MyInput extends NumberMixin(LitElement) {
|
|
41
|
+
* @query('input') input!: HTMLInputElement;
|
|
42
|
+
*
|
|
43
|
+
* handleUpClick() {
|
|
44
|
+
* this.increment();
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare const NumberMixin: <T extends Constructor<LitElement>>(superClass: T) => Constructor<NumberCapable> & T;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=number-mixin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"number-mixin.d.ts","sourceRoot":"","sources":["../../../../src/components/input/mixins/number-mixin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEjC,aAAK,WAAW,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC;IAElB;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC;IAElB;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAExC;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,WAAW,sFAkHvB,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Mixin that provides number input capabilities to input components
|
|
8
|
+
*
|
|
9
|
+
* @param superClass - The base class to extend
|
|
10
|
+
* @returns Enhanced class with number capabilities
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* export class MyInput extends NumberMixin(LitElement) {
|
|
15
|
+
* @query('input') input!: HTMLInputElement;
|
|
16
|
+
*
|
|
17
|
+
* handleUpClick() {
|
|
18
|
+
* this.increment();
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const NumberMixin = (superClass) => {
|
|
24
|
+
class NumberMixinClass extends superClass {
|
|
25
|
+
/**
|
|
26
|
+
* Get the input element - must be implemented by the component
|
|
27
|
+
*/
|
|
28
|
+
get inputElement() {
|
|
29
|
+
var _a;
|
|
30
|
+
// Try to get from shadowRoot first (for custom elements)
|
|
31
|
+
const shadowInput = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#input, input');
|
|
32
|
+
if (shadowInput) {
|
|
33
|
+
return shadowInput;
|
|
34
|
+
}
|
|
35
|
+
// Fallback to light DOM
|
|
36
|
+
const input = this.querySelector('input');
|
|
37
|
+
if (!input) {
|
|
38
|
+
throw new Error('NumberMixin requires an input element');
|
|
39
|
+
}
|
|
40
|
+
return input;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Dispatch an input event - will be overridden by components that have _dispatchInputEvent
|
|
44
|
+
*/
|
|
45
|
+
dispatchInputEvent(eventName, detail) {
|
|
46
|
+
// Try to use the component's _dispatchInputEvent method if available
|
|
47
|
+
if ('_dispatchInputEvent' in this && typeof this._dispatchInputEvent === 'function') {
|
|
48
|
+
this._dispatchInputEvent(eventName, detail);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Fallback to standard event dispatch
|
|
52
|
+
this.dispatchEvent(new CustomEvent(eventName, {
|
|
53
|
+
detail,
|
|
54
|
+
bubbles: true,
|
|
55
|
+
composed: true
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
increment() {
|
|
60
|
+
try {
|
|
61
|
+
const input = this.inputElement;
|
|
62
|
+
// If input has no value, set it to min or 0 before stepping
|
|
63
|
+
if (!input.value) {
|
|
64
|
+
const min = input.getAttribute('min');
|
|
65
|
+
input.value = min ? min : '0';
|
|
66
|
+
}
|
|
67
|
+
input.stepUp();
|
|
68
|
+
const newValue = input.value;
|
|
69
|
+
this.dispatchInputEvent('nr-input', {
|
|
70
|
+
value: newValue,
|
|
71
|
+
target: input,
|
|
72
|
+
action: 'increment'
|
|
73
|
+
});
|
|
74
|
+
// Update component value if it has one
|
|
75
|
+
if ('value' in this) {
|
|
76
|
+
this.value = newValue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.warn('Failed to increment value:', error);
|
|
81
|
+
this.dispatchInputEvent('nr-increment-error', {
|
|
82
|
+
error,
|
|
83
|
+
value: this.inputElement.value,
|
|
84
|
+
target: this.inputElement
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
decrement() {
|
|
89
|
+
try {
|
|
90
|
+
const input = this.inputElement;
|
|
91
|
+
input.stepDown();
|
|
92
|
+
const newValue = input.value;
|
|
93
|
+
this.dispatchInputEvent('nr-input', {
|
|
94
|
+
value: newValue,
|
|
95
|
+
target: input,
|
|
96
|
+
action: 'decrement'
|
|
97
|
+
});
|
|
98
|
+
// Update component value if it has one
|
|
99
|
+
if ('value' in this) {
|
|
100
|
+
this.value = newValue;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.warn('Failed to decrement value:', error);
|
|
105
|
+
this.dispatchInputEvent('nr-decrement-error', {
|
|
106
|
+
error,
|
|
107
|
+
value: this.inputElement.value,
|
|
108
|
+
target: this.inputElement
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
setStep(step) {
|
|
113
|
+
const input = this.inputElement;
|
|
114
|
+
if (step && this.isValidStep(step)) {
|
|
115
|
+
input.setAttribute('step', step);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
input.removeAttribute('step');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
isValidStep(step) {
|
|
122
|
+
if (!step)
|
|
123
|
+
return true;
|
|
124
|
+
const stepValue = parseFloat(step);
|
|
125
|
+
return !isNaN(stepValue) && stepValue > 0;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Cast return type to the superClass type passed in
|
|
129
|
+
return NumberMixinClass;
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=number-mixin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"number-mixin.js","sourceRoot":"","sources":["../../../../src/components/input/mixins/number-mixin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { LitElement } from 'lit';\n\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\n/**\n * Interface for components that support number operations\n */\nexport interface NumberCapable {\n /**\n * Increment the number value\n */\n increment(): void;\n\n /**\n * Decrement the number value\n */\n decrement(): void;\n\n /**\n * Set the step attribute for number inputs\n * @param step - The step value\n */\n setStep(step: string | undefined): void;\n\n /**\n * Validate if a step value is valid\n * @param step - The step value to validate\n * @returns True if valid\n */\n isValidStep(step: string | undefined): boolean;\n}\n\n/**\n * Mixin that provides number input capabilities to input components\n * \n * @param superClass - The base class to extend\n * @returns Enhanced class with number capabilities\n * \n * @example\n * ```typescript\n * export class MyInput extends NumberMixin(LitElement) {\n * @query('input') input!: HTMLInputElement;\n * \n * handleUpClick() {\n * this.increment();\n * }\n * }\n * ```\n */\nexport const NumberMixin = <T extends Constructor<LitElement>>(superClass: T) => {\n class NumberMixinClass extends superClass implements NumberCapable {\n /**\n * Get the input element - must be implemented by the component\n */\n protected get inputElement(): HTMLInputElement {\n // Try to get from shadowRoot first (for custom elements)\n const shadowInput = this.shadowRoot?.querySelector('#input, input') as HTMLInputElement;\n if (shadowInput) {\n return shadowInput;\n }\n \n // Fallback to light DOM\n const input = this.querySelector('input') as HTMLInputElement;\n if (!input) {\n throw new Error('NumberMixin requires an input element');\n }\n return input;\n }\n\n /**\n * Dispatch an input event - will be overridden by components that have _dispatchInputEvent\n */\n protected dispatchInputEvent(eventName: string, detail: any): void {\n // Try to use the component's _dispatchInputEvent method if available\n if ('_dispatchInputEvent' in this && typeof (this as any)._dispatchInputEvent === 'function') {\n (this as any)._dispatchInputEvent(eventName, detail);\n } else {\n // Fallback to standard event dispatch\n this.dispatchEvent(new CustomEvent(eventName, {\n detail,\n bubbles: true,\n composed: true\n }));\n }\n }\n\n increment(): void {\n try {\n const input = this.inputElement;\n \n // If input has no value, set it to min or 0 before stepping\n if (!input.value) {\n const min = input.getAttribute('min');\n input.value = min ? min : '0';\n }\n \n input.stepUp();\n const newValue = input.value;\n \n this.dispatchInputEvent('nr-input', {\n value: newValue,\n target: input,\n action: 'increment'\n });\n \n // Update component value if it has one\n if ('value' in this) {\n (this as any).value = newValue;\n }\n } catch (error) {\n console.warn('Failed to increment value:', error);\n this.dispatchInputEvent('nr-increment-error', {\n error,\n value: this.inputElement.value,\n target: this.inputElement\n });\n }\n }\n\n decrement(): void {\n try {\n const input = this.inputElement;\n input.stepDown();\n const newValue = input.value;\n \n this.dispatchInputEvent('nr-input', {\n value: newValue,\n target: input,\n action: 'decrement'\n });\n \n // Update component value if it has one\n if ('value' in this) {\n (this as any).value = newValue;\n }\n } catch (error) {\n console.warn('Failed to decrement value:', error);\n this.dispatchInputEvent('nr-decrement-error', {\n error,\n value: this.inputElement.value,\n target: this.inputElement\n });\n }\n }\n\n setStep(step: string | undefined): void {\n const input = this.inputElement;\n if (step && this.isValidStep(step)) {\n input.setAttribute('step', step);\n } else {\n input.removeAttribute('step');\n }\n }\n\n isValidStep(step: string | undefined): boolean {\n if (!step) return true;\n const stepValue = parseFloat(step);\n return !isNaN(stepValue) && stepValue > 0;\n }\n }\n\n // Cast return type to the superClass type passed in\n return NumberMixinClass as Constructor<NumberCapable> & T;\n};\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import { LitElement } from 'lit';
|
|
7
|
+
declare type Constructor<T = {}> = new (...args: any[]) => T;
|
|
8
|
+
/**
|
|
9
|
+
* Interface for components that support text selection operations
|
|
10
|
+
*/
|
|
11
|
+
export interface SelectionCapable {
|
|
12
|
+
/**
|
|
13
|
+
* Select all text in the input
|
|
14
|
+
*/
|
|
15
|
+
selectAll(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Select a range of text in the input
|
|
18
|
+
* @param start - Start position
|
|
19
|
+
* @param end - End position
|
|
20
|
+
*/
|
|
21
|
+
selectRange(start: number, end: number): void;
|
|
22
|
+
/**
|
|
23
|
+
* Get the current cursor position
|
|
24
|
+
* @returns The cursor position or null if not available
|
|
25
|
+
*/
|
|
26
|
+
getCursorPosition(): number | null;
|
|
27
|
+
/**
|
|
28
|
+
* Set the cursor position
|
|
29
|
+
* @param position - The position to set
|
|
30
|
+
*/
|
|
31
|
+
setCursorPosition(position: number): void;
|
|
32
|
+
/**
|
|
33
|
+
* Get the currently selected text
|
|
34
|
+
* @returns The selected text or empty string
|
|
35
|
+
*/
|
|
36
|
+
getSelectedText(): string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Mixin that provides text selection capabilities to input components
|
|
40
|
+
*
|
|
41
|
+
* @param superClass - The base class to extend
|
|
42
|
+
* @returns Enhanced class with selection capabilities
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* export class MyInput extends SelectionMixin(LitElement) {
|
|
47
|
+
* @query('input') input!: HTMLInputElement;
|
|
48
|
+
*
|
|
49
|
+
* handleDoubleClick() {
|
|
50
|
+
* this.selectAll();
|
|
51
|
+
* }
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare const SelectionMixin: <T extends Constructor<LitElement>>(superClass: T) => Constructor<SelectionCapable> & T;
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=selection-mixin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection-mixin.d.ts","sourceRoot":"","sources":["../../../../src/components/input/mixins/selection-mixin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEjC,aAAK,WAAW,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC;IAElB;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9C;;;OAGG;IACH,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAAC;IAEnC;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1C;;;OAGG;IACH,eAAe,IAAI,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,yFA8D1B,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Mixin that provides text selection capabilities to input components
|
|
8
|
+
*
|
|
9
|
+
* @param superClass - The base class to extend
|
|
10
|
+
* @returns Enhanced class with selection capabilities
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* export class MyInput extends SelectionMixin(LitElement) {
|
|
15
|
+
* @query('input') input!: HTMLInputElement;
|
|
16
|
+
*
|
|
17
|
+
* handleDoubleClick() {
|
|
18
|
+
* this.selectAll();
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const SelectionMixin = (superClass) => {
|
|
24
|
+
class SelectionMixinClass extends superClass {
|
|
25
|
+
/**
|
|
26
|
+
* Get the input element - must be implemented by the component
|
|
27
|
+
*/
|
|
28
|
+
get inputElement() {
|
|
29
|
+
var _a;
|
|
30
|
+
// Try to get from shadowRoot first (for custom elements)
|
|
31
|
+
const shadowInput = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#input, input, textarea');
|
|
32
|
+
if (shadowInput) {
|
|
33
|
+
return shadowInput;
|
|
34
|
+
}
|
|
35
|
+
// Fallback to light DOM
|
|
36
|
+
const input = this.querySelector('input, textarea');
|
|
37
|
+
if (!input) {
|
|
38
|
+
throw new Error('SelectionMixin requires an input or textarea element');
|
|
39
|
+
}
|
|
40
|
+
return input;
|
|
41
|
+
}
|
|
42
|
+
selectAll() {
|
|
43
|
+
const input = this.inputElement;
|
|
44
|
+
if (input) {
|
|
45
|
+
input.select();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
selectRange(start, end) {
|
|
49
|
+
const input = this.inputElement;
|
|
50
|
+
if (input && input.setSelectionRange) {
|
|
51
|
+
input.focus();
|
|
52
|
+
input.setSelectionRange(start, end);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
getCursorPosition() {
|
|
56
|
+
const input = this.inputElement;
|
|
57
|
+
if (input && typeof input.selectionStart === 'number') {
|
|
58
|
+
return input.selectionStart;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
setCursorPosition(position) {
|
|
63
|
+
const input = this.inputElement;
|
|
64
|
+
if (input && input.setSelectionRange) {
|
|
65
|
+
input.focus();
|
|
66
|
+
input.setSelectionRange(position, position);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
getSelectedText() {
|
|
70
|
+
const input = this.inputElement;
|
|
71
|
+
if (input && input.selectionStart !== null && input.selectionEnd !== null) {
|
|
72
|
+
return input.value.substring(input.selectionStart, input.selectionEnd);
|
|
73
|
+
}
|
|
74
|
+
return '';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Cast return type to the superClass type passed in
|
|
78
|
+
return SelectionMixinClass;
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=selection-mixin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection-mixin.js","sourceRoot":"","sources":["../../../../src/components/input/mixins/selection-mixin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyCH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAoC,UAAa,EAAE,EAAE;IACjF,MAAM,mBAAoB,SAAQ,UAAU;QAC1C;;WAEG;QACH,IAAc,YAAY;;YACxB,yDAAyD;YACzD,MAAM,WAAW,GAAG,MAAA,IAAI,CAAC,UAAU,0CAAE,aAAa,CAAC,yBAAyB,CAA2C,CAAC;YACxH,IAAI,WAAW,EAAE;gBACf,OAAO,WAAW,CAAC;aACpB;YAED,wBAAwB;YACxB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAA2C,CAAC;YAC9F,IAAI,CAAC,KAAK,EAAE;gBACV,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;aACzE;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,SAAS;YACP,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;YAChC,IAAI,KAAK,EAAE;gBACT,KAAK,CAAC,MAAM,EAAE,CAAC;aAChB;QACH,CAAC;QAED,WAAW,CAAC,KAAa,EAAE,GAAW;YACpC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;YAChC,IAAI,KAAK,IAAI,KAAK,CAAC,iBAAiB,EAAE;gBACpC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,KAAK,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;aACrC;QACH,CAAC;QAED,iBAAiB;YACf,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;YAChC,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ,EAAE;gBACrD,OAAO,KAAK,CAAC,cAAc,CAAC;aAC7B;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,iBAAiB,CAAC,QAAgB;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;YAChC,IAAI,KAAK,IAAI,KAAK,CAAC,iBAAiB,EAAE;gBACpC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,KAAK,CAAC,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;aAC7C;QACH,CAAC;QAED,eAAe;YACb,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;YAChC,IAAI,KAAK,IAAI,KAAK,CAAC,cAAc,KAAK,IAAI,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,EAAE;gBACzE,OAAO,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;aACxE;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;KACF;IAED,oDAAoD;IACpD,OAAO,mBAAwD,CAAC;AAClE,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { LitElement } from 'lit';\n\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\n/**\n * Interface for components that support text selection operations\n */\nexport interface SelectionCapable {\n /**\n * Select all text in the input\n */\n selectAll(): void;\n\n /**\n * Select a range of text in the input\n * @param start - Start position\n * @param end - End position\n */\n selectRange(start: number, end: number): void;\n\n /**\n * Get the current cursor position\n * @returns The cursor position or null if not available\n */\n getCursorPosition(): number | null;\n\n /**\n * Set the cursor position\n * @param position - The position to set\n */\n setCursorPosition(position: number): void;\n\n /**\n * Get the currently selected text\n * @returns The selected text or empty string\n */\n getSelectedText(): string;\n}\n\n/**\n * Mixin that provides text selection capabilities to input components\n * \n * @param superClass - The base class to extend\n * @returns Enhanced class with selection capabilities\n * \n * @example\n * ```typescript\n * export class MyInput extends SelectionMixin(LitElement) {\n * @query('input') input!: HTMLInputElement;\n * \n * handleDoubleClick() {\n * this.selectAll();\n * }\n * }\n * ```\n */\nexport const SelectionMixin = <T extends Constructor<LitElement>>(superClass: T) => {\n class SelectionMixinClass extends superClass implements SelectionCapable {\n /**\n * Get the input element - must be implemented by the component\n */\n protected get inputElement(): HTMLInputElement | HTMLTextAreaElement {\n // Try to get from shadowRoot first (for custom elements)\n const shadowInput = this.shadowRoot?.querySelector('#input, input, textarea') as HTMLInputElement | HTMLTextAreaElement;\n if (shadowInput) {\n return shadowInput;\n }\n \n // Fallback to light DOM\n const input = this.querySelector('input, textarea') as HTMLInputElement | HTMLTextAreaElement;\n if (!input) {\n throw new Error('SelectionMixin requires an input or textarea element');\n }\n return input;\n }\n\n selectAll(): void {\n const input = this.inputElement;\n if (input) {\n input.select();\n }\n }\n\n selectRange(start: number, end: number): void {\n const input = this.inputElement;\n if (input && input.setSelectionRange) {\n input.focus();\n input.setSelectionRange(start, end);\n }\n }\n\n getCursorPosition(): number | null {\n const input = this.inputElement;\n if (input && typeof input.selectionStart === 'number') {\n return input.selectionStart;\n }\n return null;\n }\n\n setCursorPosition(position: number): void {\n const input = this.inputElement;\n if (input && input.setSelectionRange) {\n input.focus();\n input.setSelectionRange(position, position);\n }\n }\n\n getSelectedText(): string {\n const input = this.inputElement;\n if (input && input.selectionStart !== null && input.selectionEnd !== null) {\n return input.value.substring(input.selectionStart, input.selectionEnd);\n }\n return '';\n }\n }\n\n // Cast return type to the superClass type passed in\n return SelectionMixinClass as Constructor<SelectionCapable> & T;\n};\n"]}
|
package/package.json
CHANGED
|
@@ -30,6 +30,10 @@ export declare class InputRenderUtils {
|
|
|
30
30
|
* Renders the copy icon when withCopy is enabled
|
|
31
31
|
*/
|
|
32
32
|
static renderCopyIcon(withCopy: boolean, disabled: boolean, readonly: boolean, onCopy: () => void, onKeydown: (e: KeyboardEvent) => void): TemplateResult | typeof nothing;
|
|
33
|
+
/**
|
|
34
|
+
* Renders the clear icon when allowClear is enabled and there's content
|
|
35
|
+
*/
|
|
36
|
+
static renderClearIcon(allowClear: boolean, value: string, disabled: boolean, readonly: boolean, onClear: () => void, onKeydown: (e: KeyboardEvent) => void): TemplateResult | typeof nothing;
|
|
33
37
|
/**
|
|
34
38
|
* Renders state-based icons (warning, error)
|
|
35
39
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-renderers.d.ts","sourceRoot":"","sources":["../../../../src/components/input/utils/input-renderers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,cAAc,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGpD;;GAEG;AACH,qBAAa,gBAAgB;IAE3B;;OAEG;IACH,MAAM,CAAC,YAAY,IAAI,cAAc;IAQrC;;OAEG;IACH,MAAM,CAAC,YAAY,IAAI,cAAc;IAQrC;;;OAGG;IACH,MAAM,CAAC,iBAAiB,CAAC,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,cAAc,GAAG,OAAO,OAAO;IAUpH;;;OAGG;IACH,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,cAAc,GAAG,OAAO,OAAO;IAUlH;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,MAAM,IAAI,EAClB,SAAS,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,GACpC,cAAc,GAAG,OAAO,OAAO;IAelC;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,OAAO;IAWtE;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,cAAc,GAAG,OAAO,OAAO;IAQlC;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,MAAM,IAAI,EACpB,SAAS,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,GACpC,cAAc,GAAG,OAAO,OAAO;IA4BlC;;OAEG;IACH,MAAM,CAAC,iBAAiB,CACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,WAAW,EAAE,MAAM,IAAI,EACvB,WAAW,EAAE,MAAM,IAAI,EACvB,SAAS,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,GACpC,cAAc,GAAG,OAAO,OAAO;CA0BnC"}
|
|
1
|
+
{"version":3,"file":"input-renderers.d.ts","sourceRoot":"","sources":["../../../../src/components/input/utils/input-renderers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,cAAc,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGpD;;GAEG;AACH,qBAAa,gBAAgB;IAE3B;;OAEG;IACH,MAAM,CAAC,YAAY,IAAI,cAAc;IAQrC;;OAEG;IACH,MAAM,CAAC,YAAY,IAAI,cAAc;IAQrC;;;OAGG;IACH,MAAM,CAAC,iBAAiB,CAAC,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,cAAc,GAAG,OAAO,OAAO;IAUpH;;;OAGG;IACH,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,cAAc,GAAG,OAAO,OAAO;IAUlH;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,MAAM,IAAI,EAClB,SAAS,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,GACpC,cAAc,GAAG,OAAO,OAAO;IAelC;;OAEG;IACH,MAAM,CAAC,eAAe,CACpB,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,MAAM,IAAI,EACnB,SAAS,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,GACpC,cAAc,GAAG,OAAO,OAAO;IAelC;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,OAAO;IAWtE;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,cAAc,GAAG,OAAO,OAAO;IAQlC;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,MAAM,IAAI,EACpB,SAAS,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,GACpC,cAAc,GAAG,OAAO,OAAO;IA4BlC;;OAEG;IACH,MAAM,CAAC,iBAAiB,CACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,WAAW,EAAE,MAAM,IAAI,EACvB,WAAW,EAAE,MAAM,IAAI,EACvB,SAAS,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,GACpC,cAAc,GAAG,OAAO,OAAO;CA0BnC"}
|
package/utils/input-renderers.js
CHANGED
|
@@ -71,6 +71,23 @@ export class InputRenderUtils {
|
|
|
71
71
|
@keydown=${onKeydown}
|
|
72
72
|
></hy-icon>`;
|
|
73
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Renders the clear icon when allowClear is enabled and there's content
|
|
76
|
+
*/
|
|
77
|
+
static renderClearIcon(allowClear, value, disabled, readonly, onClear, onKeydown) {
|
|
78
|
+
if (!allowClear || !value || disabled || readonly)
|
|
79
|
+
return nothing;
|
|
80
|
+
return html `<hy-icon
|
|
81
|
+
name="times-circle"
|
|
82
|
+
type="regular"
|
|
83
|
+
id="clear-icon"
|
|
84
|
+
role="button"
|
|
85
|
+
aria-label="Clear input value"
|
|
86
|
+
tabindex="0"
|
|
87
|
+
@click=${onClear}
|
|
88
|
+
@keydown=${onKeydown}
|
|
89
|
+
></hy-icon>`;
|
|
90
|
+
}
|
|
74
91
|
/**
|
|
75
92
|
* Renders state-based icons (warning, error)
|
|
76
93
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-renderers.js","sourceRoot":"","sources":["../../../../src/components/input/utils/input-renderers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { html, TemplateResult, nothing } from 'lit';\nimport { INPUT_TYPE, INPUT_STATE } from '../input.types.js';\n\n/**\n * Rendering utilities for input component icons and elements\n */\nexport class InputRenderUtils {\n\n /**\n * Renders prefix slot content\n */\n static renderPrefix(): TemplateResult {\n return html`\n <div class=\"input-prefix\">\n <slot name=\"prefix\"></slot>\n </div>\n `;\n }\n\n /**\n * Renders suffix slot content \n */\n static renderSuffix(): TemplateResult {\n return html`\n <div class=\"input-suffix\">\n <slot name=\"suffix\"></slot>\n </div>\n `;\n }\n\n /**\n * Renders addon before slot content (outside input borders)\n * Only renders if hasAddonBefore is true\n */\n static renderAddonBefore(hasAddonBefore: boolean, onSlotChange: (e: Event) => void): TemplateResult | typeof nothing {\n if (!hasAddonBefore) return nothing;\n \n return html`\n <div class=\"input-addon-before\">\n <slot name=\"addon-before\" @slotchange=${onSlotChange}></slot>\n </div>\n `;\n }\n\n /**\n * Renders addon after slot content (outside input borders) \n * Only renders if hasAddonAfter is true\n */\n static renderAddonAfter(hasAddonAfter: boolean, onSlotChange: (e: Event) => void): TemplateResult | typeof nothing {\n if (!hasAddonAfter) return nothing;\n \n return html`\n <div class=\"input-addon-after\">\n <slot name=\"addon-after\" @slotchange=${onSlotChange}></slot>\n </div>\n `;\n }\n\n /**\n * Renders the copy icon when withCopy is enabled\n */\n static renderCopyIcon(\n withCopy: boolean,\n disabled: boolean,\n readonly: boolean,\n onCopy: () => void,\n onKeydown: (e: KeyboardEvent) => void\n ): TemplateResult | typeof nothing {\n if (!withCopy) return nothing;\n \n return html`<hy-icon\n name=\"copy\"\n type=\"regular\"\n id=\"copy-icon\"\n role=\"button\"\n aria-label=\"Copy input value\"\n tabindex=\"0\"\n @click=${!disabled && !readonly ? onCopy : nothing}\n @keydown=${onKeydown}\n ></hy-icon>`;\n }\n\n /**\n * Renders state-based icons (warning, error)\n */\n static renderStateIcon(state: string): TemplateResult | typeof nothing {\n switch (state) {\n case INPUT_STATE.Warning:\n return html`<hy-icon name=\"warning\" id=\"warning-icon\"></hy-icon>`;\n case INPUT_STATE.Error:\n return html`<hy-icon name=\"exclamation-circle\" id=\"error-icon\"></hy-icon>`;\n default:\n return nothing;\n }\n }\n\n /**\n * Renders the calendar icon for calendar input type\n */\n static renderCalendarIcon(\n state: string,\n type: string\n ): TemplateResult | typeof nothing {\n if (state !== INPUT_STATE.Default || type !== INPUT_TYPE.CALENDAR) {\n return nothing;\n }\n \n return html`<hy-icon name=\"calendar\" type=\"regular\" id=\"calendar-icon\"></hy-icon>`;\n }\n\n /**\n * Renders password toggle icon\n */\n static renderPasswordIcon(\n type: string,\n inputType: string,\n disabled: boolean,\n readonly: boolean,\n onToggle: () => void,\n onKeydown: (e: KeyboardEvent) => void\n ): TemplateResult | typeof nothing {\n if (type !== INPUT_TYPE.PASSWORD) return nothing;\n \n if (inputType === INPUT_TYPE.TEXT) {\n return html`<hy-icon\n name=\"eye-slash\"\n type=\"regular\"\n id=\"password-icon\"\n role=\"button\"\n aria-label=\"Hide password\"\n tabindex=\"0\"\n @click=${!disabled && !readonly ? onToggle : nothing}\n @keydown=${onKeydown}\n ></hy-icon>`;\n } else {\n return html`<hy-icon\n name=\"eye\"\n type=\"regular\"\n id=\"password-icon\"\n role=\"button\"\n aria-label=\"Show password\"\n tabindex=\"0\"\n @click=${!disabled && !readonly ? onToggle : nothing}\n @keydown=${onKeydown}\n ></hy-icon>`;\n }\n }\n\n /**\n * Renders number input increment/decrement icons\n */\n static renderNumberIcons(\n type: string,\n state: string,\n disabled: boolean,\n readonly: boolean,\n onIncrement: () => void,\n onDecrement: () => void,\n onKeydown: (e: KeyboardEvent) => void\n ): TemplateResult | typeof nothing {\n if (type !== INPUT_TYPE.NUMBER) return nothing;\n \n return html`\n <div id=\"number-icons\">\n ${state !== INPUT_STATE.Default ? html`<span id=\"icons-separator\">|</span>` : nothing}\n <hy-icon \n name=\"minus\" \n aria-label=\"Decrease value\"\n role=\"button\"\n tabindex=\"0\"\n @click=${!disabled && !readonly ? onDecrement : nothing}\n @keydown=${onKeydown}\n ></hy-icon>\n <span id=\"icons-separator\">|</span>\n <hy-icon \n name=\"plus\" \n aria-label=\"Increase value\"\n role=\"button\"\n tabindex=\"0\"\n @click=${!disabled && !readonly ? onIncrement : nothing}\n @keydown=${onKeydown}\n ></hy-icon>\n </div>\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"input-renderers.js","sourceRoot":"","sources":["../../../../src/components/input/utils/input-renderers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAkB,OAAO,EAAE,MAAM,KAAK,CAAC;AAGpD;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAE3B;;OAEG;IACH,MAAM,CAAC,YAAY;QACjB,OAAO,IAAI,CAAA;;;;KAIV,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY;QACjB,OAAO,IAAI,CAAA;;;;KAIV,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,iBAAiB,CAAC,cAAuB,EAAE,YAAgC;QAChF,IAAI,CAAC,cAAc;YAAE,OAAO,OAAO,CAAC;QAEpC,OAAO,IAAI,CAAA;;gDAEiC,YAAY;;KAEvD,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,gBAAgB,CAAC,aAAsB,EAAE,YAAgC;QAC9E,IAAI,CAAC,aAAa;YAAE,OAAO,OAAO,CAAC;QAEnC,OAAO,IAAI,CAAA;;+CAEgC,YAAY;;KAEtD,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,QAAiB,EACjB,QAAiB,EACjB,QAAiB,EACjB,MAAkB,EAClB,SAAqC;QAErC,IAAI,CAAC,QAAQ;YAAE,OAAO,OAAO,CAAC;QAE9B,OAAO,IAAI,CAAA;;;;;;;eAOA,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;iBACvC,SAAS;gBACV,CAAC;IACf,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,eAAe,CACpB,UAAmB,EACnB,KAAa,EACb,QAAiB,EACjB,QAAiB,EACjB,OAAmB,EACnB,SAAqC;QAErC,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,IAAI,QAAQ,IAAI,QAAQ;YAAE,OAAO,OAAO,CAAC;QAElE,OAAO,IAAI,CAAA;;;;;;;eAOA,OAAO;iBACL,SAAS;gBACV,CAAC;IACf,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAAa;QAClC,QAAQ,KAAK,EAAE;YACb;gBACE,OAAO,IAAI,CAAA,sDAAsD,CAAC;YACpE;gBACE,OAAO,IAAI,CAAA,+DAA+D,CAAC;YAC7E;gBACE,OAAO,OAAO,CAAC;SAClB;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,KAAa,EACb,IAAY;QAEZ,IAAI,KAAK,wCAAwB,IAAI,IAAI,yCAAwB,EAAE;YACjE,OAAO,OAAO,CAAC;SAChB;QAED,OAAO,IAAI,CAAA,uEAAuE,CAAC;IACrF,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,IAAY,EACZ,SAAiB,EACjB,QAAiB,EACjB,QAAiB,EACjB,QAAoB,EACpB,SAAqC;QAErC,IAAI,IAAI,yCAAwB;YAAE,OAAO,OAAO,CAAC;QAEjD,IAAI,SAAS,iCAAoB,EAAE;YACjC,OAAO,IAAI,CAAA;;;;;;;iBAOA,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO;mBACzC,SAAS;kBACV,CAAC;SACd;aAAM;YACL,OAAO,IAAI,CAAA;;;;;;;iBAOA,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO;mBACzC,SAAS;kBACV,CAAC;SACd;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,iBAAiB,CACtB,IAAY,EACZ,KAAa,EACb,QAAiB,EACjB,QAAiB,EACjB,WAAuB,EACvB,WAAuB,EACvB,SAAqC;QAErC,IAAI,IAAI,qCAAsB;YAAE,OAAO,OAAO,CAAC;QAE/C,OAAO,IAAI,CAAA;;UAEL,KAAK,wCAAwB,CAAC,CAAC,CAAC,IAAI,CAAA,qCAAqC,CAAC,CAAC,CAAC,OAAO;;;;;;mBAM1E,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO;qBAC5C,SAAS;;;;;;;;mBAQX,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO;qBAC5C,SAAS;;;KAGzB,CAAC;IACJ,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2023 Google Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { html, TemplateResult, nothing } from 'lit';\nimport { INPUT_TYPE, INPUT_STATE } from '../input.types.js';\n\n/**\n * Rendering utilities for input component icons and elements\n */\nexport class InputRenderUtils {\n\n /**\n * Renders prefix slot content\n */\n static renderPrefix(): TemplateResult {\n return html`\n <div class=\"input-prefix\">\n <slot name=\"prefix\"></slot>\n </div>\n `;\n }\n\n /**\n * Renders suffix slot content \n */\n static renderSuffix(): TemplateResult {\n return html`\n <div class=\"input-suffix\">\n <slot name=\"suffix\"></slot>\n </div>\n `;\n }\n\n /**\n * Renders addon before slot content (outside input borders)\n * Only renders if hasAddonBefore is true\n */\n static renderAddonBefore(hasAddonBefore: boolean, onSlotChange: (e: Event) => void): TemplateResult | typeof nothing {\n if (!hasAddonBefore) return nothing;\n \n return html`\n <div class=\"input-addon-before\">\n <slot name=\"addon-before\" @slotchange=${onSlotChange}></slot>\n </div>\n `;\n }\n\n /**\n * Renders addon after slot content (outside input borders) \n * Only renders if hasAddonAfter is true\n */\n static renderAddonAfter(hasAddonAfter: boolean, onSlotChange: (e: Event) => void): TemplateResult | typeof nothing {\n if (!hasAddonAfter) return nothing;\n \n return html`\n <div class=\"input-addon-after\">\n <slot name=\"addon-after\" @slotchange=${onSlotChange}></slot>\n </div>\n `;\n }\n\n /**\n * Renders the copy icon when withCopy is enabled\n */\n static renderCopyIcon(\n withCopy: boolean,\n disabled: boolean,\n readonly: boolean,\n onCopy: () => void,\n onKeydown: (e: KeyboardEvent) => void\n ): TemplateResult | typeof nothing {\n if (!withCopy) return nothing;\n \n return html`<hy-icon\n name=\"copy\"\n type=\"regular\"\n id=\"copy-icon\"\n role=\"button\"\n aria-label=\"Copy input value\"\n tabindex=\"0\"\n @click=${!disabled && !readonly ? onCopy : nothing}\n @keydown=${onKeydown}\n ></hy-icon>`;\n }\n\n /**\n * Renders the clear icon when allowClear is enabled and there's content\n */\n static renderClearIcon(\n allowClear: boolean,\n value: string,\n disabled: boolean,\n readonly: boolean,\n onClear: () => void,\n onKeydown: (e: KeyboardEvent) => void\n ): TemplateResult | typeof nothing {\n if (!allowClear || !value || disabled || readonly) return nothing;\n \n return html`<hy-icon\n name=\"times-circle\"\n type=\"regular\"\n id=\"clear-icon\"\n role=\"button\"\n aria-label=\"Clear input value\"\n tabindex=\"0\"\n @click=${onClear}\n @keydown=${onKeydown}\n ></hy-icon>`;\n }\n\n /**\n * Renders state-based icons (warning, error)\n */\n static renderStateIcon(state: string): TemplateResult | typeof nothing {\n switch (state) {\n case INPUT_STATE.Warning:\n return html`<hy-icon name=\"warning\" id=\"warning-icon\"></hy-icon>`;\n case INPUT_STATE.Error:\n return html`<hy-icon name=\"exclamation-circle\" id=\"error-icon\"></hy-icon>`;\n default:\n return nothing;\n }\n }\n\n /**\n * Renders the calendar icon for calendar input type\n */\n static renderCalendarIcon(\n state: string,\n type: string\n ): TemplateResult | typeof nothing {\n if (state !== INPUT_STATE.Default || type !== INPUT_TYPE.CALENDAR) {\n return nothing;\n }\n \n return html`<hy-icon name=\"calendar\" type=\"regular\" id=\"calendar-icon\"></hy-icon>`;\n }\n\n /**\n * Renders password toggle icon\n */\n static renderPasswordIcon(\n type: string,\n inputType: string,\n disabled: boolean,\n readonly: boolean,\n onToggle: () => void,\n onKeydown: (e: KeyboardEvent) => void\n ): TemplateResult | typeof nothing {\n if (type !== INPUT_TYPE.PASSWORD) return nothing;\n \n if (inputType === INPUT_TYPE.TEXT) {\n return html`<hy-icon\n name=\"eye-slash\"\n type=\"regular\"\n id=\"password-icon\"\n role=\"button\"\n aria-label=\"Hide password\"\n tabindex=\"0\"\n @click=${!disabled && !readonly ? onToggle : nothing}\n @keydown=${onKeydown}\n ></hy-icon>`;\n } else {\n return html`<hy-icon\n name=\"eye\"\n type=\"regular\"\n id=\"password-icon\"\n role=\"button\"\n aria-label=\"Show password\"\n tabindex=\"0\"\n @click=${!disabled && !readonly ? onToggle : nothing}\n @keydown=${onKeydown}\n ></hy-icon>`;\n }\n }\n\n /**\n * Renders number input increment/decrement icons\n */\n static renderNumberIcons(\n type: string,\n state: string,\n disabled: boolean,\n readonly: boolean,\n onIncrement: () => void,\n onDecrement: () => void,\n onKeydown: (e: KeyboardEvent) => void\n ): TemplateResult | typeof nothing {\n if (type !== INPUT_TYPE.NUMBER) return nothing;\n \n return html`\n <div id=\"number-icons\">\n ${state !== INPUT_STATE.Default ? html`<span id=\"icons-separator\">|</span>` : nothing}\n <hy-icon \n name=\"minus\" \n aria-label=\"Decrease value\"\n role=\"button\"\n tabindex=\"0\"\n @click=${!disabled && !readonly ? onDecrement : nothing}\n @keydown=${onKeydown}\n ></hy-icon>\n <span id=\"icons-separator\">|</span>\n <hy-icon \n name=\"plus\" \n aria-label=\"Increase value\"\n role=\"button\"\n tabindex=\"0\"\n @click=${!disabled && !readonly ? onIncrement : nothing}\n @keydown=${onKeydown}\n ></hy-icon>\n </div>\n `;\n }\n}\n"]}
|