@timeax/form-palette 0.0.3 → 0.0.5

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 (120) hide show
  1. package/{src/schema/adapter.ts → dist/adapters.d.mts} +118 -43
  2. package/dist/adapters.d.ts +292 -0
  3. package/dist/adapters.js +13283 -0
  4. package/dist/adapters.js.map +1 -0
  5. package/dist/adapters.mjs +13269 -0
  6. package/dist/adapters.mjs.map +1 -0
  7. package/dist/index.d.mts +3744 -0
  8. package/dist/index.d.ts +3744 -0
  9. package/dist/index.js +43014 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/index.mjs +42965 -0
  12. package/dist/index.mjs.map +1 -0
  13. package/package.json +22 -7
  14. package/.scaffold-cache.json +0 -537
  15. package/src/.scaffold-cache.json +0 -544
  16. package/src/adapters/axios.ts +0 -117
  17. package/src/adapters/index.ts +0 -91
  18. package/src/adapters/inertia.ts +0 -187
  19. package/src/core/adapter-registry.ts +0 -87
  20. package/src/core/bound/bind-host.ts +0 -14
  21. package/src/core/bound/observe-bound-field.ts +0 -172
  22. package/src/core/bound/wait-for-bound-field.ts +0 -57
  23. package/src/core/context.ts +0 -23
  24. package/src/core/core-provider.tsx +0 -818
  25. package/src/core/core-root.tsx +0 -72
  26. package/src/core/core-shell.tsx +0 -44
  27. package/src/core/errors/error-strip.tsx +0 -71
  28. package/src/core/errors/index.ts +0 -2
  29. package/src/core/errors/map-error-bag.ts +0 -51
  30. package/src/core/errors/map-zod.ts +0 -39
  31. package/src/core/hooks/use-button.ts +0 -220
  32. package/src/core/hooks/use-core-context.ts +0 -20
  33. package/src/core/hooks/use-core-utility.ts +0 -0
  34. package/src/core/hooks/use-core.ts +0 -13
  35. package/src/core/hooks/use-field.ts +0 -497
  36. package/src/core/hooks/use-optional-field.ts +0 -28
  37. package/src/core/index.ts +0 -0
  38. package/src/core/registry/binder-registry.ts +0 -82
  39. package/src/core/registry/field-registry.ts +0 -187
  40. package/src/core/test.tsx +0 -17
  41. package/src/global.d.ts +0 -14
  42. package/src/index.ts +0 -68
  43. package/src/input/index.ts +0 -4
  44. package/src/input/input-field.tsx +0 -854
  45. package/src/input/input-layout-graph.ts +0 -230
  46. package/src/input/input-props.ts +0 -190
  47. package/src/lib/get-global-countries.ts +0 -87
  48. package/src/lib/utils.ts +0 -6
  49. package/src/presets/index.ts +0 -0
  50. package/src/presets/shadcn-preset.ts +0 -0
  51. package/src/presets/shadcn-variants/checkbox.tsx +0 -849
  52. package/src/presets/shadcn-variants/chips.tsx +0 -756
  53. package/src/presets/shadcn-variants/color.tsx +0 -284
  54. package/src/presets/shadcn-variants/custom.tsx +0 -227
  55. package/src/presets/shadcn-variants/date.tsx +0 -796
  56. package/src/presets/shadcn-variants/file.tsx +0 -764
  57. package/src/presets/shadcn-variants/keyvalue.tsx +0 -556
  58. package/src/presets/shadcn-variants/multiselect.tsx +0 -1132
  59. package/src/presets/shadcn-variants/number.tsx +0 -176
  60. package/src/presets/shadcn-variants/password.tsx +0 -737
  61. package/src/presets/shadcn-variants/phone.tsx +0 -628
  62. package/src/presets/shadcn-variants/radio.tsx +0 -578
  63. package/src/presets/shadcn-variants/select.tsx +0 -956
  64. package/src/presets/shadcn-variants/slider.tsx +0 -622
  65. package/src/presets/shadcn-variants/text.tsx +0 -343
  66. package/src/presets/shadcn-variants/textarea.tsx +0 -66
  67. package/src/presets/shadcn-variants/toggle.tsx +0 -218
  68. package/src/presets/shadcn-variants/treeselect.tsx +0 -784
  69. package/src/presets/ui/badge.tsx +0 -46
  70. package/src/presets/ui/button.tsx +0 -60
  71. package/src/presets/ui/calendar.tsx +0 -214
  72. package/src/presets/ui/checkbox.tsx +0 -115
  73. package/src/presets/ui/custom.tsx +0 -0
  74. package/src/presets/ui/dialog.tsx +0 -141
  75. package/src/presets/ui/field.tsx +0 -246
  76. package/src/presets/ui/input-mask.tsx +0 -739
  77. package/src/presets/ui/input-otp.tsx +0 -77
  78. package/src/presets/ui/input.tsx +0 -1011
  79. package/src/presets/ui/label.tsx +0 -22
  80. package/src/presets/ui/number.tsx +0 -1370
  81. package/src/presets/ui/popover.tsx +0 -46
  82. package/src/presets/ui/radio-group.tsx +0 -43
  83. package/src/presets/ui/scroll-area.tsx +0 -56
  84. package/src/presets/ui/select.tsx +0 -190
  85. package/src/presets/ui/separator.tsx +0 -28
  86. package/src/presets/ui/slider.tsx +0 -61
  87. package/src/presets/ui/switch.tsx +0 -32
  88. package/src/presets/ui/textarea.tsx +0 -634
  89. package/src/presets/ui/time-dropdowns.tsx +0 -350
  90. package/src/schema/core.ts +0 -429
  91. package/src/schema/field-map.ts +0 -0
  92. package/src/schema/field.ts +0 -224
  93. package/src/schema/index.ts +0 -0
  94. package/src/schema/input-field.ts +0 -260
  95. package/src/schema/presets.ts +0 -0
  96. package/src/schema/variant.ts +0 -216
  97. package/src/variants/core/checkbox.tsx +0 -54
  98. package/src/variants/core/chips.tsx +0 -22
  99. package/src/variants/core/color.tsx +0 -16
  100. package/src/variants/core/custom.tsx +0 -18
  101. package/src/variants/core/date.tsx +0 -25
  102. package/src/variants/core/file.tsx +0 -9
  103. package/src/variants/core/keyvalue.tsx +0 -12
  104. package/src/variants/core/multiselect.tsx +0 -28
  105. package/src/variants/core/number.tsx +0 -115
  106. package/src/variants/core/password.tsx +0 -35
  107. package/src/variants/core/phone.tsx +0 -16
  108. package/src/variants/core/radio.tsx +0 -38
  109. package/src/variants/core/select.tsx +0 -15
  110. package/src/variants/core/slider.tsx +0 -55
  111. package/src/variants/core/text.tsx +0 -114
  112. package/src/variants/core/textarea.tsx +0 -22
  113. package/src/variants/core/toggle.tsx +0 -50
  114. package/src/variants/core/treeselect.tsx +0 -11
  115. package/src/variants/helpers/selection-summary.tsx +0 -236
  116. package/src/variants/index.ts +0 -75
  117. package/src/variants/registry.ts +0 -38
  118. package/src/variants/select-shared.ts +0 -0
  119. package/src/variants/shared.ts +0 -126
  120. package/tsconfig.json +0 -14
