{"action":"created","issue":{"url":"https://api.github.com/repos/gcanti/tcomb-form/issues/254","labels_url":"https://api.github.com/repos/gcanti/tcomb-form/issues/254/labels{/name}","comments_url":"https://api.github.com/repos/gcanti/tcomb-form/issues/254/comments","events_url":"https://api.github.com/repos/gcanti/tcomb-form/issues/254/events","html_url":"https://github.com/gcanti/tcomb-form/issues/254","id":117219095,"number":254,"title":"How to style list's \"remove\", \"up\" and \"down\" buttons?","user":{"login":"Xananax","id":836082,"avatar_url":"https://avatars.githubusercontent.com/u/836082?v=3","gravatar_id":"","url":"https://api.github.com/users/Xananax","html_url":"https://github.com/Xananax","followers_url":"https://api.github.com/users/Xananax/followers","following_url":"https://api.github.com/users/Xananax/following{/other_user}","gists_url":"https://api.github.com/users/Xananax/gists{/gist_id}","starred_url":"https://api.github.com/users/Xananax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Xananax/subscriptions","organizations_url":"https://api.github.com/users/Xananax/orgs","repos_url":"https://api.github.com/users/Xananax/repos","events_url":"https://api.github.com/users/Xananax/events{/privacy}","received_events_url":"https://api.github.com/users/Xananax/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":10,"created_at":"2015-11-16T21:12:13Z","updated_at":"2015-11-19T00:53:17Z","closed_at":null,"body":"I'm having a hard time wrapping my head around the best way to customize the those buttons.\r\n\r\nThe way I see it, currently, if I wanted to replace them with icons (respectively `✖`, `▲` and `▼`), the process is quite involved.\r\n\r\nI tried following up the codepath where the buttons are created (for bootstrap templates) and it seems to me the following snippets are the important ones:\r\n\r\nIn `components.js`, in the `getItems()` method of the `List` component, the buttons options get created\r\n```js\r\nconst buttons = [];\r\n      if (!options.disableRemove) { buttons.push({ label: i18n.remove, click: this.removeItem.bind(this, i) }); }\r\n      if (!options.disableOrder)  { buttons.push({ label: i18n.up, click: this.moveUpItem.bind(this, i) }); }\r\n      if (!options.disableOrder)  { buttons.push({ label: i18n.down, click: this.moveDownItem.bind(this, i) }); }\r\n```\r\n\r\nIn `templates/bootstrap.js`, in the `list` template, the buttons get created:\r\n```js\r\nbootstrap.getCol({\r\n          breakpoints: {sm: 4, xs: 6},\r\n          children: bootstrap.getButtonGroup(item.buttons.map(function (button, i) {\r\n            return bootstrap.getButton({\r\n              click: button.click,\r\n              key: i,\r\n              label: button.label\r\n            });\r\n          }))\r\n        })\r\n```\r\n\r\nThen in the `getButton.js` file of the `uvdom-bootstrap` module, the button actually gets instantiated.\r\n\r\nSo, in order to customize the template, one would have to:\r\n\r\n1. reimplement (or extend) the `List` Component\r\n2. reimplement the `list` template\r\n3. as to not stray too far away from the core code (in order to reproduce changes easily), one has to import and learn to use `uvdom` and `uvdom-boostrap` (arguably not very hard, but still a slight additional learning curve).\r\n\r\nIt's a complex process because both the List component and the list template make use of a bunch of helper functions which are not always exposed. They are also pretty complex (in other words, easy to break when the main library changes something).\r\n\r\nAlternatively, one could create a factory that reimplements `onItemChange`, `removeItem`, `moveUpItem`, and `moveDownItem`, but you'd also have to reimplement `validate`, errors handling, and so on (so basically actually reimplementing the `List` component almost in it's entirety).\r\n\r\nIt seems to me that it would be better if the buttons were their own components, so they could be skinned just like everything else:\r\n\r\n```js\r\nf.form.Form.templates.upButton = template\r\n```\r\nor:\r\n\r\n```js\r\noptions = {\r\n    templates:{\r\n         upButton:template\r\n    }\r\n}\r\n```\r\n\r\nAm I missing something? Is there an easier way to accomplish this that I'm not seeing?"},"comment":{"url":"https://api.github.com/repos/gcanti/tcomb-form/issues/comments/157912175","html_url":"https://github.com/gcanti/tcomb-form/issues/254#issuecomment-157912175","issue_url":"https://api.github.com/repos/gcanti/tcomb-form/issues/254","id":157912175,"user":{"login":"minedeljkovic","id":1811622,"avatar_url":"https://avatars.githubusercontent.com/u/1811622?v=3","gravatar_id":"","url":"https://api.github.com/users/minedeljkovic","html_url":"https://github.com/minedeljkovic","followers_url":"https://api.github.com/users/minedeljkovic/followers","following_url":"https://api.github.com/users/minedeljkovic/following{/other_user}","gists_url":"https://api.github.com/users/minedeljkovic/gists{/gist_id}","starred_url":"https://api.github.com/users/minedeljkovic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/minedeljkovic/subscriptions","organizations_url":"https://api.github.com/users/minedeljkovic/orgs","repos_url":"https://api.github.com/users/minedeljkovic/repos","events_url":"https://api.github.com/users/minedeljkovic/events{/privacy}","received_events_url":"https://api.github.com/users/minedeljkovic/received_events","type":"User","site_admin":false},"created_at":"2015-11-19T00:53:17Z","updated_at":"2015-11-19T00:53:17Z","body":"Slightly modified version maybe?\r\n\r\nlist component:\r\n```js\r\nfunction create(overrides = {}) {\r\n\r\n  function list(locals) {\r\n    ...\r\n  }\r\n  \r\n  list.extend = create;\r\n  \r\n  list.renderAddButton = overrides.renderAddButton || function (locals) {\r\n    // default implementation\r\n  };\r\n\r\n  return list;\r\n}\r\n\r\nexport default create();\r\n```\r\n\r\nthen local override:\r\n```js\r\nfunction renderAddButton(locals) {\r\n  return <button onClick={locals.add.click}>{locals.add.label}</button>;\r\n}\r\n\r\nconst myList = t.form.Form.templates.list.extend({ renderAddButton });\r\nmyList.renderAddButton = renderAddButton;\r\n```"}}