laif-ds 0.2.47 → 0.2.49

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 (35) hide show
  1. package/dist/_virtual/index2.js +2 -5
  2. package/dist/_virtual/index3.js +5 -2
  3. package/dist/agent-docs/components/AppForm.md +66 -1
  4. package/dist/agent-docs/components/AsyncSelect.md +94 -103
  5. package/dist/components/kanban.js +544 -0
  6. package/dist/components/ui/app-form.js +76 -44
  7. package/dist/components/ui/app-kanban.js +157 -0
  8. package/dist/components/ui/app-select.js +100 -87
  9. package/dist/components/ui/async-select.js +264 -278
  10. package/dist/index.d.ts +84 -29
  11. package/dist/index.js +77 -75
  12. package/dist/node_modules/@radix-ui/react-alert-dialog/dist/index.js +1 -1
  13. package/dist/node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot/dist/index.js +12 -0
  14. package/dist/node_modules/@radix-ui/react-collection/dist/index.js +1 -1
  15. package/dist/node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot/dist/index.js +50 -0
  16. package/dist/node_modules/@radix-ui/react-dialog/dist/index.js +1 -1
  17. package/dist/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot/dist/index.js +50 -0
  18. package/dist/node_modules/@radix-ui/react-menu/dist/index.js +1 -1
  19. package/dist/node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot/dist/index.js +50 -0
  20. package/dist/node_modules/@radix-ui/react-popover/dist/index.js +1 -1
  21. package/dist/node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot/dist/index.js +50 -0
  22. package/dist/node_modules/@radix-ui/react-primitive/dist/index.js +1 -1
  23. package/dist/node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot/dist/index.js +50 -0
  24. package/dist/node_modules/@radix-ui/react-select/dist/index.js +1 -1
  25. package/dist/node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot/dist/index.js +50 -0
  26. package/dist/node_modules/@radix-ui/react-slot/dist/index.js +47 -44
  27. package/dist/node_modules/@radix-ui/react-tooltip/dist/index.js +1 -1
  28. package/dist/node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot/dist/index.js +12 -0
  29. package/dist/node_modules/eventemitter3/index.js +1 -1
  30. package/dist/node_modules/recharts/es6/util/Events.js +1 -1
  31. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +536 -502
  32. package/dist/node_modules/use-sync-external-store/shim/index.js +1 -1
  33. package/dist/styles.css +1 -1
  34. package/dist/styles.v3.css +1 -1
  35. package/package.json +4 -4
@@ -1,8 +1,5 @@
1
1
  "use client";
2
- import { getDefaultExportFromCjs as e } from "./_commonjsHelpers.js";
3
- import { __require as t } from "../node_modules/eventemitter3/index2.js";
4
- var r = t();
5
- const m = /* @__PURE__ */ e(r);
2
+ var e = { exports: {} };
6
3
  export {
7
- m as default
4
+ e as __module
8
5
  };
@@ -1,5 +1,8 @@
1
1
  "use client";
2
- var e = { exports: {} };
2
+ import { getDefaultExportFromCjs as e } from "./_commonjsHelpers.js";
3
+ import { __require as t } from "../node_modules/eventemitter3/index2.js";
4
+ var r = t();
5
+ const m = /* @__PURE__ */ e(r);
3
6
  export {
4
- e as __module
7
+ m as default
5
8
  };
