|
| 1 | +import React, { useState } from "react"; |
| 2 | + |
1 | 3 | import { MultiLevelTable } from "./components/MultiLevelTable"; |
| 4 | +import { darkTheme, lightTheme } from "./themes"; |
| 5 | +import type { ThemeProps } from "./types/theme"; |
| 6 | +import type { Column, DataItem } from "./types/types"; |
| 7 | + |
| 8 | +import "./App.css"; |
2 | 9 |
|
3 | | -const data = [ |
| 10 | +const data: DataItem[] = [ |
4 | 11 | { |
5 | 12 | id: 1, |
6 | 13 | name: "Parent 1", |
@@ -357,75 +364,103 @@ const data = [ |
357 | 364 | }, |
358 | 365 | ]; |
359 | 366 |
|
360 | | -const columns = [ |
361 | | - { |
362 | | - key: "name", |
363 | | - title: "Name", |
364 | | - filterable: true, |
365 | | - }, |
366 | | - { |
367 | | - key: "value", |
368 | | - title: "Value", |
369 | | - render: (value: unknown) => `$${value as number}`, |
370 | | - filterable: true, |
371 | | - }, |
372 | | - { |
373 | | - key: "status", |
374 | | - title: "Status", |
375 | | - filterable: true, |
376 | | - sortable: true, |
377 | | - customSortFn: (rowA: any, rowB: any, columnId: string) => { |
378 | | - const statusOrder = { 'Active': 0, 'Pending': 1, 'Inactive': 2 }; |
379 | | - const statusA = String(rowA[columnId]); |
380 | | - const statusB = String(rowB[columnId]); |
381 | | - |
382 | | - return (statusOrder[statusA as keyof typeof statusOrder] || 0) - (statusOrder[statusB as keyof typeof statusOrder] || 0); |
| 367 | +const StatusCell: React.FC<{ value: string; theme: ThemeProps }> = ({ |
| 368 | + value, |
| 369 | +}) => { |
| 370 | + return ( |
| 371 | + <span |
| 372 | + style={{ |
| 373 | + padding: "4px 8px", |
| 374 | + borderRadius: "4px", |
| 375 | + backgroundColor: "#ffffff", |
| 376 | + color: |
| 377 | + value === "Active" |
| 378 | + ? "#2ecc71" |
| 379 | + : value === "Inactive" |
| 380 | + ? "#e74c3c" |
| 381 | + : "#f1c40f", |
| 382 | + }} |
| 383 | + > |
| 384 | + {value} |
| 385 | + </span> |
| 386 | + ); |
| 387 | +}; |
| 388 | + |
| 389 | +const App: React.FC = () => { |
| 390 | + const [isDarkMode, setIsDarkMode] = useState(false); |
| 391 | + const theme = isDarkMode ? darkTheme : lightTheme; |
| 392 | + |
| 393 | + const toggleTheme = () => { |
| 394 | + setIsDarkMode((prev) => !prev); |
| 395 | + }; |
| 396 | + |
| 397 | + const columns: Column[] = [ |
| 398 | + { |
| 399 | + key: "name", |
| 400 | + title: "Name", |
| 401 | + filterable: true, |
383 | 402 | }, |
384 | | - render: (value: unknown) => ( |
385 | | - <span |
386 | | - style={{ |
387 | | - padding: "4px 8px", |
388 | | - borderRadius: "4px", |
389 | | - backgroundColor: |
390 | | - value === "Active" |
391 | | - ? "#e6ffe6" |
392 | | - : value === "Inactive" |
393 | | - ? "#ffe6e6" |
394 | | - : "#fff2e6", |
395 | | - color: |
396 | | - value === "Active" |
397 | | - ? "#006600" |
398 | | - : value === "Inactive" |
399 | | - ? "#cc0000" |
400 | | - : "#cc7700", |
401 | | - }} |
402 | | - > |
403 | | - {value as string} |
404 | | - </span> |
405 | | - ), |
406 | | - }, |
407 | | -]; |
| 403 | + { |
| 404 | + key: "value", |
| 405 | + title: "Value", |
| 406 | + filterable: true, |
| 407 | + render: (value: string | number) => `$${value}`, |
| 408 | + }, |
| 409 | + { |
| 410 | + key: "status", |
| 411 | + title: "Status", |
| 412 | + filterable: true, |
| 413 | + render: (value: string | number) => ( |
| 414 | + <StatusCell value={value as string} theme={theme} /> |
| 415 | + ), |
| 416 | + }, |
| 417 | + ]; |
408 | 418 |
|
409 | | -const renderCustomPagination = () => { |
410 | | - return <div>Custom Pagination </div>; |
411 | | -}; |
| 419 | + // eslint-disable-next-line @typescript-eslint/no-unused-vars |
| 420 | + const renderCustomPagination = () => { |
| 421 | + return <div>Custom Pagination </div>; |
| 422 | + }; |
412 | 423 |
|
413 | | -function App() { |
414 | 424 | return ( |
415 | | - <div style={{ padding: "20px", maxWidth: "1200px", margin: "0 auto" }}> |
416 | | - <h1>React Multi Level Table Demo</h1> |
417 | | - <p>Features: Sorting, Filtering, Pagination, and Nested Data</p> |
418 | | - <MultiLevelTable |
419 | | - data={data} |
420 | | - columns={columns} |
421 | | - pageSize={5} |
422 | | - sortable={true} |
423 | | - ascendingIcon={<div>↑</div>} |
424 | | - descendingIcon={<div>↓</div>} |
425 | | - renderCustomPagination={renderCustomPagination} |
426 | | - /> |
| 425 | + <div className="app" style={{ backgroundColor: theme.colors?.background }}> |
| 426 | + <header |
| 427 | + className="app-header" |
| 428 | + style={{ backgroundColor: theme.table?.header?.background }} |
| 429 | + > |
| 430 | + <h1 style={{ color: theme.table?.header?.textColor }}> |
| 431 | + Multi-Level Table Demo |
| 432 | + </h1> |
| 433 | + <button |
| 434 | + className="theme-toggle" |
| 435 | + onClick={toggleTheme} |
| 436 | + style={{ |
| 437 | + backgroundColor: theme.colors?.primaryColor, |
| 438 | + color: "#ffffff", |
| 439 | + borderColor: theme.colors?.borderColor, |
| 440 | + }} |
| 441 | + > |
| 442 | + {isDarkMode ? "☀️ Light Mode" : "🌙 Dark Mode"} |
| 443 | + </button> |
| 444 | + </header> |
| 445 | + |
| 446 | + <main className="app-content"> |
| 447 | + <div |
| 448 | + className="table-container" |
| 449 | + style={{ backgroundColor: theme.colors?.background }} |
| 450 | + > |
| 451 | + <MultiLevelTable |
| 452 | + data={data} |
| 453 | + columns={columns} |
| 454 | + theme={theme} |
| 455 | + pageSize={5} |
| 456 | + sortable={true} |
| 457 | + ascendingIcon={<div>↑</div>} |
| 458 | + descendingIcon={<div>↓</div>} |
| 459 | + /> |
| 460 | + </div> |
| 461 | + </main> |
427 | 462 | </div> |
428 | 463 | ); |
429 | | -} |
| 464 | +}; |
430 | 465 |
|
431 | 466 | export default App; |
0 commit comments