@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,230 +0,0 @@
1
- // src/input/input-layout-graph.ts
2
-
3
- import * as React from "react";
4
-
5
- import type {
6
- FieldLayoutConfig,
7
- FieldOrdering,
8
- FieldRootId,
9
- FieldSlotId,
10
- RelativeRootsMap,
11
- SlotPlacement,
12
- } from "@/schema/input-field";
13
-
14
- /**
15
- * Helper slots are all non-root slots:
16
- * - sublabel
17
- * - description
18
- * - helpText
19
- * - errorText
20
- */
21
- export type HelperSlotId = Exclude<FieldSlotId, FieldRootId>;
22
-
23
- export interface HelperSlot {
24
- id: HelperSlotId;
25
- root: FieldRootId;
26
- placement: SlotPlacement;
27
- content: React.ReactNode;
28
- }
29
-
30
- /**
31
- * Accessor for a (root, placement) group.
32
- *
33
- * - `slots()` gives you the concrete HelperSlot[] (possibly empty).
34
- * - `render(fn)` calls `fn(slots)` only if there are slots,
35
- * otherwise returns null (so React renders nothing).
36
- */
37
- export interface SlotAccessor {
38
- root: FieldRootId;
39
- placement: SlotPlacement;
40
-
41
- /**
42
- * Concrete list of slots for this root + placement.
43
- * May be an empty array.
44
- */
45
- slots(): HelperSlot[];
46
-
47
- /**
48
- * Render this group.
49
- *
50
- * If no slots are present, returns null so nothing is rendered.
51
- *
52
- * Example:
53
- * graph
54
- * .getSlotsFor("input", "below")
55
- * .render((slots) =>
56
- * slots.map((slot) =>
57
- * renderHelperSlot("input", slot, classes)
58
- * )
59
- * );
60
- */
61
- render(
62
- renderFn: (slots: HelperSlot[]) => React.ReactNode
63
- ): React.ReactNode;
64
- }
65
-
66
- /**
67
- * Layout graph for helpers.
68
- */
69
- export interface LayoutGraph {
70
- helperSlots: HelperSlot[];
71
-
72
- /**
73
- * Get a slot accessor for a given root + placement.
74
- */
75
- getSlotsFor(
76
- root: FieldRootId,
77
- placement: SlotPlacement
78
- ): SlotAccessor;
79
- }
80
-
81
- /**
82
- * Default root attachment for helpers when layout.relativeRoots
83
- * does not specify anything.
84
- */
85
- const defaultRelativeRoots: RelativeRootsMap = {
86
- sublabel: "label",
87
- description: "input",
88
- helpText: "input",
89
- errorText: "input",
90
- };
91
-
92
- /**
93
- * Default relative ordering per root when layout.ordering
94
- * is not provided.
95
- *
96
- * Only governs *priority* when multiple helpers share the same
97
- * root + placement. It does not decide the placement itself.
98
- */
99
- const defaultOrdering: FieldOrdering = {
100
- label: ["sublabel"],
101
- input: ["errorText", "description", "helpText"],
102
- };
103
-
104
- function defaultPlacementFor(id: HelperSlotId): SlotPlacement {
105
- if (id === "sublabel") {
106
- // Typical: small label text to the right of the main label
107
- return "right";
108
- }
109
- // For description/help/error, "below" the root is the usual default
110
- return "below";
111
- }
112
-
113
- interface BuildLayoutGraphArgs {
114
- layout: FieldLayoutConfig;
115
- /**
116
- * Raw contents for each helper slot.
117
- * Undefined/null means "no slot".
118
- */
119
- sublabel?: React.ReactNode;
120
- description?: React.ReactNode;
121
- helpText?: React.ReactNode;
122
- errorText?: React.ReactNode;
123
- tags?: React.ReactNode;
124
- }
125
-
126
- /**
127
- * Build a layout graph for helper slots given:
128
- * - the effective layout (after variant defaults + overrides)
129
- * - the actual content for each slot
130
- */
131
- export function buildLayoutGraph(
132
- args: BuildLayoutGraphArgs
133
- ): LayoutGraph {
134
- const { layout, sublabel, description, helpText, errorText, tags } = args;
135
-
136
- const relativeRoots: RelativeRootsMap = {
137
- ...defaultRelativeRoots,
138
- ...(layout.relativeRoots ?? {}),
139
- };
140
-
141
- const ordering: FieldOrdering = {
142
- ...defaultOrdering,
143
- ...(layout.ordering ?? {}),
144
- };
145
-
146
- const helperSlots: HelperSlot[] = [];
147
-
148
- const pushSlot = (
149
- id: HelperSlotId,
150
- content: React.ReactNode | undefined,
151
- placement: SlotPlacement | undefined
152
- ) => {
153
- if (content === undefined || content === null) return;
154
-
155
- const root: FieldRootId =
156
- relativeRoots[id] ??
157
- (id === "sublabel" ? "label" : "input");
158
-
159
- const effectivePlacement: SlotPlacement =
160
- placement ?? defaultPlacementFor(id);
161
-
162
- if (effectivePlacement === "hidden") return;
163
-
164
- helperSlots.push({
165
- id,
166
- root,
167
- placement: effectivePlacement,
168
- content,
169
- });
170
- };
171
-
172
- pushSlot("sublabel", sublabel, layout.sublabelPlacement);
173
- pushSlot("description", description, layout.descriptionPlacement);
174
- pushSlot("helpText", helpText, layout.helpTextPlacement);
175
- pushSlot("errorText", errorText, layout.errorTextPlacement);
176
- pushSlot("tags", tags, layout.tagPlacement)
177
-
178
- function makeAccessor(
179
- root: FieldRootId,
180
- placement: SlotPlacement
181
- ): SlotAccessor {
182
- // cache per accessor so multiple .slots()/.render() calls
183
- // don't keep re-filtering
184
- let cache: HelperSlot[] | null = null;
185
-
186
- const compute = (): HelperSlot[] => {
187
- if (cache) return cache;
188
-
189
- const base = helperSlots.filter(
190
- (s) => s.root === root && s.placement === placement
191
- );
192
-
193
- const order = ordering[root] ?? [];
194
- if (!order.length) {
195
- cache = base;
196
- return cache;
197
- }
198
-
199
- cache = [...base].sort((a, b) => {
200
- const ai = order.indexOf(a.id);
201
- const bi = order.indexOf(b.id);
202
-
203
- const aRank = ai === -1 ? Number.POSITIVE_INFINITY : ai;
204
- const bRank = bi === -1 ? Number.POSITIVE_INFINITY : bi;
205
-
206
- return aRank - bRank;
207
- });
208
-
209
- return cache;
210
- };
211
-
212
- return {
213
- root,
214
- placement,
215
- slots: () => compute(),
216
- render(renderFn) {
217
- const slots = compute();
218
- if (!slots.length) return null; // nothing rendered
219
- return renderFn(slots);
220
- },
221
- };
222
- }
223
-
224
- return {
225
- helperSlots,
226
- getSlotsFor(root, placement) {
227
- return makeAccessor(root, placement);
228
- },
229
- };
230
- }
@@ -1,190 +0,0 @@
1
- // src/input/input-props.ts
2
- // noinspection DuplicatedCode
3
-
4
- import * as React from "react";
5
-
6
- import type { CoreContext, Dict } from "@/schema/core";
7
- import type { Field } from "@/schema/field";
8
- import type { FieldSize, FieldDensity, ChangeDetail } from "@/variants/shared";
9
- import type {
10
- VariantKey,
11
- VariantValueFor,
12
- VariantPropsFor,
13
- } from "@/schema/variant";
14
- import type {
15
- LabelPlacement,
16
- SublabelPlacement,
17
- DescriptionPlacement,
18
- HelpTextPlacement,
19
- ErrorTextPlacement,
20
- ValidateResult,
21
- SlotPlacement,
22
- } from "@/schema/input-field";
23
-
24
- /**
25
- * Core, variant-agnostic props for InputField.
26
- *
27
- * @template TValue Logical value type for this field. Will be refined by
28
- * variant typing (VariantValueFor<K>).
29
- */
30
- export interface InputFieldBaseProps<TValue = unknown> {
31
- // ─────────────────────────────────────────────
32
- // Identity / wiring into the core runtime
33
- // ─────────────────────────────────────────────
34
-
35
- name?: string;
36
- bind?: string;
37
- groupId?: string;
38
- shared?: string;
39
- ignore?: boolean;
40
- alias?: string
41
- main?: boolean;
42
- tags?: FieldTag[];
43
- contain?: boolean
44
-
45
- // ─────────────────────────────────────────────
46
- // Chrome / description
47
- // ─────────────────────────────────────────────
48
-
49
- label?: React.ReactNode;
50
- sublabel?: React.ReactNode;
51
- description?: React.ReactNode;
52
- helpText?: React.ReactNode;
53
-
54
- /**
55
- * Optional explicit error text to display.
56
- *
57
- * This is *visual* error copy. The actual validation state still
58
- * lives in field.error / schema / onValidate.
59
- */
60
- errorText?: React.ReactNode;
61
-
62
- /**
63
- * Placement hints for label / sublabel / description / helpText / errorText.
64
- *
65
- * These are purely layout hints; actual behaviour is implemented
66
- * by the preset / host component.
67
- */
68
- labelPlacement?: LabelPlacement;
69
- sublabelPlacement?: SublabelPlacement;
70
- descriptionPlacement?: DescriptionPlacement;
71
- helpTextPlacement?: HelpTextPlacement;
72
- errorTextPlacement?: ErrorTextPlacement;
73
- tagPlacement?: SlotPlacement
74
-
75
- // ─────────────────────────────────────────────
76
- // State flags
77
- // ─────────────────────────────────────────────
78
-
79
- required?: boolean;
80
- disabled?: boolean;
81
- readOnly?: boolean;
82
-
83
- size?: FieldSize;
84
- density?: FieldDensity;
85
-
86
- // ─────────────────────────────────────────────
87
- // Layout hooks
88
- // ─────────────────────────────────────────────
89
-
90
- inline?: boolean;
91
- fullWidth?: boolean;
92
-
93
- // ─────────────────────────────────────────────
94
- // Validation hooks
95
- // ─────────────────────────────────────────────
96
-
97
- onValidate?(
98
- value: TValue | undefined,
99
- field: Field,
100
- form: CoreContext<Dict>
101
- ): ValidateResult;
102
-
103
- /**
104
- * Per-field change hook at the InputField level.
105
- *
106
- * - `value` is what the variant is trying to set.
107
- * - `detail` comes from the variant (`ChangeDetail`).
108
- * - If you return `undefined`, the original value is used.
109
- * - If you return *anything else*, that is what will be stored
110
- * in the core (and emitted to the form).
111
- */
112
- onChange?(e: {
113
- value: TValue | undefined,
114
- preventDefault(): void;
115
- event?: React.SyntheticEvent;
116
- readonly isDefaultPrevented?: boolean;
117
- readonly detail: ChangeDetail
118
- }): void;
119
- }
120
-
121
-
122
- export type Events<TRaw, TValue, TMeta> = {
123
- onValidate?(
124
- value: TValue | undefined,
125
- field: Field,
126
- form: CoreContext<Dict>
127
- ): ValidateResult;
128
-
129
- /**
130
- * Per-field change hook at the InputField level.
131
- *
132
- * - `value` is what the variant is trying to set.
133
- * - `detail` comes from the variant (`ChangeDetail`).
134
- * - If you return `undefined`, the original value is used.
135
- * - If you return *anything else*, that is what will be stored
136
- * in the core (and emitted to the form).
137
- */
138
- onChange?(e: {
139
- value: TValue | undefined,
140
- preventDefault(): void;
141
- event?: React.SyntheticEvent;
142
- readonly isDefaultPrevented?: boolean;
143
- readonly detail: ChangeDetail<TMeta, TRaw>
144
- }): void;
145
- }
146
-
147
- /**
148
- * Public props for <InputField />.
149
- *
150
- * - `variant` selects the variant module.
151
- * - All variant-specific props are merged directly into the field props
152
- * via `VariantPropsFor<K>`.
153
- *
154
- * NOTE: this is a type alias (not an interface) so we can safely intersect
155
- * unions coming from VariantPropsFor<K> / VariantValueFor<K>.
156
- */
157
- export type InputFieldProps<K extends VariantKey = VariantKey, H = unknown> =
158
- InputFieldBaseProps<VariantValueFor<K, H>> &
159
- VariantPropsFor<K, H> &
160
- Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> & {
161
- variant: K;
162
- classes?: Partial<InputFieldClassNames>;
163
- };
164
-
165
- export interface InputFieldClassNames {
166
- root?: string;
167
- labelRow?: string;
168
- inlineRow?: string;
169
- label?: string;
170
- sublabel?: string;
171
- description?: string;
172
- helpText?: string;
173
- error?: string;
174
- group?: string;
175
- content?: string;
176
- variant?: string;
177
- inlineInputColumn?: string
178
- inlineLabelColumn?: string;
179
- required?: string;
180
- tag?: string
181
- }
182
-
183
-
184
- export interface FieldTag {
185
- label: React.ReactNode;
186
- icon?: React.ReactNode;
187
- className?: string;
188
- color?: string; // text color
189
- bgColor?: string; // background color
190
- }
@@ -1,87 +0,0 @@
1
- import { PhoneCountry } from "@/presets/shadcn-variants/phone";
2
-
3
- // e.g. src/lib/get-global-countries.ts
4
- let cachedCountries: PhoneCountry[] | null = null;
5
-
6
- const DEFAULT_COUNTRIES: PhoneCountry[] = [
7
- {
8
- code: "NG",
9
- label: "Nigeria",
10
- dial: "234",
11
- mask: "999 999 9999",
12
- flag: "πŸ‡³πŸ‡¬",
13
- },
14
- {
15
- code: "US",
16
- label: "United States",
17
- dial: "1",
18
- mask: "(999) 999-9999",
19
- flag: "πŸ‡ΊπŸ‡Έ",
20
- },
21
- {
22
- code: "GB",
23
- label: "United Kingdom",
24
- dial: "44",
25
- mask: "9999 999 999",
26
- flag: "πŸ‡¬πŸ‡§",
27
- },
28
- ];
29
-
30
- cachedCountries = DEFAULT_COUNTRIES;
31
- let validatedOnce = false;
32
-
33
- function isPhoneCountry(value: unknown): value is PhoneCountry {
34
- if (!value || typeof value !== "object") return false;
35
-
36
- const v = value as Record<string, unknown>;
37
-
38
- return (
39
- typeof v.code === "string" &&
40
- typeof v.label === "string" &&
41
- typeof v.dial === "string" &&
42
- typeof v.mask === "string"
43
- // flag is optional & can be anything React can render, so we don't
44
- // validate it beyond existence.
45
- );
46
- }
47
-
48
- export function getGlobalCountryList(): PhoneCountry[] {
49
- // If we've already validated & cached, just return it.
50
- if (cachedCountries) return cachedCountries;
51
-
52
- if (typeof window === "undefined") {
53
- cachedCountries = [];
54
- return cachedCountries;
55
- }
56
-
57
- const raw = window["form-palette"]?.countries;
58
-
59
- if (!Array.isArray(raw)) {
60
- if (!validatedOnce && process.env.NODE_ENV !== "production") {
61
- console.warn(
62
- "['form-palette'] window.'form-palette'.countries is not an array:",
63
- raw,
64
- );
65
- }
66
- validatedOnce = true;
67
- cachedCountries = [];
68
- return cachedCountries;
69
- }
70
-
71
- const result: PhoneCountry[] = [];
72
-
73
- for (const item of raw) {
74
- if (isPhoneCountry(item)) {
75
- result.push(item);
76
- } else if (process.env.NODE_ENV !== "production") {
77
- console.warn(
78
- "['form-palette'] Ignoring invalid PhoneCountry entry:",
79
- item,
80
- );
81
- }
82
- }
83
-
84
- validatedOnce = true;
85
- cachedCountries = result;
86
- return result;
87
- }
package/src/lib/utils.ts DELETED
@@ -1,6 +0,0 @@
1
- import { clsx, type ClassValue } from "clsx";
2
- import { twMerge } from "tailwind-merge";
3
-
4
- export function cn(...inputs: ClassValue[]) {
5
- return twMerge(clsx(inputs));
6
- }
File without changes
File without changes