@@ -22,7 +22,9 @@ export interface AppFormItem {
22
22
  | "datepicker"
23
23
  | "radio"
24
24
  | "switch"
25
- | "slider"; // Field type
25
+ | "slider"
26
+ | "async"
27
+ | "async-multiple"; // Field type
26
28
  name: string; // Field name (used for form state and validation)
27
29
  inputType?: string; // HTML input type for "input" component (e.g. "text", "email", "password", "number")
28
30
  defaultValue?: string | boolean | number | string[] | Date | number[]; // Initial value
@@ -34,6 +36,15 @@ export interface AppFormItem {
34
36
  min?: number; // Minimum value for slider
35
37
  max?: number; // Maximum value for slider
36
38
  step?: number; // Step value for slider
39
+ fetcher?: (query?: string) => Promise<any[]>; // Async select data loader
40
+ renderOptionItem?: (option: any) => React.ReactNode; // Customize render of async option
41
+ resolveOptionValue?: (option: any) => string; // Value extractor for async option
42
+ renderSelectedValue?: (option: any) => React.ReactNode; // Customize render of selected async option
43
+ initialOptions?: any[]; // Optional cache for async select hydration
44
+ notFound?: React.ReactNode;
45
+ noResultsMessage?: string;
46
+ debounce?: number;
47
+ clearable?: boolean;
37
48
  }
38
49
  ```
39
50
 
@@ -116,6 +127,8 @@ export function SubmitInsideVsOutside() {
116
127
 
117
128
  ### input
118
129
 
130
+ Standard text input field
131
+
119
132
  Standard text input field. When `component: "input"`, you can use the `inputType` property to control the underlying HTML input type (e.g. `"text"`, `"email"`, `"password"`, `"number"`, `"url"`).
120
133
 
121
134
  For a complete showcase of different input types, see the Storybook story `UI/AppForm/DifferentInputTypes`.
@@ -132,6 +145,58 @@ Single selection dropdown using AppSelect
132
145
 
133
146
  Multiple selection dropdown using AppSelect with `multiple` prop
134
147
 
148
+ ### async / async-multiple
149
+
150
+ Use `AsyncSelect` for server-side driven selects. `async` gestisce un valore singolo, `async-multiple` un array di stringhe. Richiede i seguenti prop sull'item:
151
+
152
+ - `fetcher`: funzione che restituisce `Promise<Option[]>`
153
+ - `renderOptionItem`, `resolveOptionValue`, `renderSelectedValue`: per gestire il rendering e la selezione
154
+ - `initialOptions` (opzionale ma consigliata) per idratare i valori preimpostati
155
+ - `defaultValue` va impostato nei `defaultValues` di React Hook Form
156
+
157
+ Esempio:
158
+
159
+ ```tsx
160
+ const items: AppFormItem[] = [
161
+ {
162
+ component: "async",
163
+ name: "business",
164
+ label: "Business (async)",
165
+ placeholder: "Seleziona un business",
166
+ fetcher: mockAsyncSelectFetcher,
167
+ initialOptions: asyncSelectMockUsers,
168
+ renderOptionItem: (user) => (
169
+ <div>
170
+ <strong>{user.name}</strong>
171
+ <span className="text-muted-foreground text-xs">{user.email}</span>
172
+ </div>
173
+ ),
174
+ resolveOptionValue: (user) => user.id,
175
+ renderSelectedValue: (user) => user.name,
176
+ },
177
+ {
178
+ component: "async-multiple",
179
+ name: "team",
180
+ label: "Team (async)",
181
+ placeholder: "Seleziona i membri",
182
+ fetcher: mockAsyncSelectFetcher,
183
+ initialOptions: asyncSelectMockUsers,
184
+ renderOptionItem: (user) => user.name,
185
+ resolveOptionValue: (user) => user.id,
186
+ renderSelectedValue: (user) => user.name,
187
+ },
188
+ ];
189
+
190
+ const form = useForm({
191
+ defaultValues: {
192
+ business: asyncSelectMockUsers[0]?.id ?? "",
193
+ team: asyncSelectMockUsers.slice(0, 2).map((u) => u.id),
194
+ },
195
+ });
196
+ ```
197
+
198
+ Ricorda che il fetch parte solo quando il menu è aperto; eventuali valori iniziali devono essere già presenti in `initialOptions`.
199
+
135
200
  ### datepicker
136
201
 
137
202
  Date picker component with optional range selection via `calendarRange`
@@ -1,102 +1,94 @@
1
- # AsyncSelect
2
-
3
- ## Overview
4
-
5
- Generic async select with search input, popover list, optional preload and multiple selection. Fully render-prop driven for option content and value extraction.
6
-
7
- ---
8
-
9
- ## Props
10
-
11
- | Prop | Type | Default | Description |
12
- | ----------------- | -------------------------------------------- | ----------- | ----------- |
13
- | `fetcher` | `(query?: string) => Promise<T[]>` | **required**| Async loader for options. Called on open and on search. |
14
- | `preload` | `boolean` | `false` | Preload all data once; then client-filter using `filterFn`. |
15
- | `filterFn` | `(option: T, query: string) => boolean` | `undefined` | Custom client-side filter when `preload=true`. |
16
- | `renderOption` | `(option: T) => React.ReactNode` | **required**| How to render each option row. |
17
- | `getOptionValue` | `(option: T) => string` | **required**| Extract option id. |
18
- | `getDisplayValue` | `(option: T) => React.ReactNode` | **required**| Display value for trigger. |
19
- | `multiple` | `boolean` | `false` | Enable multi-selection. Controls `value` type. |
20
- | `value` | `string | string[]` | `undefined` | Controlled value. |
21
- | `onChange` | `(value: string | string[]) => void` | `undefined` | Change callback. |
22
- | `label` | `string | React.ReactNode` | `undefined` | Optional label above. |
23
- | `labelClassName` | `string` | `undefined` | Label classes. |
24
- | `placeholder` | `string` | `"Select..."` | Placeholder when empty. |
25
- | `disabled` | `boolean` | `false` | Disable trigger and input. |
26
- | `width` | `string | number | "auto"` | `200px` | Popover width; `auto` matches trigger width. |
27
- | `triggerClassName`| `string` | `undefined` | Extra classes for trigger button. |
28
- | `noResultsMessage`| `string` | `undefined` | Message when list is empty. |
29
- | `clearable` | `boolean` | `true` | Show clear icon when a value is set. |
30
- | `size` | `"sm" | "default" | "lg"` | `"default"` | Trigger size. |
31
- | `loadingSkeleton` | `React.ReactNode` | `undefined` | Custom loading skeleton list. |
32
- | `notFound` | `React.ReactNode` | `undefined` | Custom empty content. |
33
-
34
- ---
35
-
36
- ## Behavior
37
-
38
- - **Search**: Debounced input (0ms when `preload=true`, 300ms otherwise).
39
- - **Caching**: Results cached by query; reused when re-typing.
40
- - **Multiple**: Renders selected count or first label; supports checkbox UI per item.
41
- - **Clear**: Built-in clear icon (uses DS `Icon`), respects `clearable`.
42
- - **A11y**: Trigger focus ring and keyboard navigation via `cmdk`.
43
-
44
- ---
45
-
46
- ## Examples
47
-
48
- ### Preloaded
49
-
50
- ```tsx
51
- import * as React from "react";
52
- import { AsyncSelect } from "laif-ds";
53
-
54
- type User = { id: number; name: string; email: string };
55
-
56
- async function fetchUsers(query?: string): Promise<User[]> {
57
- const res = await fetch("https://jsonplaceholder.typicode.com/users");
58
- const data: User[] = await res.json();
59
- if (!query) return data;
60
- const q = query.toLowerCase();
61
- return data.filter((u) => u.name.toLowerCase().includes(q));
62
- }
63
-
64
- export function PreloadedUsers() {
65
- const [value, setValue] = React.useState("");
66
- return (
67
- <AsyncSelect<User>
68
- preload
69
- fetcher={fetchUsers}
70
- value={value}
71
- onChange={setValue}
72
- renderOption={(u) => (
73
- <div className="truncate">
74
- <div className="font-medium">{u.name}</div>
75
- <div className="text-d-muted-foreground text-xs">{u.email}</div>
76
- </div>
77
- )}
78
- getOptionValue={(u) => String(u.id)}
79
- getDisplayValue={(u) => u.name}
80
- placeholder="Select a user..."
81
- width="300px"
82
- />
83
- );
84
- }
85
- ```
86
-
87
- ### Multiple with Steps
88
-
89
- ```tsx
90
- import * as React from "react";
91
- import { AsyncSelect } from "laif-ds";
92
-
1
+ # AsyncSelect
2
+
3
+ ## Overview
4
+
5
+ Generic async select with search input, popover list, server-side filtering, and optional multiple selection. Fully render-prop driven for option content and value extraction.
6
+
7
+ ---
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --------------------- | ------------------------------------- | ------------- | ----------------------------------------------------------------------------------- |
13
+ | `fetcher` | `(query?: string) => Promise<T[]>` | **required** | Async loader for options. Called on open and on search. |
14
+ | `renderOptionItem` | `(option: T) => React.ReactNode` | **required** | Custom renderer for each menu row. |
15
+ | `resolveOptionValue` | `(option: T) => string` | **required** | Returns the unique ID stored in `value`. |
16
+ | `renderSelectedValue` | `(option: T) => React.ReactNode` | **required** | Content shown in the trigger when selected. |
17
+ | `multiple` | `boolean` | `false` | Enables multi-selection and switches `value` to `string[]`. |
18
+ | `value` | `string \| string[] \| undefined` | `undefined` | Controlled value. |
19
+ | `onChange` | `(value: string \| string[]) => void` | `undefined` | Emits the next value when the selection changes. |
20
+ | `label` | `string \| React.ReactNode` | `undefined` | Optional label rendered above the trigger. |
21
+ | `placeholder` | `string` | `"Select..."` | Placeholder when no value is selected. |
22
+ | `disabled` | `boolean` | `false` | Disables trigger and input interactions. |
23
+ | `className` | `string` | `undefined` | Extra classes for the trigger button. |
24
+ | `wrpClassName` | `string` | `undefined` | Classes applied to the outer wrapper (use this to control width, e.g. `w-[200px]`). |
25
+ | `noResultsMessage` | `string` | `undefined` | Message shown inside the default empty state. |
26
+ | `clearable` | `boolean` | `true` | Shows the clear icon when a value is present. |
27
+ | `size` | `"sm" \| "default" \| "lg"` | `"default"` | Trigger size variant. |
28
+ | `notFound` | `React.ReactNode` | `undefined` | Custom fallback when there are no options. |
29
+ | `initialOptions` | `T[]` | `undefined` | Prefills cache/selection with a known options list. |
30
+ | `debounce` | `number` | `300` | Debounce delay (ms) before calling `fetcher`. |
31
+
32
+ ---
33
+
34
+ ## Behavior
35
+
36
+ - **Search**: Debounced input (300ms) that always hits the provided `fetcher`.
37
+ - **Caching**: Results cached by query; reused when re-typing.
38
+ - **Multiple**: Renders selected count or first label; supports checkbox UI per item.
39
+ - **Clear**: Built-in clear icon (uses DS `Icon`), respects `clearable`.
40
+ - **A11y**: Trigger focus ring and keyboard navigation via `cmdk`.
41
+
42
+ ---
43
+
44
+ ## Examples
45
+
46
+ ### Multiple with Steps
47
+
48
+ ```tsx
49
+ import * as React from "react";
50
+ import { AsyncSelect } from "laif-ds";
51
+
52
+ type Tag = { id: string; label: string };
53
+ const tags: Tag[] = [
54
+ { id: "react", label: "React" },
55
+ { id: "nextjs", label: "Next.js" },
56
+ { id: "tailwind", label: "Tailwind" },
57
+ ];
58
+
59
+ export function MultipleTags() {
60
+ const [value, setValue] = React.useState<string[]>([]);
61
+ const fetcher = async (q?: string) =>
62
+ !q ? tags : tags.filter((t) => t.label.toLowerCase().includes(q!.toLowerCase()));
63
+ return (
64
+ <AsyncSelect<Tag>
65
+ multiple
66
+ fetcher={fetcher}
67
+ value={value}
68
+ onChange={setValue}
69
+ renderOptionItem={(t) => t.label}
70
+ resolveOptionValue={(t) => t.id}
71
+ renderSelectedValue={(t) => t.label}
72
+ placeholder="Select tags..."
73
+ wrpClassName="w-[280px]"
74
+ />
75
+ );
76
+ }
77
+
78
+ ---
79
+
80
+ ## Notes
81
+
82
+ - **Trigger width**: Use `width="auto"` to match trigger width; or a fixed `number|string`.
83
+ - **Filtering**: Always handled server-side via `fetcher`, with cached responses per query.
84
+ - **Theming**: Uses DS token classes across trigger, list, and states.
93
85
  type Tag = { id: string; label: string };
94
86
  const tags: Tag[] = [
95
87
  { id: "react", label: "React" },
96
88
  { id: "nextjs", label: "Next.js" },
97
89
  { id: "tailwind", label: "Tailwind" },
98
90
  ];
99
-
91
+
100
92
  export function MultipleTags() {
101
93
  const [value, setValue] = React.useState<string[]>([]);
102
94
  const fetcher = async (q?: string) =>
@@ -115,13 +107,12 @@
115
107
  />
116
108
  );
117
109
  }
118
- ```
119
-
120
- ---
121
-
122
- ## Notes
123
-
124
- - **Trigger width**: Use `width="auto"` to match trigger width; or a fixed `number|string`.
125
- - **Filtering**: For big datasets prefer server search (no `preload`); for small datasets prefer `preload` + `filterFn`.
126
- - **Theming**: Uses DS token classes across trigger, list, and states.
127
-
110
+ ```
111
+
112
+ ---
113
+
114
+ ## Notes
115
+
116
+ - **Trigger width**: Use `width="auto"` to match trigger width; or a fixed `number|string`.
117
+ - **Filtering**: Always handled server-side via `fetcher`, with cached responses per query.
118
+ - **Theming**: Uses DS token classes across trigger, list, and states.