kennzeichen 0.1.0 → 0.1.3

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 (2) hide show
  1. package/README.md +27 -82
  2. package/package.json +31 -31
package/README.md CHANGED
@@ -18,44 +18,22 @@ npm install kennzeichen
18
18
 
19
19
  ## Usage
20
20
 
21
- ### Core (any environment)
22
-
23
- The core module works in any JavaScript environment (Node.js, browser, Deno, etc.).
21
+ ### Core
24
22
 
25
23
  ```typescript
26
- import {
27
- parseLicensePlate,
28
- formatParsedPlate,
29
- isValidLicensePlate,
30
- sanitizeLicensePlate,
31
- LOCATION,
32
- } from "kennzeichen";
24
+ import { parseLicensePlate, isValidLicensePlate } from "kennzeichen";
33
25
 
34
26
  // Parse a license plate
35
- const result = parseLicensePlate("M-AB 1234");
27
+ parseLicensePlate("M-AB 1234");
36
28
  // { type: 'unambiguous', plate: { part1: 'M', part2: 'AB', part3: '1234' } }
37
29
 
38
- // Handle ambiguous input (no separator)
39
- const ambiguous = parseLicensePlate("CEE1234");
40
- // { type: 'ambiguous', options: [
41
- // { part1: 'C', part2: 'EE', part3: '1234' },
42
- // { part1: 'CE', part2: 'E', part3: '1234' }
43
- // ] }
44
-
45
- // Format a parsed plate
46
- formatParsedPlate({ part1: "M", part2: "AB", part3: "1234" });
47
- // 'M-AB 1234'
30
+ // Ambiguous input returns multiple options
31
+ parseLicensePlate("CEE1234");
32
+ // { type: 'ambiguous', options: [...] }
48
33
 
49
34
  // Validate
50
35
  isValidLicensePlate("M-AB 1234"); // true
51
- isValidLicensePlate("XX-AB 1234"); // false (invalid location)
52
-
53
- // Sanitize (remove separators)
54
- sanitizeLicensePlate("M-AB 1234"); // 'MAB1234'
55
-
56
- // Check if a location code exists
57
- LOCATION.includes("M"); // true
58
- LOCATION.includes("XX"); // false
36
+ isValidLicensePlate("XX-AB 1234"); // false
59
37
  ```
60
38
 
61
39
  ### Parse Result Types
