{"id":27719387,"url":"https://github.com/repetitioestmaterstudiorum/dynamic-list-react","last_synced_at":"2026-05-02T03:08:52.888Z","repository":{"id":193501926,"uuid":"688468005","full_name":"repetitioestmaterstudiorum/dynamic-list-react","owner":"repetitioestmaterstudiorum","description":"React component to render a list of input items that can be added to, updated and removed from without any buttons.","archived":false,"fork":false,"pushed_at":"2023-10-08T13:32:35.000Z","size":1501,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-09T05:02:56.792Z","etag":null,"topics":["dynamiclist","nomodes","react"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/dynamic-list-react","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/repetitioestmaterstudiorum.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2023-09-07T12:12:29.000Z","updated_at":"2023-09-09T12:35:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"4595a316-90a0-4f7e-a4c1-4d780108f644","html_url":"https://github.com/repetitioestmaterstudiorum/dynamic-list-react","commit_stats":null,"previous_names":["repetitioestmaterstudiorum/dynamic-list-react"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/repetitioestmaterstudiorum/dynamic-list-react","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repetitioestmaterstudiorum%2Fdynamic-list-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repetitioestmaterstudiorum%2Fdynamic-list-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repetitioestmaterstudiorum%2Fdynamic-list-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repetitioestmaterstudiorum%2Fdynamic-list-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/repetitioestmaterstudiorum","download_url":"https://codeload.github.com/repetitioestmaterstudiorum/dynamic-list-react/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/repetitioestmaterstudiorum%2Fdynamic-list-react/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32521139,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T01:12:54.858Z","status":"online","status_checked_at":"2026-05-02T02:00:05.923Z","response_time":132,"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":["dynamiclist","nomodes","react"],"created_at":"2025-04-27T07:44:38.273Z","updated_at":"2026-05-02T03:08:52.874Z","avatar_url":"https://github.com/repetitioestmaterstudiorum.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dynamic-list-react\n\nInspired by Larry Tesler's work, this package contains a react component to render a list of input items that can be added to, updated and removed from without switching between edit and view modes and without any buttons (optionally, a delete button can be shown for each item).\n\n## Installation\n\n`npm install dynamic-list-react`\n\n## Usage\n\n### Basic Example\n\n![Basic Example Illustration](https://github.com/repetitioestmaterstudiorum/dynamic-list-react/raw/main/assets/basic-example.gif?raw=true)\n\n```javascript\nimport React from 'react';\nimport { DynamicList, type HandleInputChange } from 'dynamic-list-react';\n\nexport function ExampleDynamicList() {\n\tconst data = getCurrentData();\n\tconst defaultItem = { name: '' };\n\n\tconst updateKeyValue = (_id: string, key: string, value: any) =\u003e {\n\t\tconst currentData = getCurrentData();\n\t\tconst itemToUpdate = currentData.find(item =\u003e item._id === _id);\n\t\tif (itemToUpdate) {\n\t\t\titemToUpdate[key] = value;\n\t\t\tsetData(currentData);\n\t\t}\n\t}\n\n\tconst removeItem = (_id: string) =\u003e {\n\t\tconst currentData = getCurrentData();\n\t\tsetData(currentData.filter(item =\u003e item._id !== _id));\n\t}\n\n\tconst addItem = (item: ItemType) =\u003e {\n\t\tconst currentData = getCurrentData();\n\t\tsetData(currentData.concat(item));\n\t}\n\n\tconst InputComponent = (item: ItemType, handleInputChange: HandleInputChange\u003cItemType\u003e) =\u003e (\n\t\t\u003cdiv key={item._id}\u003e\n\t\t\t\u003cinput\n\t\t\t\tplaceholder=\"Name\"\n\t\t\t\tvalue={item.name}\n\t\t\t\tonChange={e =\u003e handleInputChange(item._id, 'name', e.target.value)}\n\t\t\t/\u003e\n\t\t\u003c/div\u003e\n\t);\n\n\treturn (\n\t\t\u003cDynamicList\u003cItemType\u003e\n\t\t\trenderComponent={InputComponent}\n\t\t\tdataProp={data}\n\t\t\taddItem={addItem}\n\t\t\tupdateKeyValue={updateKeyValue}\n\t\t\tremoveItem={removeItem}\n\t\t\tdefaultItem={defaultItem}\n\t\t/\u003e\n\t);\n}\n\nfunction getCurrentData() {\n\t\treturn JSON.parse(localStorage.getItem('storageKey') || '[]') as ItemType[];\n\t}\n\nfunction setData(data: ItemType[]) {\n\tlocalStorage.setItem('storageKey', JSON.stringify(data));\n}\n\ntype ItemType = Record\u003cstring, any\u003e;\n```\n\n### Advanced Example\n\n![Advanced Example Illustration](https://github.com/repetitioestmaterstudiorum/dynamic-list-react/raw/main/assets/advanced-example.gif?raw=true)\n\n```javascript\nimport React from 'react'\nimport { DynamicList, type HandleDelete, type HandleInputChange } from 'dynamic-list-react'\n\nexport function ExampleDynamicList() {\n\tconst data = getCurrentData()\n\tconst defaultItem = {\n\t\tfirstName: '',\n\t\tlastName: '',\n\t\tscore: '',\n\t}\n\n\tconst updateKeyValue = (_id: string, key: string, value: any) =\u003e {\n\t\tconst currentData = getCurrentData()\n\t\tconst itemToUpdate = currentData.find((item) =\u003e item._id === _id)\n\t\tif (itemToUpdate) {\n\t\t\titemToUpdate[key] = value\n\t\t\tsetData(currentData)\n\t\t}\n\t}\n\n\tconst removeItem = (_id: string) =\u003e {\n\t\tconst currentData = getCurrentData()\n\t\tsetData(currentData.filter((item) =\u003e item._id !== _id))\n\t}\n\n\tconst addItem = (item: ItemType) =\u003e {\n\t\tconst currentData = getCurrentData()\n\t\tsetData(currentData.concat(item))\n\t}\n\n\tconst InputComponent = (\n\t\titem: ItemType,\n\t\thandleInputChange: HandleInputChange\u003cItemType\u003e,\n\t\thandleDelete: HandleDelete,\n\t\tisLastItem: boolean,\n\t\tidx: number\n\t) =\u003e (\n\t\t\u003cdiv key={item._id}\u003e\n\t\t\t\u003cp\u003eItem {idx + 1}\u003c/p\u003e\n\t\t\t\u003cinput\n\t\t\t\tplaceholder='First Name'\n\t\t\t\tvalue={item.firstName}\n\t\t\t\tonChange={(e) =\u003e handleInputChange(item._id, 'firstName', e.target.value)}\n\t\t\t/\u003e\n\t\t\t\u003cinput\n\t\t\t\tplaceholder='Last Name'\n\t\t\t\tvalue={item.lastName}\n\t\t\t\tonChange={(e) =\u003e handleInputChange(item._id, 'lastName', e.target.value)}\n\t\t\t/\u003e\n\t\t\t\u003cinput\n\t\t\t\tplaceholder='Score'\n\t\t\t\tvalue={item.score}\n\t\t\t\tonChange={(e) =\u003e handleInputChange(item._id, 'score', e.target.value)}\n\t\t\t/\u003e\n\t\t\t{isLastItem ? null : \u003cbutton onClick={() =\u003e handleDelete(item._id)}\u003eDelete\u003c/button\u003e}\n\t\t\u003c/div\u003e\n\t)\n\n\treturn (\n\t\t\u003cDynamicList\u003cItemType\u003e\n\t\t\trenderComponent={InputComponent}\n\t\t\tdataProp={data}\n\t\t\taddItem={addItem}\n\t\t\tupdateKeyValue={updateKeyValue}\n\t\t\tremoveItem={removeItem}\n\t\t\tdefaultItem={defaultItem}\n\t\t\tgetRandomId={getRandomId}\n\t\t/\u003e\n\t)\n}\n\nfunction getCurrentData() {\n\treturn JSON.parse(localStorage.getItem('storageKey') || '[]') as ItemType[]\n}\n\nfunction setData(data: ItemType[]) {\n\tlocalStorage.setItem('storageKey', JSON.stringify(data))\n}\n\nfunction getRandomId() {\n\t// e.g. crypto.randomUUID() or uuidv4()\n\treturn Date.now().toString()\n}\n\ntype ItemType = Record\u003cstring, any\u003e\n```\n\n## Larry Tesler: No Modes\n\n\u003e One of Mr Tesler's firmest beliefs was that computer systems should stop using \"modes\", which were common in software design at the time.\n\u003e Modes allow users to switch between functions on software and apps but make computers both time-consuming and complicated.\n\u003e So strong was this belief that Mr Tesler's website was called \"nomodes.com\", his Twitter handle was \"@nomodes\", and even his car's registration plate was \"No Modes\".\n\nSource: https://www.bbc.com/news/world-us-canada-51567695\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frepetitioestmaterstudiorum%2Fdynamic-list-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frepetitioestmaterstudiorum%2Fdynamic-list-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frepetitioestmaterstudiorum%2Fdynamic-list-react/lists"}