@timeax/form-palette 0.0.1

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 (109) hide show
  1. package/.scaffold-cache.json +537 -0
  2. package/package.json +42 -0
  3. package/src/.scaffold-cache.json +544 -0
  4. package/src/adapters/axios.ts +117 -0
  5. package/src/adapters/index.ts +91 -0
  6. package/src/adapters/inertia.ts +187 -0
  7. package/src/core/adapter-registry.ts +87 -0
  8. package/src/core/bound/bind-host.ts +14 -0
  9. package/src/core/bound/observe-bound-field.ts +172 -0
  10. package/src/core/bound/wait-for-bound-field.ts +57 -0
  11. package/src/core/context.ts +23 -0
  12. package/src/core/core-provider.tsx +818 -0
  13. package/src/core/core-root.tsx +72 -0
  14. package/src/core/core-shell.tsx +44 -0
  15. package/src/core/errors/error-strip.tsx +71 -0
  16. package/src/core/errors/index.ts +2 -0
  17. package/src/core/errors/map-error-bag.ts +51 -0
  18. package/src/core/errors/map-zod.ts +39 -0
  19. package/src/core/hooks/use-button.ts +220 -0
  20. package/src/core/hooks/use-core-context.ts +20 -0
  21. package/src/core/hooks/use-core-utility.ts +0 -0
  22. package/src/core/hooks/use-core.ts +13 -0
  23. package/src/core/hooks/use-field.ts +497 -0
  24. package/src/core/hooks/use-optional-field.ts +28 -0
  25. package/src/core/index.ts +0 -0
  26. package/src/core/registry/binder-registry.ts +82 -0
  27. package/src/core/registry/field-registry.ts +187 -0
  28. package/src/core/test.tsx +17 -0
  29. package/src/global.d.ts +14 -0
  30. package/src/index.ts +68 -0
  31. package/src/input/index.ts +4 -0
  32. package/src/input/input-field.tsx +854 -0
  33. package/src/input/input-layout-graph.ts +230 -0
  34. package/src/input/input-props.ts +190 -0
  35. package/src/lib/get-global-countries.ts +87 -0
  36. package/src/lib/utils.ts +6 -0
  37. package/src/presets/index.ts +0 -0
  38. package/src/presets/shadcn-preset.ts +0 -0
  39. package/src/presets/shadcn-variants/checkbox.tsx +849 -0
  40. package/src/presets/shadcn-variants/chips.tsx +756 -0
  41. package/src/presets/shadcn-variants/color.tsx +284 -0
  42. package/src/presets/shadcn-variants/custom.tsx +227 -0
  43. package/src/presets/shadcn-variants/date.tsx +796 -0
  44. package/src/presets/shadcn-variants/file.tsx +764 -0
  45. package/src/presets/shadcn-variants/keyvalue.tsx +556 -0
  46. package/src/presets/shadcn-variants/multiselect.tsx +1132 -0
  47. package/src/presets/shadcn-variants/number.tsx +176 -0
  48. package/src/presets/shadcn-variants/password.tsx +737 -0
  49. package/src/presets/shadcn-variants/phone.tsx +628 -0
  50. package/src/presets/shadcn-variants/radio.tsx +578 -0
  51. package/src/presets/shadcn-variants/select.tsx +956 -0
  52. package/src/presets/shadcn-variants/slider.tsx +622 -0
  53. package/src/presets/shadcn-variants/text.tsx +343 -0
  54. package/src/presets/shadcn-variants/textarea.tsx +66 -0
  55. package/src/presets/shadcn-variants/toggle.tsx +218 -0
  56. package/src/presets/shadcn-variants/treeselect.tsx +784 -0
  57. package/src/presets/ui/badge.tsx +46 -0
  58. package/src/presets/ui/button.tsx +60 -0
  59. package/src/presets/ui/calendar.tsx +214 -0
  60. package/src/presets/ui/checkbox.tsx +115 -0
  61. package/src/presets/ui/custom.tsx +0 -0
  62. package/src/presets/ui/dialog.tsx +141 -0
  63. package/src/presets/ui/field.tsx +246 -0
  64. package/src/presets/ui/input-mask.tsx +739 -0
  65. package/src/presets/ui/input-otp.tsx +77 -0
  66. package/src/presets/ui/input.tsx +1011 -0
  67. package/src/presets/ui/label.tsx +22 -0
  68. package/src/presets/ui/number.tsx +1370 -0
  69. package/src/presets/ui/popover.tsx +46 -0
  70. package/src/presets/ui/radio-group.tsx +43 -0
  71. package/src/presets/ui/scroll-area.tsx +56 -0
  72. package/src/presets/ui/select.tsx +190 -0
  73. package/src/presets/ui/separator.tsx +28 -0
  74. package/src/presets/ui/slider.tsx +61 -0
  75. package/src/presets/ui/switch.tsx +32 -0
  76. package/src/presets/ui/textarea.tsx +634 -0
  77. package/src/presets/ui/time-dropdowns.tsx +350 -0
  78. package/src/schema/adapter.ts +217 -0
  79. package/src/schema/core.ts +429 -0
  80. package/src/schema/field-map.ts +0 -0
  81. package/src/schema/field.ts +224 -0
  82. package/src/schema/index.ts +0 -0
  83. package/src/schema/input-field.ts +260 -0
  84. package/src/schema/presets.ts +0 -0
  85. package/src/schema/variant.ts +216 -0
  86. package/src/variants/core/checkbox.tsx +54 -0
  87. package/src/variants/core/chips.tsx +22 -0
  88. package/src/variants/core/color.tsx +16 -0
  89. package/src/variants/core/custom.tsx +18 -0
  90. package/src/variants/core/date.tsx +25 -0
  91. package/src/variants/core/file.tsx +9 -0
  92. package/src/variants/core/keyvalue.tsx +12 -0
  93. package/src/variants/core/multiselect.tsx +28 -0
  94. package/src/variants/core/number.tsx +115 -0
  95. package/src/variants/core/password.tsx +35 -0
  96. package/src/variants/core/phone.tsx +16 -0
  97. package/src/variants/core/radio.tsx +38 -0
  98. package/src/variants/core/select.tsx +15 -0
  99. package/src/variants/core/slider.tsx +55 -0
  100. package/src/variants/core/text.tsx +114 -0
  101. package/src/variants/core/textarea.tsx +22 -0
  102. package/src/variants/core/toggle.tsx +50 -0
  103. package/src/variants/core/treeselect.tsx +11 -0
  104. package/src/variants/helpers/selection-summary.tsx +236 -0
  105. package/src/variants/index.ts +75 -0
  106. package/src/variants/registry.ts +38 -0
  107. package/src/variants/select-shared.ts +0 -0
  108. package/src/variants/shared.ts +126 -0
  109. package/tsconfig.json +14 -0