@@ -76,40 +54,22 @@ type ParsedPlate = {
76
54
 
77
55
  ### React Hook
78
56
 
79
- The hook provides full control over the input state and disambiguation logic.
80
-
81
57
  ```tsx
82
58
  import { useLicensePlate, formatParsedPlate } from "kennzeichen/react";
83
59
 
84
- function MyLicensePlateInput({ value, onChange }) {
85
- const lp = useLicensePlate({ value, onChange });
60
+ function LicensePlateInput({ value, onChange }) {
61
+ const { inputValue, handleChange, isDropdownOpen, options, selectOption } =
62
+ useLicensePlate({ value, onChange });
86
63
 
87
64
  return (
88
- <div className="relative">
89
- <input
90
- value={lp.inputValue}
91
- onChange={lp.handleChange}
92
- onKeyDown={lp.handleKeyDown}
93
- onBlur={lp.handleBlur}
94
- placeholder="z.B. M-AB 1234"
95
- />
96
- {lp.isDropdownOpen && lp.options && (
97
- <ul className="absolute mt-1 border rounded bg-white shadow-lg">
98
- {lp.options.map((opt, i) => (
99
- <li
100
- key={i}
101
- className={`px-3 py-2 cursor-pointer ${
102
- i === lp.activeIndex ? "bg-blue-100" : "hover:bg-gray-100"
103
- }`}
104
- onMouseEnter={() => lp.setActiveIndex(i)}
105
- onMouseDown={(e) => e.preventDefault()}
106
- onClick={() => lp.selectOption(opt)}
107
- >
108
- {formatParsedPlate(opt)}
109
- </li>
110
- ))}
111
- </ul>
112
- )}
65
+ <div>
66
+ <input value={inputValue} onChange={handleChange} />
67
+ {isDropdownOpen &&
68
+ options?.map((opt, i) => (
69
+ <button key={i} onClick={() => selectOption(opt)}>
70
+ {formatParsedPlate(opt)}
71
+ </button>
72
+ ))}
113
73
  </div>
114
74
  );
115
75
  }
@@ -117,36 +77,21 @@ function MyLicensePlateInput({ value, onChange }) {
117
77
 
118
78
  ### React Headless Component
119
79
 
120
- The headless component uses render props to reduce boilerplate while still giving you full control over the UI.
121
-
122
80
  ```tsx
123
81
  import { LicensePlateInput } from "kennzeichen/react";
124
82
 
125
- function MyLicensePlateInput({ value, onChange }) {
83
+ function MyInput({ value, onChange }) {
126
84
  return (
127
85
  <LicensePlateInput value={value} onChange={onChange}>
128
86
  {({ inputProps, isOpen, options }) => (
129
- <div className="relative">
130
- <input
131
- {...inputProps}
132
- className="border rounded px-3 py-2 w-full"
133
- placeholder="z.B. M-AB 1234"
134
- />
135
- {isOpen && options && (
136
- <ul className="absolute mt-1 border rounded bg-white shadow-lg w-full">
137
- {options.map((opt) => (
138
- <li
139
- key={opt.formatted}
140
- className={`px-3 py-2 cursor-pointer ${
141
- opt.isActive ? "bg-blue-100" : "hover:bg-gray-100"
142
- }`}
143
- {...opt.getProps()}
144
- >
145
- {opt.formatted}
146
- </li>
147
- ))}
148
- </ul>
149
- )}
87
+ <div>
88
+ <input {...inputProps} />
89
+ {isOpen &&
90
+ options?.map((opt) => (
91
+ <button key={opt.formatted} {...opt.getProps()}>
92
+ {opt.formatted}
93
+ </button>
94
+ ))}
150
95
  </div>
151
96
  )}
152
97
  </LicensePlateInput>
package/package.json CHANGED
@@ -1,21 +1,38 @@
1
1
  {
2
2
  "name": "kennzeichen",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "German license plate parsing and validation",
5
+ "keywords": [
6
+ "german",
7
+ "license-plate",
8
+ "kennzeichen",
9
+ "parser",
10
+ "validation"
11
+ ],
12
+ "homepage": "https://github.com/canida-software/kennzeichen#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/canida-software/kennzeichen/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/canida-software/kennzeichen.git"
19
+ },
20
+ "license": "MIT",
21
+ "author": "Canida Software <bui.qd@canida.io>",
5
22
  "type": "module",
6
23
  "sideEffects": false,
7
24
  "exports": {
8
25
  ".": {
9
- "import": "./dist/core/index.js",
10
- "types": "./dist/core/index.d.ts"
26
+ "types": "./dist/core/index.d.ts",
27
+ "import": "./dist/core/index.js"
11
28
  },
12
29
  "./core": {
13
- "import": "./dist/core/index.js",
14
- "types": "./dist/core/index.d.ts"
30
+ "types": "./dist/core/index.d.ts",
31
+ "import": "./dist/core/index.js"
15
32
  },
16
33
  "./react": {
17
- "import": "./dist/react/index.js",
18
- "types": "./dist/react/index.d.ts"
34
+ "types": "./dist/react/index.d.ts",
35
+ "import": "./dist/react/index.js"
19
36
  }
20
37
  },
21
38
  "files": [
@@ -23,8 +40,8 @@
23
40
  ],
24
41
  "scripts": {
25
42
  "build": "tsup",
26
- "test": "vitest run",
27
43
  "lint": "oxlint -D recommended --ignore-pattern node_modules",
44
+ "test": "vitest run",
28
45
  "typecheck": "tsc --noEmit"
29
46
  },
30
47
  "peerDependencies": {
@@ -36,28 +53,11 @@
36
53
  }
37
54
  },
38
55
  "devDependencies": {
39
- "@types/react": "^18.0.0",
40
- "oxlint": "^0.16.0",
41
- "react": "^18.0.0",
42
- "tsup": "^8.0.0",
43
- "typescript": "^5.0.0",
44
- "vitest": "^2.0.0"
45
- },
46
- "keywords": [
47
- "german",
48
- "license-plate",
49
- "kennzeichen",
50
- "parser",
51
- "validation"
52
- ],
53
- "license": "MIT",
54
- "author": "Canida Software <bui.qd@canida.io>",
55
- "repository": {
56
- "type": "git",
57
- "url": "git+https://github.com/canida-software/kennzeichen.git"
58
- },
59
- "homepage": "https://github.com/canida-software/kennzeichen#readme",
60
- "bugs": {
61
- "url": "https://github.com/canida-software/kennzeichen/issues"
56
+ "@types/react": "^19.2.9",
57
+ "oxlint": "^1.41.0",
58
+ "react": "^19.2.3",
59
+ "tsup": "^8.5.1",
60
+ "typescript": "^5.9.3",
61
+ "vitest": "^4.0.18"
62
62
  }
63
63
  }