{"id":26409791,"url":"https://github.com/erikvullings/mithril-materialized","last_synced_at":"2026-04-07T23:01:29.409Z","repository":{"id":43810575,"uuid":"157682357","full_name":"erikvullings/mithril-materialized","owner":"erikvullings","description":"A Materialize-css library for the Mithril framework.","archived":false,"fork":false,"pushed_at":"2026-03-19T18:35:40.000Z","size":24450,"stargazers_count":26,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-03-20T08:57:10.181Z","etag":null,"topics":["materialize","materialize-css","materializecss","mithril","mithril-components","mithril-ui"],"latest_commit_sha":null,"homepage":"https://erikvullings.github.io/mithril-materialized/index.html","language":"TypeScript","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/erikvullings.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-11-15T09:04:42.000Z","updated_at":"2026-03-19T18:35:41.000Z","dependencies_parsed_at":"2024-04-17T04:10:19.118Z","dependency_job_id":"a2475aa0-c1c3-4ba0-a9b9-a0a0517a2ae6","html_url":"https://github.com/erikvullings/mithril-materialized","commit_stats":{"total_commits":348,"total_committers":2,"mean_commits":174.0,"dds":"0.011494252873563204","last_synced_commit":"ebd0e3399137b96de23c3361ab480df232c8ab26"},"previous_names":[],"tags_count":60,"template":false,"template_full_name":null,"purl":"pkg:github/erikvullings/mithril-materialized","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvullings%2Fmithril-materialized","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvullings%2Fmithril-materialized/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvullings%2Fmithril-materialized/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvullings%2Fmithril-materialized/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erikvullings","download_url":"https://codeload.github.com/erikvullings/mithril-materialized/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvullings%2Fmithril-materialized/sbom","scorecard":{"id":381267,"data":{"date":"2025-08-11","repo":{"name":"github.com/erikvullings/mithril-materialized","commit":"f08c3fa6784bc8f2042df97570ef525e11f68a54"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":4,"reason":"5 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"16 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-ghr5-ch3p-vcr6","Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp","Warn: Project is vulnerable to: GHSA-4www-5p9h-95mh","Warn: Project is vulnerable to: GHSA-9gqv-wp59-fq42","Warn: Project is vulnerable to: GHSA-7752-f4gf-94gc","Warn: Project is vulnerable to: GHSA-98f7-p5rc-jx67","Warn: Project is vulnerable to: GHSA-rg3q-jxmp-pvjj","Warn: Project is vulnerable to: GHSA-7jvx-f994-rfw2","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T15:30:24.203Z","repository_id":43810575,"created_at":"2025-08-18T15:30:24.203Z","updated_at":"2025-08-18T15:30:24.203Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31532336,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["materialize","materialize-css","materializecss","mithril","mithril-components","mithril-ui"],"created_at":"2025-03-17T19:36:56.849Z","updated_at":"2026-04-07T23:01:29.395Z","avatar_url":"https://github.com/erikvullings.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mithril-materialized\n\nA Mithril.js component library inspired by [materialize-css](https://materializecss.com) design principles, [available on npm](https://www.npmjs.com/package/mithril-materialized). This library provides you with ready-to-use Mithril components that follow Material Design guidelines, with **no external JavaScript dependencies**.\n\n## 🚀 v3.15 - Latest Release\n\n### ✨ What's New in v3.15\n\n- **📊 DataTable Horizontal Scrolling**: DataTable now correctly enables horizontal scrolling when `responsive` is set, preventing overflow on small screens\n\n### ✨ What's New in v3.14\n\n- ** ConfirmButton Component**: Purpose-built component for delete and submit actions\n  - Click once to initialize the action, click again to confirm\n  - Button icon is changed, e.g. from 'delete' to 'checkmark' to confirm the action\n  - Removes the need for yet another confirmation dialog \"Are you sure?\"\n  - Support for different icons and delays\n\n### ✨ What's New in v3.13\n\n- **📊 LikertScale Component**: Purpose-built component for survey questions and rating scales\n  - Horizontal/vertical/responsive layouts for desktop and mobile\n  - Scale anchor labels (start/middle/end) for semantic meaning\n  - Multi-question alignment for professional survey forms\n  - Optional tooltips and number display\n  - Size and density variants for different contexts\n  - Full keyboard navigation and accessibility support\n- **⭐ Enhanced Rating Component**: Tooltips now display correctly on hover\n- **📝 Rich Collection Content**: Collection items now support rich content via `content` property\n\n### ✨ Previous Major Features (v3.12)\n\n- **🎯 Enhanced Toast Component**: Toasts with simple actions (undo, confirmation) and custom classes\n- **🏷️ Badge Component**: New badge component for labels and notifications\n- **⏱️ Progress Components**: CircularProgress and LinearProgress for loading states\n- **🔘 Toggle Components**: ToggleGroup and ToggleButton for grouped selections\n- **🕐 Advanced Time Components**: TimeRangePicker, AnalogClock, and DigitalClock\n- **🎨 Enhanced Sidenav**: Collapsible/expandable sidebar with submenu support\n- **⚡ Waves Effect**: Material Design ripple animations on buttons and FABs\n\n### ✨ Key Features Since v3.4\n\n- **🔥 Zero External JS Dependencies**: No longer requires `materialize-css` JavaScript or `material-icons` fonts\n- **📦 Smaller Bundle Size**: Reduced package size by eliminating external dependencies\n- **⚡ Better Performance**: Direct implementations without jQuery or other heavy dependencies\n- **🛠️ Enhanced Components**: Improved DatePicker with date ranges, week numbers, and TimePicker with configurable AM/PM/24h or inline style\n- **🛠️ Rich Component Library**: DataTable, TreeView, Timeline, Masonry, RatingControl, ImageList, Wizard/Stepper, Breadcrumb, Progress indicators, and more\n- **📱 Modern Architecture**: Factory components with proper TypeScript support\n- **🎯 CSS-Only Styling**: Uses only CSS for styling - no JavaScript initialization needed\n- **🎨 Custom SVG Icons**: Built-in MaterialIcon component with custom SVG icons (caret, close)\n\n### ✨ Key Features\n\n- **🔥 Zero External JS Dependencies**: No longer requires `materialize-css` JavaScript or `material-icons` fonts\n- **📦 Smaller Bundle Size**: Reduced package size by eliminating external dependencies  \n- **🎨 Custom SVG Icons**: Built-in MaterialIcon component with custom SVG icons\n- **⚡ Better Performance**: Direct implementations without jQuery or other heavy dependencies\n- **🛠️ Enhanced Components**: Comprehensive component library with modern features\n- **🌗 Dark Theme Support**: Built-in light/dark theme system with CSS custom properties\n- **📱 Modern Architecture**: Factory components with proper TypeScript support, and clear separation between [controlled and uncontrolled](CONTROLLED_COMPONENTS.md) component state\n- **🎯 CSS-Only Styling**: Uses only CSS for styling - no JavaScript initialization needed\n\n### 📦 Installation\n\n```bash\nnpm install mithril mithril-materialized\n```\n\n## Supported Components\n\nComponents marked with an * are not included in the original materialize-css library.\n\n- [Buttons](https://erikvullings.github.io/mithril-materialized/#!/buttons)\n  - Button\n  - FlatButton\n  - RoundButton\n  - SubmitButton\n- [Inputs](https://erikvullings.github.io/mithril-materialized/#!/inputs)\n  - TextInput\n  - TextArea\n  - AutoComplete\n  - UrlInput\n  - EmailInput\n  - NumberInput\n  - ColorInput\n  - RangeInput* (with vertical, double-thumb support, and smart tooltip display)\n  - Chips\n- [Pickers](https://erikvullings.github.io/mithril-materialized/#!/pickers)\n  - DatePicker (with optional week numbers and date range selection)*\n  - TimePicker (with inline mode and switchable AM/PM/24h)*\n  - TimeRangePicker* (select time ranges with analog or digital clock display)\n  - AnalogClock* (standalone analog clock component)\n  - DigitalClock* (standalone digital clock component)\n- [Selections](https://erikvullings.github.io/mithril-materialized/#!/selections)\n  - Select\n  - SearchSelect*, a searchable select dropdown\n  - Options\n  - RadioButtons\n  - LikertScale* (survey rating scales with anchor labels)\n  - Switch\n  - Dropdown\n  - ToggleGroup* (grouped toggle buttons for multiple selection)\n  - ToggleButton* (single toggle button component)\n- [Collections](https://erikvullings.github.io/mithril-materialized/#!/collections)\n  - Basic, Link and Avatar Collections\n  - Collapsible or accordion\n- [Theme \u0026 Upload](https://erikvullings.github.io/mithril-materialized/#!/theme)\n  - ThemeSwitcher* (light/dark/auto theme switching)\n  - ThemeToggle* (simple light/dark toggle)\n  - FileUpload* (drag-and-drop with validation and preview)\n- [Navigation](https://erikvullings.github.io/mithril-materialized/#!/navigation)\n  - Sidenav (responsive navigation drawer)\n  - Breadcrumb* (navigation path indicator)\n  - Wizard/Stepper* (multi-step process guidance)\n- [Others](https://erikvullings.github.io/mithril-materialized/#!/modals)\n  - ModalPanel\n  - MaterialBox\n  - Carousel\n  - Pagination\n  - PaginationControls*\n  - Parallax\n  - Toast* (notifications with optional actions)\n  - Badge* (labels and notification indicators)\n- Layout \u0026 Display\n  - [Masonry](https://erikvullings.github.io/mithril-materialized/#!/masonry)* (Pinterest-style responsive grid layout)\n  - [ImageList](https://erikvullings.github.io/mithril-materialized/#!/image-list)* (responsive image galleries with various layouts)\n  - [Timeline](https://erikvullings.github.io/mithril-materialized/#!/timeline)* (vertical timeline with events and milestones)\n  - CircularProgress* (circular loading indicator)\n  - LinearProgress* (linear loading indicator)\n- [Rating](https://erikvullings.github.io/mithril-materialized/#!/rating)*\n  - RatingControl (Horizontal control, configurable range and step size, optionally with custom icons)\n- [Data \u0026 Tables](https://erikvullings.github.io/mithril-materialized/#!/datatable)\n  - DataTable* (sorting, filtering, pagination, selection)\n  - TreeView* (hierarchical data with expand/collapse, selection, and customizable icons)\n- Additional\n  - Label\n  - HelperText\n  - CodeBlock\n  - Icon, a simple wrapper for creating icons using material-icons font\n  - MaterialIcon, for creating the close/clear and caret as SVG\n\n## 📖 Usage Instructions\n\nOnline [flems](flems.io) examples: [FlatButton](https://flems.io/#0=N4IgtglgJlA2CmIBcBWFA6AnAJgDQgGd4EBjAF3imRHTIJHwDMIF6kBtUAOwEMxEkNABZkwsBiBIB7LhVnUAPLAhcA1gAIATsQC8AHUJkAnqyHx4ZA+qHbG+kCLIAHAkgD0bgK5cnqgObo0mBukGQ2LAC0YDwUmhA8ygBelG5QEARkbipQ8AAegQQEBgB8elwSRKRkEDJsIACMSAAMIAC+uNx8AjR0EtKy8PKC-RnqwOoAYrAxAEKeZGQy6q3qOuoA7tlS6+wA5KHhsFEx8HEJEMlQuwC6ANxlZSNk6jIkyiQaawAUAJSrxeoEqcyF9dqoAFZCCG7H4PLhgdDaLg5TRfKBSEiefiydAAIykUCMuHUYC+U1m80WXGJ42muOISHUBgAskZJtNnrjKTIDMTXu8NK0fj97lwyhViPByDUuHUAGzNNodEC8fjUAr0fD9ORkahta74ZRqNicFVdagHOLifCeTTiQSOFzuLw+fyBKTBS0sAAC2HQAGZ0AB2EIQMJW9CQLjocGakDGJzdAgkOJOXXtTpqwReo7RWLxJKUCS2+0OBZOjzeXwBIKh8ORPOnAsXSjewOBgAsqXSmWyeXQWKgMbjCaTKYgaf1rSAA) and [Select](https://flems.io/#0=N4IgtglgJlA2CmIBcBWFA6AnAJgDQgGd4EBjAF3imRHTIJHwDMIF6kBtUAOwEMxEkNABZkwsBiBIB7LhVnUAPLAhcA1gAIATsQC8AHUJkAnqyHx4ZA+qHbG+kCLIAHAkgD0bgK5cnqgObo0mBukGQ2LAC0YDwUmhA8ygBelG5QEARkbipQ8AAegQQEBgB8elwSRKRkEDJsIACMSAAMIAC+uNx8AjR0EtKy8PKC-RnqwOoAysTw5Oqt6jrqAO7ZUkvsAOSh4bBRMfBxCRDJUBsAugDcZWUIZOokZiSqlACSUAvqG9gbV1xlYOgwFJvGQABRQKQkTz8WToABGUigRlwY2uZAAbhB4EskOpQQBKBbFdRgUEbdCaNYbFHjDImeC48bRTR+FQAFSkTlxG3qTScuQ2czmKLK6jFJNBUyqNPUsB4cOI3KlMzu-Gp6lF4rFTjlJHgQiksBymm5AGFlE91DJ4NTNVqHjNnlA3rg7eLOdVarj2G6teNoNz6uq5QrYNyAPJOT1cdRB4W+8X+qDc74okOKz6R6Pqb7xmNaxPqAOfADMwflGY2WZqMbLeYL6jOrvzWpkDx4XD8DLx6MJOmJwATYodT1e70W6N+Dfabta+LKc+uf3K+EqKprdSazQi2EaLXanX41AK9Hw-TkZGobSbIGUajYnBAvCPgm2cXE+E8mnEgkcLncXg+P4gRSMEb4sAAAtg6AlugADsIQQGE76Aio6AAFaniAxhON0BAkHEUZtB0T5dNQ4G7NEsTxEklASF+P4OGQziuB43i+AEQSIchkRUQcNHHJQEGwbBAAsqTpJk2R5Og0JQBhWE4XhBEQERrRnK0QA).\n\n### Quick Start\n\n1. **Install the package**:\n\n   ```bash\n   npm install mithril mithril-materialized\n   ```\n\n2. **Import the CSS** (optional, for Material Design styling):\n\n   ```typescript\n   import 'mithril-materialized/index.css';\n   ```\n\n3. **Use components in your app**:\n\n   ```typescript\n   import m from 'mithril';\n   import {\n     TextInput,\n     Button,\n     RangeInput,\n     DatePicker,\n     TimePicker,\n     TimeRangePicker,\n     AnalogClock,\n     DigitalClock,\n     DataTable,\n     TreeView,\n     ThemeToggle,\n     FileUpload,\n     Sidenav,\n     Breadcrumb,\n     Wizard,\n     Masonry,\n     Timeline,\n     ImageList,\n     Badge,\n     CircularProgress,\n     LinearProgress,\n     ToggleGroup,\n     LikertScale,\n     Rating,\n     Toast\n   } from 'mithril-materialized';\n\n   const MyComponent = () =\u003e ({\n     view: () =\u003e m('.container', [\n       // Theme toggle in header\n       m('nav', [\n         m('.nav-wrapper', [\n           m('.right', m(ThemeToggle))\n         ])\n       ]),\n       \n       // Breadcrumb navigation\n       m(Breadcrumb, {\n         items: [\n           { text: 'Home', href: '/' },\n           { text: 'Products', href: '/products' },\n           { text: 'Details', active: true }\n         ]\n       }),\n       \n       // Form inputs\n       m(TextInput, {\n         label: 'Your name',\n         onchange: (value) =\u003e console.log(value)\n       }),\n       \n       // Enhanced range sliders with smart tooltips\n       m(RangeInput, {\n         label: 'Volume',\n         min: 0,\n         max: 100,\n         valueDisplay: 'auto', // Show tooltip on drag\n         onchange: (value) =\u003e console.log('Volume:', value)\n       }),\n       \n       m(RangeInput, {\n         label: 'Price Range',\n         min: 0,\n         max: 1000,\n         minmax: true,\n         minValue: 100,\n         maxValue: 500,\n         valueDisplay: 'always', // Always show values\n         onchange: (min, max) =\u003e console.log('Range:', min, '-', max)\n       }),\n       \n       m(RangeInput, {\n         label: 'Vertical Slider',\n         min: 0,\n         max: 100,\n         vertical: true,\n         height: '200px',\n         valueDisplay: 'auto',\n         tooltipPos: 'right',\n         onchange: (value) =\u003e console.log('Vertical:', value)\n       }),\n       \n       // Enhanced DatePicker with range selection\n       m(DatePicker, {\n         label: 'Event Date',\n         helperText: 'Select a single date',\n         format: 'mmmm d, yyyy',\n         onchange: (value) =\u003e console.log('Date:', value)\n       }),\n       \n       m(DatePicker, {\n         dateRange: true,\n         label: 'Project Timeline',\n         helperText: 'Select start and end dates',\n         format: 'mmmm d, yyyy',\n         minDateRange: 1,\n         maxDateRange: 30,\n         onchange: (value) =\u003e console.log('Date range:', value)\n       }),\n       \n       m(Button, {\n         label: 'Submit',\n         onclick: () =\u003e alert('Hello!')\n       }),\n\n       // Progress indicators\n       m(CircularProgress, {\n         color: 'blue',\n         size: 'medium'\n       }),\n\n       m(LinearProgress, {\n         progress: 65,\n         color: 'green'\n       }),\n\n       // Badge component\n       m('.section', [\n         m('span', { style: 'position: relative' }, [\n           'Notifications',\n           m(Badge, { value: 3, color: 'red' })\n         ])\n       ]),\n\n       // Toggle Group for selections\n       m(ToggleGroup, {\n         items: [\n           { id: 'left', label: 'Left', icon: 'align_left' },\n           { id: 'center', label: 'Center', icon: 'align_center' },\n           { id: 'right', label: 'Right', icon: 'align_right' }\n         ],\n         selectedIds: ['center'],\n         onchange: (selectedIds) =\u003e console.log('Selected:', selectedIds)\n       }),\n\n       // LikertScale for survey questions\n       m(LikertScale, {\n         label: 'How satisfied are you with our service?',\n         min: 1,\n         max: 5,\n         value: 3,\n         onchange: (value) =\u003e console.log('Rating:', value),\n         startLabel: 'Very Dissatisfied',\n         middleLabel: 'Neutral',\n         endLabel: 'Very Satisfied',\n         showTooltips: true,\n         tooltipLabels: ['Very Dissatisfied', 'Dissatisfied', 'Neutral', 'Satisfied', 'Very Satisfied']\n       }),\n\n       // Multi-question survey with alignment\n       m('.survey-section', [\n         m('h5', 'Employee Satisfaction Survey'),\n         m(LikertScale, {\n           label: 'How happy are you at work?',\n           alignLabels: true,\n           min: 1,\n           max: 5,\n           value: 4,\n           onchange: (v) =\u003e console.log('Happiness:', v),\n           startLabel: 'Unhappy',\n           endLabel: 'Happy'\n         }),\n         m(LikertScale, {\n           label: 'How satisfied are you with your role?',\n           alignLabels: true,\n           min: 1,\n           max: 5,\n           value: 3,\n           onchange: (v) =\u003e console.log('Satisfaction:', v),\n           startLabel: 'Dissatisfied',\n           endLabel: 'Satisfied'\n         })\n       ]),\n\n       // Rating component with tooltips\n       m(Rating, {\n         value: 4,\n         max: 5,\n         showTooltips: true,\n         tooltipLabels: ['Poor', 'Fair', 'Good', 'Very Good', 'Excellent'],\n         onchange: (value) =\u003e console.log('Rating:', value)\n       }),\n\n       // Time Range Picker\n       m(TimeRangePicker, {\n         label: 'Select Time Range',\n         startTime: '09:00',\n         endTime: '17:00',\n         clockType: 'analog',\n         onchange: (start, end) =\u003e console.log('Time range:', start, '-', end)\n       }),\n\n       // File upload\n       m(FileUpload, {\n         accept: 'image/*',\n         multiple: true,\n         onFilesSelected: (files) =\u003e console.log(files)\n       }),\n       \n       // TreeView for hierarchical data\n       m(TreeView, {\n         data: [\n           {\n             id: 'root',\n             label: 'Project Root',\n             expanded: true,\n             children: [\n               { id: 'src', label: 'src/' },\n               { id: 'docs', label: 'docs/' },\n             ]\n           }\n         ],\n         selectionMode: 'multiple',\n         iconType: 'caret',\n         showConnectors: true,\n         onselection: (selectedIds) =\u003e console.log('Selected:', selectedIds)\n       }),\n       \n       // Layout components\n       m(Masonry, {\n         items: [\n           { id: 1, title: 'Card 1', content: 'Short content' },\n           { id: 2, title: 'Card 2', content: 'Much longer content...' },\n           { id: 3, title: 'Card 3', content: 'Medium content' }\n         ],\n         columnWidth: 250,\n         gap: 16,\n         renderItem: (item) =\u003e m('.card', [\n           m('.card-content', [\n             m('span.card-title', item.title),\n             m('p', item.content)\n           ])\n         ])\n       }),\n       \n       m(Timeline, {\n         events: [\n           {\n             id: 1,\n             title: 'Project Started',\n             date: '2024-01-15',\n             description: 'Initial project kickoff',\n             type: 'milestone'\n           },\n           {\n             id: 2,\n             title: 'First Release',\n             date: '2024-03-20',\n             description: 'Released version 1.0',\n             type: 'release'\n           }\n         ]\n       }),\n       \n       m(ImageList, {\n         images: [\n           { src: '/image1.jpg', alt: 'Image 1' },\n           { src: '/image2.jpg', alt: 'Image 2' },\n           { src: '/image3.jpg', alt: 'Image 3' }\n         ],\n         layout: 'masonry', // 'grid' | 'masonry' | 'quilted'\n         cols: 3\n       })\n     ])\n   });\n   ```\n\n### Integration with Build Tools\n\n**Webpack/Vite/Parcel**: The library works out-of-the-box with modern bundlers.\n\n**CSS Framework Integration**: You can use the components with any CSS framework. The included CSS provides Material Design styling, but you can override it with your own styles.\n\n**TypeScript**: Full TypeScript support with comprehensive type definitions included.\n\nSee the [live documentation](https://erikvullings.github.io/mithril-materialized/index.html) for examples and component APIs.\n\n\u003e **Note**: The date range picker is now fully implemented with comprehensive validation and formatting support.\n\n## 🗺️ Roadmap \u0026 Planned Improvements\n\n### 🚀 Phase 1: Core Optimizations \u0026 New Components (In Progress)\n\n**✅ Completed:**\n\n- ✅ Modular CSS architecture with tree-shaking support\n- ✅ Dark theme system with CSS custom properties  \n- ✅ File upload component with drag-and-drop\n- ✅ Theme switching components (ThemeSwitcher, ThemeToggle)\n- ✅ Sidenav component with responsive behavior\n- ✅ Breadcrumb navigation component\n- ✅ Wizard/Stepper component for multi-step forms\n\n**✅ Recently Completed (v3.2.x):**\n\n- ✅ **TextArea Height Alignment**: Fixed single-line `textarea` height to match TextInput components perfectly\n- ✅ **Improved AutoResize Logic**: TextArea now only sets custom height for multi-line content, matching Materialize CSS reference behavior\n- ✅ **Better Mithril Integration**: Hidden div for height measurement now properly managed within Mithril's render cycle\n- ✅ DataTable component with sorting, filtering, and pagination\n- ✅ TreeView component for hierarchical data with expand/collapse, selection, and VSCode-style connectors\n- ✅ Enhanced TypeScript definitions with better JSDoc comments\n- ✅ Performance optimizations and bundle size improvements\n- ✅ Enhanced RangeInput with vertical orientation, double-thumb range selection, and smart tooltip display\n- ✅ Advanced DatePicker with date range selection, constraints, and format support\n- ✅ Layout components: Masonry (Pinterest-style grid), Timeline (vertical event display), ImageList (responsive galleries)\n- ✅ RatingControl with configurable icons, min/max, tooltip/helpers, readonly and disabled mode\n- ✅ Improved RangeInput components converted to proper Mithril components with better lifecycle management\n- ✅ Enhanced accessibility with individual thumb slider elements and PageUp/PageDown keyboard support\n\n### 🎯 Phase 2: Advanced Components \u0026 Features\n\n**Data Display:**\n\n- Card layouts with enhanced Material Design 3.0 styling\n- Advanced tree operations (drag \u0026 drop, context menus)\n\n**Input \u0026 Forms:**\n\n- ✅ Advanced date range picker with validation and constraints\n- Autocomplete with async data loading\n\n**Navigation \u0026 Layout:**\n\n- AppBar/Toolbar component with responsive behavior\n- Bottom navigation component for mobile apps\n- Drawer/Sidebar component with overlay and push modes\n- Grid system enhancements with CSS Grid support\n\n### 🔮 Phase 3: Modern Features \u0026 Integration\n\n**Developer Experience:**\n\n- Storybook integration for component documentation\n- Figma design system integration\n- CLI tools for component generation\n- Better accessibility (ARIA) support throughout\n\n**Performance \u0026 Optimization:**\n\n- Virtual scrolling for large lists\n- Lazy loading component utilities\n- Bundle analyzer and optimization tools\n- CSS-in-JS runtime support option\n\n### 📊 Bundle Size Targets\n\n**Current Status (v3.2.2):**\n\n- Total: ~65KB gzipped (42KB JS + 23KB CSS)\n- Modular CSS can reduce bundle by 30-50%\n- Optimized component implementations reduce overhead\n\n**Phase 1 Targets:**\n\n- Core bundle: \u003c40KB gzipped\n- Modular approach: \u003c25KB for typical apps\n- Tree-shaking effectiveness: 60%+\n\n**Long-term Goals:**\n\n- Individual components: \u003c2KB each\n- Micro-bundle support for single components\n- Zero-runtime CSS option for static sites\n\n### 🤝 Contributing\n\nWe welcome contributions! Priority areas for community involvement:\n\n1. **Usage**: Accessibility improvements, performance optimizations\n2. **Documentation**: Examples, guides, API documentation\n3. **Testing**: Unit tests, visual regression tests, browser compatibility\n\nSee our [contributing guide](CONTRIBUTING.md) for detailed information.\n\n### 📈 Performance Benchmarks\n\n**Bundle Size Comparison:**\n\n- mithril-materialized v3.2.2: ~65KB gzipped\n- Material-UI: ~350KB gzipped\n- Materialize CSS + jQuery: ~180KB gzipped\n- Vuetify: ~250KB gzipped\n\n**Runtime Performance:**\n\n- Component initialization: \u003c5ms average\n- Theme switching: \u003c10ms for full page\n- File upload processing: Real-time without blocking\n- TextArea auto-resize: \u003c1ms per keystroke\n\n## Build instructions\n\nThis repository consists of two packages, combined using `lerna`: the `lib` package that is published to `npm`, as well as an `example` project which uses this library to display the Mithril components that it contains.\n\nTo install the dependencies, you can use `npm i`, or, alternatively, use `pnpm m i` (assuming you have installed `pnpm` as alternative package manager using `npm i -g pnpm`) to perform a multi-repository install. Next, build everything using `npm start` and visit the documentation page on [http://localhost:1234](http://localhost:1234) in case port 1234 is not occupied already.\n\n## 🎨 Styling \u0026 CSS\n\n### CSS Usage\n\nThe library includes carefully crafted CSS that provides Material Design styling without external dependencies. You can import the ready-to-use CSS:\n\n```typescript\nimport 'mithril-materialized/index.css';\n```\n\n**Important**: The CSS styling is **completely independent** of the original materialize-css. This means:\n\n- ✅ No conflicting styles from materialize-css\n- ✅ Smaller CSS bundle size\n- ✅ Custom optimizations for better performance\n- ✅ No external font dependencies\n\n### 🔥 NEW: Modular CSS Architecture\n\n**Tree-shakable CSS modules** for optimal bundle sizes! Import only the CSS you need:\n\n```typescript\n// Option 1: Import everything (64KB total)\nimport 'mithril-materialized/index.css';\n\n// Option 2: Import only what you need (modular approach)\nimport 'mithril-materialized/core.css';      // Essential styles (18KB)\nimport 'mithril-materialized/forms.css';     // Form components only\nimport 'mithril-materialized/components.css'; // Interactive components\n\n// Option 3: Advanced components only when needed\nimport 'mithril-materialized/pickers.css';   // Date/Time pickers\nimport 'mithril-materialized/advanced.css';  // Carousel, sidenav, etc.\nimport 'mithril-materialized/utilities.css'; // Badges, icons, cards\n```\n\n**CSS Modules Available:**\n\n- `core.css` (18KB) - Essential foundation (normalize, grid, typography, variables)\n- `components.css` - Interactive components (buttons, dropdowns, modals, tabs)\n- `forms.css` - All form components (inputs, selects, switches, file upload)\n- `pickers.css` - Date and time picker components\n- `advanced.css` - Specialized components (carousel, sidenav, navbar, preloader)\n- `utilities.css` - Visual utilities (badges, cards, icons, toast, chips)\n\n**Bundle Size Optimization:**\n\n- Full bundle: 64KB gzipped (44KB JS + 20KB CSS)\n- Modular approach can reduce CSS by 30-50%\n- Use only `core.css` + specific modules for your use case\n\n### 🌓 Dark Theme Support\n\nBuilt-in dark theme support with CSS custom properties:\n\n```typescript\nimport { ThemeManager, ThemeSwitcher } from 'mithril-materialized';\n\n// Programmatic theme control\nThemeManager.setTheme('dark');    // 'light' | 'dark' | 'auto'\nThemeManager.toggle();            // Toggle between light/dark\nThemeManager.getTheme();          // Get current theme\n\n// UI Components\nm(ThemeSwitcher, {\n  onThemeChange: (theme) =\u003e console.log('Theme:', theme)\n});\n\nm(ThemeToggle); // Simple toggle button\n```\n\n**CSS Custom Properties**: All colors use CSS variables for runtime theme switching:\n\n```css\n:root {\n  --mm-primary-color: #26a69a;\n  --mm-background-color: #ffffff;\n  --mm-text-primary: rgba(0, 0, 0, 0.87);\n}\n\n[data-theme=\"dark\"] {\n  --mm-primary-color: #80cbc4;\n  --mm-background-color: #121212;\n  --mm-text-primary: rgba(255, 255, 255, 0.87);\n}\n```\n\n### SASS Usage\n\nFor advanced customization, you can use the SASS source files directly:\n\n```css\n// Import all SASS components\n@import 'mithril-materialized/sass/materialize.scss';\n\n// Or import individual components\n@import 'mithril-materialized/sass/components/buttons';\n@import 'mithril-materialized/sass/components/forms';\n@import 'mithril-materialized/sass/components/grid';\n```\n\n**SASS Variables**: You can customize colors, spacing, and other design tokens by overriding SASS variables before importing:\n\n```css\n// Customize Material Design variables\n$primary-color: #2196F3;\n$secondary-color: #FF9800;\n\n// Then import the library\n@import 'mithril-materialized/sass/materialize.scss';\n```\n\n### Custom Styles\n\nThe library includes these additional styles for enhanced functionality:\n\n```css\n/* For the switch */\n.clear,\n.clear-10,\n.clear-15 {\n  clear: both;\n  /* overflow: hidden; Precaution pour IE 7 */\n}\n.clear-10 {\n  margin-bottom: 10px;\n}\n.clear-15 {\n  margin-bottom: 15px;\n}\n\nspan.mandatory {\n  margin-left: 5px;\n  color: red;\n}\n\nlabel+.switch {\n  margin-top: 1rem;\n}\n\n/* For the color input */\ninput[type='color']:not(.browser-default) {\n  margin: 0px 0 8px 0;\n  /** Copied from input[type=number] */\n  background-color: transparent;\n  border: none;\n  border-bottom: 1px solid #9e9e9e;\n  border-radius: 0;\n  outline: none;\n  height: 3rem;\n  width: 100%;\n  font-size: 16px;\n  padding: 0;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n  -webkit-transition: border 0.3s, -webkit-box-shadow 0.3s;\n  transition: border 0.3s, -webkit-box-shadow 0.3s;\n  transition: box-shadow 0.3s, border 0.3s;\n  transition: box-shadow 0.3s, border 0.3s, -webkit-box-shadow 0.3s;\n}\n\n/* For the options' label */\n.input-field.options \u003e label {\n  top: -2.5rem;\n}\n\n/* For the code block */\n.codeblock {\n  margin: 1.5rem 0 2.5rem 0;\n}\n.codeblock \u003e div {\n  margin-bottom: 1rem;\n}\n.codeblock \u003e label {\n  display: inline-block;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferikvullings%2Fmithril-materialized","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferikvullings%2Fmithril-materialized","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferikvullings%2Fmithril-materialized/lists"}