From 882439787b4815eb1a209514ba4e58c7d703a07b Mon Sep 17 00:00:00 2001 From: fathima Date: Mon, 28 Jul 2025 17:48:25 +0530 Subject: [PATCH] fix: Update readme, remove unused files --- README.md | 370 +++++++++++++++++++++++++-------- example/README.md | 82 -------- src/styles/ExportDropdown.css | 43 ---- src/styles/FilterDropdown.css | 252 ---------------------- src/styles/RowDetailsPopup.css | 184 ---------------- src/styles/SidePanel.css | 47 ----- src/styles/SidePanelInput.css | 41 ---- 7 files changed, 280 insertions(+), 739 deletions(-) delete mode 100644 example/README.md delete mode 100644 src/styles/ExportDropdown.css delete mode 100644 src/styles/FilterDropdown.css delete mode 100644 src/styles/RowDetailsPopup.css delete mode 100644 src/styles/SidePanel.css delete mode 100644 src/styles/SidePanelInput.css diff --git a/README.md b/README.md index 47a7f69..1661b1d 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,19 @@ - [Component Props](#22-component-props) - [Customization](#3-customization) - [Column Configuration](#31-column-configuration) - - [Expand Icon Customization](#32-expand-icon-customization) - - [Selection Props](#33-selection-props) - - [Sort Icons](#34-sort-icons) - - [Pagination](#35-pagination) - - [Theme Customization](#36-theme-customization) + - [DataItem Interface](#32-dataitem-interface) + - [FilterOption Interface](#33-filteroption-interface) + - [Expand Icon Customization](#34-expand-icon-customization) + - [Selection Props](#35-selection-props) + - [Sort Icons](#36-sort-icons) + - [Search and Filter Features](#37-search-and-filter-features) + - [Export Functionality](#38-export-functionality) + - [Delete Functionality](#39-delete-functionality) + - [Dropdown Management](#310-dropdown-management) + - [Row Actions](#311-row-actions) + - [Row Expansion](#312-row-expansion) + - [Pagination](#313-pagination) + - [Theme Customization](#314-theme-customization) - [Development](#4-development) - [Project Structure](#41-project-structure) - [Development Commands](#42-development-commands) @@ -194,19 +202,44 @@ Each column object should have the following properties: | Property | Type | Required | Description | |----------|------|----------|-------------| | key | string | Yes | Key to access the data in each row | -| title | string | Yes | Column header text | +| title | string \| ReactNode | Yes | Column header text or custom component | | render | function | No | Custom render function for the column. Receives (value: string \| number, item: DataItem) as parameters | | filterable | boolean | No | Whether the column can be filtered | | sortable | boolean | No | Whether the column can be sorted | | customSortFn | function | No | Custom sorting function. Receives (rowA: DataItem, rowB: DataItem, columnId: string) as parameters | -| width | string | No | Column width (e.g., '150px', '20%') | -| minWidth | string | No | Minimum column width | -| maxWidth | string | No | Maximum column width | -| align | string | No | Text alignment ('left', 'center', 'right') | -| className | string | No | Custom CSS class for the column | -| style | object | No | Custom inline styles for the column | +| filterOptions | FilterOption[] | No | Array of filter options for the column | -### 3.2 Expand Icon Customization +### 3.2 DataItem Interface + +The data items should conform to the following interface: + +```tsx +interface DataItem { + id: number; + resourceType: string; + name: string; + dateTime: string; + status: 'Active' | 'Inactive' | 'Pending' | 'Processing' | 'Provisioning'; + orchestration: string; + imageURL?: string; + subtext?: string; + showActionButtons?: boolean; + children?: DataItem[]; +} +``` + +### 3.3 FilterOption Interface + +Filter options for columns should conform to: + +```tsx +interface FilterOption { + label: string; + value: string | number; +} +``` + +### 3.4 Expand Icon Customization You can customize the expand icon for rows with children using the `expandIcon` prop: @@ -220,7 +253,7 @@ You can customize the expand icon for rows with children using the `expandIcon` The expand icon will be displayed for rows that have children. You can provide any React component as the icon. -### 3.3 Selection Props +### 3.5 Selection Props The table supports row selection with the following props: @@ -229,8 +262,15 @@ The table supports row selection with the following props: data={data} columns={columns} selectable={true} // Enable row selection - onSelectionChange={(selectedRows) => { - console.log('Selected rows:', selectedRows); + selectionState={{ + selectedRows: new Set(), + isAllSelected: false + }} + onSelectAll={() => { + // Handle select all + }} + onRowSelect={(rowId) => { + // Handle individual row selection }} /> ``` @@ -238,11 +278,13 @@ The table supports row selection with the following props: | Prop | Type | Description | |------|------|-------------| | selectable | boolean | Enable/disable row selection functionality | -| onSelectionChange | function | Callback function that receives a Set of selected row IDs | +| selectionState | SelectionState | Current selection state with selected rows and all selected flag | +| onSelectAll | function | Callback function for select all checkbox | +| onRowSelect | function | Callback function for individual row selection | **Note**: Child rows (nested rows) do not display checkboxes. They automatically show placeholder spacers to maintain alignment with parent rows. -### 3.4 Sort Icons +### 3.6 Sort Icons You can customize the sort icons for ascending and descending states: @@ -261,21 +303,23 @@ You can customize the sort icons for ascending and descending states: | ascendingIcon | ReactNode | Custom icon component for ascending sort state | | descendingIcon | ReactNode | Custom icon component for descending sort state | -### 3.5 Search and Filter Features +### 3.7 Search and Filter Features The table provides comprehensive search and filtering capabilities: #### Global Search -- **Searchable**: Enable/disable global search across all columns +- **Searchable**: Parent level search - **Search Input**: Real-time search with debounced input - **Search Icon**: Customizable search icon with proper positioning - **Placeholder Text**: Customizable placeholder text for search input +- **Searchable Columns**: Specify which columns to include in search via `searchableColumns` prop #### Column Filtering - **Filterable Columns**: Individual columns can be marked as filterable - **Filter Dropdowns**: Dropdown-based filtering with multiple selection - **Filter Options**: Custom filter options for each column - **Filter State**: Maintains filter state across pagination +- **Filter Column**: Specify which column to filter via `filterColumn` prop **Important Note**: Search and filter features are currently implemented at the parent level only. Child rows (nested rows) are not included in search results or filter operations. This ensures consistent behavior and performance. @@ -295,37 +339,93 @@ const columns = [ ]; ``` -### 3.6 Export Functionality +### 3.8 Export Functionality -The table supports data export with customizable options: +The table supports data export through the action buttons. Export functionality is handled through the `onButtonClick` prop when export buttons are clicked. -| Prop | Type | Description | -|------|------|-------------| -| exportable | boolean | Enable/disable export functionality | -| exportFormats | array | Available export formats (csv, excel, json) | -| onExport | function | Custom export handler function | +### 3.9 Delete Functionality + +The table supports both individual and bulk delete operations: + +#### Individual Delete +- **Delete Buttons**: Action buttons in each row for individual deletion +- **Delete Confirmation**: Popup confirmation for delete actions +- **Delete State**: `deletePopup` state manages confirmation popup + +#### Bulk Delete +- **Bulk Selection**: Select multiple rows for bulk operations +- **Bulk Delete Button**: Action button for bulk deletion +- **Bulk Delete Confirmation**: Popup confirmation for bulk delete actions +- **Bulk Delete State**: `bulkDeletePopup` state manages bulk confirmation popup + +```tsx + { + // Handle individual delete click + }} + onDeleteConfirm={() => { + // Handle delete confirmation + }} + onDeleteCancel={() => { + // Handle delete cancellation + }} + onBulkDeleteClick={() => { + // Handle bulk delete click + }} + onBulkDeleteConfirm={() => { + // Handle bulk delete confirmation + }} + onBulkDeleteCancel={() => { + // Handle bulk delete cancellation + }} +/> +``` + +### 3.10 Dropdown Management + +The table provides comprehensive dropdown state management: ```tsx { - // Custom export logic - console.log('Exporting:', data, format); + openDropdowns={new Set()} + onDropdownToggle={(buttonId, isOpen) => { + // Handle dropdown toggle + }} + onDropdownClose={(buttonId) => { + // Handle dropdown close + }} + onButtonClick={(button) => { + // Handle button clicks }} /> ``` -### 3.7 Row Actions +### 3.11 Row Actions -The table supports row-level actions: +The table supports row-level actions through customizable action icons and buttons: | Prop | Type | Description | |------|------|-------------| | onRowClick | function | Callback when parent row is clicked | -| onDelete | function | Callback for row deletion with confirmation | + +**Action Icons and Functionality:** +- **showActionButtons**: DataItem property to control action button visibility per row +- **Customizable Actions**: You can add action icons like edit, delete, view, etc. through the `render` function in columns +- **Action Handlers**: Handle action clicks through the `onButtonClick` prop or custom render functions +- **Flexible Implementation**: Actions can be implemented as icons, buttons, or custom components within cell content ```tsx { console.log('Row clicked:', row); }} - onDelete={(rowId, rowName) => { - console.log('Delete row:', rowId, rowName); + onButtonClick={(button) => { + console.log('Action button clicked:', button); + }} +/> +``` + +### 3.12 Row Expansion + +The table supports expandable rows with nested data: + +```tsx + { + // Handle row expansion/collapse }} /> ``` -### 3.8 Pagination +### 3.13 Pagination The table component provides comprehensive pagination functionality. You can either use the default pagination or create a custom one using the pagination props: @@ -409,7 +524,7 @@ const CustomPagination = ({ /> ``` -### 3.9 Theme Customization +### 3.14 Theme Customization The table component supports comprehensive theme customization through the `theme` prop. Here's the complete theme interface: @@ -629,45 +744,45 @@ npm run lint Here's a complete example showing how to use the component with all features enabled: ```tsx -import React from 'react'; +import React, { useState } from 'react'; import { MultiLevelTable } from '@keyvaluesystems/multilevel-table'; function App() { + // State management + const [selectedRows, setSelectedRows] = useState(new Set()); + const [searchTerm, setSearchTerm] = useState(''); + const [selectedFilterValues, setSelectedFilterValues] = useState(new Set()); + const [deletePopup, setDeletePopup] = useState({ isOpen: false, itemId: null, itemName: '' }); + const [bulkDeletePopup, setBulkDeletePopup] = useState({ isOpen: false, selectedCount: 0 }); + const [openDropdowns, setOpenDropdowns] = useState(new Set()); + const [expandedRows, setExpandedRows] = useState(new Set()); + const data = [ { id: 1, - name: 'Parent 1', - value: 100, - status: 'active', + resourceType: 'Application', + name: 'web-service', + dateTime: '12-Jun-2024, 10:30 AM', + status: 'Active', + orchestration: 'ECS', + showActionButtons: true, children: [ { - id: 2, - name: 'Child 1', - value: 50, - status: 'pending', - }, - { - id: 3, - name: 'Child 2', - value: 50, - status: 'completed', + id: 101, + resourceType: 'Service', + name: 'api-gateway', + dateTime: '12-Jun-2024, 10:30 AM', + status: 'Active', + orchestration: 'ECS', }, ], }, ]; const columns = [ - { - key: 'name', - title: 'Name', - filterable: true, - }, - { - key: 'value', - title: 'Value', - filterable: true, - render: (value) => `$${value}`, - }, + { key: 'resourceType', title: 'Resource Type', filterable: true }, + { key: 'name', title: 'Name', filterable: true }, + { key: 'dateTime', title: 'Date & Time', filterable: true }, { key: 'status', title: 'Status', @@ -676,15 +791,14 @@ function App() { {value} ), }, + { key: 'orchestration', title: 'Orchestration', filterable: true }, ]; const theme = { @@ -715,28 +829,104 @@ function App() { }; return ( -
- { - console.log('Selected rows:', selectedRows); - }} - onRowClick={(row) => { - console.log('Row clicked:', row); - }} - onDelete={(rowId, rowName) => { - console.log('Delete row:', rowId, rowName); - }} - /> -
+ 0 + }} + searchTerm={searchTerm} + selectedFilterValues={selectedFilterValues} + deletePopup={deletePopup} + bulkDeletePopup={bulkDeletePopup} + openDropdowns={openDropdowns} + expandedRows={expandedRows} + + // Handler props + onSearchChange={setSearchTerm} + onFilterChange={setSelectedFilterValues} + onDeleteClick={(itemId, itemName) => { + setDeletePopup({ isOpen: true, itemId, itemName }); + }} + onDeleteConfirm={() => { + console.log('Delete confirmed'); + setDeletePopup({ isOpen: false, itemId: null, itemName: '' }); + }} + onDeleteCancel={() => { + setDeletePopup({ isOpen: false, itemId: null, itemName: '' }); + }} + onBulkDeleteClick={() => { + setBulkDeletePopup({ isOpen: true, selectedCount: selectedRows.size }); + }} + onBulkDeleteConfirm={() => { + console.log('Bulk delete confirmed'); + setSelectedRows(new Set()); + setBulkDeletePopup({ isOpen: false, selectedCount: 0 }); + }} + onBulkDeleteCancel={() => { + setBulkDeletePopup({ isOpen: false, selectedCount: 0 }); + }} + onDropdownToggle={(buttonId, isOpen) => { + const newSet = new Set(openDropdowns); + if (isOpen) { + newSet.add(buttonId); + } else { + newSet.delete(buttonId); + } + setOpenDropdowns(newSet); + }} + onDropdownClose={(buttonId) => { + const newSet = new Set(openDropdowns); + newSet.delete(buttonId); + setOpenDropdowns(newSet); + }} + onButtonClick={(button) => { + console.log('Button clicked:', button); + }} + onSelectAll={() => { + const newIsAllSelected = selectedRows.size !== data.length; + const newSelectedRows = new Set(); + if (newIsAllSelected) { + data.forEach(item => newSelectedRows.add(item.id)); + } + setSelectedRows(newSelectedRows); + }} + onRowSelect={(rowId) => { + const newSet = new Set(selectedRows); + if (newSet.has(rowId)) { + newSet.delete(rowId); + } else { + newSet.add(rowId); + } + setSelectedRows(newSet); + }} + onRowToggle={(rowId) => { + const newSet = new Set(expandedRows); + if (newSet.has(rowId)) { + newSet.delete(rowId); + } else { + newSet.add(rowId); + } + setExpandedRows(newSet); + }} + + // Other props + onRowClick={(row) => console.log('Row clicked:', row)} + searchableColumns={['resourceType', 'name', 'dateTime', 'orchestration']} + filterColumn="status" + tableTitle="Multi-Level Table Demo" + tableSubtitle="A comprehensive table showing resource management" + showDarkMode={false} + isDarkMode={false} + onToggleTheme={() => console.log('Theme toggled')} + /> ); } diff --git a/example/README.md b/example/README.md deleted file mode 100644 index 2c786e6..0000000 --- a/example/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# Multi-Level Table Example - -This is an example project demonstrating the usage of `@keyvaluesystems/multilevel-table`. - -## Features Demonstrated - -- Multi-level data display -- Custom column rendering -- Row selection -- Sorting -- Filtering -- Pagination -- Theme customization -- Export functionality (CSV) -- Generic Button components -- Action button groups with dropdowns - -## Getting Started - -1. Install dependencies: -```bash -npm install -``` - -2. Start the development server: -```bash -npm run dev -``` - -3. Open [http://localhost:5173](http://localhost:5173) to view the example in your browser. - -## Project Structure - -- `src/App.tsx` - Main application component with table implementation -- `src/App.css` - Styles for the example -- `src/main.tsx` - Application entry point - -## Example Features - -The example demonstrates: - -1. **Data Structure** - - Three levels of nested data - - Parent-child relationships - - Various data types (string, number) - -2. **Column Configuration** - - Custom rendering for status column - - Filterable columns - - Formatted value display - -3. **Theme Customization** - - Custom colors - - Nested level styling - - Component-specific styling - -4. **Interactive Features** - - Row selection - - Sorting - - Filtering - - Pagination - - CSV Export with dropdown - - Action buttons with badges - - Delete functionality with confirmation popup - -5. **Button Components** - - Generic Button component with icon and text - - ButtonGroup for managing multiple action buttons - - Support for badges, dropdowns, and custom icons - - Theme-aware styling - - Flexible icon positioning (left or right of text) - -6. **Popup Component** - - Generic confirmation popup - - Customizable icon, title, text, and buttons - - Theme-aware styling - - Accessibility features (ESC key, click outside) - - Responsive design - -## Learn More - -For more information about the component, visit the [main documentation](../../README.md). diff --git a/src/styles/ExportDropdown.css b/src/styles/ExportDropdown.css deleted file mode 100644 index 719f49e..0000000 --- a/src/styles/ExportDropdown.css +++ /dev/null @@ -1,43 +0,0 @@ -.export-dropdown { - position: absolute; - top: calc(100% + 8px); - right: 0; - min-width: 180px; - background-color: #ffffff; - border: 1px solid #F0F0F0; - border-radius: 8px; - box-shadow: 0px 0px 1px 0px #00000033, 0px 8px 24px -6px #00000014; - z-index: 1000; - overflow: hidden; - font-family: 'DM Sans', sans-serif; -} - -.export-dropdown-content { - padding: 8px 0; -} - -.export-option { - display: flex; - align-items: center; - width: 100%; - padding: 12px 16px; - background: none; - border: none; - cursor: pointer; - gap: 12px; - transition: background-color 0.2s ease; - font-family: 'DM Sans', sans-serif; - font-size: 14px; - font-weight: 500; - text-align: left; -} - -.export-option:hover { - background-color: #f5f5f5; -} - -.export-icon { - font-size: 16px; - width: 20px; - text-align: center; -} \ No newline at end of file diff --git a/src/styles/FilterDropdown.css b/src/styles/FilterDropdown.css deleted file mode 100644 index 4868bcc..0000000 --- a/src/styles/FilterDropdown.css +++ /dev/null @@ -1,252 +0,0 @@ -.filter-dropdown { - position: absolute; - top: calc(100% + 8px); - right: 0; - min-width: 400px; - max-width: 500px; - max-height: 500px; - background-color: #ffffff; - border: 1px solid #F0F0F0; - border-radius: 8px; - box-shadow: 0px 0px 1px 0px #00000033, 0px 8px 24px -6px #00000014; - z-index: 1000; - overflow: hidden; - font-family: 'DM Sans', sans-serif; -} - -.filter-dropdown-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 12px 16px; - border-bottom: 1px solid #d9d9d9; - font-weight: 600; -} - -.filter-dropdown-title { - display: flex; - align-items: center; - gap: 8px; -} - -.filter-count { - background: #5D5FEF; - color: #FFFFFF; - padding: 2px 8px; - border-radius: 12px; - font-size: 12px; - font-weight: 500; -} - -.filter-dropdown-content { - padding: 8px 0; - max-height: 350px; - overflow-y: auto; -} - - - -/* Two-section layout */ -.filter-sections-container { - display: flex; - gap: 0; - min-height: 200px; -} - -.filter-section { - flex: 1; - border-right: 1px solid #d9d9d9; -} - -.filter-section:last-child { - border-right: none; -} - -.filter-section-header { - padding: 8px 16px; - border-bottom: 1px solid #f0f0f0; -} - -.filter-section-content { - padding: 8px 0; - max-height: 250px; - overflow-y: auto; -} - -/* Categories section */ -.categories-section .category-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 16px; - cursor: default; - transition: background-color 0.2s ease; -} - -.categories-section .category-item:hover { - background-color: #f5f5f5; -} - -.category-name { - font-size: 14px; - font-weight: 500; - color: #262626; -} - -.category-count { - display: flex; - align-items: center; - justify-content: center; - width: 20px; - height: 20px; - background-color: #5D5FEF; - color: white; - border-radius: 50%; - font-size: 12px; - font-weight: 600; - min-width: 20px; -} - -/* Filters section */ -.filters-section .filter-dropdown-option { - padding: 8px 16px; -} - -.filter-dropdown-option { - display: flex; - align-items: center; - padding: 8px 16px; - cursor: pointer; - user-select: none; - gap: 8px; - transition: background-color 0.2s ease; -} - -.filter-dropdown-option:hover { - background-color: #f5f5f5; -} - -.select-all-option { - display: flex; - align-items: center; - padding: 8px 0; - gap: 8px; - font-weight: 600; - font-size: 16px; - cursor: default; -} - -.select-all-option:hover { - background-color: transparent; -} - -.filter-section-header .filter-dropdown-option:hover { - background-color: transparent; -} - -.filter-dropdown-option input[type="checkbox"] { - width: 16px; - height: 16px; - border-radius: 2px; - border: 1px solid #BFBFBF; - background: #fff; - appearance: none; - -webkit-appearance: none; - outline: none; - cursor: pointer; - position: relative; - display: inline-block; - margin: 0; - vertical-align: middle; - box-sizing: border-box; -} - -.filter-dropdown-option input[type="checkbox"]:checked { - background: #5D5FEF; - border: 1.2px solid #5D5FEF; - border-radius: 2px; -} - -.filter-dropdown-option input[type="checkbox"]:checked::after { - content: ""; - position: absolute; - left: 5px; - top: 2.5px; - width: 4px; - height: 8px; - border: solid #ffffff; - border-width: 0 2px 2px 0; - border-radius: 1px; - transform: rotate(45deg); - display: block; - box-sizing: border-box; -} - -.filter-dropdown-option span { - flex: 1; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.filter-dropdown-footer { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 16px; - border-top: 1px solid #d9d9d9; - min-height: 50px; -} - -.filter-reset-btn { - background: none; - border: none; - color: #8C8C8C; - font-weight: 600; - font-size: 14px; - cursor: pointer; - padding: 0; - transition: color 0.2s ease; -} - -.filter-reset-btn:hover { - color: #666666; -} - -.filter-action-buttons { - display: flex; - gap: 8px; -} - -.filter-cancel-btn { - background: #F0F0F0; - color: #262626; - border: none; - border-radius: 8px; - padding: 8px 16px; - font-size: 14px; - font-weight: 600; - cursor: pointer; - transition: background-color 0.2s ease; -} - -.filter-cancel-btn:hover { - background: #e0e0e0; -} - -.filter-apply-btn { - background: #5D5FEF; - color: #FFFFFF; - border: none; - border-radius: 8px; - height: 36px; - padding: 0 16px; - font-size: 14px; - font-weight: 600; - cursor: pointer; - transition: background-color 0.2s ease; -} - -.filter-apply-btn:hover { - background: #4a4bdf; -} \ No newline at end of file diff --git a/src/styles/RowDetailsPopup.css b/src/styles/RowDetailsPopup.css deleted file mode 100644 index b231d5c..0000000 --- a/src/styles/RowDetailsPopup.css +++ /dev/null @@ -1,184 +0,0 @@ -.row-details-popup-overlay { - background-color: rgba(0, 0, 0, 0.5); - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 1000; - display: flex; - align-items: center; - justify-content: center; -} - -.row-details-popup { - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - background-color: #ffffff; - border-radius: 8px; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); - z-index: 1001; - max-width: 500px; - width: 90%; - max-height: 80vh; - overflow: hidden; - font-family: 'DM Sans', sans-serif; -} - -.row-details-popup-header { - padding: 1.5rem; - border-bottom: 1px solid #e0e0e0; - display: flex; - justify-content: space-between; - align-items: center; -} - -.row-details-popup-title { - margin: 0; - font-size: 1.25rem; - font-weight: 600; - color: #333333; - font-family: 'DM Sans', sans-serif; -} - -.row-details-popup-close-button { - background: none; - border: none; - font-size: 1.5rem; - cursor: pointer; - color: #333333; - padding: 0.25rem; - font-family: 'DM Sans', sans-serif; -} - -.row-details-popup-content { - padding: 1.5rem; - max-height: 60vh; - overflow-y: auto; -} - -.row-details-popup-footer { - padding: 1rem 1.5rem; - border-top: 1px solid #e0e0e0; - display: flex; - justify-content: flex-end; - gap: 0.75rem; -} - -.row-details-popup-close-action { - padding: 0.5rem 1rem; - background-color: transparent; - color: #666666; - border: 1px solid #e0e0e0; - border-radius: 4px; - font-size: 0.875rem; - font-weight: 500; - cursor: pointer; - font-family: 'DM Sans', sans-serif; - transition: all 0.2s; -} - -.row-details-popup-close-action:hover { - background-color: #f5f5f5; -} - -.detail-row { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0.75rem 0; -} - -.detail-row-label { - font-size: 16px; - font-weight: 500; - color: #666666; - font-family: 'DM Sans', sans-serif; -} - -.detail-row-value { - font-size: 16px; - color: #333333; - font-family: 'DM Sans', sans-serif; - text-align: right; - flex: 1; - margin-left: 1rem; -} - -.detail-row-value-monospace { - font-family: monospace; - font-size: 0.875rem; - color: #666666; -} - -.detail-row-value-small { - font-size: 0.875rem; - color: #666666; -} - -.detail-row-value-status { - font-size: 0.875rem; - font-weight: 500; -} - -.detail-row-value-status-yes { - color: #28a745; -} - -.detail-row-value-status-no { - color: #dc3545; -} - -.status-badge { - font-size: 12px; - font-weight: 400; - padding: 4px 8px; - border-radius: 12px; -} - -.resource-type-container { - display: flex; - align-items: center; - gap: 8px; - font-size: 14px; - font-weight: 500; -} - -.resource-type-icon { - width: 36px; - height: 36px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 14px; - font-weight: 600; - border: 2px solid; -} - -.resource-type-icon-with-image { - background-color: transparent; - color: transparent; - border: none; -} - -.resource-type-icon-without-image { - background-color: #E3F2FD; - color: #5D5FEF; - border-color: #BBDEFB; -} - -.resource-type-image { - width: 100%; - height: 100%; - border-radius: 50%; - object-fit: cover; - object-position: center; -} - -/* Disable background scroll when popup is open */ -body.popup-open { - overflow: hidden; -} \ No newline at end of file diff --git a/src/styles/SidePanel.css b/src/styles/SidePanel.css deleted file mode 100644 index b90dc64..0000000 --- a/src/styles/SidePanel.css +++ /dev/null @@ -1,47 +0,0 @@ -.side-panel-overlay { - animation: fadeIn 0.3s ease-in-out; -} - -.side-panel { - box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1); -} - -@keyframes fadeIn { - from { - opacity: 0; - } - to { - opacity: 1; - } -} - -/* Ensure the side panel is above other content */ -.side-panel { - z-index: 1001; -} - -/* Smooth transition for the overlay */ -.side-panel-overlay { - transition: opacity 0.3s ease-in-out; -} - -/* Prevent body scroll when side panel is open */ -body.side-panel-open { - overflow: hidden; - position: fixed; - width: 100%; -} - -/* Prevent scrolling on all table containers when side panel is open */ -body.side-panel-open .table-wrapper, -body.side-panel-open .table-container, -body.side-panel-open .app-content, -body.side-panel-open .app { - overflow: hidden !important; - pointer-events: none; -} - -/* Allow scrolling only within the side panel */ -body.side-panel-open .side-panel { - pointer-events: auto; -} \ No newline at end of file diff --git a/src/styles/SidePanelInput.css b/src/styles/SidePanelInput.css deleted file mode 100644 index 2329305..0000000 --- a/src/styles/SidePanelInput.css +++ /dev/null @@ -1,41 +0,0 @@ -.side-panel-input-container { - margin-bottom: 1.5rem; -} - -.side-panel-input-label { - display: block; - font-size: 0.875rem; - font-weight: 500; - color: #333333; - margin-bottom: 0.5rem; - font-family: 'DM Sans', sans-serif; -} - -.side-panel-input-field { - width: 100%; - font-size: 1rem; - color: #333333; - padding: 0.75rem; - background-color: #ffffff; - border: 1px solid #e0e0e0; - border-radius: 4px; - font-family: 'DM Sans', sans-serif; - box-sizing: border-box; -} - -.side-panel-input-field:focus { - outline: none; - border-color: #5D5FEF; -} - -.side-panel-input-display { - font-size: 1rem; - color: #333333; - padding: 0.75rem; - background-color: #f5f5f5; - border: 1px solid #e0e0e0; - border-radius: 4px; - font-family: 'DM Sans', sans-serif; - cursor: not-allowed; - opacity: 0.7; -} \ No newline at end of file