geez-input 1.0.5 → 1.0.6
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 +1 -1
- package/dist/components/geez-input.d.ts +3 -30
- package/dist/components/geez-textarea.d.ts +3 -31
- package/dist/main.js +107 -125
- package/package.json +1 -1
- package/dist/assets/main.css +0 -1
package/README.md
CHANGED
|
@@ -23,21 +23,16 @@ export interface GeezInputProps extends Omit<React.InputHTMLAttributes<HTMLInput
|
|
|
23
23
|
* This is an alias for inputClassName for consistency with standard HTML inputs
|
|
24
24
|
*/
|
|
25
25
|
className?: string;
|
|
26
|
-
/**
|
|
27
|
-
* Additional CSS classes to apply to the toggle button
|
|
28
|
-
*/
|
|
29
|
-
buttonClassName?: string;
|
|
30
26
|
}
|
|
31
27
|
/**
|
|
32
|
-
*
|
|
28
|
+
* Input component with built-in Geez phonetic keyboard support
|
|
33
29
|
*
|
|
34
30
|
* Features:
|
|
35
|
-
* -
|
|
31
|
+
* - Press Cmd+Shift+S (or Ctrl+Shift+S) to toggle between Geez and English input modes
|
|
36
32
|
* - Phonetic transformation (type 'hello' → 'ሀልሎ')
|
|
37
33
|
* - Full support for controlled and uncontrolled component patterns
|
|
38
34
|
* - Forward ref support for form libraries
|
|
39
|
-
* -
|
|
40
|
-
* - Supports Tailwind CSS, CSS modules, or any CSS framework
|
|
35
|
+
* - Supports any CSS framework via className props
|
|
41
36
|
*
|
|
42
37
|
* @example
|
|
43
38
|
* \`\`\`tsx
|
|
@@ -68,27 +63,5 @@ export interface GeezInputProps extends Omit<React.InputHTMLAttributes<HTMLInput
|
|
|
68
63
|
* return <GeezInput {...register('name')} />
|
|
69
64
|
* }
|
|
70
65
|
* \`\`\`
|
|
71
|
-
*
|
|
72
|
-
* @example
|
|
73
|
-
* \`\`\`tsx
|
|
74
|
-
* // Custom styling with Tailwind CSS
|
|
75
|
-
* <GeezInput
|
|
76
|
-
* wrapperClassName="mb-4"
|
|
77
|
-
* inputClassName="rounded-lg shadow-md"
|
|
78
|
-
* buttonClassName="hover:opacity-80"
|
|
79
|
-
* placeholder="Type here..."
|
|
80
|
-
* />
|
|
81
|
-
* \`\`\`
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* \`\`\`tsx
|
|
85
|
-
* // Custom styling with CSS classes
|
|
86
|
-
* <GeezInput
|
|
87
|
-
* wrapperClassName="my-custom-wrapper"
|
|
88
|
-
* inputClassName="my-custom-input"
|
|
89
|
-
* buttonClassName="my-custom-button"
|
|
90
|
-
* placeholder="Type here..."
|
|
91
|
-
* />
|
|
92
|
-
* \`\`\`
|
|
93
66
|
*/
|
|
94
67
|
export declare const GeezInput: React.ForwardRefExoticComponent<GeezInputProps & React.RefAttributes<HTMLInputElement>>;
|
|
@@ -23,22 +23,16 @@ export interface GeezTextAreaProps extends Omit<React.TextareaHTMLAttributes<HTM
|
|
|
23
23
|
* This is an alias for textareaClassName for consistency with standard HTML textareas
|
|
24
24
|
*/
|
|
25
25
|
className?: string;
|
|
26
|
-
/**
|
|
27
|
-
* Additional CSS classes to apply to the toggle button
|
|
28
|
-
*/
|
|
29
|
-
buttonClassName?: string;
|
|
30
26
|
}
|
|
31
27
|
/**
|
|
32
|
-
*
|
|
28
|
+
* Textarea component with built-in Geez phonetic keyboard support
|
|
33
29
|
*
|
|
34
30
|
* Features:
|
|
35
|
-
* -
|
|
31
|
+
* - Press Cmd+Shift+S (or Ctrl+Shift+S) to toggle between Geez and English input modes
|
|
36
32
|
* - Phonetic transformation for longer text
|
|
37
33
|
* - Full support for controlled and uncontrolled component patterns
|
|
38
34
|
* - Forward ref support for form libraries
|
|
39
|
-
* -
|
|
40
|
-
* - Supports Tailwind CSS, CSS modules, or any CSS framework
|
|
41
|
-
* - Minimum height of 150px for comfortable writing
|
|
35
|
+
* - Supports any CSS framework via className props
|
|
42
36
|
*
|
|
43
37
|
* @example
|
|
44
38
|
* \`\`\`tsx
|
|
@@ -66,27 +60,5 @@ export interface GeezTextAreaProps extends Omit<React.TextareaHTMLAttributes<HTM
|
|
|
66
60
|
* // Start with English mode
|
|
67
61
|
* <GeezTextArea defaultGeez={false} placeholder="Type here..." />
|
|
68
62
|
* \`\`\`
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* \`\`\`tsx
|
|
72
|
-
* // Custom styling with Tailwind CSS
|
|
73
|
-
* <GeezTextArea
|
|
74
|
-
* wrapperClassName="mb-4"
|
|
75
|
-
* textareaClassName="rounded-lg shadow-md resize-none"
|
|
76
|
-
* buttonClassName="hover:opacity-80"
|
|
77
|
-
* placeholder="Write here..."
|
|
78
|
-
* />
|
|
79
|
-
* \`\`\`
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* \`\`\`tsx
|
|
83
|
-
* // Custom styling with CSS classes
|
|
84
|
-
* <GeezTextArea
|
|
85
|
-
* wrapperClassName="my-custom-wrapper"
|
|
86
|
-
* textareaClassName="my-custom-textarea"
|
|
87
|
-
* buttonClassName="my-custom-button"
|
|
88
|
-
* placeholder="Write here..."
|
|
89
|
-
* />
|
|
90
|
-
* \`\`\`
|
|
91
63
|
*/
|
|
92
64
|
export declare const GeezTextArea: React.ForwardRefExoticComponent<GeezTextAreaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
package/dist/main.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useCallback as
|
|
3
|
-
|
|
1
|
+
import { jsx as y } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback as N, forwardRef as v, useState as D } from "react";
|
|
3
|
+
const g = {
|
|
4
4
|
h: "ህ",
|
|
5
5
|
l: "ል",
|
|
6
6
|
m: "ም",
|
|
@@ -40,7 +40,7 @@ import './assets/main.css';const E = {
|
|
|
40
40
|
A: "ኣ",
|
|
41
41
|
E: "ኤ",
|
|
42
42
|
O: "ዖ"
|
|
43
|
-
},
|
|
43
|
+
}, p = {
|
|
44
44
|
አ: {
|
|
45
45
|
e: "አ",
|
|
46
46
|
u: "ኡ",
|
|
@@ -321,13 +321,13 @@ import './assets/main.css';const E = {
|
|
|
321
321
|
o: "ቮ",
|
|
322
322
|
ua: "ቯ"
|
|
323
323
|
}
|
|
324
|
-
},
|
|
324
|
+
}, K = {
|
|
325
325
|
ስh: "ሽ",
|
|
326
326
|
ችh: "ች",
|
|
327
327
|
ንy: "ኝ",
|
|
328
328
|
ዝh: "ዥ",
|
|
329
329
|
ጽh: "ፁ"
|
|
330
|
-
},
|
|
330
|
+
}, b = {
|
|
331
331
|
":": "፡",
|
|
332
332
|
"፡:": "።",
|
|
333
333
|
"።:": "፡",
|
|
@@ -335,7 +335,7 @@ import './assets/main.css';const E = {
|
|
|
335
335
|
"፣,": "፤",
|
|
336
336
|
";": "፤"
|
|
337
337
|
};
|
|
338
|
-
class
|
|
338
|
+
class z {
|
|
339
339
|
/**
|
|
340
340
|
* Transform input text based on a new key press
|
|
341
341
|
*
|
|
@@ -367,54 +367,66 @@ class G {
|
|
|
367
367
|
* // → { transformedValue: 'ሽ', newCursorPosition: 1, isReplacement: true }
|
|
368
368
|
* \`\`\`
|
|
369
369
|
*/
|
|
370
|
-
static transform(e,
|
|
371
|
-
const
|
|
372
|
-
if (
|
|
370
|
+
static transform(e, t, i) {
|
|
371
|
+
const a = e.slice(-1), l = a + i;
|
|
372
|
+
if (b[l])
|
|
373
373
|
return {
|
|
374
|
-
transformedValue: e.slice(0, -1) +
|
|
374
|
+
transformedValue: e.slice(0, -1) + b[l] + t,
|
|
375
375
|
newCursorPosition: e.length,
|
|
376
376
|
isReplacement: !0
|
|
377
377
|
};
|
|
378
|
-
if (
|
|
378
|
+
if (b[i])
|
|
379
379
|
return {
|
|
380
|
-
transformedValue: e +
|
|
380
|
+
transformedValue: e + b[i] + t,
|
|
381
381
|
newCursorPosition: e.length + 1,
|
|
382
382
|
isReplacement: !1
|
|
383
383
|
};
|
|
384
|
-
if (
|
|
384
|
+
if (K[l])
|
|
385
385
|
return {
|
|
386
|
-
transformedValue: e.slice(0, -1) +
|
|
386
|
+
transformedValue: e.slice(0, -1) + K[l] + t,
|
|
387
387
|
newCursorPosition: e.length,
|
|
388
388
|
isReplacement: !0
|
|
389
389
|
};
|
|
390
|
-
const
|
|
391
|
-
if (
|
|
390
|
+
const s = p[a];
|
|
391
|
+
if (s && s[i])
|
|
392
392
|
return {
|
|
393
|
-
transformedValue: e.slice(0, -1) +
|
|
393
|
+
transformedValue: e.slice(0, -1) + s[i] + t,
|
|
394
394
|
newCursorPosition: e.length,
|
|
395
395
|
isReplacement: !0
|
|
396
396
|
};
|
|
397
|
-
if (
|
|
398
|
-
const
|
|
399
|
-
if (
|
|
400
|
-
const
|
|
401
|
-
if (
|
|
402
|
-
|
|
403
|
-
|
|
397
|
+
if (i === "e" && a) {
|
|
398
|
+
const o = this.findSadisBase(a);
|
|
399
|
+
if (o && o !== a) {
|
|
400
|
+
const u = p[o];
|
|
401
|
+
if (u && u.ee)
|
|
402
|
+
return {
|
|
403
|
+
transformedValue: e.slice(0, -1) + u.ee + t,
|
|
404
|
+
newCursorPosition: e.length,
|
|
405
|
+
isReplacement: !0
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (["a", "i"].includes(i)) {
|
|
410
|
+
const o = this.findSadisBase(a);
|
|
411
|
+
if (o) {
|
|
412
|
+
const u = p[o];
|
|
413
|
+
if (u) {
|
|
414
|
+
const c = i + i, r = u[c];
|
|
415
|
+
if (r)
|
|
404
416
|
return {
|
|
405
|
-
transformedValue: e.slice(0, -1) +
|
|
417
|
+
transformedValue: e.slice(0, -1) + r + t,
|
|
406
418
|
newCursorPosition: e.length,
|
|
407
419
|
isReplacement: !0
|
|
408
420
|
};
|
|
409
421
|
}
|
|
410
422
|
}
|
|
411
423
|
}
|
|
412
|
-
return
|
|
413
|
-
transformedValue: e +
|
|
424
|
+
return g[i] ? {
|
|
425
|
+
transformedValue: e + g[i] + t,
|
|
414
426
|
newCursorPosition: e.length + 1,
|
|
415
427
|
isReplacement: !1
|
|
416
428
|
} : {
|
|
417
|
-
transformedValue: e +
|
|
429
|
+
transformedValue: e + i + t,
|
|
418
430
|
newCursorPosition: e.length + 1,
|
|
419
431
|
isReplacement: !1
|
|
420
432
|
};
|
|
@@ -437,15 +449,15 @@ class G {
|
|
|
437
449
|
* \`\`\`
|
|
438
450
|
*/
|
|
439
451
|
static findSadisBase(e) {
|
|
440
|
-
for (const [
|
|
441
|
-
if (
|
|
452
|
+
for (const [t, i] of Object.entries(p))
|
|
453
|
+
if (t === e || Object.values(i).includes(e)) return t;
|
|
442
454
|
return null;
|
|
443
455
|
}
|
|
444
456
|
}
|
|
445
|
-
const
|
|
446
|
-
const { enabled: e = !0, onTransform:
|
|
447
|
-
return { onKeyDown:
|
|
448
|
-
(
|
|
457
|
+
const E = (w = {}) => {
|
|
458
|
+
const { enabled: e = !0, onTransform: t } = w;
|
|
459
|
+
return { onKeyDown: N(
|
|
460
|
+
(a) => {
|
|
449
461
|
if (!e || [
|
|
450
462
|
"Backspace",
|
|
451
463
|
"Delete",
|
|
@@ -460,112 +472,82 @@ const D = (r = {}) => {
|
|
|
460
472
|
"Escape",
|
|
461
473
|
"PageUp",
|
|
462
474
|
"PageDown"
|
|
463
|
-
].includes(
|
|
464
|
-
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
let
|
|
468
|
-
typeof InputEvent < "u" ?
|
|
475
|
+
].includes(a.key) || a.ctrlKey || a.metaKey || a.key.length !== 1 || a.altKey) return;
|
|
476
|
+
a.preventDefault();
|
|
477
|
+
const s = a.currentTarget, { selectionStart: o, selectionEnd: u, value: c } = s, r = c.substring(0, o || 0), m = c.substring(u || 0), d = z.transform(r, m, a.key), f = Object.getOwnPropertyDescriptor(s.constructor.prototype, "value");
|
|
478
|
+
f && f.set ? f.set.bind(s)(d.transformedValue) : s.value = d.transformedValue;
|
|
479
|
+
let n;
|
|
480
|
+
typeof InputEvent < "u" ? n = new InputEvent("input", {
|
|
469
481
|
bubbles: !0,
|
|
470
482
|
cancelable: !0,
|
|
471
483
|
inputType: "insertText",
|
|
472
|
-
data:
|
|
473
|
-
}) :
|
|
474
|
-
const
|
|
484
|
+
data: a.key
|
|
485
|
+
}) : n = new Event("input", { bubbles: !0, cancelable: !0 }), s.dispatchEvent(n);
|
|
486
|
+
const h = new Event("change", {
|
|
475
487
|
bubbles: !0,
|
|
476
488
|
cancelable: !0
|
|
477
489
|
});
|
|
478
|
-
|
|
479
|
-
if (document.activeElement ===
|
|
490
|
+
s.dispatchEvent(h), requestAnimationFrame(() => {
|
|
491
|
+
if (document.activeElement === s)
|
|
480
492
|
try {
|
|
481
|
-
|
|
493
|
+
s.setSelectionRange(d.newCursorPosition, d.newCursorPosition);
|
|
482
494
|
} catch {
|
|
483
495
|
}
|
|
484
|
-
}),
|
|
496
|
+
}), t && t(d);
|
|
485
497
|
},
|
|
486
|
-
[e,
|
|
498
|
+
[e, t]
|
|
487
499
|
) };
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
),
|
|
511
|
-
/* @__PURE__ */ f(
|
|
512
|
-
"button",
|
|
513
|
-
{
|
|
514
|
-
type: "button",
|
|
515
|
-
onClick: () => b(!o),
|
|
516
|
-
className: m(
|
|
517
|
-
"geez-input-toggle",
|
|
518
|
-
o ? "geez-input-toggle--active" : "geez-input-toggle--inactive",
|
|
519
|
-
a
|
|
520
|
-
),
|
|
521
|
-
title: o ? "Switch to English" : "Switch to Ge'ez",
|
|
522
|
-
tabIndex: -1,
|
|
523
|
-
children: o ? "አማ" : "EN"
|
|
524
|
-
}
|
|
525
|
-
)
|
|
526
|
-
] });
|
|
500
|
+
}, P = v(
|
|
501
|
+
({ defaultGeez: w = !0, wrapperClassName: e, inputClassName: t, className: i, onChange: a, onKeyDown: l, value: s, ...o }, u) => {
|
|
502
|
+
const [c, r] = D(w), { onKeyDown: m } = E({ enabled: c });
|
|
503
|
+
return /* @__PURE__ */ y("div", { className: e, children: /* @__PURE__ */ y(
|
|
504
|
+
"input",
|
|
505
|
+
{
|
|
506
|
+
...o,
|
|
507
|
+
...s !== void 0 && { value: s },
|
|
508
|
+
ref: u,
|
|
509
|
+
onKeyDown: (n) => {
|
|
510
|
+
if ((n.metaKey || n.ctrlKey) && n.shiftKey && n.key === "S") {
|
|
511
|
+
n.preventDefault(), r((h) => !h);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
m(n), l && l(n);
|
|
515
|
+
},
|
|
516
|
+
onChange: (n) => {
|
|
517
|
+
a && a(n);
|
|
518
|
+
},
|
|
519
|
+
className: i || t
|
|
520
|
+
}
|
|
521
|
+
) });
|
|
527
522
|
}
|
|
528
523
|
);
|
|
529
524
|
P.displayName = "GeezInput";
|
|
530
|
-
const
|
|
531
|
-
({ defaultGeez:
|
|
532
|
-
const [
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
type: "button",
|
|
553
|
-
onClick: () => b(!o),
|
|
554
|
-
className: m(
|
|
555
|
-
"geez-textarea-toggle",
|
|
556
|
-
o ? "geez-textarea-toggle--active" : "geez-textarea-toggle--inactive",
|
|
557
|
-
a
|
|
558
|
-
),
|
|
559
|
-
title: o ? "Switch to English" : "Switch to Ge'ez",
|
|
560
|
-
tabIndex: -1,
|
|
561
|
-
children: o ? "አማ" : "EN"
|
|
562
|
-
}
|
|
563
|
-
)
|
|
564
|
-
] });
|
|
525
|
+
const T = v(
|
|
526
|
+
({ defaultGeez: w = !0, wrapperClassName: e, textareaClassName: t, className: i, onChange: a, onKeyDown: l, value: s, ...o }, u) => {
|
|
527
|
+
const [c, r] = D(w), { onKeyDown: m } = E({ enabled: c });
|
|
528
|
+
return /* @__PURE__ */ y("div", { className: e, children: /* @__PURE__ */ y(
|
|
529
|
+
"textarea",
|
|
530
|
+
{
|
|
531
|
+
...o,
|
|
532
|
+
...s !== void 0 && { value: s },
|
|
533
|
+
ref: u,
|
|
534
|
+
onKeyDown: (n) => {
|
|
535
|
+
if ((n.metaKey || n.ctrlKey) && n.shiftKey && n.key === "S") {
|
|
536
|
+
n.preventDefault(), r((h) => !h);
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
m(n), l && l(n);
|
|
540
|
+
},
|
|
541
|
+
onChange: (n) => {
|
|
542
|
+
a && a(n);
|
|
543
|
+
},
|
|
544
|
+
className: i || t
|
|
545
|
+
}
|
|
546
|
+
) });
|
|
565
547
|
}
|
|
566
548
|
);
|
|
567
|
-
|
|
549
|
+
T.displayName = "GeezTextArea";
|
|
568
550
|
export {
|
|
569
551
|
P as GeezInput,
|
|
570
|
-
|
|
552
|
+
T as GeezTextArea
|
|
571
553
|
};
|
package/package.json
CHANGED
package/dist/assets/main.css
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.geez-input-wrapper{position:relative;width:100%}.geez-input-field{width:100%;background-color:var(--geez-bg-paper, #fefefe);border:2px solid var(--geez-border-gold, rgba(212, 175, 55, .2));outline:none;padding:1rem;font-family:var(--geez-font-serif, Georgia, serif);font-size:1.125rem;transition:all .2s ease}.geez-input-field:focus{border-color:var(--geez-border-crimson, #dc143c)}.geez-input-toggle{position:absolute;right:1rem;top:50%;transform:translateY(-50%);padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease;z-index:10;font-weight:600;font-size:.875rem;border:none;cursor:pointer}.geez-input-toggle--active{background-color:var(--geez-bg-crimson, #dc143c);color:var(--geez-text-white, #ffffff)}.geez-input-toggle--inactive{background-color:var(--geez-bg-gold-light, rgba(212, 175, 55, .1));color:var(--geez-text-gold, #d4af37)}.geez-textarea-wrapper{position:relative;width:100%}.geez-textarea-field{width:100%;background-color:var(--geez-bg-paper, #fefefe);border:2px solid var(--geez-border-gold, rgba(212, 175, 55, .2));outline:none;padding:1.5rem;font-family:var(--geez-font-serif, Georgia, serif);font-size:1.125rem;line-height:1.75;transition:all .2s ease;min-height:150px}.geez-textarea-field:focus{border-color:var(--geez-border-crimson, #dc143c)}.geez-textarea-toggle{position:absolute;right:1rem;top:1rem;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease;z-index:10;font-weight:600;font-size:.875rem;border:none;cursor:pointer}.geez-textarea-toggle--active{background-color:var(--geez-bg-crimson, #dc143c);color:var(--geez-text-white, #ffffff)}.geez-textarea-toggle--inactive{background-color:var(--geez-bg-gold-light, rgba(212, 175, 55, .1));color:var(--geez-text-gold, #d4af37)}
|