kelt-ui-kit-react 1.7.5 → 1.7.8

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kelt-ui-kit-react",
3
3
  "type": "module",
4
- "version": "1.7.5",
4
+ "version": "1.7.8",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { useEffect, useMemo, useState } from "react";
1
+ import { CSSProperties, useEffect, useMemo, useState } from "react";
2
2
  import "./damier.css";
3
3
  import { DamierCell } from "./damierCell/DamierCell";
4
4
  import { DamierCellInterface } from "./damierCell/damierCell.interface";
@@ -17,7 +17,7 @@ export const Damier = ({
17
17
  onClick,
18
18
  }: DamierProps) => {
19
19
  const nbCols = useMemo(() => cols ?? 9, [cols]);
20
- const nbRows = useMemo(() => rows ?? 9, [rows]);
20
+ const nbRows = useMemo(() => Math.max(1, rows ?? 9), [rows]);
21
21
  const [currentPage, setCurrentPage] = useState(1);
22
22
  useEffect(() => {
23
23
  setCurrentPage(page);
@@ -30,26 +30,35 @@ export const Damier = ({
30
30
  for (let col = 0; col < nbCols; col++) {
31
31
  const position = col + row * nbCols;
32
32
  const cell = damierCells?.find(
33
- (cell) => cell.position === position + 1
33
+ (cell) => cell.position === position + 1,
34
34
  );
35
35
  if (!cell) {
36
36
  colsArray.push(
37
- <div key={`${row}-${col}`} className="cell cell--empty"></div>
37
+ <div key={`${row}-${col}`} className="cell cell--empty"></div>,
38
38
  );
39
39
  } else {
40
40
  colsArray.push(
41
- <DamierCell onClick={onClick} key={`${row}-${col}`} cell={cell} />
41
+ <DamierCell onClick={onClick} key={`${row}-${col}`} cell={cell} />,
42
42
  );
43
43
  }
44
44
  }
45
45
  rowsArray.push(
46
46
  <div key={row} className="row">
47
47
  {colsArray}
48
- </div>
48
+ </div>,
49
49
  );
50
50
  }
51
51
  return rowsArray;
52
52
  }, [nbCols, nbRows, currentPage]);
53
53
 
54
- return <div className="damier">{grid}</div>;
54
+ const damierStyle = useMemo(
55
+ () => ({ "--rows": String(nbRows) }) as CSSProperties,
56
+ [nbRows],
57
+ );
58
+
59
+ return (
60
+ <div className="damier" style={damierStyle}>
61
+ {grid}
62
+ </div>
63
+ );
55
64
  };
@@ -5,10 +5,12 @@
5
5
  margin-bottom: 1rem;
6
6
  width: 100%;
7
7
  --sizeDamier: 630;
8
+ --rows: 9;
9
+
8
10
  .row {
9
11
  display: flex;
10
12
  height: 90px;
11
- width: calc(var(--sizeDamier) / 9);
13
+ width: calc(var(--sizeDamier) / var(--rows));
12
14
  min-height: 40px;
13
15
  }
14
16
 
@@ -22,9 +24,11 @@
22
24
  align-items: center;
23
25
  justify-content: center;
24
26
  background-color: #fff;
27
+
25
28
  &.cell--empty {
26
29
  background: #f9f9f9;
27
30
  }
31
+
28
32
  &:not(.cell--empty) {
29
33
  cursor: pointer;
30
34
  }
@@ -34,11 +38,13 @@
34
38
  @media (min-width: 768px) {
35
39
  .damier {
36
40
  --sizeDamier: 990;
41
+
37
42
  .row {
38
- height: calc(100vh / 9.6);
43
+ height: calc(100vh / var(--rows));
39
44
  }
45
+
40
46
  .cell {
41
- height: calc(100vh / 9) - 1;
47
+ height: calc((100vh / var(--rows)) - 1px);
42
48
  }
43
49
  }
44
- }
50
+ }
@@ -55,7 +55,7 @@ export function DataTable<T>(props: DataTableProps<T>) {
55
55
 
56
56
  const loaderRef = useRef<HTMLDivElement | null>(null);
57
57
  const [selectedRowIds, setSelectedRowIds] = useState<Set<string | number>>(
58
- new Set(),
58
+ new Set()
59
59
  );
60
60
  const toggleSelectAll = useCallback(() => {
61
61
  if (selectedRowIds.size === data.length) {
@@ -63,7 +63,7 @@ export function DataTable<T>(props: DataTableProps<T>) {
63
63
  onSelectionChange?.([]);
64
64
  } else {
65
65
  let allIds = data.map((d) =>
66
- getRowId ? getRowId(d) : ((d as any).id ?? d),
66
+ getRowId ? getRowId(d) : (d as any).id ?? d
67
67
  );
68
68
 
69
69
  if (limitSelect && allIds.length > limitSelect) {
@@ -74,8 +74,8 @@ export function DataTable<T>(props: DataTableProps<T>) {
74
74
  setSelectedRowIds(newSelection);
75
75
  onSelectionChange?.(
76
76
  data.filter((d) =>
77
- newSelection.has(getRowId ? getRowId(d) : ((d as any).id ?? d)),
78
- ),
77
+ newSelection.has(getRowId ? getRowId(d) : (d as any).id ?? d)
78
+ )
79
79
  );
80
80
  }
81
81
  }, [data, onSelectionChange, limitSelect, getRowId, selectedRowIds.size]);
@@ -87,12 +87,12 @@ export function DataTable<T>(props: DataTableProps<T>) {
87
87
  onRowClick?.(row);
88
88
  }
89
89
  },
90
- [onRowClick],
90
+ [onRowClick]
91
91
  );
92
92
  const toggleRow = useCallback(
93
93
  (e: React.ChangeEvent<HTMLInputElement>, row: T) => {
94
94
  e.stopPropagation();
95
- const rowId = getRowId ? getRowId(row) : ((row as any).id ?? row);
95
+ const rowId = getRowId ? getRowId(row) : (row as any).id ?? row;
96
96
  const newSelection = new Set(selectedRowIds);
97
97
 
98
98
  if (newSelection.has(rowId)) {
@@ -107,11 +107,11 @@ export function DataTable<T>(props: DataTableProps<T>) {
107
107
 
108
108
  setSelectedRowIds(newSelection);
109
109
  const selectedItems = data.filter((d) =>
110
- newSelection.has(getRowId ? getRowId(d) : ((d as any).id ?? d)),
110
+ newSelection.has(getRowId ? getRowId(d) : (d as any).id ?? d)
111
111
  );
112
112
  onSelectionChange?.(selectedItems);
113
113
  },
114
- [data, getRowId, limitSelect, onSelectionChange, selectedRowIds],
114
+ [data, getRowId, limitSelect, onSelectionChange, selectedRowIds]
115
115
  );
116
116
  useEffect(() => {
117
117
  if (!onLoadMore || !hasMore) return;
@@ -126,7 +126,7 @@ export function DataTable<T>(props: DataTableProps<T>) {
126
126
  root: null,
127
127
  rootMargin: "0px",
128
128
  threshold: 1.0,
129
- },
129
+ }
130
130
  );
131
131
 
132
132
  if (loaderRef.current) {
@@ -139,11 +139,6 @@ export function DataTable<T>(props: DataTableProps<T>) {
139
139
  }
140
140
  };
141
141
  }, [onLoadMore, hasMore]);
142
- const hasNestedColumns = columns.some((col) => col.children?.length);
143
-
144
- const flatColumns = columns.flatMap((col) =>
145
- col.children?.length ? col.children : [col],
146
- );
147
142
  return (
148
143
  <div className="data-table-container">
149
144
  {name && <h2 className="mb-2">{name}</h2>}
@@ -167,11 +162,9 @@ export function DataTable<T>(props: DataTableProps<T>) {
167
162
  />
168
163
  </th>
169
164
  )}
170
-
171
165
  {columns.map((column, idx) => (
172
- <DataTableColumn<T>
166
+ <DataTableColumn
173
167
  key={idx}
174
- hasNestedColumns={hasNestedColumns}
175
168
  column={column}
176
169
  idx={idx}
177
170
  onColumnClick={onColumnClick}
@@ -184,26 +177,9 @@ export function DataTable<T>(props: DataTableProps<T>) {
184
177
  }}
185
178
  align="right"
186
179
  key={"actions"}
187
- rowSpan={hasNestedColumns ? 2 : 1}
188
180
  ></th>
189
181
  )}
190
182
  </tr>
191
- {hasNestedColumns && (
192
- <tr>
193
- {columns.flatMap(
194
- (col, idx) =>
195
- col.children?.map((child, childIdx) => (
196
- <th
197
- key={`${idx}-${childIdx}`}
198
- style={{ textAlign: child.align ?? "left" }}
199
- onClick={() => onColumnClick?.(child)}
200
- >
201
- {child.label}
202
- </th>
203
- )) ?? [],
204
- )}
205
- </tr>
206
- )}
207
183
  </thead>
208
184
  <tbody>
209
185
  {loading ? (
@@ -233,17 +209,17 @@ export function DataTable<T>(props: DataTableProps<T>) {
233
209
  limitSelect !== undefined &&
234
210
  selectedRowIds.size >= limitSelect &&
235
211
  !selectedRowIds.has(
236
- getRowId ? getRowId(row) : ((row as any).id ?? row),
212
+ getRowId ? getRowId(row) : (row as any).id ?? row
237
213
  )
238
214
  }
239
215
  checked={selectedRowIds.has(
240
- getRowId ? getRowId(row) : ((row as any).id ?? row),
216
+ getRowId ? getRowId(row) : (row as any).id ?? row
241
217
  )}
242
218
  onChange={(e) => toggleRow(e, row)} // empêche le clic de déclencher onRowClick
243
219
  />
244
220
  </td>
245
221
  )}
246
- {flatColumns.map((column, idx) => (
222
+ {columns.map((column, idx) => (
247
223
  <DataTableRow column={column} idx={idx} row={row} key={idx} />
248
224
  ))}
249
225
  {actions.length > 0 && (
@@ -7,7 +7,6 @@ export interface dataTableColumnsInterface<T> {
7
7
  maxWidth?: number;
8
8
  width?: number;
9
9
  align?: "right" | "left" | "center";
10
- alignText?: "right" | "left" | "center";
11
10
  format?: (value: any) => string;
12
11
  sortable?: boolean;
13
12
  filterable?: boolean;
@@ -16,9 +15,7 @@ export interface dataTableColumnsInterface<T> {
16
15
  options?: { label: string; value: string }[];
17
16
  onEdit?: (value: any, row: T) => void;
18
17
  onRowStyle?: (row: T) => React.CSSProperties;
19
- renderComponent?: (value: any, row: T) => JSX.Element;
20
18
  type: HTMLInputTypeAttribute | "select";
21
- children?: dataTableColumnsInterface<T>[];
22
19
  }
23
20
  export interface dataTableActionsInterface<T> {
24
21
  id: string;
@@ -1,16 +1,15 @@
1
1
  import { dataTableColumnsInterface } from "../dataTable.interface";
2
2
 
3
- export function DataTableColumn<T>({
3
+ type DataTableColumnProps = {
4
+ column: dataTableColumnsInterface<any>;
5
+ idx: number;
6
+ onColumnClick?: (column: dataTableColumnsInterface<any>) => void;
7
+ };
8
+ export const DataTableColumn = ({
4
9
  column,
5
10
  idx,
6
11
  onColumnClick,
7
- hasNestedColumns,
8
- }: {
9
- hasNestedColumns: boolean;
10
- column: dataTableColumnsInterface<T>;
11
- idx: number;
12
- onColumnClick?: (column: dataTableColumnsInterface<T>) => void;
13
- }) {
12
+ }: DataTableColumnProps) => {
14
13
  return (
15
14
  <th
16
15
  key={`colonne-${column.id}-${idx}`}
@@ -18,15 +17,11 @@ export function DataTableColumn<T>({
18
17
  minWidth: column.minWidth,
19
18
  maxWidth: column.maxWidth,
20
19
  width: column.width,
21
- textAlign: column.align ?? "left",
22
- alignContent: column.children ? "center" : "flex-end",
20
+ textAlign: column.align || "left",
23
21
  }}
24
- className={column.children ? "has-children" : ""}
25
- colSpan={column.children?.length ?? 1}
26
- rowSpan={!column.children?.length && hasNestedColumns ? 2 : 1}
27
22
  onClick={() => onColumnClick?.(column)}
28
23
  >
29
24
  {column.label}
30
25
  </th>
31
26
  );
32
- }
27
+ };
@@ -1,5 +1,5 @@
1
+ import { Select } from "../../select/Select";
1
2
  import { dataTableColumnsInterface } from "../dataTable.interface";
2
- import { DataTableRowValue } from "./dataTableRowValue/DataTableRowValue";
3
3
 
4
4
  type DataTableRowProps = {
5
5
  column: dataTableColumnsInterface<any>;
@@ -13,16 +13,41 @@ export const DataTableRow = ({ column, idx, row }: DataTableRowProps) => {
13
13
  <td
14
14
  style={{
15
15
  minWidth: column.minWidth,
16
- textAlign: column.alignText ? column.alignText : column.align || "left",
16
+ textAlign: column.align || "left",
17
17
  maxWidth: column.maxWidth,
18
18
  width: column.width,
19
19
  ...style,
20
20
  }}
21
21
  key={`row-${column.id}-${idx}`}
22
22
  >
23
- {column.renderComponent ? column.renderComponent(value, row) : null}
24
- {!column.renderComponent && (
25
- <DataTableRowValue column={column} value={value} row={row} idx={idx} />
23
+ {column.editable ? (
24
+ column.type === "select" ? (
25
+ <Select
26
+ options={column.options ?? []}
27
+ value={value}
28
+ onChange={(e) => {
29
+ if (column.onEdit) {
30
+ column.onEdit(e, row);
31
+ }
32
+ }}
33
+ />
34
+ ) : (
35
+ <input
36
+ type={column.type}
37
+ value={value}
38
+ step="0.01"
39
+ style={{ textAlign: column.align || "left" }}
40
+ onChange={(e) => {
41
+ if (column.onEdit) {
42
+ column.onEdit(e.target.value, row);
43
+ }
44
+ }}
45
+ />
46
+ )
47
+ ) : column.format ? (
48
+ column.format(value)
49
+ ) : (
50
+ value
26
51
  )}
27
52
  </td>
28
53
  );
@@ -17,7 +17,6 @@ export interface InputProps {
17
17
  required?: boolean;
18
18
  minLength?: number;
19
19
  maxLength?: number;
20
- width?: string;
21
20
  autoComplete?: string;
22
21
  step?: string;
23
22
  tabIndex?: number;
@@ -35,7 +34,6 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
35
34
  name,
36
35
  type = TypeInputEnum.TEXT,
37
36
  value,
38
- width,
39
37
  onInvalid,
40
38
  placeholder,
41
39
  className,
@@ -54,16 +52,13 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
54
52
  onClick,
55
53
  handleKeyDown,
56
54
  },
57
- ref,
55
+ ref
58
56
  ) => {
59
57
  // Si le type est password, on utilise l'input de type password
60
58
  const [showPassword, setShowPassword] = useState(false);
61
59
 
62
60
  return (
63
- <div
64
- className={`input-container ${`input-container-${type}`} `}
65
- style={{ width }}
66
- >
61
+ <div className={`input-container ${`input-container-${type}`} `}>
67
62
  <input name={`hide-${name}`} type="text" style={{ display: "none" }} />
68
63
 
69
64
  <input
@@ -105,7 +100,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
105
100
  )}
106
101
  </div>
107
102
  );
108
- },
103
+ }
109
104
  );
110
105
 
111
106
  Input.displayName = "Input";
@@ -8,8 +8,10 @@ export type InputNumberProps = {
8
8
  value?: string; // ⚠️ string pour gérer la saisie manuelle
9
9
  placeholder?: string;
10
10
  className?: string;
11
+ pattern?: string; // regex pour validation (ex: "^-?\\d*[.,]?\\d*$" pour nombre décimal)
11
12
  disabled?: boolean;
12
13
  required?: boolean;
14
+ inputMode?: "numeric" | "decimal";
13
15
  autoFocus?: boolean;
14
16
  maxLength?: number;
15
17
  autoComplete?: string;
@@ -17,7 +19,7 @@ export type InputNumberProps = {
17
19
  onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
18
20
  onChange?: (
19
21
  e: React.ChangeEvent<HTMLInputElement>,
20
- valueFormat?: string
22
+ valueFormat?: string,
21
23
  ) => void;
22
24
  onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
23
25
  onClick?: (e: React.MouseEvent<HTMLInputElement>) => void;
@@ -38,13 +40,15 @@ export const InputNumber = forwardRef<HTMLInputElement, InputNumberProps>(
38
40
  maxLength = 10,
39
41
  autoComplete = "off",
40
42
  tabIndex = 0,
43
+ inputMode = "numeric",
44
+ pattern,
41
45
  onChange,
42
46
  onBlur,
43
47
  onClick,
44
48
  onKeyDown,
45
49
  onFocus,
46
50
  },
47
- ref
51
+ ref,
48
52
  ) => {
49
53
  const handleChange = useCallback(
50
54
  (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -62,7 +66,7 @@ export const InputNumber = forwardRef<HTMLInputElement, InputNumberProps>(
62
66
 
63
67
  onChange?.(e, newValue);
64
68
  },
65
- [onChange, maxLength]
69
+ [onChange, maxLength],
66
70
  );
67
71
 
68
72
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
@@ -72,7 +76,7 @@ export const InputNumber = forwardRef<HTMLInputElement, InputNumberProps>(
72
76
  // ✅ Autoriser chiffres, contrôle, ., , et -
73
77
  const allowed =
74
78
  /[0-9]|Backspace|Delete|ArrowLeft|ArrowRight|Tab|Enter|Home|End/.test(
75
- e.key
79
+ e.key,
76
80
  ) ||
77
81
  e.key === "." ||
78
82
  e.key === "," ||
@@ -105,8 +109,9 @@ export const InputNumber = forwardRef<HTMLInputElement, InputNumberProps>(
105
109
  required={required}
106
110
  autoFocus={autoFocus}
107
111
  autoComplete={autoComplete}
112
+ pattern={pattern}
108
113
  tabIndex={tabIndex}
109
- inputMode="numeric" // mobile keyboard adaptatif
114
+ inputMode={inputMode} // mobile keyboard adaptatif
110
115
  spellCheck="false"
111
116
  className={`input-field ${className ?? ""}`}
112
117
  onChange={handleChange}
@@ -121,7 +126,7 @@ export const InputNumber = forwardRef<HTMLInputElement, InputNumberProps>(
121
126
  />
122
127
  </div>
123
128
  );
124
- }
129
+ },
125
130
  );
126
131
 
127
132
  InputNumber.displayName = "InputNumber";
@@ -18,7 +18,7 @@ export const InputPrice = forwardRef<HTMLInputElement, InputPriceProps>(
18
18
  onChange,
19
19
  ...props
20
20
  },
21
- ref
21
+ ref,
22
22
  ) => {
23
23
  const handleBlur = useCallback(() => {
24
24
  if (onChange) {
@@ -31,10 +31,12 @@ export const InputPrice = forwardRef<HTMLInputElement, InputPriceProps>(
31
31
  <InputNumber
32
32
  {...props}
33
33
  ref={ref}
34
+ pattern="[0-9]*[.,]?[0-9]*"
35
+ inputMode="decimal" // mobile keyboard adaptatif
34
36
  value={value ?? ""}
35
37
  onChange={(e) => onChange?.(e.target.value)}
36
38
  onBlur={handleBlur} // Force le formatage à 2 décimales en sortie
37
39
  />
38
40
  );
39
- }
41
+ },
40
42
  );
package/src/index.ts CHANGED
@@ -24,7 +24,6 @@ export { Badge } from "./badge/Badge";
24
24
  export { Button } from "./button/Button";
25
25
  export { ButtonActions } from "./button/buttonActions/ButtonActions";
26
26
  export { ButtonFile } from "./button/buttonFile/ButtonFile";
27
- export { ButtonFilters } from "./button/buttonFilters/ButtonFilters";
28
27
  export { Card } from "./card/Card";
29
28
  export { Carousel } from "./carousel/Carousel";
30
29
  export { Damier } from "./damier/Damier";
@@ -1,31 +0,0 @@
1
- name: Build & Publish npm Package
2
-
3
- on:
4
- push:
5
- branches:
6
- - develop
7
-
8
- jobs:
9
- publish:
10
- runs-on: ubuntu-latest
11
-
12
- steps:
13
- - name: Checkout code
14
- uses: actions/checkout@v4
15
-
16
- - name: Setup Node.js
17
- uses: actions/setup-node@v4
18
- with:
19
- node-version: "20"
20
- registry-url: "https://registry.npmjs.org"
21
-
22
- - name: Install dependencies
23
- run: npm ci
24
-
25
- - name: Build package
26
- run: npm run build
27
-
28
- - name: Publish to npm
29
- run: npm publish --access public
30
- env:
31
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -1,10 +0,0 @@
1
- import { dataTableColumnsInterface } from '../../dataTable.interface';
2
-
3
- type DataTableRowValueProps = {
4
- column: dataTableColumnsInterface<any>;
5
- idx: number;
6
- value: any;
7
- row: any;
8
- };
9
- export declare const DataTableRowValue: ({ column, row, value, }: DataTableRowValueProps) => import("react/jsx-runtime").JSX.Element;
10
- export {};
@@ -1,52 +0,0 @@
1
- import { Select } from "../../../select/Select";
2
- import { dataTableColumnsInterface } from "../../dataTable.interface";
3
-
4
- type DataTableRowValueProps = {
5
- column: dataTableColumnsInterface<any>;
6
- idx: number;
7
- value: any;
8
- row: any;
9
- };
10
- export const DataTableRowValue = ({
11
- column,
12
- row,
13
- value,
14
- }: DataTableRowValueProps) => {
15
- return (
16
- <>
17
- {column.editable ? (
18
- column.type === "select" ? (
19
- <Select
20
- options={column.options ?? []}
21
- value={value}
22
- onChange={(e) => {
23
- if (column.onEdit) {
24
- column.onEdit(e, row);
25
- }
26
- }}
27
- />
28
- ) : (
29
- <input
30
- type={column.type}
31
- value={value}
32
- step="0.01"
33
- style={{
34
- textAlign: column.alignText
35
- ? column.alignText
36
- : column.align || "left",
37
- }}
38
- onChange={(e) => {
39
- if (column.onEdit) {
40
- column.onEdit(e.target.value, row);
41
- }
42
- }}
43
- />
44
- )
45
- ) : column.format ? (
46
- column.format(value)
47
- ) : (
48
- value
49
- )}
50
- </>
51
- );
52
- };