@lastbrain/ai-ui-react 1.0.68 → 1.0.70

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 (76) hide show
  1. package/dist/components/AiChipLabel.d.ts +8 -3
  2. package/dist/components/AiChipLabel.d.ts.map +1 -1
  3. package/dist/components/AiChipLabel.js +23 -70
  4. package/dist/components/AiContextButton.d.ts +10 -2
  5. package/dist/components/AiContextButton.d.ts.map +1 -1
  6. package/dist/components/AiContextButton.js +73 -291
  7. package/dist/components/AiImageButton.d.ts +5 -1
  8. package/dist/components/AiImageButton.d.ts.map +1 -1
  9. package/dist/components/AiImageButton.js +6 -142
  10. package/dist/components/AiInput.d.ts +5 -3
  11. package/dist/components/AiInput.d.ts.map +1 -1
  12. package/dist/components/AiInput.js +13 -25
  13. package/dist/components/AiPromptPanel.d.ts.map +1 -1
  14. package/dist/components/AiPromptPanel.js +64 -212
  15. package/dist/components/AiSelect.d.ts +5 -3
  16. package/dist/components/AiSelect.d.ts.map +1 -1
  17. package/dist/components/AiSelect.js +21 -30
  18. package/dist/components/AiStatusButton.d.ts +4 -1
  19. package/dist/components/AiStatusButton.d.ts.map +1 -1
  20. package/dist/components/AiStatusButton.js +211 -676
  21. package/dist/components/AiTextarea.d.ts +4 -2
  22. package/dist/components/AiTextarea.d.ts.map +1 -1
  23. package/dist/components/AiTextarea.js +14 -26
  24. package/dist/components/LBApiKeySelector.d.ts.map +1 -1
  25. package/dist/components/LBApiKeySelector.js +5 -166
  26. package/dist/components/LBConnectButton.d.ts +4 -7
  27. package/dist/components/LBConnectButton.d.ts.map +1 -1
  28. package/dist/components/LBConnectButton.js +17 -86
  29. package/dist/components/LBSigninModal.d.ts +1 -1
  30. package/dist/components/LBSigninModal.d.ts.map +1 -1
  31. package/dist/components/LBSigninModal.js +42 -320
  32. package/dist/context/LBAuthProvider.d.ts +35 -3
  33. package/dist/context/LBAuthProvider.d.ts.map +1 -1
  34. package/dist/context/LBAuthProvider.js +2 -0
  35. package/dist/examples/AiUiPremiumShowcase.d.ts +2 -0
  36. package/dist/examples/AiUiPremiumShowcase.d.ts.map +1 -0
  37. package/dist/examples/AiUiPremiumShowcase.js +15 -0
  38. package/dist/hooks/useAiModels.d.ts.map +1 -1
  39. package/dist/hooks/useModelManagement.d.ts.map +1 -1
  40. package/dist/index.d.ts +2 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +2 -0
  43. package/dist/styles/inline.d.ts +1 -0
  44. package/dist/styles/inline.d.ts.map +1 -1
  45. package/dist/styles/inline.js +25 -129
  46. package/dist/styles.css +1268 -369
  47. package/dist/types.d.ts +3 -0
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/utils/errorHandler.d.ts +2 -2
  50. package/dist/utils/errorHandler.d.ts.map +1 -1
  51. package/dist/utils/errorHandler.js +8 -1
  52. package/dist/utils/modelManagement.d.ts +13 -10
  53. package/dist/utils/modelManagement.d.ts.map +1 -1
  54. package/dist/utils/modelManagement.js +19 -2
  55. package/package.json +2 -2
  56. package/src/components/AiChipLabel.tsx +68 -101
  57. package/src/components/AiContextButton.tsx +142 -413
  58. package/src/components/AiImageButton.tsx +29 -190
  59. package/src/components/AiInput.tsx +49 -74
  60. package/src/components/AiPromptPanel.tsx +81 -260
  61. package/src/components/AiSelect.tsx +61 -69
  62. package/src/components/AiStatusButton.tsx +496 -1327
  63. package/src/components/AiTextarea.tsx +50 -63
  64. package/src/components/LBApiKeySelector.tsx +93 -271
  65. package/src/components/LBConnectButton.tsx +39 -336
  66. package/src/components/LBSigninModal.tsx +141 -472
  67. package/src/context/LBAuthProvider.tsx +45 -6
  68. package/src/examples/AiUiPremiumShowcase.tsx +94 -0
  69. package/src/hooks/useAiModels.ts +2 -1
  70. package/src/hooks/useModelManagement.ts +2 -1
  71. package/src/index.ts +3 -0
  72. package/src/styles/inline.ts +27 -148
  73. package/src/styles.css +1268 -369
  74. package/src/types.ts +3 -0
  75. package/src/utils/errorHandler.ts +16 -3
  76. package/src/utils/modelManagement.ts +53 -15
