toolbar.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import { each, zip } from '@lumino/algorithm';
  4. import { Message } from '@lumino/messaging';
  5. import { ISignal, Signal } from '@lumino/signaling';
  6. import { Widget } from '@lumino/widgets';
  7. import { Styling } from '@jupyterlab/apputils';
  8. /**
  9. * The supported parsing delimiters.
  10. */
  11. const DELIMITERS = [',', ';', '\t', '|', '#'];
  12. /**
  13. * The labels for each delimiter as they appear in the dropdown menu.
  14. */
  15. const LABELS = [',', ';', 'tab', 'pipe', 'hash'];
  16. /**
  17. * The class name added to a csv toolbar widget.
  18. */
  19. const CSV_DELIMITER_CLASS = 'jp-CSVDelimiter';
  20. const CSV_DELIMITER_LABEL_CLASS = 'jp-CSVDelimiter-label';
  21. /**
  22. * The class name added to a csv toolbar's dropdown element.
  23. */
  24. const CSV_DELIMITER_DROPDOWN_CLASS = 'jp-CSVDelimiter-dropdown';
  25. /**
  26. * A widget for selecting a delimiter.
  27. */
  28. export class CSVDelimiter extends Widget {
  29. /**
  30. * Construct a new csv table widget.
  31. */
  32. constructor(options: CSVToolbar.IOptions) {
  33. super({ node: Private.createNode(options.selected) });
  34. this.addClass(CSV_DELIMITER_CLASS);
  35. }
  36. /**
  37. * A signal emitted when the delimiter selection has changed.
  38. */
  39. get delimiterChanged(): ISignal<this, string> {
  40. return this._delimiterChanged;
  41. }
  42. /**
  43. * The delimiter dropdown menu.
  44. */
  45. get selectNode(): HTMLSelectElement {
  46. return this.node.getElementsByTagName('select')![0];
  47. }
  48. /**
  49. * Handle the DOM events for the widget.
  50. *
  51. * @param event - The DOM event sent to the widget.
  52. *
  53. * #### Notes
  54. * This method implements the DOM `EventListener` interface and is
  55. * called in response to events on the dock panel's node. It should
  56. * not be called directly by user code.
  57. */
  58. handleEvent(event: Event): void {
  59. switch (event.type) {
  60. case 'change':
  61. this._delimiterChanged.emit(this.selectNode.value);
  62. break;
  63. default:
  64. break;
  65. }
  66. }
  67. /**
  68. * Handle `after-attach` messages for the widget.
  69. */
  70. protected onAfterAttach(msg: Message): void {
  71. this.selectNode.addEventListener('change', this);
  72. }
  73. /**
  74. * Handle `before-detach` messages for the widget.
  75. */
  76. protected onBeforeDetach(msg: Message): void {
  77. this.selectNode.removeEventListener('change', this);
  78. }
  79. private _delimiterChanged = new Signal<this, string>(this);
  80. }
  81. /**
  82. * A namespace for `CSVToolbar` statics.
  83. */
  84. export namespace CSVToolbar {
  85. /**
  86. * The instantiation options for a CSV toolbar.
  87. */
  88. export interface IOptions {
  89. /**
  90. * The initially selected delimiter.
  91. */
  92. selected: string;
  93. }
  94. }
  95. /**
  96. * A namespace for private toolbar methods.
  97. */
  98. namespace Private {
  99. /**
  100. * Create the node for the delimiter switcher.
  101. */
  102. export function createNode(selected: string): HTMLElement {
  103. const div = document.createElement('div');
  104. const label = document.createElement('span');
  105. const select = document.createElement('select');
  106. label.textContent = 'Delimiter: ';
  107. label.className = CSV_DELIMITER_LABEL_CLASS;
  108. each(zip(DELIMITERS, LABELS), ([delimiter, label]) => {
  109. const option = document.createElement('option');
  110. option.value = delimiter;
  111. option.textContent = label;
  112. if (delimiter === selected) {
  113. option.selected = true;
  114. }
  115. select.appendChild(option);
  116. });
  117. div.appendChild(label);
  118. const node = Styling.wrapSelect(select);
  119. node.classList.add(CSV_DELIMITER_DROPDOWN_CLASS);
  120. div.appendChild(node);
  121. return div;
  122. }
  123. }