{"id":30083153,"url":"https://github.com/metaory/data-grid-selector","last_synced_at":"2025-08-18T12:25:34.061Z","repository":{"id":307142983,"uuid":"1028334841","full_name":"metaory/data-grid-selector","owner":"metaory","description":"🚧  A lightweight, framework-agnostic web component for interactive boolean data visualization. Click and drag to toggle cells on/off 🚧","archived":false,"fork":false,"pushed_at":"2025-08-07T18:16:38.000Z","size":3796,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-08T22:10:10.103Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://metaory.github.io/data-grid-selector/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/metaory.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-29T11:28:51.000Z","updated_at":"2025-08-08T14:44:52.000Z","dependencies_parsed_at":"2025-07-29T19:02:23.369Z","dependency_job_id":"ad1f7007-de14-4d2a-9546-b2f1a913c2cc","html_url":"https://github.com/metaory/data-grid-selector","commit_stats":null,"previous_names":["metaory/data-grid-selector"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/metaory/data-grid-selector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaory%2Fdata-grid-selector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaory%2Fdata-grid-selector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaory%2Fdata-grid-selector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaory%2Fdata-grid-selector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metaory","download_url":"https://codeload.github.com/metaory/data-grid-selector/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaory%2Fdata-grid-selector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270992197,"owners_count":24681372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-08T22:01:54.988Z","updated_at":"2025-08-18T12:25:34.007Z","avatar_url":"https://github.com/metaory.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003e\n    \u003cimg valign=\"middle\" src=\".github/assets/logo.png\" alt=\"logo\" height=\"48\" /\u003e\n    DataGrid Selector\n  \u003c/h1\u003e\n  \u003cstrong\u003e\n    A lightweight, framework-agnostic web component\n  \u003c/strong\u003e\n  \u003cbr\u003e\n  for interactive boolean data visualization\n  \u003cbr\u003e\n  Click and drag to toggle cells on/off with smooth selection feedback\n  \u003cbr\u003e\n  \u003cimg valign=\"middle\" src=\"https://raw.githubusercontent.com/metaory/data-grid-selector/refs/heads/master/.github/assets/gifcast.gif\" alt=\"datagrid\" width=\"80%\" /\u003e\n\u003c/div\u003e\n\n---\n\n## Features\n\n- **Click and drag selection** for bulk operations\n- **Customizable themes** with CSS variables\n- **Framework agnostic** - works in any project\n- **No dependencies** - pure vanilla JavaScript\n- **Accessible** with proper ARIA attributes\n- **Responsive design** with sticky headers\n- **Custom scrollbars** for better UX\n- **Functional API** with property getters/setters\n- **No wrapper needed** - use directly in any framework\n\n## Demo\n\n🎮 **Live Demo**: [https://metaory.github.io/data-grid-selector](https://metaory.github.io/data-grid-selector)\n\nTry the interactive demo with different themes and see the component in action!\n\n## Installation\n\n```bash\nnpm install data-grid-selector\n```\n\n## Usage\n\n### Basic Usage\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cscript type=\"module\"\u003e\n    import 'data-grid-selector';\n  \u003c/script\u003e\n  \u003cstyle\u003e\n    /* Customize with CSS variables */\n    data-grid {\n      --grid-primary: #3b82f6;\n      --grid-bg: #ffffff;\n      --grid-border: #e2e8f0;\n      --grid-text: #1f2937;\n      --grid-text-muted: #64748b;\n      --grid-header-bg: #f1f5f9;\n      --grid-cell-size: 30px;\n      --grid-header-width: 80px;\n    }\n  \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cdata-grid \n    rows=\"7\" \n    cols=\"24\" \n    title=\"Weekly Schedule\"\u003e\n  \u003c/data-grid\u003e\n  \n  \u003cscript\u003e\n    const grid = document.querySelector('data-grid');\n    grid.addEventListener('dataChange', (e) =\u003e {\n      console.log('Data changed:', e.detail);\n    });\n  \u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Functional API\n\n```html\n\u003cdata-grid rows=\"31\" cols=\"24\" title=\"Monthly Schedule\"\u003e\u003c/data-grid\u003e\n\n\u003cscript\u003e\n  const grid = document.querySelector('data-grid');\n  \n  // Set data and labels\n  grid.setData(Array(31).fill(null).map(() =\u003e Array(24).fill(false)));\n  grid.setRowLabels(Array.from({length: 31}, (_, i) =\u003e `Day ${i + 1}`));\n  grid.setColLabels(Array.from({length: 24}, (_, i) =\u003e `${i}h`));\n  \n  grid.addEventListener('dataChange', (e) =\u003e {\n    console.log('Data changed:', e.detail);\n  });\n\u003c/script\u003e\n```\n\n### Framework Integration (Svelte Example)\n\n```svelte\n\u003cscript\u003e\n  import 'data-grid-selector';\n  \n  let gridElement;\n  let gridData = Array(7).fill(null).map(() =\u003e Array(24).fill(false));\n  \n  $effect(() =\u003e {\n    if (gridElement) {\n      gridElement.setData(gridData);\n      gridElement.setRowLabels(['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']);\n      gridElement.setColLabels(Array.from({length: 24}, (_, i) =\u003e `${i}:00`));\n      \n      gridElement.addEventListener('dataChange', (e) =\u003e {\n        gridData = e.detail;\n      });\n    }\n  });\n\u003c/script\u003e\n\n\u003cdata-grid bind:this={gridElement} rows={7} cols={24}\u003e\u003c/data-grid\u003e\n```\n\n## API\n\n### Attributes\n\n- `rows` - Number of rows (default: 30)\n- `cols` - Number of columns (default: 24)\n- `title` - Accessibility title (default: \"Data Grid\")\n\n### Methods\n\n```javascript\n// Get/set grid data\ngrid.setData(booleanArray);\nconst data = grid.getData();\n\n// Get/set row labels\ngrid.setRowLabels(['Row 1', 'Row 2', ...]);\n\n// Get/set column labels\ngrid.setColLabels(['Col 1', 'Col 2', ...]);\n\n// Reset to empty grid\ngrid.reset();\n```\n\n### Theme Updates\n\n```javascript\n// Update theme with CSS variables\ngrid.updateTheme({\n  '--grid-primary': '#3b82f6',\n  '--grid-bg': '#ffffff',\n  '--grid-cell-bg': '#f8fafc'\n});\n```\n\n### Events\n\n```javascript\ngrid.addEventListener('dataChange', (e) =\u003e {\n  const data = e.detail; // 2D boolean array\n  console.log('Grid data changed:', data);\n});\n```\n\n## CSS Custom Properties\n\nCustomize the appearance using CSS variables:\n\n```css\ndata-grid {\n  --grid-primary: #3b82f6;                    /* Active cell color */\n  --grid-bg: #ffffff;                         /* Background color */\n  --grid-border: #e2e8f0;                     /* Border color */\n  --grid-text: #1f2937;                       /* Text color */\n  --grid-text-muted: #64748b;                 /* Muted text color */\n  --grid-header-bg: #f1f5f9;                  /* Header background */\n  --grid-cell-size: 30px;                     /* Cell size */\n  --grid-header-width: 80px;                  /* Header width */\n  --grid-hover-bg: #f1f5f9;                   /* Hover background */\n  --grid-selection-bg: rgba(59, 130, 246, 0.25); /* Selection background */\n  --grid-selection-active-bg: rgba(59, 130, 246, 0.7); /* Active selection */\n}\n```\n\n## Examples\n\n### Monthly Schedule Grid\n\n```html\n\u003cdata-grid rows=\"31\" cols=\"24\" title=\"Monthly Schedule\"\u003e\u003c/data-grid\u003e\n\n\u003cscript\u003e\n  const grid = document.querySelector('data-grid');\n  \n  grid.setData(Array(31).fill(null).map(() =\u003e Array(24).fill(false)));\n  grid.setRowLabels(Array.from({length: 31}, (_, i) =\u003e `Day ${i + 1}`));\n  grid.setColLabels(Array.from({length: 24}, (_, i) =\u003e `${i}h`));\n  \n  grid.addEventListener('dataChange', (e) =\u003e {\n    const activeHours = e.detail.flat().filter(cell =\u003e cell).length;\n    console.log(`Active hours: ${activeHours}`);\n  });\n\u003c/script\u003e\n```\n\n### Attendance Tracker\n\n```html\n\u003cdata-grid rows=\"7\" cols=\"24\" title=\"Weekly Attendance\"\u003e\u003c/data-grid\u003e\n\n\u003cscript\u003e\n  const grid = document.querySelector('data-grid');\n  \n  grid.setData(Array(7).fill(null).map(() =\u003e Array(24).fill(false)));\n  grid.setRowLabels(['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']);\n  grid.setColLabels(Array.from({length: 24}, (_, i) =\u003e `${i}:00`));\n\u003c/script\u003e\n```\n\n### React Integration\n\n```jsx\nimport 'data-grid-selector';\nimport { useEffect, useRef } from 'react';\n\nfunction AttendanceGrid({ data, onDataChange }) {\n  const gridRef = useRef();\n  \n  useEffect(() =\u003e {\n    if (gridRef.current) {\n      gridRef.current.setData(data);\n      gridRef.current.setRowLabels(['Mon', 'Tue', 'Wed', 'Thu', 'Fri']);\n      gridRef.current.setColLabels(Array.from({length: 24}, (_, i) =\u003e `${i}:00`));\n      \n      gridRef.current.addEventListener('dataChange', onDataChange);\n    }\n  }, [data, onDataChange]);\n  \n  return \u003cdata-grid ref={gridRef} rows={5} cols={24} /\u003e;\n}\n```\n\n### Theme Switching\n\n```javascript\n// Apply different themes\nconst themes = {\n  dark: {\n    '--grid-primary': '#3b82f6',\n    '--grid-bg': '#1e293b',\n    '--grid-cell-bg': '#2d3748',\n    '--grid-text': '#f1f5f9'\n  },\n  light: {\n    '--grid-primary': '#2563eb',\n    '--grid-bg': '#ffffff',\n    '--grid-cell-bg': '#f1f5f9',\n    '--grid-text': '#1f2937'\n  }\n};\n\nconst applyTheme = (theme) =\u003e {\n  const grid = document.querySelector('data-grid');\n  Object.entries(themes[theme]).forEach(([property, value]) =\u003e {\n    grid.style.setProperty(property, value);\n  });\n  grid.updateTheme();\n};\n\n// Usage\napplyTheme('dark');\n```\n\n## Browser Support\n\n- Modern browsers with Web Components support\n- Chrome 67+, Firefox 63+, Safari 10.1+, Edge 79+\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetaory%2Fdata-grid-selector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetaory%2Fdata-grid-selector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetaory%2Fdata-grid-selector/lists"}