@privaty/ui-forms 0.3.2 → 0.4.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/README.md CHANGED
@@ -102,10 +102,17 @@ everywhere else.
102
102
  // Checkboxes: unchecked submits NOTHING — the schema supplies the false.
103
103
  inStock: v.optional(v.boolean(), false),
104
104
 
105
- // Placeholder selects: the disabled placeholder is skipped by submission —
106
- // default "" so YOUR message fires instead of a raw missing-key error.
105
+ // REQUIRED placeholder selects: the disabled prompt is skipped by
106
+ // submission — default "" so YOUR message fires instead of a raw
107
+ // missing-key error. (Optional selects are clearable instead: the empty
108
+ // pick SUBMITS "", so a plain v.optional(v.string()) receives it.)
107
109
  category: v.pipe(v.optional(v.string(), ""), v.picklist(categories, "required")),
108
110
 
111
+ // Optional selects, when the handler prefers undefined over "": FormData
112
+ // cannot carry an absent value from an enabled option, so normalize at
113
+ // the schema boundary — the designed seam for exactly this.
114
+ categoryId: v.optional(v.pipe(v.string(), v.transform((value) => value || undefined))),
115
+
109
116
  // Month inputs submit "YYYY-MM"; empty submits "".
110
117
  availableFrom: v.pipe(v.string(), v.nonEmpty("required"), v.regex(/^\d{4}-\d{2}$/, "invalid-month")),
111
118
  ```
@@ -27,8 +27,11 @@ instead of disabling — a disabled select is excluded from FormData.
27
27
  * `{ value: s, label: s }`; values must be unique — they key the
28
28
  * rendered list. */
29
29
  options: readonly (string | SelectOption)[];
30
- /** Rendered as a disabled empty option, shown until a value is chosen.
31
- * Its presence also makes "" the default seed for an unseeded field. */
30
+ /** The empty option's label — a disabled prompt on required fields, a
31
+ * selectable "none" row on optional ones (see Select's `clearable`;
32
+ * this input derives it from `required`, which never becomes the
33
+ * native attribute). Its presence also makes "" the default seed for
34
+ * an unseeded field. */
32
35
  placeholder?: string;
33
36
 
34
37
  /** Label placement: "top" (default), "left", or "hidden" — floating is
@@ -139,6 +142,7 @@ instead of disabling — a disabled select is excluded from FormData.
139
142
  {labelStyle}
140
143
  {options}
141
144
  {placeholder}
145
+ clearable={!required}
142
146
  errors={wired.errors}
143
147
  marker={wired.marker}
144
148
  aria-invalid={wired.errors.length > 0 ? true : undefined}
@@ -11,8 +11,11 @@ interface Props {
11
11
  * `{ value: s, label: s }`; values must be unique — they key the
12
12
  * rendered list. */
13
13
  options: readonly (string | SelectOption)[];
14
- /** Rendered as a disabled empty option, shown until a value is chosen.
15
- * Its presence also makes "" the default seed for an unseeded field. */
14
+ /** The empty option's label — a disabled prompt on required fields, a
15
+ * selectable "none" row on optional ones (see Select's `clearable`;
16
+ * this input derives it from `required`, which never becomes the
17
+ * native attribute). Its presence also makes "" the default seed for
18
+ * an unseeded field. */
16
19
  placeholder?: string;
17
20
  /** Label placement: "top" (default), "left", or "hidden" — floating is
18
21
  * not offered for selects. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@privaty/ui-forms",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,25 +39,25 @@
39
39
  "access": "public"
40
40
  },
41
41
  "peerDependencies": {
42
+ "@privaty/ui": "^0.4.0",
42
43
  "@sveltejs/kit": "^3.0.0-next.0",
43
- "svelte": "^5.29.0",
44
- "@privaty/ui": "^0.3.2"
44
+ "svelte": "^5.29.0"
45
45
  },
46
46
  "dependencies": {
47
- "@lucide/svelte": "^1.34.0",
47
+ "@lucide/svelte": "^1.39.0",
48
48
  "@standard-schema/spec": "^1.1.0"
49
49
  },
50
50
  "devDependencies": {
51
+ "@config/eslint": "0.0.0",
52
+ "@config/typescript": "0.0.0",
53
+ "@privaty/ui": "0.4.0",
51
54
  "@sveltejs/kit": "3.0.0-next.25",
52
55
  "@sveltejs/package": "^2.5.8",
53
56
  "eslint": "^10.9.1",
54
- "publint": "^0.3.21",
55
- "svelte": "^5.56.10",
57
+ "publint": "^0.3.24",
58
+ "svelte": "^5.57.0",
56
59
  "svelte-check": "^4.7.6",
57
- "typescript": "^6.0.3",
58
- "@config/eslint": "0.0.0",
59
- "@config/typescript": "0.0.0",
60
- "@privaty/ui": "0.3.2"
60
+ "typescript": "^6.0.3"
61
61
  },
62
62
  "scripts": {
63
63
  "check": "svelte-check --tsconfig ./tsconfig.json",