@@ -0,0 +1,176 @@
1
+ import React from "react";
2
+ import { InputNumber, InputNumberProps, InputNumberValueChangeEvent } from "../ui/number";
3
+ import { cn } from "@/lib/utils";
4
+ import { ChevronUp, ChevronDown, Plus, Minus } from "lucide-react";
5
+
6
+ // Wrapper-level props for the variant
7
+ export type ShadcnNumberVariantProps =
8
+ // All the usual number stuff (mode, locale, prefix, suffix, etc.)
9
+ Omit<InputNumberProps,
10
+ | "onValueChange"
11
+ | "onChange"
12
+ | "leadingControl"
13
+ | "trailingControl"
14
+ >
15
+ & {
16
+ /**
17
+ * Show +/- buttons around the numeric field.
18
+ * Defaults to false.
19
+ */
20
+ showButtons?: boolean;
21
+
22
+ /**
23
+ * How the step buttons are laid out when showButtons is true.
24
+ *
25
+ * - 'inline': "-" on the left, "+" on the right
26
+ * - 'stacked': vertical +/- stack on the right
27
+ */
28
+ buttonLayout?: "inline" | "stacked";
29
+ };
30
+
31
+
32
+ export const ShadcnNumberVariant = React.forwardRef<
33
+ HTMLInputElement,
34
+ ShadcnNumberVariantProps
35
+ >(function ShadcnNumberVariant(props, forwardedRef) {
36
+ const {
37
+ showButtons,
38
+ buttonLayout = "stacked",
39
+ disabled, // Extract disabled to style buttons
40
+ ...rest
41
+ } = props;
42
+
43
+ // we still want access to these for stepping logic
44
+ const {
45
+ step = 1,
46
+ min,
47
+ value,
48
+ max,
49
+ onValue: onValueChange,
50
+ name,
51
+ id,
52
+ inputId,
53
+ } = rest as ShadcnNumberVariantProps;
54
+
55
+ const handleChange = React.useCallback(
56
+ (e: InputNumberValueChangeEvent) => {
57
+ if (onValueChange) {
58
+ onValueChange(e.value as any, {
59
+ source: "user",
60
+ nativeEvent: e.originalEvent as any,
61
+ raw: e.value,
62
+ });
63
+ }
64
+ },
65
+ [onValueChange]
66
+ );
67
+
68
+ const handleStep = React.useCallback(
69
+ (direction: 1 | -1, originalEvent: React.SyntheticEvent<any>) => {
70
+ if (disabled) return;
71
+
72
+ const current = value ?? 0;
73
+ let next = current + direction * step;
74
+
75
+ if (typeof min === "number") next = Math.max(next, min);
76
+ if (typeof max === "number") next = Math.min(next, max);
77
+
78
+ // Prime-style event
79
+ const e: InputNumberValueChangeEvent = {
80
+ originalEvent,
81
+ value: next,
82
+ stopPropagation: () => originalEvent.stopPropagation(),
83
+ preventDefault: () => originalEvent.preventDefault(),
84
+ target: {
85
+ name,
86
+ id: id ?? inputId ?? null,
87
+ value: next,
88
+ },
89
+ };
90
+
91
+ handleChange(e)
92
+ },
93
+ [value, step, min, max, onValueChange, name, id, inputId, disabled, handleChange]
94
+ );
95
+
96
+ // --- Styles ---
97
+ // Common styles for the interactive buttons
98
+ const btnBase = "flex h-full items-center justify-center bg-transparent text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:opacity-50 disabled:cursor-not-allowed";
99
+
100
+ // Build controls based on layout
101
+ let leadingControl: React.ReactNode | undefined;
102
+ let trailingControl: React.ReactNode | undefined;
103
+
104
+ if (showButtons) {
105
+ if (buttonLayout === "inline") {
106
+ // INLINE: "-" on the left, "+" on the right
107
+ leadingControl = (
108
+ <button
109
+ type="button"
110
+ tabIndex={-1} // Prevent tabbing to buttons
111
+ disabled={disabled}
112
+ onClick={(e) => handleStep(-1, e)}
113
+ className={cn(btnBase, "border-r border-input px-3")}
114
+ aria-label="Decrease value"
115
+ >
116
+ <Minus className="h-4 w-4" />
117
+ </button>
118
+ );
119
+
120
+ trailingControl = (
121
+ <button
122
+ type="button"
123
+ tabIndex={-1}
124
+ disabled={disabled}
125
+ onClick={(e) => handleStep(1, e)}
126
+ className={cn(btnBase, "border-l border-input px-3")}
127
+ aria-label="Increase value"
128
+ >
129
+ <Plus className="h-4 w-4" />
130
+ </button>
131
+ );
132
+ } else {
133
+ // STACKED: vertical +/- on the right
134
+ trailingControl = (
135
+ <div className="flex h-full flex-col border-l border-input">
136
+ <button
137
+ type="button"
138
+ tabIndex={-1}
139
+ disabled={disabled}
140
+ onClick={(e) => handleStep(1, e)}
141
+ className={cn(btnBase, "h-1/2 px-2 border-b border-input")}
142
+ aria-label="Increase value"
143
+ >
144
+ <ChevronUp className="h-3 w-3" />
145
+ </button>
146
+ <button
147
+ type="button"
148
+ tabIndex={-1}
149
+ disabled={disabled}
150
+ onClick={(e) => handleStep(-1, e)}
151
+ className={cn(btnBase, "h-1/2 px-2")}
152
+ aria-label="Decrease value"
153
+ >
154
+ <ChevronDown className="h-3 w-3" />
155
+ </button>
156
+ </div>
157
+ );
158
+ }
159
+ }
160
+
161
+ return (
162
+ <InputNumber
163
+ ref={forwardedRef}
164
+ value={value}
165
+ disabled={disabled}
166
+ {...rest}
167
+ onValueChange={handleChange}
168
+ leadingControl={leadingControl}
169
+ trailingControl={trailingControl}
170
+ extendBoxToControls
171
+ // Ensure the controls sit flush inside the container
172
+ leadingControlClassName={cn("flex h-full", rest.leadingControlClassName)}
173
+ trailingControlClassName={cn("flex h-full", rest.trailingControlClassName)}
174
+ />
175
+ );
176
+ });