@ramses1er/cbk-toolkit 1.0.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.
- package/README.md +280 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +135 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +2 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# CBK Toolkit
|
|
2
|
+
|
|
3
|
+
Package de composants React réutilisables, framework-agnostic.
|
|
4
|
+
**Livré avec son propre CSS Tailwind pré-compilé + la police Merriweather** — le consommateur n'a pas besoin d'installer Tailwind.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
npm install @ramses1er/cbk-toolkit
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## CSS et police
|
|
13
|
+
|
|
14
|
+
Le package fournit **tout le CSS nécessaire** (Tailwind + Merriweather).
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import "@ramses1er/cbk-toolkit/styles.css";
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Ne **surtout pas** avoir d'import Tailwind parallèle dans votre CSS, sinon les valeurs du package (police Merriweather, thème) seront écrasées.
|
|
21
|
+
|
|
22
|
+
### Dans un projet Next.js
|
|
23
|
+
|
|
24
|
+
Commenter ou supprimer ces lignes dans `src/app/globals.css` :
|
|
25
|
+
|
|
26
|
+
```css
|
|
27
|
+
/* @import "tailwindcss"; */
|
|
28
|
+
|
|
29
|
+
/* @theme inline {
|
|
30
|
+
--color-background: var(--background);
|
|
31
|
+
--color-foreground: var(--foreground);
|
|
32
|
+
--font-sans: var(--font-geist-sans);
|
|
33
|
+
--font-mono: var(--font-geist-mono);
|
|
34
|
+
} */
|
|
35
|
+
|
|
36
|
+
/* body {
|
|
37
|
+
background: var(--background);
|
|
38
|
+
color: var(--foreground);
|
|
39
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
40
|
+
} */
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Supprimer aussi `transpilePackages: ["@ramses1er/cbk-toolkit"]` de `next.config.ts` (inutile, le package est pré-compilé).
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## SideNav
|
|
48
|
+
|
|
49
|
+
Sidebar de navigation latérale avec header, sous-menus imbriqués, footer et branding configurable. Compatible Next.js, Vite, React Router.
|
|
50
|
+
|
|
51
|
+
### Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install @ramses1er/cbk-toolkit
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { SideNav, createSideNav } from "@ramses1er/cbk-toolkit";
|
|
59
|
+
import "@ramses1er/cbk-toolkit/styles.css";
|
|
60
|
+
import type { NavItem } from "@ramses1er/cbk-toolkit";
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### API factory (recommandée)
|
|
64
|
+
|
|
65
|
+
Créer un fichier de configuration de la sidebar :
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
// config/side-nav.ts
|
|
69
|
+
import { createSideNav } from "@ramses1er/cbk-toolkit";
|
|
70
|
+
|
|
71
|
+
export const MySideNav = createSideNav({
|
|
72
|
+
brand: {
|
|
73
|
+
name: "Genesis",
|
|
74
|
+
tagline: "Gestion scolaire",
|
|
75
|
+
logo: "/logo.png",
|
|
76
|
+
},
|
|
77
|
+
mainItems: [
|
|
78
|
+
{ id: "dashboard", label: "Accueil", icon: "🏠", href: "/dashboard" },
|
|
79
|
+
{
|
|
80
|
+
id: "students",
|
|
81
|
+
label: "Élèves",
|
|
82
|
+
icon: "🎓",
|
|
83
|
+
href: "/students",
|
|
84
|
+
subItems: [
|
|
85
|
+
{ id: "list", label: "Liste", href: "/students" },
|
|
86
|
+
{ id: "classes", label: "Classes", href: "/students/classes" },
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
{ id: "payments", label: "Paiements", icon: "💳", href: "/payments" },
|
|
90
|
+
],
|
|
91
|
+
footer: [
|
|
92
|
+
{ icon: "⚙️", label: "Paramètres", href: "/settings" },
|
|
93
|
+
],
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Le `title` du header est automatiquement déduit du menu actif (son `label` ou son champ `title` optionnel). Voir la section [Titre dynamique](#titre-dynamique).
|
|
98
|
+
|
|
99
|
+
### Intégration dans le layout
|
|
100
|
+
|
|
101
|
+
#### Next.js (App Router)
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
// app/layout.tsx
|
|
105
|
+
"use client";
|
|
106
|
+
|
|
107
|
+
import { usePathname } from "next/navigation";
|
|
108
|
+
import { MySideNav } from "@/config/side-nav";
|
|
109
|
+
import "@ramses1er/cbk-toolkit/styles.css";
|
|
110
|
+
|
|
111
|
+
export default function Layout({ children }: { children: React.ReactNode }) {
|
|
112
|
+
const pathname = usePathname();
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<html lang="fr">
|
|
116
|
+
<body>
|
|
117
|
+
<MySideNav currentPath={pathname}>{children}</MySideNav>
|
|
118
|
+
</body>
|
|
119
|
+
</html>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Notes pour Next.js :**
|
|
125
|
+
- Le layout doit être `"use client"` à cause de `usePathname`
|
|
126
|
+
- Voir la section [CSS et police](#css-et-politique) pour les lignes à commenter dans `globals.css`
|
|
127
|
+
- Pas besoin de `transpilePackages` dans `next.config.ts`
|
|
128
|
+
- Pas besoin d'importer des polices via `next/font/google` — le package fournit Merriweather
|
|
129
|
+
|
|
130
|
+
#### Vite + React Router
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
// src/App.tsx ou src/layouts/MainLayout.tsx
|
|
134
|
+
import "@ramses1er/cbk-toolkit/styles.css";
|
|
135
|
+
import { MySideNav } from "./config/side-nav";
|
|
136
|
+
import { useLocation } from "react-router-dom";
|
|
137
|
+
|
|
138
|
+
function MainLayout({ children }: { children: React.ReactNode }) {
|
|
139
|
+
const { pathname } = useLocation();
|
|
140
|
+
|
|
141
|
+
return <MySideNav currentPath={pathname}>{children}</MySideNav>;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export default MainLayout;
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Notes pour Vite :**
|
|
148
|
+
- Voir la section [CSS et police](#css-et-politique) pour les lignes à commenter dans `globals.css`
|
|
149
|
+
- Si vous utilisez PostCSS + Tailwind (`@tailwindcss/postcss`), supprimer la config ou ne pas importer Tailwind dans le CSS
|
|
150
|
+
- Pas besoin d'importer des polices via Google Fonts manuellement — le package fournit Merriweather
|
|
151
|
+
|
|
152
|
+
#### Vite vanilla (sans React Router)
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
import "@ramses1er/cbk-toolkit/styles.css";
|
|
156
|
+
import { MySideNav } from "./config/side-nav";
|
|
157
|
+
import { useState, useEffect } from "react";
|
|
158
|
+
|
|
159
|
+
function App() {
|
|
160
|
+
const [pathname, setPathname] = useState(window.location.pathname);
|
|
161
|
+
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
const onPopState = () => setPathname(window.location.pathname);
|
|
164
|
+
window.addEventListener("popstate", onPopState);
|
|
165
|
+
return () => window.removeEventListener("popstate", onPopState);
|
|
166
|
+
}, []);
|
|
167
|
+
|
|
168
|
+
return <MySideNav currentPath={pathname}>{children}</MySideNav>;
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### API directe
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
<SideNav
|
|
176
|
+
currentPath={pathname}
|
|
177
|
+
brand={{ name: "Mon App", logo: "/logo.svg", tagline: "Slogan" }}
|
|
178
|
+
mainItems={[
|
|
179
|
+
{ id: "dashboard", label: "Dashboard", icon: "🏠", href: "/dashboard" },
|
|
180
|
+
{ id: "students", label: "Élèves", icon: "🎓", href: "/students" },
|
|
181
|
+
]}
|
|
182
|
+
title="Dashboard"
|
|
183
|
+
>
|
|
184
|
+
<YourContent />
|
|
185
|
+
</SideNav>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Titre dynamique
|
|
191
|
+
|
|
192
|
+
Le header affiché en haut de la page (à droite de la sidebar) est déterminé automatiquement selon cet ordre de priorité :
|
|
193
|
+
|
|
194
|
+
1. **`title` explicite** (prop passée à `SideNav` ou `createSideNav`)
|
|
195
|
+
2. **`title` optionnel** dans `NavItem` de l'entrée active
|
|
196
|
+
3. **`label`** de l'entrée active (par défaut)
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
mainItems: [
|
|
200
|
+
{
|
|
201
|
+
id: "dashboard",
|
|
202
|
+
label: "Accueil", // header = "Accueil"
|
|
203
|
+
title: "Tableau de bord", // header = "Tableau de bord" si défini
|
|
204
|
+
href: "/dashboard",
|
|
205
|
+
},
|
|
206
|
+
];
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Props
|
|
212
|
+
|
|
213
|
+
### SideNavStaticConfig (configuration statique)
|
|
214
|
+
|
|
215
|
+
| Prop | Type | Défaut | Description |
|
|
216
|
+
|------|------|--------|-------------|
|
|
217
|
+
| `mainItems` | `NavItem[]` | requis | Entrées de navigation |
|
|
218
|
+
| `brand` | `{ logo?, name?, tagline? }` | — | Branding en haut de la sidebar |
|
|
219
|
+
| `footer` | `{ icon?, label, href }[]` | — | Liens en pied de sidebar |
|
|
220
|
+
| `title` | `string` | — | Titre du header (override le titre auto) |
|
|
221
|
+
| `toggleIcon` | `ReactNode` | `"▼"/"▶"` | Icône de toggle des sous-menus |
|
|
222
|
+
|
|
223
|
+
### Props dynamiques (passées au render)
|
|
224
|
+
|
|
225
|
+
| Prop | Type | Défaut | Description |
|
|
226
|
+
|------|------|--------|-------------|
|
|
227
|
+
| `children` | `ReactNode` | requis | Contenu principal |
|
|
228
|
+
| `currentPath` | `string` | requis | Chemin actif pour le surlignage |
|
|
229
|
+
|
|
230
|
+
### NavItem
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
type NavItem = {
|
|
234
|
+
id: string;
|
|
235
|
+
label: string;
|
|
236
|
+
title?: string; // Optionnel : surcharge le titre dans le header
|
|
237
|
+
icon?: ReactNode;
|
|
238
|
+
href: string;
|
|
239
|
+
subItems?: NavItem[];
|
|
240
|
+
};
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Police Merriweather
|
|
246
|
+
|
|
247
|
+
Le package charge et applique automatiquement Merriweather (poids 300, 400, 700, 900) via Google Fonts avec `display=swap`. Aucune configuration requise.
|
|
248
|
+
|
|
249
|
+
**Pour que la police fonctionne :**
|
|
250
|
+
- Le CSS du package (`@ramses1er/cbk-toolkit/styles.css`) doit être importé **avant** le CSS local
|
|
251
|
+
- Ne pas avoir d'import Tailwind parallèle qui écrase `--font-sans`
|
|
252
|
+
- Ne pas avoir `body { font-family: ... }` dans son propre CSS qui écrase la valeur
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Composants commentés
|
|
257
|
+
|
|
258
|
+
Les composants suivants sont temporairement mis en commentaire en attendant leur refactoring :
|
|
259
|
+
|
|
260
|
+
Confirmation, Date, ErrorDisplay, FieldContainer, Form, HeaderContent, Input, InputSearch, InstallPrompt, Label, LoaderSubmit, Loading, Modal, Option, Select, SelectSearch, SwRegistration, Table, TextArea, TopicIllustration
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Développement
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
pnpm install
|
|
268
|
+
pnpm dev # Build watch avec tsup (JS uniquement)
|
|
269
|
+
pnpm build # Build JS + CSS de production (dist/)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Le CSS est généré via Tailwind v4 en scannant les sources `packages/*/src/`.
|
|
273
|
+
Les fichiers de sortie :
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
dist/
|
|
277
|
+
index.js # Bundle JS (composants)
|
|
278
|
+
index.d.ts # Types TypeScript
|
|
279
|
+
styles.css # CSS Tailwind compilé + Merriweather (minifié)
|
|
280
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, ComponentType } from 'react';
|
|
3
|
+
|
|
4
|
+
type IconType = ReactNode | ComponentType<{
|
|
5
|
+
size?: number;
|
|
6
|
+
}>;
|
|
7
|
+
interface NavItem {
|
|
8
|
+
id: string;
|
|
9
|
+
label: string;
|
|
10
|
+
title?: string;
|
|
11
|
+
icon?: IconType;
|
|
12
|
+
href: string;
|
|
13
|
+
subItems?: NavItem[];
|
|
14
|
+
}
|
|
15
|
+
interface SideNavStaticConfig {
|
|
16
|
+
brand?: {
|
|
17
|
+
logo?: ReactNode;
|
|
18
|
+
name?: string;
|
|
19
|
+
tagline?: string;
|
|
20
|
+
};
|
|
21
|
+
mainItems: NavItem[];
|
|
22
|
+
title?: string;
|
|
23
|
+
footer?: {
|
|
24
|
+
icon?: IconType;
|
|
25
|
+
label: string;
|
|
26
|
+
href: string;
|
|
27
|
+
}[];
|
|
28
|
+
toggleIcon?: ReactNode;
|
|
29
|
+
}
|
|
30
|
+
interface SideNavProps extends SideNavStaticConfig {
|
|
31
|
+
children: ReactNode;
|
|
32
|
+
currentPath: string;
|
|
33
|
+
}
|
|
34
|
+
declare function SideNav({ children, title, mainItems, currentPath, brand, footer, toggleIcon, }: SideNavProps): react.JSX.Element;
|
|
35
|
+
|
|
36
|
+
declare function createSideNav(config: SideNavStaticConfig): ({ children, currentPath, }: {
|
|
37
|
+
children: React.ReactNode;
|
|
38
|
+
currentPath: string;
|
|
39
|
+
}) => react.JSX.Element;
|
|
40
|
+
|
|
41
|
+
export { type NavItem, SideNav, type SideNavProps, type SideNavStaticConfig, createSideNav };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// packages/ui/src/layouts/side-nav.tsx
|
|
2
|
+
import {
|
|
3
|
+
useState,
|
|
4
|
+
createElement,
|
|
5
|
+
isValidElement
|
|
6
|
+
} from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
function isActive(href, currentPath) {
|
|
9
|
+
return currentPath === href || currentPath.startsWith(href + "/");
|
|
10
|
+
}
|
|
11
|
+
function isExactActive(href, currentPath) {
|
|
12
|
+
return currentPath === href;
|
|
13
|
+
}
|
|
14
|
+
function SideNav({
|
|
15
|
+
children,
|
|
16
|
+
title,
|
|
17
|
+
mainItems,
|
|
18
|
+
currentPath,
|
|
19
|
+
brand,
|
|
20
|
+
footer,
|
|
21
|
+
toggleIcon
|
|
22
|
+
}) {
|
|
23
|
+
const activeMain = mainItems.find((item) => isActive(item.href, currentPath));
|
|
24
|
+
const headerTitle = title ?? activeMain?.title ?? activeMain?.label;
|
|
25
|
+
const [expandedSection, setExpandedSection] = useState(
|
|
26
|
+
activeMain?.id ?? null
|
|
27
|
+
);
|
|
28
|
+
const toggleSection = (id) => {
|
|
29
|
+
setExpandedSection((prev) => prev === id ? null : id);
|
|
30
|
+
};
|
|
31
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-screen", children: [
|
|
32
|
+
/* @__PURE__ */ jsxs("aside", { className: "w-64 bg-white border-r border-gray-200 flex flex-col fixed h-full", children: [
|
|
33
|
+
brand && /* @__PURE__ */ jsx("div", { className: "p-[6.5px] border-b border-gray-100", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-2 items-center", children: [
|
|
34
|
+
brand.logo && (typeof brand.logo === "string" ? /* @__PURE__ */ jsx(
|
|
35
|
+
"img",
|
|
36
|
+
{
|
|
37
|
+
src: brand.logo,
|
|
38
|
+
alt: brand.name ?? "",
|
|
39
|
+
className: "w-12.5 h-12.5"
|
|
40
|
+
}
|
|
41
|
+
) : brand.logo),
|
|
42
|
+
brand.name && /* @__PURE__ */ jsx("p", { className: "text-gray-500 text-base font-semibold", children: brand.name })
|
|
43
|
+
] }) }),
|
|
44
|
+
/* @__PURE__ */ jsx("nav", { className: "flex-1 p-4 overflow-y-auto", children: /* @__PURE__ */ jsx("ul", { className: "space-y-1", children: mainItems.map((item) => {
|
|
45
|
+
const active = isActive(item.href, currentPath);
|
|
46
|
+
const isExpanded = expandedSection === item.id;
|
|
47
|
+
const hasSubItems = item.subItems && item.subItems.length > 0;
|
|
48
|
+
return /* @__PURE__ */ jsxs("li", { children: [
|
|
49
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
50
|
+
/* @__PURE__ */ jsxs(
|
|
51
|
+
"a",
|
|
52
|
+
{
|
|
53
|
+
href: item.href,
|
|
54
|
+
className: `flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors flex-1 ${active ? "bg-gray-200 text-black" : "text-gray-500 hover:bg-gray-100"}`,
|
|
55
|
+
children: [
|
|
56
|
+
item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx("span", { className: "text-lg", children: item.icon }) : isValidElement(item.icon) ? item.icon : createElement(
|
|
57
|
+
item.icon,
|
|
58
|
+
{ size: 20 }
|
|
59
|
+
)),
|
|
60
|
+
item.label
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
active && hasSubItems && /* @__PURE__ */ jsx(
|
|
65
|
+
"button",
|
|
66
|
+
{
|
|
67
|
+
onClick: () => toggleSection(item.id),
|
|
68
|
+
className: `p-1.5 rounded-lg transition-colors ${active ? "text-black hover:bg-gray-100" : "text-gray-500 hover:bg-gray-100"}`,
|
|
69
|
+
title: isExpanded ? "R\xE9duire" : "D\xE9velopper",
|
|
70
|
+
children: toggleIcon ? /* @__PURE__ */ jsx(
|
|
71
|
+
"span",
|
|
72
|
+
{
|
|
73
|
+
className: `inline-block transition-transform duration-200 ${isExpanded ? "rotate-0" : "-rotate-90"}`,
|
|
74
|
+
children: toggleIcon
|
|
75
|
+
}
|
|
76
|
+
) : /* @__PURE__ */ jsx("span", { className: "text-xs", children: isExpanded ? "\u25BC" : "\u25B6" })
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
] }),
|
|
80
|
+
active && hasSubItems && /* @__PURE__ */ jsx(
|
|
81
|
+
"div",
|
|
82
|
+
{
|
|
83
|
+
className: `grid transition-all duration-300 ease-in-out ${isExpanded ? "grid-rows-[1fr]" : "grid-rows-[0fr]"}`,
|
|
84
|
+
children: /* @__PURE__ */ jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsx("ul", { className: "ml-4 mt-1 space-y-1 pl-2", children: item.subItems.map((sub) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
85
|
+
"a",
|
|
86
|
+
{
|
|
87
|
+
href: sub.href,
|
|
88
|
+
className: `flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors ${isExactActive(sub.href, currentPath) ? "bg-gray-200 text-black" : "text-gray-500 hover:bg-gray-100"}`,
|
|
89
|
+
children: sub.label
|
|
90
|
+
}
|
|
91
|
+
) }, sub.id)) }) })
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
] }, item.id);
|
|
95
|
+
}) }) }),
|
|
96
|
+
footer && footer.length > 0 && /* @__PURE__ */ jsx("div", { className: "p-4 border-t border-gray-100 space-y-1", children: footer.map((item) => /* @__PURE__ */ jsxs(
|
|
97
|
+
"a",
|
|
98
|
+
{
|
|
99
|
+
href: item.href,
|
|
100
|
+
className: "flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-100 transition-colors",
|
|
101
|
+
children: [
|
|
102
|
+
typeof item.icon === "string" ? /* @__PURE__ */ jsx("span", { className: "text-lg", children: item.icon }) : isValidElement(item.icon) ? item.icon : createElement(item.icon, {
|
|
103
|
+
size: 20
|
|
104
|
+
}),
|
|
105
|
+
item.label
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
item.label
|
|
109
|
+
)) })
|
|
110
|
+
] }),
|
|
111
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 ml-64", children: [
|
|
112
|
+
headerTitle && /* @__PURE__ */ jsxs("header", { className: "h-16 bg-white border-b border-gray-200 flex items-center justify-between px-6 fixed top-0 right-0 left-64 z-10", children: [
|
|
113
|
+
/* @__PURE__ */ jsx("h1", { className: "text-base font-semibold text-gray-500", children: headerTitle }),
|
|
114
|
+
brand?.tagline && /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: brand.tagline })
|
|
115
|
+
] }),
|
|
116
|
+
/* @__PURE__ */ jsx("main", { className: headerTitle ? "p-6 pt-20" : "p-6", children })
|
|
117
|
+
] })
|
|
118
|
+
] });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// packages/ui/src/config/create-side-nav.tsx
|
|
122
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
123
|
+
function createSideNav(config) {
|
|
124
|
+
return function ConfiguredSideNav({
|
|
125
|
+
children,
|
|
126
|
+
currentPath
|
|
127
|
+
}) {
|
|
128
|
+
return /* @__PURE__ */ jsx2(SideNav, { ...config, currentPath, children });
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export {
|
|
132
|
+
SideNav,
|
|
133
|
+
createSideNav
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../packages/ui/src/layouts/side-nav.tsx","../packages/ui/src/config/create-side-nav.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n ReactNode,\n useState,\n createElement,\n isValidElement,\n type ComponentType,\n} from \"react\";\n\ntype IconType = ReactNode | ComponentType<{ size?: number }>;\n\nexport interface NavItem {\n id: string;\n label: string;\n title?: string;\n icon?: IconType;\n href: string;\n subItems?: NavItem[];\n}\n\nexport interface SideNavStaticConfig {\n brand?: {\n logo?: ReactNode;\n name?: string;\n tagline?: string;\n };\n mainItems: NavItem[];\n title?: string;\n footer?: { icon?: IconType; label: string; href: string }[];\n toggleIcon?: ReactNode;\n}\n\nexport interface SideNavProps extends SideNavStaticConfig {\n children: ReactNode;\n currentPath: string;\n}\n\nfunction isActive(href: string, currentPath: string) {\n return currentPath === href || currentPath.startsWith(href + \"/\");\n}\n\nfunction isExactActive(href: string, currentPath: string) {\n return currentPath === href;\n}\n\nexport function SideNav({\n children,\n title,\n mainItems,\n currentPath,\n brand,\n footer,\n toggleIcon,\n}: SideNavProps) {\n const activeMain = mainItems.find((item) => isActive(item.href, currentPath));\n const headerTitle = title ?? activeMain?.title ?? activeMain?.label;\n const [expandedSection, setExpandedSection] = useState<string | null>(\n activeMain?.id ?? null,\n );\n\n const toggleSection = (id: string) => {\n setExpandedSection((prev) => (prev === id ? null : id));\n };\n\n return (\n <div className=\"flex min-h-screen\">\n <aside className=\"w-64 bg-white border-r border-gray-200 flex flex-col fixed h-full\">\n {brand && (\n <div className=\"p-[6.5px] border-b border-gray-100\">\n <div className=\"flex flex-row gap-2 items-center\">\n {brand.logo &&\n (typeof brand.logo === \"string\" ? (\n <img\n src={brand.logo}\n alt={brand.name ?? \"\"}\n className=\"w-12.5 h-12.5\"\n />\n ) : (\n brand.logo\n ))}\n {brand.name && (\n <p className=\"text-gray-500 text-base font-semibold\">\n {brand.name}\n </p>\n )}\n </div>\n </div>\n )}\n\n <nav className=\"flex-1 p-4 overflow-y-auto\">\n <ul className=\"space-y-1\">\n {mainItems.map((item) => {\n const active = isActive(item.href, currentPath);\n const isExpanded = expandedSection === item.id;\n const hasSubItems = item.subItems && item.subItems.length > 0;\n\n return (\n <li key={item.id}>\n <div className=\"flex items-center gap-1\">\n <a\n href={item.href}\n className={`flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors flex-1 ${\n active\n ? \"bg-gray-200 text-black\"\n : \"text-gray-500 hover:bg-gray-100\"\n }`}\n >\n {item.icon &&\n (typeof item.icon === \"string\" ? (\n <span className=\"text-lg\">{item.icon}</span>\n ) : isValidElement(item.icon) ? (\n item.icon\n ) : (\n createElement(\n item.icon as ComponentType<{ size?: number }>,\n { size: 20 },\n )\n ))}\n {item.label}\n </a>\n {active && hasSubItems && (\n <button\n onClick={() => toggleSection(item.id)}\n className={`p-1.5 rounded-lg transition-colors ${\n active\n ? \"text-black hover:bg-gray-100\"\n : \"text-gray-500 hover:bg-gray-100\"\n }`}\n title={isExpanded ? \"Réduire\" : \"Développer\"}\n >\n {toggleIcon ? (\n <span\n className={`inline-block transition-transform duration-200 ${\n isExpanded ? \"rotate-0\" : \"-rotate-90\"\n }`}\n >\n {toggleIcon}\n </span>\n ) : (\n <span className=\"text-xs\">\n {isExpanded ? \"▼\" : \"▶\"}\n </span>\n )}\n </button>\n )}\n </div>\n\n {active && hasSubItems && (\n <div\n className={`grid transition-all duration-300 ease-in-out ${\n isExpanded ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\"\n }`}\n >\n <div className=\"overflow-hidden\">\n <ul className=\"ml-4 mt-1 space-y-1 pl-2\">\n {item.subItems!.map((sub) => (\n <li key={sub.id}>\n <a\n href={sub.href}\n className={`flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors ${\n isExactActive(sub.href, currentPath)\n ? \"bg-gray-200 text-black\"\n : \"text-gray-500 hover:bg-gray-100\"\n }`}\n >\n {sub.label}\n </a>\n </li>\n ))}\n </ul>\n </div>\n </div>\n )}\n </li>\n );\n })}\n </ul>\n </nav>\n\n {footer && footer.length > 0 && (\n <div className=\"p-4 border-t border-gray-100 space-y-1\">\n {footer.map((item) => (\n <a\n key={item.label}\n href={item.href}\n className=\"flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-100 transition-colors\"\n >\n {typeof item.icon === \"string\" ? (\n <span className=\"text-lg\">{item.icon}</span>\n ) : isValidElement(item.icon) ? (\n item.icon\n ) : (\n createElement(item.icon as ComponentType<{ size?: number }>, {\n size: 20,\n })\n )}\n {item.label}\n </a>\n ))}\n </div>\n )}\n </aside>\n\n <div className=\"flex-1 ml-64\">\n {headerTitle && (\n <header className=\"h-16 bg-white border-b border-gray-200 flex items-center justify-between px-6 fixed top-0 right-0 left-64 z-10\">\n <h1 className=\"text-base font-semibold text-gray-500\">\n {headerTitle}\n </h1>\n {brand?.tagline && (\n <span className=\"text-sm text-gray-500\">{brand.tagline}</span>\n )}\n </header>\n )}\n <main className={headerTitle ? \"p-6 pt-20\" : \"p-6\"}>{children}</main>\n </div>\n </div>\n );\n}\n","import { SideNav, type SideNavStaticConfig } from \"../layouts/side-nav\";\n\nexport function createSideNav(config: SideNavStaticConfig) {\n return function ConfiguredSideNav({\n children,\n currentPath,\n }: {\n children: React.ReactNode;\n currentPath: string;\n }) {\n return (\n <SideNav {...config} currentPath={currentPath}>\n {children}\n </SideNav>\n );\n };\n}\n"],"mappings":"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","names":["jsx"]}
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@import "https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700;900&display=swap";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:"Merriweather", Georgia, serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-700:oklch(55.4% .135 66.442);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-blue-950:oklch(28.2% .091 267.935);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-2xl:42rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-y-0{inset-block:0}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.right-0{right:0}.right-2{right:calc(var(--spacing) * 2)}.right-4{right:calc(var(--spacing) * 4)}.right-8{right:calc(var(--spacing) * 8)}.bottom-4{bottom:calc(var(--spacing) * 4)}.left-0{left:0}.left-4{left:calc(var(--spacing) * 4)}.left-64{left:calc(var(--spacing) * 64)}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.mt-1{margin-top:var(--spacing)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-auto{margin-top:auto}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-1{margin-left:var(--spacing)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-64{margin-left:calc(var(--spacing) * 64)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-12\.5{height:calc(var(--spacing) * 12.5)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-full{height:100%}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-\[85vh\]{max-height:85vh}.min-h-0{min-height:0}.min-h-\[200px\]{min-height:200px}.min-h-screen{min-height:100vh}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-10{width:calc(var(--spacing) * 10)}.w-12\.5{width:calc(var(--spacing) * 12.5)}.w-14{width:calc(var(--spacing) * 14)}.w-64{width:calc(var(--spacing) * 64)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-md{max-width:var(--container-md)}.min-w-\[32px\]{min-width:32px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.table-fixed{table-layout:fixed}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-full{--tw-translate-y:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-0{--tw-translate-y:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.-rotate-90{rotate:-90deg}.rotate-0{rotate:0deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-rows-\[0fr\]{grid-template-rows:0fr}.grid-rows-\[1fr\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-gray-200>:not(:last-child)){border-color:var(--color-gray-200)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-lg{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.rounded-b-md{border-bottom-right-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-blue-100{border-color:var(--color-blue-100)}.border-blue-200{border-color:var(--color-blue-200)}.border-gray-100{border-color:var(--color-gray-100)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-400{border-color:var(--color-gray-400)}.border-red-200{border-color:var(--color-red-200)}.border-yellow-200{border-color:var(--color-yellow-200)}.bg-\[\#0C44AA\]{background-color:#0c44aa}.bg-black\/20{background-color:#0003}@supports (color:color-mix(in lab, red, red)){.bg-black\/20{background-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-700{background-color:var(--color-gray-700)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-400{background-color:var(--color-red-400)}.bg-red-500{background-color:var(--color-red-500)}.bg-white{background-color:var(--color-white)}.bg-yellow-50{background-color:var(--color-yellow-50)}.bg-yellow-100{background-color:var(--color-yellow-100)}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-blue-50{--tw-gradient-from:var(--color-blue-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-blue-100{--tw-gradient-to:var(--color-blue-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.bg-contain{background-size:contain}.bg-right{background-position:100%}.bg-no-repeat{background-repeat:no-repeat}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-\[6\.5px\]{padding:6.5px}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-20{padding-block:calc(var(--spacing) * 20)}.pt-20{padding-top:calc(var(--spacing) * 20)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-10{padding-right:calc(var(--spacing) * 10)}.pr-16{padding-right:calc(var(--spacing) * 16)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.whitespace-nowrap{white-space:nowrap}.text-black{color:var(--color-black)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-gray-100{color:var(--color-gray-100)}.text-gray-200{color:var(--color-gray-200)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-white{color:var(--color-white)}.text-yellow-700{color:var(--color-yellow-700)}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.placeholder-gray-400::placeholder{color:var(--color-gray-400)}.opacity-0{opacity:0}.opacity-60{opacity:.6}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-gray-900\/5{--tw-ring-color:#1018280d}@supports (color:color-mix(in lab, red, red)){.ring-gray-900\/5{--tw-ring-color:color-mix(in oklab, var(--color-gray-900) 5%, transparent)}}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ring-inset{--tw-ring-inset:inset}@media (hover:hover){.group-hover\:from-blue-100:is(:where(.group):hover *){--tw-gradient-from:var(--color-blue-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.group-hover\:to-blue-200:is(:where(.group):hover *){--tw-gradient-to:var(--color-blue-200);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.group-hover\:text-blue-700:is(:where(.group):hover *){color:var(--color-blue-700)}.group-hover\:text-gray-600:is(:where(.group):hover *){color:var(--color-gray-600)}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\:ring-blue-300\/50:is(:where(.group):hover *){--tw-ring-color:#90c5ff80}@supports (color:color-mix(in lab, red, red)){.group-hover\:ring-blue-300\/50:is(:where(.group):hover *){--tw-ring-color:color-mix(in oklab, var(--color-blue-300) 50%, transparent)}}.hover\:cursor-pointer:hover{cursor:pointer}.hover\:border-blue-300:hover{border-color:var(--color-blue-300)}.hover\:bg-\[\#0a3a94\]:hover{background-color:#0a3a94}.hover\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-600:hover{background-color:var(--color-gray-600)}.hover\:bg-red-200:hover{background-color:var(--color-red-200)}.hover\:bg-red-500:hover{background-color:var(--color-red-500)}.hover\:text-gray-600:hover{color:var(--color-gray-600)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:shadow:hover{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hover\:shadow-xl:hover{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\:border-transparent:focus{border-color:#0000}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-blue-400:focus{--tw-ring-color:var(--color-blue-400)}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\:ring-gray-500:focus{--tw-ring-color:var(--color-gray-500)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (hover:hover){.disabled\:hover\:bg-red-500:disabled:hover{background-color:var(--color-red-500)}.disabled\:hover\:bg-white:disabled:hover{background-color:var(--color-white)}}@media (min-width:48rem){.md\:inline-flex{display:inline-flex}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}}@media (prefers-color-scheme:dark){.dark\:border-blue-900{border-color:var(--color-blue-900)}.dark\:bg-blue-600{background-color:var(--color-blue-600)}.dark\:bg-blue-900{background-color:var(--color-blue-900)}.dark\:bg-blue-950{background-color:var(--color-blue-950)}.dark\:bg-gray-800{background-color:var(--color-gray-800)}.dark\:text-blue-300{color:var(--color-blue-300)}.dark\:text-gray-100{color:var(--color-gray-100)}.dark\:text-gray-300{color:var(--color-gray-300)}.dark\:text-gray-400{color:var(--color-gray-400)}@media (hover:hover){.dark\:hover\:bg-blue-500:hover{background-color:var(--color-blue-500)}.dark\:hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.dark\:hover\:text-gray-300:hover{color:var(--color-gray-300)}}}@media print{.print\:hidden{display:none}.print\:table-row-group{display:table-row-group}.print\:table-fixed{table-layout:fixed}}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ramses1er/cbk-toolkit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./styles.css": "./dist/styles.css"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"react": ">=18",
|
|
19
|
+
"react-dom": ">=18"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@tailwindcss/cli": "^4.3.1",
|
|
23
|
+
"@types/react": "^19",
|
|
24
|
+
"@types/react-dom": "^19",
|
|
25
|
+
"tailwindcss": "^4.3.1",
|
|
26
|
+
"tsup": "^8.5.0"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup && pnpm build:css",
|
|
30
|
+
"build:css": "pnpm exec tailwindcss -i src/styles.css -o dist/styles.css --minify",
|
|
31
|
+
"dev": "tsup --watch",
|
|
32
|
+
"clean": "rm -rf dist"
|
|
33
|
+
}
|
|
34
|
+
}
|