{"_id":"@2londres/data-table-clar","_rev":"2-7c257b6148e977caf6da1d80457ef8c2","name":"@2londres/data-table-clar","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@2londres/data-table-clar","version":"1.0.0","_id":"@2londres/data-table-clar@1.0.0","maintainers":[{"name":"martio007","email":"managerboah@gmail.com"}],"dist":{"shasum":"d6058c6d3850531a307b951343838d54766a00c7","tarball":"https://registry.npmjs.org/@2londres/data-table-clar/-/data-table-clar-1.0.0.tgz","fileCount":5,"integrity":"sha512-hLjPrwVVGFXvBTO5CXjkblw9Vs7oU+9WPVHDRLWI+OXOSiTYwl9/kgWNzX+ffaVuU1bXUK1rendnftrDt+Yvmg==","signatures":[{"sig":"MEUCIH87TP2ZdxrWS0XSWlDhehzB0Y0N2aDa2lA44r7v6lGaAiEAhiIwxpxm1hzfSoN+1D+4Z+3JEEfQPf0TZVtSbBk5r5M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":194617},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"ffa505f6f93300f02a61b629b2fe09a1f0943cd4","scripts":{"build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"martio007","email":"managerboah@gmail.com"},"_npmVersion":"11.12.0","description":"DataTableClar — table TanStack avec pagination, filtres, export CSV (client/serveur).","directories":{},"sideEffects":false,"_nodeVersion":"25.8.0","dependencies":{"clsx":"^2.1.1","xlsx":"^0.18.5","js-cookie":"^3.0.5","tailwind-merge":"^3.4.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","react":"^19.2.0","react-dom":"^19.2.0","typescript":"~5.9.3","@types/react":"^19.2.5","@types/js-cookie":"^3.0.6","@types/react-dom":"^19.2.3","class-variance-authority":"^0.7.1"},"peerDependencies":{"cmdk":"^1.0.0","react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0","lucide-react":">=0.400.0","react-i18next":">=13.0.0","react-router-dom":"^6.0.0","@radix-ui/react-slot":"^1.2.0","@radix-ui/react-label":"^2.1.0","@tanstack/react-table":"^8.21.0","@radix-ui/react-dialog":"^1.1.0","@radix-ui/react-select":"^2.2.0","@radix-ui/react-popover":"^1.1.0","class-variance-authority":"^0.7.1","@radix-ui/react-radio-group":"^1.3.0"},"_npmOperationalInternal":{"tmp":"tmp/data-table-clar_1.0.0_1774534133542_0.40628630064004767","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@2londres/data-table-clar","version":"1.0.1","description":"DataTableClar — table TanStack avec pagination, filtres, export CSV (client/serveur).","type":"module","sideEffects":false,"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"peerDependencies":{"@radix-ui/react-dialog":"^1.1.0","@radix-ui/react-label":"^2.1.0","@radix-ui/react-popover":"^1.1.0","@radix-ui/react-radio-group":"^1.3.0","@radix-ui/react-select":"^2.2.0","@radix-ui/react-slot":"^1.2.0","@tanstack/react-table":"^8.21.0","class-variance-authority":"^0.7.1","cmdk":"^1.0.0","lucide-react":">=0.400.0","react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0","react-i18next":">=13.0.0","react-router-dom":"^6.0.0"},"dependencies":{"clsx":"^2.1.1","js-cookie":"^3.0.5","tailwind-merge":"^3.4.0","xlsx":"^0.18.5"},"devDependencies":{"@types/js-cookie":"^3.0.6","@types/react":"^19.2.5","@types/react-dom":"^19.2.3","class-variance-authority":"^0.7.1","react":"^19.2.0","react-dom":"^19.2.0","tsup":"^8.5.0","typescript":"~5.9.3"},"scripts":{"build":"tsup","typecheck":"tsc --noEmit"},"_id":"@2londres/data-table-clar@1.0.1","_integrity":"sha512-aD3O3bONygVJM+4nJteXRL66Rv43mNxYB5NDoptyMsGdOc5Mf9o1DoRhB0p7WPjAkaq2p/Ac13YNGR6Q7lzvCQ==","_resolved":"/private/var/folders/35/hyb4ps8n75j9b_m55_nrmdv40000gp/T/13896f8d1a7cb286f4c946256ca71c42/2londres-data-table-clar-1.0.1.tgz","_from":"file:2londres-data-table-clar-1.0.1.tgz","_nodeVersion":"25.8.0","_npmVersion":"11.12.0","dist":{"integrity":"sha512-aD3O3bONygVJM+4nJteXRL66Rv43mNxYB5NDoptyMsGdOc5Mf9o1DoRhB0p7WPjAkaq2p/Ac13YNGR6Q7lzvCQ==","shasum":"ad527c2a1cd22a5cbd30e9b2942068dc704f3ff2","tarball":"https://registry.npmjs.org/@2londres/data-table-clar/-/data-table-clar-1.0.1.tgz","fileCount":5,"unpackedSize":195332,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIF4c6EOknscs4rAi9CBx3E1uEKSMHE3mQDrVeejAOInFAiEAvwxUemnv2Fuh/D7F7IJELnB/Tya3iPSqQErTNTNKM7s="}]},"_npmUser":{"name":"martio007","email":"managerboah@gmail.com"},"directories":{},"maintainers":[{"name":"martio007","email":"managerboah@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/data-table-clar_1.0.1_1776114076975_0.3354402358621218"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-26T14:08:53.440Z","modified":"2026-04-13T21:01:17.270Z","1.0.0":"2026-03-26T14:08:53.692Z","1.0.1":"2026-04-13T21:01:17.119Z"},"description":"DataTableClar — table TanStack avec pagination, filtres, export CSV (client/serveur).","maintainers":[{"name":"martio007","email":"managerboah@gmail.com"}],"readme":"# `@2londres/data-table-clar`\n\nTable **TanStack Table** : filtres en en-tête, pagination compacte (pages + ellipses + « aller à la page »), export CSV (page courante ou liste complète), mode **client** ou **serveur**.\n\n**Guide d'utilisation** — ce document décrit l'installation, les props, des exemples copiables et les pièges courants.\n\n<!-- GIF : démo globale du composant -->\n![Démo DataTableClar](./assets/demo-overview.gif)\n\n---\n\n## Sommaire\n\n1. [Intégration (ce dépôt vs npm)](#intégration-ce-dépôt-vs-npm)\n2. [Prérequis](#prérequis)\n3. [Démarrage rapide — mode client](#démarrage-rapide--mode-client)\n4. [Mode serveur — filtres & pagination](#mode-serveur--filtres--pagination)\n5. [Référence des props `DataTableClar`](#référence-des-props-datatableclar)\n6. [Colonnes, `meta` et filtres UI](#colonnes-meta-et-filtres-ui)\n7. [États chargement / erreur / vide](#états-chargement--erreur--vide)\n8. [Sélection de lignes](#sélection-de-lignes)\n9. [Export CSV](#export-csv)\n10. [Internationalisation (i18n)](#internationalisation-i18n)\n11. [Package vs application (filtres API)](#package-vs-application-filtres-api)\n12. [API exportée](#api-exportée)\n13. [Publication npm & peers](#publication-npm--peers)\n14. [Tailwind](#tailwind)\n\n---\n\n## Intégration (ce dépôt vs npm)\n\n### Dans **Process-Maker** (alias, sans `npm install` du package)\n\n- **Vite** [`vite.config.ts`](../../vite.config.ts) : `resolve.alias[\"@2londres/data-table-clar\"]` → `./packages/data-table-clar/src/index.ts`\n- **TypeScript** [`tsconfig.app.json`](../../tsconfig.app.json) : `paths[\"@2londres/data-table-clar\"]` → le même fichier\n\nÉcrans métier (recommandé) :\n\n```ts\nimport { DataTableClar } from \"@/components/shared/DataListTable/dataTableClar\";\n```\n\nLe wrapper réinjecte les comportements banque (droits CSV, notifications, `LoadScreen`, `EmptyTable` / `ErrorTable` / `LoadingTable`).\n\n### Import **direct** du package (lib seule)\n\n```ts\nimport { DataTableClar } from \"@2londres/data-table-clar\";\n```\n\n### Après publication **npm**\n\n```bash\ncd packages/data-table-clar && npm install && npm run build && npm publish\n```\n\nLes entrées `main` / `exports` du `package.json` pointent vers `dist/` une fois le build exécuté.\n\n---\n\n## Prérequis\n\n| Besoin | Détail |\n|--------|--------|\n| **React 18+** | Composants client (`\"use client\"` côté Next si besoin). |\n| **`react-router-dom`** | `columnsClar` reçoit `navigate` pour les liens / actions dans les cellules. |\n| **`react-i18next`** | Le package appelle `useTranslation()` ; fournir un `I18nextProvider` et les clés listées [plus bas](#internationalisation-i18n). |\n| **TanStack Table** | Déjà une peer du package ; les colonnes sont des `ColumnDef`. |\n| **Styles** | Tailwind (ou équivalent) : le package utilise des classes utilitaires (`shadcn`-like). |\n\n---\n\n## Démarrage rapide — mode client\n\nIdéal quand **toutes les lignes** sont déjà chargées dans `data` (filtrage + pagination **locaux** TanStack).\n\n<!-- GIF : mode client — filtres locaux + pagination -->\n![Mode client](./assets/demo-client-mode.gif)\n\n```tsx\nimport { useMemo, useState } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { DataTableClar } from \"@2londres/data-table-clar\";\n\ntype Row = { id: string; name: string };\n\nconst buildColumns = (_navigate: ReturnType<typeof useNavigate>): ColumnDef<Row, unknown>[] => [\n  {\n    id: \"name\",\n    accessorKey: \"name\",\n    header: \"Nom\",\n    meta: { type: \"text\" },\n  },\n];\n\nexport function MyListPage() {\n  const navigate = useNavigate();\n  const [data] = useState<Row[]>([{ id: \"1\", name: \"Alpha\" }]);\n\n  const columnsClar = useMemo(() => buildColumns, []);\n\n  return (\n    <DataTableClar<Row>\n      title=\"Ma liste\"\n      exportFileName=\"export\"\n      data={data}\n      columnsClar={columnsClar}\n      itemPerPage={10}\n      // paginationMode omis → \"client\"\n    />\n  );\n}\n```\n\n- Chaque ligne doit avoir un **`id: string`** stable (obligatoire pour les clés React et la sélection).\n- **`exportFileName`** : préfixe du fichier CSV téléchargé.\n\n---\n\n## Mode serveur — filtres & pagination\n\nQuand les données viennent d'une **API** paginée et/ou filtrée.\n\n<!-- GIF : mode serveur — pagination + filtres API -->\n![Mode serveur](./assets/demo-server-mode.gif)\n\n### Props obligatoires côté tableau\n\n- `paginationMode=\"server\"`\n- `pagination` + `onPaginationChange` (état contrôlé, ex. `useState`)\n- `columnFilters` + `onColumnFiltersChange`\n- `serverPageCount` : nombre de pages renvoyé par l'API (0 si aucune page)\n- `totalItemsCount` : total d'éléments pour le compteur sous le titre\n\n### Ce que fait **ton** code (hors package)\n\n1. Stocker `pagination` et `columnFilters` (souvent `useState`).\n2. À chaque changement, **mapper** `columnFilters` → query params / body attendus par ton API.\n3. Lancer la requête (ex. **React Query**) avec `page`, `limit` dérivés de `pagination.pageIndex` / `pagination.pageSize`.\n4. Passer **`data`** = page courante, **`serverPageCount`**, **`totalItemsCount`** depuis la réponse.\n\n### Exemple minimal (schéma)\n\n```tsx\nconst [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });\nconst [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);\n\n// Dans ton useQuery / queryFn :\nconst apiParams = {\n  page: pagination.pageIndex + 1,\n  limit: pagination.pageSize,\n  ...mapColumnFiltersToApi(columnFilters), // à implémenter dans ton app\n};\n\n<DataTableClar<Row>\n  paginationMode=\"server\"\n  pagination={pagination}\n  onPaginationChange={setPagination}\n  columnFilters={columnFilters}\n  onColumnFiltersChange={setColumnFilters}\n  serverPageCount={meta.totalPages}\n  totalItemsCount={meta.totalItems}\n  data={rows}\n  columnsClar={columnsClar}\n  title=\"Liste\"\n  exportFileName=\"liste\"\n/>\n```\n\n### Colonnes sans filtre API\n\nUtilise `meta: { type: \"denied\" }` pour **ne pas afficher** de contrôle de filtre sur une colonne (souvent après mapping automatique de tes définitions de colonnes).\n\n### Avertissement dev\n\nSi `pagination` est contrôlé en mode serveur **sans** `columnFilters` / `onColumnFiltersChange`, un `console.warn` peut s'afficher : branche bien les deux.\n\n---\n\n## Référence des props `DataTableClar`\n\nProps principales (voir `DataTableClarProps` dans le code pour la liste exhaustive).\n\n| Prop | Type | Description |\n|------|------|-------------|\n| `data` | `TData[]` | Lignes affichées (page courante en mode serveur). |\n| `title` | `string` | Titre de la carte. |\n| `exportFileName` | `string` | Préfixe des fichiers CSV. |\n| `columnsClar` | `(navigate) => ColumnDef[]` | Définition des colonnes ; `navigate` pour actions/liens. |\n| `itemPerPage` | `number?` | Taille de page initiale / attendue. |\n| `paginationMode` | `\"client\" \\| \"server\"?` | Défaut `\"client\"`. |\n| `pagination` | `PaginationState?` | `{ pageIndex, pageSize }` — **requis** en serveur contrôlé. |\n| `onPaginationChange` | `OnChangeFn` | **Requis** en serveur contrôlé. |\n| `columnFilters` | `ColumnFiltersState?` | Filtres TanStack — **requis** côté serveur si tu filtres. |\n| `onColumnFiltersChange` | `OnChangeFn` | Idem. |\n| `serverPageCount` | `number?` | Nombre total de pages (serveur). |\n| `totalItemsCount` | `number?` | Total éléments (serveur). |\n| `loading` | `{ isLoading, loaderComponent?, isFetching? }?` | Skeleton + indicateur de refetch. |\n| `error` | `{ message, refetch? }?` | Affichage erreur + option recharge. |\n| `enableSelection` | `boolean?` | Colonne cases à cocher. |\n| `onSelectionChange` | `(ids: string[]) => void` | IDs sélectionnés. |\n| `onExportFullList` | `() => Promise<TData[]>` | Export CSV « liste complète » en mode serveur. |\n| `showCsvExportButton` | `boolean?` | Affiche le bouton CSV (souvent `false` par défaut dans le package ; le wrapper Process-Maker lie l'admin). |\n| `enableClientVolumeControl` | `boolean?` | Mode client : sélecteur « volume » + cookie (désactivable). |\n| `renderVolumeControl` | `ReactNode?` | Remplace le sélecteur de volume intégré. |\n| `onNotifyWarning` / `onNotifyError` / `onNotifyInfo` | callbacks | Feedback export / volume (si pas de wrapper app). |\n| `renderLoading` / `renderEmpty` / `renderError` | fonctions | Personnalise les états (le wrapper Process-Maker fournit les tabs par défaut). |\n| `renderCsvExportLoading` | `() => ReactNode` | Overlay pendant l'export async liste complète. |\n\n---\n\n## Colonnes, `meta` et filtres UI\n\nLes filtres en tête suivent `columnDef.meta` (`DataTableColumnMetaType`) :\n\n<!-- GIF : types de filtres (text, date, select) -->\n![Filtres colonnes](./assets/demo-column-filters.gif)\n\n| `meta.type` | Comportement |\n|-------------|----------------|\n| `\"text\"` | Champ texte ; valeur filtre = `string`. |\n| `\"date\"` | `input type=\"date\"` ; valeur `YYYY-MM-DD`. |\n| `\"date_from\"` / `\"date_end\"` | Plage : valeur souvent `{ from?, to? }` selon ta logique. |\n| `\"select\"` | `meta.options: { value, label }[]` ; pour tout afficher, une option `value: \"Tout\"` vide le filtre. |\n| `\"denied\"` | Pas de contrôle (ex. pas de filtre API). |\n| `\"selection\"` | Réservé à la colonne de sélection interne. |\n\n**Alignement** : `headerAlign`, `cellAlign` : `\"left\"` \\| `\"center\"` \\| `\"right\"`.\n\n**Filtre date plage côté client** : exporter `dateRangeFilterFn` du package dans `columnDef.filterFn` si tu filtres localement sur une colonne date.\n\n---\n\n## États chargement / erreur / vide\n\n<!-- GIF : états loading → empty → error -->\n![États chargement / erreur / vide](./assets/demo-loading-states.gif)\n\n- **`loading.isLoading`** : affiche le skeleton (ou `loaderComponent`) **à la place des lignes**.\n- **`loading.isFetching`** + `data.length === 0`** : même chose (chargement initial).\n- **`loading.isFetching`** + données présentes : le tableau reste affiché ; une barre d'indication de refetch peut apparaître en bas (comportement du package).\n- **`error.message`** : affiche l'état erreur ; `refetch` affiche un bouton de retry si fourni.\n\nPersonnalisation : `renderLoading`, `renderEmpty`, `renderError`.\n\n---\n\n## Sélection de lignes\n\n<!-- GIF : sélection checkbox + callback -->\n![Sélection de lignes](./assets/demo-row-selection.gif)\n\n```tsx\n<DataTableClar\n  enableSelection\n  onSelectionChange={(ids) => console.log(ids)}\n  // ...\n/>\n```\n\nLes IDs correspondent à `row.original.id` : chaque ligne doit avoir un **`id` unique**.\n\n---\n\n## Export CSV\n\n<!-- GIF : export CSV page courante + liste complète -->\n![Export CSV](./assets/demo-csv-export.gif)\n\n- **`showCsvExportButton`** : affiche le bouton (à brancher sur tes droits métier).\n- Dialogue : page courante **ou** liste complète.\n- **Client** : liste complète = toutes les lignes filtrées en mémoire (`getPrePaginationRowModel` côté implémentation).\n- **Serveur** : liste complète = **`onExportFullList`** doit retourner une `Promise` des lignes (souvent un fetch avec les mêmes filtres que la liste). Plafond : `DATA_TABLE_EXPORT_MAX_ROWS` / `clampExportLimit`.\n\n---\n\n## Internationalisation (i18n)\n\nLe package utilise **`useTranslation()`** sans namespace imposé. Prévoir au minimum des clés du type :\n\n- `dataTable*`, `dataTableCsvExport*`, `dataTablePagination*`, `dataTableFilter*`, `dataTableVolume*`, `dataTableResetFilters`, `dataTableNoSelectOptions`, …\n- `selectAll`, `loadingText`, `cancel`, `previous`, `next`, `loadErrorDescription`, `noDataToExport`\n- Textes table vides / erreurs si tu utilises les composants par défaut du package : `noTableDataToDisplay`, `tableErrorText`, `reload`, etc.\n\nCopier les entrées depuis les fichiers de locales du projet hôte ou les redéfinir.\n\n---\n\n## Package vs application (filtres API)\n\n| Couche | Rôle |\n|--------|------|\n| **Package** | UI des filtres selon `meta`, état TanStack `columnFilters` / `pagination`, pagination visuelle, export. |\n| **Ton app** | Contrat API : transformation `ColumnFiltersState` → paramètres HTTP, désactivation UI (`denied`), clés React Query. |\n\n---\n\n## API exportée\n\n| Catégorie | Exports |\n|-----------|---------|\n| Composants | `DataTableClar`, `DataTableCsvExportDialog`, `DataTablePaginationBar` |\n| Utilitaires | `downloadCsvFromRows`, `clampExportLimit`, `DATA_TABLE_EXPORT_MAX_ROWS`, `getVisiblePaginationSegments`, `dateRangeFilterFn` |\n| Types | `DataTableClarProps`, `DataTableColumnMetaType`, `DataTableRowBase`, `DataTableCsvExportScope`, `DataTablePaginationBarProps`, `PaginationSegment`, … |\n\n---\n\n## Publication npm & peers\n\n```bash\ncd packages/data-table-clar\nnpm install\nnpm run build\nnpm publish --access public   # si le scope npm est configuré\n```\n\nPeers listées dans [`package.json`](./package.json) : `react`, `react-dom`, `@tanstack/react-table`, `react-router-dom`, `react-i18next`, Radix UI, `lucide-react`, `cmdk`, `class-variance-authority`, etc.\n\n---\n\n## Tailwind\n\nInclure les sources du package dans le **content** / scan des classes Tailwind du consommateur. Dans ce monorepo, l'import via Vite inclut déjà `packages/data-table-clar/src`, donc les classes sont prises en compte au build.\n\n---\n\n## Pièges fréquents\n\n| Problème | Piste |\n|----------|--------|\n| Filtres serveur sans effet | Vérifier `onColumnFiltersChange` + mapping vers l'API + invalidation / clés de requête. |\n| Pagination bloquée | `serverPageCount` cohérent avec l'API (`Math.ceil(total / pageSize)` ou champ `totalPages`). |\n| Mauvaise ligne sélectionnée | `getRowId` utilise `row.id` : garantir des **id uniques** côté données. |\n| Pas de styles | Scanner les chemins du package dans Tailwind. |\n| Export liste complète serveur vide | Implémenter `onExportFullList` ; sinon seule la page courante est exportable. |\n","readmeFilename":"README.md"}