tablecellpropertiesview.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module table/tablecellproperties/ui/tablecellpropertiesview
  7. */
  8. import View from '@ckeditor/ckeditor5-ui/src/view';
  9. import ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';
  10. import submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';
  11. import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
  12. import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
  13. import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';
  14. import LabeledView from '@ckeditor/ckeditor5-ui/src/labeledview/labeledview';
  15. import { createLabeledDropdown, createLabeledInputText } from '@ckeditor/ckeditor5-ui/src/labeledview/utils';
  16. import LabelView from '@ckeditor/ckeditor5-ui/src/label/labelview';
  17. import { addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';
  18. import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
  19. import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
  20. import { fillToolbar, getBorderStyleDefinitions, getBorderStyleLabels } from '../../ui/utils';
  21. import FormRowView from '../../ui/formrowview';
  22. import FormHeaderView from '../../ui/formheaderview';
  23. import checkIcon from '@ckeditor/ckeditor5-core/theme/icons/check.svg';
  24. import cancelIcon from '@ckeditor/ckeditor5-core/theme/icons/cancel.svg';
  25. import alignLeftIcon from '@ckeditor/ckeditor5-core/theme/icons/align-left.svg';
  26. import alignRightIcon from '@ckeditor/ckeditor5-core/theme/icons/align-right.svg';
  27. import alignCenterIcon from '@ckeditor/ckeditor5-core/theme/icons/align-center.svg';
  28. import alignJustifyIcon from '@ckeditor/ckeditor5-core/theme/icons/align-justify.svg';
  29. import alignTopIcon from '@ckeditor/ckeditor5-core/theme/icons/align-top.svg';
  30. import alignMiddleIcon from '@ckeditor/ckeditor5-core/theme/icons/align-middle.svg';
  31. import alignBottomIcon from '@ckeditor/ckeditor5-core/theme/icons/align-bottom.svg';
  32. import ColorInputView from '@ckeditor/ckeditor5-ui/src/colorinputview/colorinputview';
  33. import '../../../theme/form.css';
  34. import '../../../theme/tableform.css';
  35. import '../../../theme/tablecellproperties.css';
  36. const ALIGNMENT_ICONS = {
  37. left: alignLeftIcon,
  38. center: alignCenterIcon,
  39. right: alignRightIcon,
  40. justify: alignJustifyIcon,
  41. top: alignTopIcon,
  42. middle: alignMiddleIcon,
  43. bottom: alignBottomIcon
  44. };
  45. /**
  46. * The class representing a table cell properties form, allowing users to customize
  47. * certain style aspects of a table cell, for instance, border, padding, text alignment, etc..
  48. *
  49. * @extends module:ui/view~View
  50. */
  51. export default class TableCellPropertiesView extends View {
  52. /**
  53. * @inheritDoc
  54. */
  55. constructor( locale ) {
  56. super( locale );
  57. const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
  58. const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
  59. const { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();
  60. /**
  61. * Tracks information about the DOM focus in the form.
  62. *
  63. * @readonly
  64. * @member {module:utils/focustracker~FocusTracker}
  65. */
  66. this.focusTracker = new FocusTracker();
  67. /**
  68. * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
  69. *
  70. * @readonly
  71. * @member {module:utils/keystrokehandler~KeystrokeHandler}
  72. */
  73. this.keystrokes = new KeystrokeHandler();
  74. /**
  75. * A collection of child views in the form.
  76. *
  77. * @readonly
  78. * @type {module:ui/viewcollection~ViewCollection}
  79. */
  80. this.children = this.createCollection();
  81. this.set( {
  82. /**
  83. * The value of the cell border style.
  84. *
  85. * @observable
  86. * @default 'none'
  87. * @member #borderStyle
  88. */
  89. borderStyle: 'none',
  90. /**
  91. * The value of the cell border width style.
  92. *
  93. * @observable
  94. * @default ''
  95. * @member #borderWidth
  96. */
  97. borderWidth: '',
  98. /**
  99. * The value of the cell border color style.
  100. *
  101. * @observable
  102. * @default ''
  103. * @member #borderColor
  104. */
  105. borderColor: '',
  106. /**
  107. * The value of the cell padding style.
  108. *
  109. * @observable
  110. * @default ''
  111. * @member #padding
  112. */
  113. padding: '',
  114. /**
  115. * The value of the cell background color style.
  116. *
  117. * @observable
  118. * @default ''
  119. * @member #backgroundColor
  120. */
  121. backgroundColor: '',
  122. /**
  123. * The value of the table cell width style.
  124. *
  125. * @observable
  126. * @default ''
  127. * @member #width
  128. */
  129. width: '',
  130. /**
  131. * The value of the table cell height style.
  132. *
  133. * @observable
  134. * @default ''
  135. * @member #height
  136. */
  137. height: '',
  138. /**
  139. * The value of the horizontal text alignment style.
  140. *
  141. * @observable
  142. * @default 'left'
  143. * @member #horizontalAlignment
  144. */
  145. horizontalAlignment: 'left',
  146. /**
  147. * The value of the vertical text alignment style.
  148. *
  149. * @observable
  150. * @default 'middle'
  151. * @member #verticalAlignment
  152. */
  153. verticalAlignment: 'middle'
  154. } );
  155. /**
  156. * A dropdown that allows selecting the style of the table cell border.
  157. *
  158. * @readonly
  159. * @member {module:ui/dropdown/dropdownview~DropdownView}
  160. */
  161. this.borderStyleDropdown = borderStyleDropdown;
  162. /**
  163. * An input that allows specifying the width of the table cell border.
  164. *
  165. * @readonly
  166. * @member {module:ui/inputtext/inputtextview~InputTextView}
  167. */
  168. this.borderWidthInput = borderWidthInput;
  169. /**
  170. * An input that allows specifying the color of the table cell border.
  171. *
  172. * @readonly
  173. * @member {module:ui/inputtext/inputtextview~InputTextView}
  174. */
  175. this.borderColorInput = borderColorInput;
  176. /**
  177. * An input that allows specifying the table cell background color.
  178. *
  179. * @readonly
  180. * @member {module:ui/inputtext/inputtextview~InputTextView}
  181. */
  182. this.backgroundInput = this._createBackgroundField();
  183. /**
  184. * An input that allows specifying the table cell padding.
  185. *
  186. * @readonly
  187. * @member {module:ui/inputtext/inputtextview~InputTextView}
  188. */
  189. this.paddingInput = this._createPaddingField();
  190. /**
  191. * An input that allows specifying the table cell width.
  192. *
  193. * @readonly
  194. * @member {module:ui/inputtext/inputtextview~InputTextView}
  195. */
  196. this.widthInput = widthInput;
  197. /**
  198. * An input that allows specifying the table cell height.
  199. *
  200. * @readonly
  201. * @member {module:ui/inputtext/inputtextview~InputTextView}
  202. */
  203. this.heightInput = heightInput;
  204. /**
  205. * A toolbar with buttons that allow changing the horizontal text alignment in a table cell.
  206. *
  207. * @readonly
  208. * @member {module:ui/toolbar/toolbar~ToolbarView}
  209. */
  210. this.horizontalAlignmentToolbar = horizontalAlignmentToolbar;
  211. /**
  212. * A toolbar with buttons that allow changing the vertical text alignment in a table cell.
  213. *
  214. * @readonly
  215. * @member {module:ui/toolbar/toolbar~ToolbarView}
  216. */
  217. this.verticalAlignmentToolbar = verticalAlignmentToolbar;
  218. // Defer creating to make sure other fields are present and the Save button can
  219. // bind its #isEnabled to their error messages so there's no way to save unless all
  220. // fields are valid.
  221. const { saveButtonView, cancelButtonView } = this._createActionButtons();
  222. /**
  223. * The "Save" button view.
  224. *
  225. * @member {module:ui/button/buttonview~ButtonView}
  226. */
  227. this.saveButtonView = saveButtonView;
  228. /**
  229. * The "Cancel" button view.
  230. *
  231. * @member {module:ui/button/buttonview~ButtonView}
  232. */
  233. this.cancelButtonView = cancelButtonView;
  234. /**
  235. * A collection of views that can be focused in the form.
  236. *
  237. * @readonly
  238. * @protected
  239. * @member {module:ui/viewcollection~ViewCollection}
  240. */
  241. this._focusables = new ViewCollection();
  242. /**
  243. * Helps cycling over {@link #_focusables} in the form.
  244. *
  245. * @readonly
  246. * @protected
  247. * @member {module:ui/focuscycler~FocusCycler}
  248. */
  249. this._focusCycler = new FocusCycler( {
  250. focusables: this._focusables,
  251. focusTracker: this.focusTracker,
  252. keystrokeHandler: this.keystrokes,
  253. actions: {
  254. // Navigate form fields backwards using the Shift + Tab keystroke.
  255. focusPrevious: 'shift + tab',
  256. // Navigate form fields forwards using the Tab key.
  257. focusNext: 'tab'
  258. }
  259. } );
  260. // Form header.
  261. this.children.add( new FormHeaderView( locale, {
  262. label: this.t( 'Cell properties' )
  263. } ) );
  264. // Border row.
  265. this.children.add( new FormRowView( locale, {
  266. labelView: borderRowLabel,
  267. children: [
  268. borderRowLabel,
  269. borderStyleDropdown,
  270. borderColorInput,
  271. borderWidthInput
  272. ],
  273. class: 'ck-table-form__border-row'
  274. } ) );
  275. // Background.
  276. this.children.add( new FormRowView( locale, {
  277. children: [
  278. this.backgroundInput
  279. ]
  280. } ) );
  281. // Dimensions row and padding.
  282. this.children.add( new FormRowView( locale, {
  283. children: [
  284. // Dimensions row.
  285. new FormRowView( locale, {
  286. labelView: dimensionsLabel,
  287. children: [
  288. dimensionsLabel,
  289. widthInput,
  290. operatorLabel,
  291. heightInput
  292. ],
  293. class: 'ck-table-cell-properties-form__dimensions-row'
  294. } ),
  295. // Padding row.
  296. new FormRowView( locale, {
  297. children: [
  298. this.paddingInput
  299. ],
  300. class: 'ck-table-cell-properties-form__padding-row'
  301. } )
  302. ]
  303. } ) );
  304. // Text alignment row.
  305. this.children.add( new FormRowView( locale, {
  306. labelView: alignmentLabel,
  307. children: [
  308. alignmentLabel,
  309. horizontalAlignmentToolbar,
  310. verticalAlignmentToolbar,
  311. ],
  312. class: 'ck-table-cell-properties-form__alignment-row'
  313. } ) );
  314. // Action row.
  315. this.children.add( new FormRowView( locale, {
  316. children: [
  317. this.saveButtonView,
  318. this.cancelButtonView,
  319. ],
  320. class: 'ck-table-form__action-row'
  321. } ) );
  322. this.setTemplate( {
  323. tag: 'form',
  324. attributes: {
  325. class: [
  326. 'ck',
  327. 'ck-form',
  328. 'ck-table-form',
  329. 'ck-table-cell-properties-form'
  330. ],
  331. // https://github.com/ckeditor/ckeditor5-link/issues/90
  332. tabindex: '-1'
  333. },
  334. children: this.children
  335. } );
  336. }
  337. /**
  338. * @inheritDoc
  339. */
  340. render() {
  341. super.render();
  342. // Enable the "submit" event for this view. It can be triggered by the #saveButtonView
  343. // which is of the "submit" DOM "type".
  344. submitHandler( {
  345. view: this
  346. } );
  347. [
  348. this.borderStyleDropdown,
  349. this.borderColorInput,
  350. this.borderWidthInput,
  351. this.backgroundInput,
  352. this.widthInput,
  353. this.heightInput,
  354. this.paddingInput,
  355. this.horizontalAlignmentToolbar,
  356. this.verticalAlignmentToolbar,
  357. this.saveButtonView,
  358. this.cancelButtonView
  359. ].forEach( view => {
  360. // Register the view as focusable.
  361. this._focusables.add( view );
  362. // Register the view in the focus tracker.
  363. this.focusTracker.add( view.element );
  364. } );
  365. // Mainly for closing using "Esc" and navigation using "Tab".
  366. this.keystrokes.listenTo( this.element );
  367. }
  368. /**
  369. * Focuses the fist focusable field in the form.
  370. */
  371. focus() {
  372. this._focusCycler.focusFirst();
  373. }
  374. /**
  375. * Creates the following form fields:
  376. *
  377. * * {@link #borderStyleDropdown},
  378. * * {@link #borderWidthInput},
  379. * * {@link #borderColorInput}.
  380. *
  381. * @private
  382. * @returns {Object.<String,module:ui/view~View>}
  383. */
  384. _createBorderFields() {
  385. const locale = this.locale;
  386. const t = this.t;
  387. // -- Group label ---------------------------------------------
  388. const borderRowLabel = new LabelView( locale );
  389. borderRowLabel.text = t( 'Border' );
  390. // -- Style ---------------------------------------------------
  391. const styleLabels = getBorderStyleLabels( t );
  392. const borderStyleDropdown = new LabeledView( locale, createLabeledDropdown );
  393. borderStyleDropdown.set( {
  394. label: t( 'Style' ),
  395. class: 'ck-table-form__border-style'
  396. } );
  397. borderStyleDropdown.view.buttonView.set( {
  398. isOn: false,
  399. withText: true,
  400. tooltip: t( 'Style' )
  401. } );
  402. borderStyleDropdown.view.buttonView.bind( 'label' ).to( this, 'borderStyle', value => {
  403. return styleLabels[ value ];
  404. } );
  405. borderStyleDropdown.view.on( 'execute', evt => {
  406. this.borderStyle = evt.source._borderStyleValue;
  407. } );
  408. addListToDropdown( borderStyleDropdown.view, getBorderStyleDefinitions( this ) );
  409. // -- Width ---------------------------------------------------
  410. const borderWidthInput = new LabeledView( locale, createLabeledInputText );
  411. borderWidthInput.set( {
  412. label: t( 'Width' ),
  413. class: 'ck-table-form__border-width',
  414. } );
  415. borderWidthInput.view.bind( 'value' ).to( this, 'borderWidth' );
  416. borderWidthInput.bind( 'isEnabled' ).to( this, 'borderStyle', value => {
  417. return value !== 'none';
  418. } );
  419. borderWidthInput.view.on( 'input', () => {
  420. this.borderWidth = borderWidthInput.view.element.value;
  421. } );
  422. // -- Color ---------------------------------------------------
  423. const borderColorInput = new ColorInputView( locale );
  424. borderColorInput.label = t( 'Color' );
  425. borderColorInput.bind( 'value' ).to( this, 'borderColor' );
  426. borderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', value => {
  427. return value !== 'none';
  428. } );
  429. borderColorInput.on( 'setColor', ( evt, data ) => {
  430. this.borderColor = data.value;
  431. } );
  432. return {
  433. borderRowLabel,
  434. borderStyleDropdown,
  435. borderColorInput,
  436. borderWidthInput,
  437. };
  438. }
  439. /**
  440. * Creates the following form fields:
  441. *
  442. * * {@link #backgroundInput}.
  443. *
  444. * @private
  445. * @returns {module:ui/labeledview/labeledview~LabeledView}
  446. */
  447. _createBackgroundField() {
  448. const locale = this.locale;
  449. const t = this.t;
  450. const backgroundInput = new LabeledView( locale, createLabeledInputText );
  451. backgroundInput.set( {
  452. label: t( 'Background' ),
  453. class: 'ck-table-cell-properties-form__background',
  454. } );
  455. backgroundInput.view.bind( 'value' ).to( this, 'backgroundColor' );
  456. backgroundInput.view.on( 'input', () => {
  457. this.backgroundColor = backgroundInput.view.element.value;
  458. } );
  459. return backgroundInput;
  460. }
  461. /**
  462. * Creates the following form fields:
  463. *
  464. * * {@link #widthInput}.
  465. * * {@link #heightInput}.
  466. *
  467. * @private
  468. * @returns {module:ui/labeledview/labeledview~LabeledView}
  469. */
  470. _createDimensionFields() {
  471. const locale = this.locale;
  472. const t = this.t;
  473. // -- Label ---------------------------------------------------
  474. const dimensionsLabel = new LabelView( locale );
  475. dimensionsLabel.text = t( 'Dimensions' );
  476. // -- Width ---------------------------------------------------
  477. const widthInput = new LabeledView( locale, createLabeledInputText );
  478. widthInput.set( {
  479. label: t( 'Width' ),
  480. class: 'ck-table-cell-properties-form__width',
  481. } );
  482. widthInput.view.bind( 'value' ).to( this, 'width' );
  483. widthInput.view.on( 'input', () => {
  484. this.width = widthInput.view.element.value;
  485. } );
  486. // -- Operator ---------------------------------------------------
  487. const operatorLabel = new View( locale );
  488. operatorLabel.setTemplate( {
  489. tag: 'span',
  490. attributes: {
  491. class: [
  492. 'ck-table-form__dimension-operator'
  493. ]
  494. },
  495. children: [
  496. { text: '×' }
  497. ]
  498. } );
  499. // -- Height ---------------------------------------------------
  500. const heightInput = new LabeledView( locale, createLabeledInputText );
  501. heightInput.set( {
  502. label: t( 'Height' ),
  503. class: 'ck-table-cell-properties-form__height',
  504. } );
  505. heightInput.view.bind( 'value' ).to( this, 'height' );
  506. heightInput.view.on( 'input', () => {
  507. this.height = heightInput.view.element.value;
  508. } );
  509. return {
  510. dimensionsLabel,
  511. widthInput,
  512. operatorLabel,
  513. heightInput
  514. };
  515. }
  516. /**
  517. * Creates the following form fields:
  518. *
  519. * * {@link #paddingInput}.
  520. *
  521. * @private
  522. * @returns {module:ui/labeledview/labeledview~LabeledView}
  523. */
  524. _createPaddingField() {
  525. const locale = this.locale;
  526. const t = this.t;
  527. const paddingInput = new LabeledView( locale, createLabeledInputText );
  528. paddingInput.set( {
  529. label: t( 'Padding' ),
  530. class: 'ck-table-cell-properties-form__padding',
  531. } );
  532. paddingInput.view.bind( 'value' ).to( this, 'padding' );
  533. paddingInput.view.on( 'input', () => {
  534. this.padding = paddingInput.view.element.value;
  535. } );
  536. return paddingInput;
  537. }
  538. /**
  539. * Creates the following form fields:
  540. *
  541. * * {@link #horizontalAlignmentToolbar},
  542. * * {@link #verticalAlignmentToolbar}.
  543. *
  544. * @private
  545. * @returns {Object.<String,module:ui/view~View>}
  546. */
  547. _createAlignmentFields() {
  548. const locale = this.locale;
  549. const t = this.t;
  550. const alignmentLabel = new LabelView( locale );
  551. alignmentLabel.text = t( 'Text alignment' );
  552. // -- Horizontal ---------------------------------------------------
  553. const horizontalAlignmentToolbar = new ToolbarView( locale );
  554. horizontalAlignmentToolbar.set( {
  555. isCompact: true,
  556. ariaLabel: t( 'Horizontal text alignment toolbar' )
  557. } );
  558. fillToolbar( {
  559. view: this,
  560. icons: ALIGNMENT_ICONS,
  561. toolbar: horizontalAlignmentToolbar,
  562. labels: this._horizontalAlignmentLabels,
  563. propertyName: 'horizontalAlignment'
  564. } );
  565. // -- Vertical -----------------------------------------------------
  566. const verticalAlignmentToolbar = new ToolbarView( locale );
  567. verticalAlignmentToolbar.set( {
  568. isCompact: true,
  569. ariaLabel: t( 'Vertical text alignment toolbar' )
  570. } );
  571. fillToolbar( {
  572. view: this,
  573. icons: ALIGNMENT_ICONS,
  574. toolbar: verticalAlignmentToolbar,
  575. labels: this._verticalAlignmentLabels,
  576. propertyName: 'verticalAlignment'
  577. } );
  578. return {
  579. horizontalAlignmentToolbar,
  580. verticalAlignmentToolbar,
  581. alignmentLabel
  582. };
  583. }
  584. /**
  585. * Creates the following form controls:
  586. *
  587. * * {@link #saveButtonView},
  588. * * {@link #cancelButtonView}.
  589. *
  590. * @private
  591. * @returns {Object.<String,module:ui/view~View>}
  592. */
  593. _createActionButtons() {
  594. const locale = this.locale;
  595. const t = this.t;
  596. const saveButtonView = new ButtonView( locale );
  597. const cancelButtonView = new ButtonView( locale );
  598. const fieldsThatShouldValidateToSave = [
  599. this.borderWidthInput,
  600. this.borderColorInput,
  601. this.backgroundInput,
  602. this.paddingInput
  603. ];
  604. saveButtonView.set( {
  605. label: t( 'Save' ),
  606. icon: checkIcon,
  607. class: 'ck-button-save',
  608. type: 'submit',
  609. withText: true,
  610. } );
  611. saveButtonView.bind( 'isEnabled' ).toMany( fieldsThatShouldValidateToSave, 'errorText', ( ...errorTexts ) => {
  612. return errorTexts.every( errorText => !errorText );
  613. } );
  614. cancelButtonView.set( {
  615. label: t( 'Cancel' ),
  616. icon: cancelIcon,
  617. class: 'ck-button-cancel',
  618. type: 'cancel',
  619. withText: true,
  620. } );
  621. cancelButtonView.delegate( 'execute' ).to( this, 'cancel' );
  622. return {
  623. saveButtonView, cancelButtonView
  624. };
  625. }
  626. /**
  627. * Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.
  628. *
  629. * @private
  630. * @type {Object.<String,String>}
  631. */
  632. get _horizontalAlignmentLabels() {
  633. const t = this.t;
  634. return {
  635. left: t( 'Align cell text to the left' ),
  636. center: t( 'Align cell text to the center' ),
  637. right: t( 'Align cell text to the right' ),
  638. justify: t( 'Justify cell text' ),
  639. };
  640. }
  641. /**
  642. * Provides localized labels for {@link #verticalAlignmentToolbar} buttons.
  643. *
  644. * @private
  645. * @type {Object.<String,String>}
  646. */
  647. get _verticalAlignmentLabels() {
  648. const t = this.t;
  649. return {
  650. top: t( 'Align cell text to the top' ),
  651. middle: t( 'Align cell text to the middle' ),
  652. bottom: t( 'Align cell text to the bottom' )
  653. };
  654. }
  655. }