@llmnative/react 1.43.0 → 1.45.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.
@@ -113,6 +113,10 @@ export interface I18nDict {
113
113
  gallery: {
114
114
  selectItem: string;
115
115
  };
116
+ sortableList: {
117
+ handle: string;
118
+ moved: string;
119
+ };
116
120
  crop: {
117
121
  enableCrop: string;
118
122
  variants: string;
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { type ListCardProps } from './ListCard';
3
+ /** What a card of the list shows: the content of a compact ListCard. */
4
+ export type SortableListCard = Pick<ListCardProps, 'title' | 'description' | 'meta' | 'badge' | 'icon' | 'trailing' | 'active' | 'disabled'>;
5
+ export type SortableListReorderMeta<TItem> = {
6
+ fromIndex: number;
7
+ toIndex: number;
8
+ item: TItem;
9
+ };
10
+ export interface SortableListProps<TItem> {
11
+ /** The items, in their order. */
12
+ items: TItem[];
13
+ /** A stable key of an item. */
14
+ getKey: (item: TItem) => string;
15
+ /** The card of an item. */
16
+ renderItem: (item: TItem, index: number) => SortableListCard;
17
+ /** The items in their new order, after a drag or a key press on a handle. */
18
+ onReorder?: (items: TItem[], meta: SortableListReorderMeta<TItem>) => void;
19
+ /** The name of the list, for assistive technologies. */
20
+ label?: string;
21
+ /** Shows the position of each item (1, 2, 3…) before its card. */
22
+ numbered?: boolean;
23
+ /** No reordering: the handles are left out. */
24
+ disabled?: boolean;
25
+ /** What the list shows without items. */
26
+ emptyState?: React.ReactNode;
27
+ className?: string;
28
+ itemClassName?: string;
29
+ cardClassName?: string;
30
+ }
31
+ /** `items` with the one at `from` moved to `to`. */
32
+ export declare function moveItem<TItem>(items: readonly TItem[], from: number, to: number): TItem[];
33
+ /**
34
+ * A list of compact cards in an order the person chooses (CR-120): each card is dragged by its handle, or
35
+ * moved with the arrow keys on it; `onReorder` gets the new order. A screen reader hears where it went.
36
+ */
37
+ export default function SortableList<TItem>({ items, getKey, renderItem, onReorder, label, numbered, disabled, emptyState, className, itemClassName, cardClassName, }: SortableListProps<TItem>): React.JSX.Element | null;
@@ -61,6 +61,8 @@ export * from './ui/fields/ContextMenu';
61
61
  export { default as Menu } from './blocks/Menu';
62
62
  export { default as ListCard } from './blocks/ListCard';
63
63
  export type { ListCardProps } from './blocks/ListCard';
64
+ export { default as SortableList, moveItem } from './blocks/SortableList';
65
+ export type { SortableListProps, SortableListCard, SortableListReorderMeta } from './blocks/SortableList';
64
66
  export { default as SideNav } from './blocks/SideNav';
65
67
  export type { SideNavProps, SideNavItemDef } from './blocks/SideNav';
66
68
  export { default as Form, useFormContext } from './widgets/Form';
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { AIModelPricing } from '../../providers/ai/AIProvider';
3
+ import { type BadgeType } from '../ui/Badge';
3
4
  import { type EditorCommand } from '../ui/fields/ContextMenu';
4
5
  /**
5
6
  * Chatbot — l'input/composer AI condiviso, estratto da `Prompt` (CR-071): textarea,
@@ -46,11 +47,18 @@ export interface ChatbotModelOption {
46
47
  /** Section the option is listed under (e.g. its provider). When any option has one, the
47
48
  * picker renders one sticky header per group, in order of first appearance. */
48
49
  group?: string;
50
+ /** A badge on the right of the header of its group (CR-121), e.g. how the group is paid; the
51
+ * first option of a group that has one gives it. */
52
+ groupBadge?: {
53
+ label: string;
54
+ variant?: BadgeType;
55
+ };
49
56
  }
50
57
  /** Consecutive-or-not options sharing a `group` end up in one section, keeping the order in
51
58
  * which each group first appears; options without a group form an unnamed leading section. */
52
59
  export declare const groupModelOptions: (options: ChatbotModelOption[]) => Array<{
53
60
  group?: string;
61
+ badge?: ChatbotModelOption["groupBadge"];
54
62
  options: ChatbotModelOption[];
55
63
  }>;
56
64
  export declare const isFreeModelOption: (option: ChatbotModelOption) => boolean;
package/llms-full.txt CHANGED
@@ -1022,6 +1022,28 @@ e lasciano il menu aperto salvo `closeOnClick`.
1022
1022
  | `onClick` | `(e) => void` |
1023
1023
  | Classi CSS: `titleClassName`, `descriptionClassName`, `metaClassName`, `badgeClassName`, `leadingClassName`, `bodyClassName`, `headerClassName`, `trailingClassName`, `footerClassName` | `string` |
1024
1024
 
1025
+ **SortableList (CR-120):** card compatte (ListCard) in un ordine che la persona sceglie: le trascina per la
1026
+ maniglia, o con le frecce su/giù sulla maniglia; l'annuncio della nuova posizione va agli screen reader.
1027
+ ```tsx
1028
+ <SortableList
1029
+ items={accounts}
1030
+ getKey={(a) => a.id}
1031
+ label="Account"
1032
+ numbered
1033
+ onReorder={(next, { fromIndex, toIndex, item }) => setAccounts(next)}
1034
+ renderItem={(a) => ({ title: a.email, meta: a.added, badge: <Badge variant="success">Disponibile</Badge>, trailing: <ActionButton icon="trash-2" … /> })}
1035
+ emptyState={<p>Nessun account</p>}
1036
+ />
1037
+ moveItem(['a', 'b', 'c'], 0, 2) // ['b', 'c', 'a']
1038
+ ```
1039
+ | Prop | Tipo |
1040
+ |---|---|
1041
+ | `items` / `getKey` | `TItem[]` / `(item) => string` |
1042
+ | `renderItem` | `(item, index) => SortableListCard` (`title`, `description`, `meta`, `badge`, `icon`, `trailing`, `active`, `disabled` di ListCard) |
1043
+ | `onReorder` | `(items, { fromIndex, toIndex, item }) => void`; senza, nessuna maniglia |
1044
+ | `label` / `numbered` / `disabled` / `emptyState` | `string` / `boolean` / `boolean` / `ReactNode` |
1045
+ | Classi CSS: `className`, `itemClassName`, `cardClassName` | `string` |
1046
+
1025
1047
  **Dropdown:**
1026
1048
  | Prop | Tipo |
1027
1049
  |---|---|
@@ -1128,6 +1150,8 @@ const catalog = getAIModelCatalog() // modelli disponibili
1128
1150
  // non trovato (il modello resta in lista). isFreeAIModel(m) → input e output a 0.
1129
1151
  // Il model picker di Prompt/Chatbot mostra "$in / $out", evidenzia i free, segnala i mancanti,
1130
1152
  // e raggruppa per provider (ChatbotModelOption.group = providerLabel) con header sticky.
1153
+ // CR-121: il pulsante mostra la `label` del modello scelto (non il suo valore); `groupBadge: { label, variant? }`
1154
+ // su un'opzione mette un Badge a destra nell'header del suo gruppo (es. Abbonamento / A consumo).
1131
1155
 
1132
1156
  // Provider adapter restituito da useAIProvider()
1133
1157
  const text = await provider.fetch("Scrivi un titolo per: {keyword}", { keyword: "React" })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llmnative/react",
3
- "version": "1.43.0",
3
+ "version": "1.45.0",
4
4
  "description": "LLM-native React framework for deterministic UI generation. Data-driven by default, schema-driven optional. Ultra-low token consumption — built for AI agents, not just humans.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",