package/dist/types.d.ts CHANGED
@@ -4,6 +4,9 @@ export type ToastType = {
4
4
  code?: string;
5
5
  };
6
6
  export type UiMode = "modal" | "drawer";
7
+ export type AiSize = "sm" | "md" | "lg";
8
+ export type AiRadius = "none" | "sm" | "md" | "lg" | "full";
9
+ export type AiVariant = "default" | "light";
7
10
  export interface BaseAiProps {
8
11
  baseUrl?: string;
9
12
  apiKeyId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AACF,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAExC,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AACF,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AACxC,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACxC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAC5D,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -6,7 +6,7 @@ export interface ParsedError {
6
6
  /**
7
7
  * Parse et uniformise la gestion des erreurs des composants AI
8
8
  */
9
- export declare function parseAIError(error: any): ParsedError;
9
+ export declare function parseAIError(error: unknown): ParsedError;
10
10
  /**
11
11
  * Interface pour la callback de gestion d'erreur uniforme
12
12
  */
@@ -23,7 +23,7 @@ export interface ErrorToastCallback {
23
23
  * @param onToast Callback externe optionnelle fournie par le parent
24
24
  * @param showInternalToast Callback interne optionnelle pour afficher un toast dans le composant
25
25
  */
26
- export declare function handleAIError(error: any, onToast?: ErrorToastCallback, showInternalToast?: (error: {
26
+ export declare function handleAIError(error: unknown, onToast?: ErrorToastCallback, showInternalToast?: (error: {
27
27
  message: string;
28
28
  code?: string;
29
29
  }) => void): void;
@@ -1 +1 @@
1
- {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/utils/errorHandler.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,GAAG,WAAW,CA8CpD;AAyFD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAClE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,GAAG,EACV,OAAO,CAAC,EAAE,kBAAkB,EAC5B,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,GACtE,IAAI,CAuBN"}
1
+ {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/utils/errorHandler.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB;AAeD;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CA8CxD;AAyFD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAClE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,kBAAkB,EAC5B,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,GACtE,IAAI,CAuBN"}
@@ -1,11 +1,18 @@
1
1
  "use client";
2
2
  import { ErrorCode } from "@lastbrain/ai-ui-core";
3
+ function isNormalizedErrorLike(value) {
4
+ if (!value || typeof value !== "object") {
5
+ return false;
6
+ }
7
+ const v = value;
8
+ return typeof v.code === "string" && typeof v.message === "string";
9
+ }
3
10
  /**
4
11
  * Parse et uniformise la gestion des erreurs des composants AI
5
12
  */
6
13
  export function parseAIError(error) {
7
14
  // Si l'erreur est déjà un objet normalisé
8
- if (error?.code && error?.message) {
15
+ if (isNormalizedErrorLike(error)) {
9
16
  return {
10
17
  message: getUserFriendlyMessage(error.code, error.message),
11
18
  code: error.code,
@@ -5,25 +5,28 @@ export interface ModelToggleOptions {
5
5
  apiKey?: string;
6
6
  baseUrl?: string;
7
7
  }
8
- /**
9
- * Active ou désactive un modèle pour l'utilisateur courant
10
- */
11
- export declare function toggleUserModel(modelId: string, isActive: boolean, options?: ModelToggleOptions): Promise<void>;
12
- /**
13
- * Récupère tous les modèles disponibles avec API key ou via proxy
14
- */
15
- export declare function getAvailableModels(options?: ModelToggleOptions): Promise<Array<{
8
+ type ModelCategory = "text" | "image" | "audio" | "video";
9
+ interface ModelInfo {
16
10
  id: string;
17
11
  name: string;
18
12
  description?: string;
19
13
  provider: string;
20
- category: "text" | "image" | "audio" | "video";
14
+ category: ModelCategory;
21
15
  isActive?: boolean;
22
16
  isPro?: boolean;
23
17
  costPer1M?: number;
24
- }>>;
18
+ }
19
+ /**
20
+ * Active ou désactive un modèle pour l'utilisateur courant
21
+ */
22
+ export declare function toggleUserModel(modelId: string, isActive: boolean, options?: ModelToggleOptions): Promise<void>;
23
+ /**
24
+ * Récupère tous les modèles disponibles avec API key ou via proxy
25
+ */
26
+ export declare function getAvailableModels(options?: ModelToggleOptions): Promise<ModelInfo[]>;
25
27
  /**
26
28
  * Récupère les modèles activés par l'utilisateur avec API key
27
29
  */
28
30
  export declare function getUserModels(options?: ModelToggleOptions): Promise<string[]>;
31
+ export {};
29
32
  //# sourceMappingURL=modelManagement.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"modelManagement.d.ts","sourceRoot":"","sources":["../../src/utils/modelManagement.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAUD;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,EACjB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAqCf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CACR,KAAK,CAAC;IACJ,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CACH,CAsDA;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC,CAkDnB"}
1
+ {"version":3,"file":"modelManagement.d.ts","sourceRoot":"","sources":["../../src/utils/modelManagement.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAcD,KAAK,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1D,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8BD;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,EACjB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAqCf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,SAAS,EAAE,CAAC,CA0DtB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC,CAkDnB"}
@@ -1,6 +1,21 @@
1
1
  /**
2
2
  * Utilitaires pour la gestion des modèles IA
3
3
  */
4
+ function isModelCategory(value) {
5
+ return (value === "text" ||
6
+ value === "image" ||
7
+ value === "audio" ||
8
+ value === "video");
9
+ }
10
+ function isModelInfo(value) {
11
+ if (!value || typeof value !== "object")
12
+ return false;
13
+ const v = value;
14
+ return (typeof v.id === "string" &&
15
+ typeof v.name === "string" &&
16
+ typeof v.provider === "string" &&
17
+ isModelCategory(v.category));
18
+ }
4
19
  function isAuthTokenCandidate(value) {
5
20
  if (!value)
6
21
  return false;
@@ -76,10 +91,12 @@ export async function getAvailableModels(options = {}) {
76
91
  }
77
92
  const data = await response.json();
78
93
  if (Array.isArray(data?.models)) {
79
- return data.models;
94
+ return data.models.filter(isModelInfo);
80
95
  }
81
96
  if (Array.isArray(data?.providers)) {
82
- return data.providers.flatMap((provider) => Array.isArray(provider.models) ? provider.models : []);
97
+ return (data.providers?.flatMap((provider) => Array.isArray(provider.models)
98
+ ? provider.models.filter(isModelInfo)
99
+ : []) || []);
83
100
  }
84
101
  return [];
85
102
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lastbrain/ai-ui-react",
3
- "version": "1.0.68",
3
+ "version": "1.0.70",
4
4
  "description": "Headless React components for LastBrain AI UI Kit",
5
5
  "private": false,
6
6
  "type": "module",
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "lucide-react": "^0.257.0",
51
- "@lastbrain/ai-ui-core": "1.0.52"
51
+ "@lastbrain/ai-ui-core": "1.0.53"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/react": "^19.2.0",
@@ -2,7 +2,6 @@
2
2
 
3
3
  import React, { useState, useRef, KeyboardEvent } from "react";
4
4
  import { X, Sparkles, Lock } from "lucide-react";
5
- import { aiStyles } from "../styles/inline";
6
5
  import { AiPromptPanel } from "./AiPromptPanel";
7
6
  import { LBSigninModal } from "./LBSigninModal";
8
7
  import { useAiCallText } from "../hooks/useAiCallText";
@@ -10,10 +9,13 @@ import { useAiModels } from "../hooks/useAiModels";
10
9
  import { useAiContext } from "../context/AiProvider";
11
10
  import { useLB } from "../context/LBAuthProvider";
12
11
  import { handleAIError } from "../utils/errorHandler";
12
+ import type { AiRadius, AiSize } from "../types";
13
13
 
14
14
  export interface AiChipLabelProps {
15
15
  children: React.ReactNode;
16
- variant?: "default" | "success" | "warning" | "danger";
16
+ variant?: "default" | "selected" | "warning" | "success" | "danger";
17
+ size?: AiSize;
18
+ radius?: AiRadius;
17
19
  className?: string;
18
20
  style?: React.CSSProperties;
19
21
  }
@@ -21,36 +23,23 @@ export interface AiChipLabelProps {
21
23
  export function AiChipLabel({
22
24
  children,
23
25
  variant = "default",
26
+ size = "md",
27
+ radius = "full",
24
28
  className,
25
29
  style: customStyle,
26
30
  }: AiChipLabelProps) {
27
- const variantStyles: Record<string, React.CSSProperties> = {
28
- default: {},
29
- success: {
30
- background: "#10b98110",
31
- color: "#10b981",
32
- borderColor: "#10b98130",
33
- },
34
- warning: {
35
- background: "#f59e0b10",
36
- color: "#f59e0b",
37
- borderColor: "#f59e0b30",
38
- },
39
- danger: {
40
- background: "#ef444410",
41
- color: "#ef4444",
42
- borderColor: "#ef444430",
43
- },
31
+ const variantClassMap: Record<string, string> = {
32
+ default: "",
33
+ selected: "ai-chip--selected",
34
+ warning: "ai-chip--success",
35
+ success: "ai-chip--success",
36
+ danger: "ai-chip--danger",
44
37
  };
45
38
 
46
39
  return (
47
40
  <span
48
- style={{
49
- ...aiStyles.chip,
50
- ...variantStyles[variant],
51
- ...customStyle,
52
- }}
53
- className={className}
41
+ style={customStyle}
42
+ className={`ai-chip ai-size-${size} ai-radius-${radius} ${variantClassMap[variant]} ${className || ""}`}
54
43
  >
55
44
  {children}
56
45
  </span>
@@ -70,6 +59,8 @@ export interface AiChipInputProps {
70
59
  // Props optionnelles pour override du contexte (si nécessaire)
71
60
  baseUrl?: string;
72
61
  apiKeyId?: string;
62
+ size?: AiSize;
63
+ radius?: AiRadius;
73
64
  }
74
65
 
75
66
  export function AiChipInput({
@@ -84,6 +75,8 @@ export function AiChipInput({
84
75
  artifactTitle,
85
76
  baseUrl: propBaseUrl,
86
77
  apiKeyId: propApiKeyId,
78
+ size = "md",
79
+ radius = "full",
87
80
  }: AiChipInputProps) {
88
81
  const [inputValue, setInputValue] = useState("");
89
82
  const [showPromptPanel, setShowPromptPanel] = useState(false);
@@ -199,92 +192,66 @@ Exemple de réponse attendue: javascript, react, frontend, api, development`;
199
192
  onChange?.(updatedChips);
200
193
  };
201
194
 
202
- console.log("AiChipInput render - value:", value, "length:", value.length);
195
+ const sizeClass = `ai-size-${size}`;
196
+ const radiusClass = `ai-radius-${radius}`;
203
197
 
204
198
  return (
205
199
  <div className={className}>
206
200
  {/* Input avec bouton génération */}
207
- <div style={{ position: "relative", marginBottom: "8px" }}>
208
- <input
209
- ref={inputRef}
210
- type="text"
211
- value={inputValue}
212
- onChange={(e) => setInputValue(e.target.value)}
213
- onKeyDown={handleKeyDown}
214
- placeholder={placeholder}
215
- style={{
216
- ...aiStyles.input,
217
- paddingRight: "40px", // Space for button
218
- }}
219
- />
220
- <button
221
- onClick={() => {
222
- if (isAuthenticated) {
223
- handleGenerateChips();
224
- } else {
225
- setShowSigninModal(true);
201
+ <div className="ai-control-group ai-glow mb-2">
202
+ <div className={`ai-shell ${sizeClass} ${radiusClass}`}>
203
+ <input
204
+ ref={inputRef}
205
+ type="text"
206
+ value={inputValue}
207
+ onChange={(e) => setInputValue(e.target.value)}
208
+ onKeyDown={handleKeyDown}
209
+ placeholder={placeholder}
210
+ className={`ai-control ai-control-input ai-control-input--with-action ${sizeClass} ${radiusClass}`}
211
+ />
212
+ <button
213
+ onClick={() => {
214
+ if (isAuthenticated) {
215
+ handleGenerateChips();
216
+ } else {
217
+ setShowSigninModal(true);
218
+ }
219
+ }}
220
+ className={`ai-control-action ai-spark ${sizeClass} ${radiusClass}`}
221
+ aria-label={
222
+ isAuthenticated
223
+ ? "Générer des tags avec l'IA"
224
+ : "Connexion requise"
226
225
  }
227
- }}
228
- style={{
229
- position: "absolute",
230
- right: "8px",
231
- top: "50%",
232
- transform: "translateY(-50%)",
233
- background: "none",
234
- border: "none",
235
- cursor: "pointer",
236
- padding: "4px",
237
- borderRadius: "4px",
238
- display: "flex",
239
- alignItems: "center",
240
- color: isAuthenticated ? "#6366f1" : "#ef4444",
241
- }}
242
- title={
243
- isAuthenticated
244
- ? "Générer des tags avec l'IA"
245
- : "Se connecter pour utiliser l'IA"
246
- }
247
- >
248
- {isAuthenticated ? <Sparkles size={16} /> : <Lock size={16} />}
249
- </button>
226
+ title={
227
+ isAuthenticated
228
+ ? "Générer des tags avec l'IA"
229
+ : "Se connecter pour utiliser l'IA"
230
+ }
231
+ >
232
+ {isAuthenticated ? <Sparkles size={16} /> : <Lock size={16} />}
233
+ </button>
234
+ </div>
250
235
  </div>
251
236
 
252
237
  {/* Chips affichées */}
253
238
  {value.length > 0 && (
254
- <div style={{ display: "flex", flexWrap: "wrap", gap: "6px" }}>
255
- {value.map((chip, index) => {
256
- console.log("Rendering chip:", chip, "at index:", index);
257
- return (
258
- <div
259
- key={index}
260
- style={{
261
- ...aiStyles.chip,
262
- display: "flex",
263
- alignItems: "center",
264
- gap: "6px",
265
- paddingRight: "6px",
266
- }}
239
+ <div className="ai-chip-input">
240
+ {value.map((chip, index) => (
241
+ <div
242
+ key={index}
243
+ className={`ai-chip ai-chip--with-close ${sizeClass} ${radiusClass}`}
244
+ >
245
+ <span>{chip}</span>
246
+ <button
247
+ onClick={() => removeChip(index)}
248
+ className="ai-chip-remover"
249
+ title="Supprimer"
267
250
  >
268
- <span>{chip}</span>
269
- <button
270
- onClick={() => removeChip(index)}
271
- style={{
272
- background: "none",
273
- border: "none",
274
- cursor: "pointer",
275
- padding: "0",
276
- display: "flex",
277
- alignItems: "center",
278
- color: "currentColor",
279
- opacity: 0.7,
280
- }}
281
- title="Supprimer"
282
- >
283
- <X size={14} />
284
- </button>
285
- </div>
286
- );
287
- })}
251
+ <X size={14} />
252
+ </button>
253
+ </div>
254
+ ))}
288
255
  </div>
289
256
  )}
290
257