@@ -1,236 +0,0 @@
1
- import * as React from "react";
2
- import { X } from "lucide-react";
3
- import { cn } from "@/lib/utils";
4
- import {
5
- Popover,
6
- PopoverTrigger,
7
- PopoverContent,
8
- } from "@/presets/ui/popover";
9
-
10
- type NormalizedMultiItem = {
11
- key: string;
12
- value: string | number;
13
- labelNode: React.ReactNode;
14
- labelText: string; // Used for width calculation
15
- disabled?: boolean;
16
- };
17
-
18
- export interface SelectionSummaryProps {
19
- selectedItems: NormalizedMultiItem[];
20
- placeholder?: React.ReactNode;
21
- onRemoveValue?: (value: NormalizedMultiItem) => void;
22
- }
23
-
24
- /**
25
- * Helper: Measure text width using a canvas.
26
- * Much faster than rendering hidden DOM elements.
27
- */
28
- function getTextWidth(text: string, font: string) {
29
- if (typeof window === "undefined") return 0;
30
- const canvas =
31
- (window as any).__canvas ||
32
- ((window as any).__canvas = document.createElement("canvas"));
33
- const context = canvas.getContext("2d");
34
- context.font = font;
35
- const metrics = context.measureText(text);
36
- return metrics.width;
37
- }
38
-
39
- export const SelectionSummary: React.FC<SelectionSummaryProps> = ({
40
- selectedItems,
41
- placeholder,
42
- onRemoveValue,
43
- }) => {
44
- const containerRef = React.useRef<HTMLSpanElement | null>(null);
45
- const [visibleCount, setVisibleCount] = React.useState(0);
46
- const [moreOpen, setMoreOpen] = React.useState(false);
47
-
48
- // Measure available width and calculate how many items fit
49
- React.useLayoutEffect(() => {
50
- const el = containerRef.current;
51
- if (!el) return;
52
-
53
- const computeVisibleItems = () => {
54
- const containerWidth = el.clientWidth;
55
-
56
- // 1. Get current font styles to ensure accurate measurement
57
- const computedStyle = window.getComputedStyle(el);
58
- const font = `${computedStyle.fontWeight} ${computedStyle.fontSize} ${computedStyle.fontFamily}`;
59
-
60
- // 2. Calculate the "Buffer" (12 characters width)
61
- // This is the space reserved for the "+ N more" trigger if truncation happens.
62
- // We use 'M' or '0' as an average widest character approximation, or a standard string.
63
- const bufferWidth = getTextWidth("000000000000", font);
64
-
65
- // 3. Width of the separator (e.g., ", ")
66
- const commaWidth = getTextWidth(", ", font);
67
-
68
- let usedWidth = 0;
69
- let count = 0;
70
- const totalItems = selectedItems.length;
71
-
72
- for (let i = 0; i < totalItems; i++) {
73
- const item = selectedItems[i];
74
- const itemWidth = getTextWidth(item.labelText, font);
75
-
76
- // Is this the very last item in the entire list?
77
- const isLastItem = i === totalItems - 1;
78
-
79
- // If it's the last item, we don't need the buffer space.
80
- // If it's NOT the last item, we must ensure we have space for this item AND the buffer.
81
- // (Because if we can't fit the *next* item, we'll need the buffer to show the badge).
82
- const spaceNeeded = isLastItem
83
- ? itemWidth
84
- : itemWidth + commaWidth + bufferWidth;
85
-
86
- if (usedWidth + spaceNeeded <= containerWidth) {
87
- usedWidth += itemWidth + commaWidth;
88
- count++;
89
- } else {
90
- // No more space
91
- break;
92
- }
93
- }
94
-
95
- // Ensure we show at least 1 item if there are items,
96
- // unless even the first item is wider than the container (then CSS truncation handles it).
97
- setVisibleCount(Math.max(1, count));
98
- };
99
-
100
- computeVisibleItems();
101
-
102
- const ro = new ResizeObserver(computeVisibleItems);
103
- ro.observe(el);
104
- return () => ro.disconnect();
105
- }, [selectedItems, selectedItems.length]); // Re-run if items change
106
-
107
- const totalCount = selectedItems.length;
108
-
109
- if (!totalCount) {
110
- return (
111
- <span ref={containerRef} className="truncate text-muted-foreground w-full block">
112
- {placeholder ?? "Select options…"}
113
- </span>
114
- );
115
- }
116
-
117
- const visibleItems = selectedItems.slice(0, visibleCount);
118
- // If visible count covers everything, overflow is 0
119
- const overflowCount = totalCount - visibleItems.length;
120
-
121
- // Safety check: if our calculation says we can show X, but X < Total,
122
- // strictly ensure we render the "More" chip.
123
- // If calculation resulted in showing all items, overflow is 0.
124
- const showMore = overflowCount > 0;
125
-
126
- const handleRemove = (value: NormalizedMultiItem) => {
127
- if (!onRemoveValue) return;
128
- onRemoveValue(value);
129
- };
130
-
131
- return (
132
- <span
133
- ref={containerRef}
134
- className="flex items-center w-full overflow-hidden whitespace-nowrap"
135
- >
136
- {/* Render Visible Items */}
137
- {visibleItems.map((item, index) => (
138
- <React.Fragment key={item.key}>
139
- <span className="truncate flex-shrink-0">
140
- {item.labelNode}
141
- </span>
142
- {/* Add comma if it's not the last visible item */}
143
- {index < visibleItems.length - 1 && (
144
- <span className="text-muted-foreground mr-1">,</span>
145
- )}
146
- </React.Fragment>
147
- ))}
148
-
149
- {/* Render Separator before "More" if needed */}
150
- {showMore && (
151
- <span className="text-muted-foreground mr-1">,</span>
152
- )}
153
-
154
- {/* Render "+N more" Chip */}
155
- {showMore && (
156
- <Popover open={moreOpen} onOpenChange={setMoreOpen}>
157
- <PopoverTrigger asChild>
158
- <button
159
- type="button"
160
- className="inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground underline underline-offset-2 flex-shrink-0"
161
- onClick={(e) => e.stopPropagation()}
162
- >
163
- +{overflowCount} more
164
- </button>
165
- </PopoverTrigger>
166
- <PopoverContent
167
- align="start"
168
- className="w-56 max-h-64 overflow-y-auto p-2 text-sm"
169
- onClick={(e) => e.stopPropagation()}
170
- >
171
- <div className="flex items-center justify-between mb-1">
172
- <span className="font-medium text-xs text-muted-foreground">
173
- Selected ({totalCount})
174
- </span>
175
- <button
176
- type="button"
177
- className="p-1 rounded hover:bg-muted"
178
- onClick={() => setMoreOpen(false)}
179
- >
180
- <X className="h-3 w-3" />
181
- </button>
182
- </div>
183
-
184
- <div className="space-y-1">
185
- {selectedItems.map((item) => (
186
- <div
187
- key={item.key}
188
- className={cn(
189
- "flex items-center justify-between gap-2 rounded px-2 py-1",
190
- "bg-muted/40"
191
- )}
192
- >
193
- <span className="truncate">{item.labelNode}</span>
194
- {onRemoveValue && (
195
- <button
196
- type="button"
197
- className="flex h-4 w-4 shrink-0 items-center justify-center rounded hover:bg-muted text-muted-foreground hover:text-foreground"
198
- onClick={(e) => {
199
- e.stopPropagation();
200
- handleRemove(item);
201
- }}
202
- >
203
- <X className="h-3 w-3" />
204
- </button>
205
- )}
206
- </div>
207
- ))}
208
- </div>
209
- </PopoverContent>
210
- </Popover>
211
- )}
212
- </span>
213
- );
214
- };
215
-
216
-
217
- // src/variants/select-utils.ts (or wherever you keep small helpers)
218
-
219
- export type SelectPrimitive = string | number;
220
-
221
- /**
222
- * Remove a single value from a selection array.
223
- *
224
- * - Works even if the selection is undefined/null.
225
- * - Compares using String() so "1" and 1 are treated consistently.
226
- */
227
- export function removeSelectValue<T extends SelectPrimitive>(
228
- current: readonly T[] | undefined | null,
229
- valueToRemove: T
230
- ): T[] {
231
- if (!current || current.length === 0) return [];
232
-
233
- const target = String(valueToRemove);
234
-
235
- return current.filter((v) => String(v) !== target);
236
- }
@@ -1,75 +0,0 @@
1
- // src/variants/index.ts
2
-
3
- import {
4
- registerVariant as _register,
5
- getVariant as _get,
6
- listVariants as _list,
7
- } from "@/variants/registry";
8
- import type {
9
- VariantKey,
10
- VariantModule,
11
- VariantValueFor,
12
- VariantPropsFor,
13
- } from "@/schema/variant";
14
- import { textVariant } from "@/variants/core/text";
15
- import { numberVariant } from "./core/number";
16
- import { PhoneVariantModule } from "./core/phone";
17
- import { ColorVariantModule } from "./core/color";
18
- import passwordVariant from "./core/password";
19
- import { dateVariant } from "./core/date";
20
- import { chipVariant } from "./core/chips";
21
- import { textareaVariant } from "./core/textarea";
22
- import ToggleVariantModule from "./core/toggle";
23
- import { radioVariantModule } from "./core/radio";
24
- import { checkboxModule } from "./core/checkbox";
25
- import { selectModule } from "./core/select";
26
- import multiSelectVariantModule from "./core/multiselect";
27
- import sliderModule from './core/slider'
28
- import { keyValueModule } from "./core/keyvalue";
29
- import customVariant from "./core/custom";
30
- import treeselectModule from "./core/treeselect";
31
- import { fileManagerModule } from "./core/file";
32
-
33
- export type { VariantKey, VariantModule, VariantValueFor, VariantPropsFor };
34
- export {
35
- _register as registerVariant,
36
- _get as getVariant,
37
- _list as listVariants,
38
- };
39
- export { textVariant };
40
-
41
-
42
- const variants = [
43
- textVariant,
44
- numberVariant,
45
- PhoneVariantModule,
46
- ColorVariantModule,
47
- passwordVariant,
48
- dateVariant,
49
- chipVariant,
50
- textareaVariant,
51
- ToggleVariantModule,
52
- radioVariantModule,
53
- checkboxModule,
54
- selectModule,
55
- multiSelectVariantModule,
56
- sliderModule,
57
- keyValueModule,
58
- customVariant,
59
- treeselectModule,
60
- fileManagerModule
61
- ]
62
-
63
- /**
64
- * Register all core/built-in variants.
65
- *
66
- * Hosts can call this once at bootstrap:
67
- *
68
- * import { registerCoreVariants } from "@timeax/form-palette/variants";
69
- * registerCoreVariants();
70
- */
71
- export function registerCoreVariants(): void {
72
- variants.forEach(item => _register(item as any))
73
- }
74
-
75
- registerCoreVariants();
@@ -1,38 +0,0 @@
1
- // src/variants/registry.ts
2
-
3
- import type { VariantKey, VariantModule } from "@/schema/variant";
4
-
5
- /**
6
- * Internal storage for registered variants.
7
- */
8
- const registry = new Map<VariantKey, VariantModule<any>>();
9
-
10
- /**
11
- * Register (or overwrite) a variant module.
12
- *
13
- * Typically called from presets, e.g.:
14
- *
15
- * registerVariant(textVariant);
16
- * registerVariant(numberVariant);
17
- */
18
- export function registerVariant<K extends VariantKey>(
19
- module: VariantModule<K>
20
- ): void {
21
- registry.set(module.variant, module as VariantModule<any>);
22
- }
23
-
24
- /**
25
- * Look up a variant module by key.
26
- */
27
- export function getVariant<K extends VariantKey>(
28
- key: K
29
- ): VariantModule<K> | undefined {
30
- return registry.get(key) as VariantModule<K> | undefined;
31
- }
32
-
33
- /**
34
- * List all registered variant modules.
35
- */
36
- export function listVariants(): VariantModule<VariantKey>[] {
37
- return Array.from(registry.values()) as VariantModule<VariantKey>[];
38
- }
File without changes
@@ -1,126 +0,0 @@
1
- // src/variants/shared.ts
2
-
3
- import React from "react";
4
-
5
- /**
6
- * Size hint for field variants.
7
- *
8
- * Presets can interpret these however they like (font size, padding, etc.).
9
- */
10
- export type FieldSize = "sm" | "md" | "lg";
11
-
12
- /**
13
- * Density hint for field variants.
14
- *
15
- * - "compact" → tight vertical spacing
16
- * - "comfortable" → default spacing
17
- * - "loose" → extra breathing room
18
- */
19
- export type FieldDensity = "compact" | "comfortable" | "loose";
20
-
21
- /**
22
- * Logical source of a change event.
23
- *
24
- * Variants and utilities can tag changes to help the host reason
25
- * about where a value came from.
26
- */
27
- export type ChangeSource =
28
- | "variant"
29
- | "paste"
30
- | "programmatic"
31
- | "util"
32
- | (string & {}); // allow custom tags
33
-
34
- /**
35
- * Additional context passed along with value changes.
36
- */
37
- export interface ChangeDetail<TMeta = unknown, TRaw = unknown> {
38
- /**
39
- * Logical source for this change.
40
- */
41
- source: ChangeSource;
42
-
43
- /**
44
- * Optional raw input that produced this value.
45
- *
46
- * Example: original keyboard input or pasted string.
47
- */
48
- raw?: TRaw;
49
-
50
- nativeEvent?: React.SyntheticEvent;
51
- /**
52
- * Variant-specific metadata (e.g. cursor position).
53
- */
54
- meta?: TMeta;
55
- }
56
-
57
- /**
58
- * Base props shared by all variant components.
59
- *
60
- * Each variant module will extend this with its own props type.
61
- */
62
- export interface VariantBaseProps<TValue> {
63
- /**
64
- * Current logical value for this field.
65
- */
66
- value?: TValue | undefined;
67
-
68
- /**
69
- * Called whenever the variant wants to update the value.
70
- *
71
- * The detail payload describes where the change came from.
72
- */
73
- onValue?(value: TValue | undefined, detail?: ChangeDetail): void;
74
-
75
- /**
76
- * State flags.
77
- */
78
- disabled?: boolean;
79
- defaultValue?: TValue;
80
- readOnly?: boolean;
81
- required?: boolean;
82
-
83
- alias?: string;
84
- main?: boolean;
85
- /**
86
- * Current error message for this field, if any.
87
- */
88
- error?: string;
89
-
90
- /**
91
- * Size & density hints.
92
- *
93
- * Variants are free to ignore these, but presets (e.g. Shadcn)
94
- * will typically honour them.
95
- */
96
- size?: FieldSize;
97
- density?: FieldDensity;
98
- }
99
-
100
- export interface Extras {
101
- trailingIcons?: React.ReactNode[];
102
- leadingIcons?: React.ReactNode[];
103
- icon?: React.ReactNode;
104
- iconGap?: number;
105
- trailingIconSpacing?: number;
106
- leadingIconSpacing?: number;
107
- trailingControl?: React.ReactNode;
108
- leadingControl?: React.ReactNode;
109
- /**
110
- * Optional className applied to the container that wraps the leading control.
111
- * This does not affect the control node itself, only the wrapper div.
112
- */
113
- leadingControlClassName?: string;
114
- /**
115
- * Optional className applied to the container that wraps the trailing control.
116
- * This does not affect the control node itself, only the wrapper div.
117
- */
118
- trailingControlClassName?: string;
119
- px?: number;
120
- py?: number
121
- pb?: number;
122
- pe?: number;
123
- ps?: number;
124
- }
125
-
126
- export type ExtraFieldProps<Props> = Extras & Props;
package/tsconfig.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "declaration": true,
6
- "declarationMap": true,
7
- "sourceMap": true,
8
- "rootDir": "src",
9
- "jsx": "react-jsx"
10
- },
11
- "include": [
12
- "src"
13
- ]
14
- }