--- /dev/null
+<?php
+
+namespace OOUI;
+
+/**
+ * Base class for input widgets.
+ *
+ * @abstract
+ */
+class InputWidget extends Widget {
+ use FlaggedElement;
+ use TabIndexedElement;
+ use TitledElement;
+ use AccessKeyedElement;
+
+ /* Properties */
+
+ /**
+ * Input element.
+ *
+ * @var Tag
+ */
+ protected $input;
+
+ /**
+ * Input value.
+ *
+ * @var string
+ */
+ protected $value = '';
+
+ /**
+ * @param array $config Configuration options
+ * @param string $config['name'] HTML input name (default: '')
+ * @param string $config['value'] Input value (default: '')
+ * @param string $config['dir'] The directionality of the input (ltr/rtl)
+ * @param string $config['inputId'] The value of the input’s HTML `id` attribute.
+ */
+ public function __construct( array $config = [] ) {
+ // Parent constructor
+ parent::__construct( $config );
+
+ // Properties
+ $this->input = $this->getInputElement( $config );
+
+ // Traits
+ $this->initializeFlaggedElement( array_merge( $config, [ 'flagged' => $this ] ) );
+ $this->initializeTabIndexedElement(
+ array_merge( $config, [ 'tabIndexed' => $this->input ] ) );
+ $this->initializeTitledElement(
+ array_merge( $config, [ 'titled' => $this->input ] ) );
+ $this->initializeAccessKeyedElement(
+ array_merge( $config, [ 'accessKeyed' => $this->input ] ) );
+
+ // Initialization
+ if ( isset( $config['name'] ) ) {
+ $this->input->setAttributes( [ 'name' => $config['name'] ] );
+ }
+ if ( $this->isDisabled() ) {
+ $this->input->setAttributes( [ 'disabled' => 'disabled' ] );
+ }
+ $this
+ ->addClasses( [ 'oo-ui-inputWidget' ] )
+ ->appendContent( $this->input );
+ $this->input->addClasses( [ 'oo-ui-inputWidget-input' ] );
+ $this->setValue( isset( $config['value'] ) ? $config['value'] : null );
+ if ( isset( $config['dir'] ) ) {
+ $this->setDir( $config['dir'] );
+ }
+ if ( isset( $config['inputId'] ) ) {
+ $this->setInputId( $config['inputId'] );
+ }
+ }
+
+ /**
+ * Get input element.
+ *
+ * @param array $config Configuration options
+ * @return Tag Input element
+ */
+ protected function getInputElement( $config ) {
+ return new Tag( 'input' );
+ }
+
+ /**
+ * Get the value of the input.
+ *
+ * @return string Input value
+ */
+ public function getValue() {
+ return $this->value;
+ }
+
+ /**
+ * Set the directionality of the input.
+ *
+ * @param string $dir Text directionality: 'ltr', 'rtl' or 'auto'
+ * @return $this
+ */
+ public function setDir( $dir ) {
+ $this->input->setAttributes( [ 'dir' => $dir ] );
+ return $this;
+ }
+
+ /**
+ * Set the value of the input.
+ *
+ * @param string $value New value
+ * @return $this
+ */
+ public function setValue( $value ) {
+ $this->value = $this->cleanUpValue( $value );
+ $this->input->setValue( $this->value );
+ return $this;
+ }
+
+ /**
+ * Clean up incoming value.
+ *
+ * Ensures value is a string, and converts null to empty string.
+ *
+ * @param string $value Original value
+ * @return string Cleaned up value
+ */
+ protected function cleanUpValue( $value ) {
+ if ( $value === null ) {
+ return '';
+ } else {
+ return (string)$value;
+ }
+ }
+
+ public function setDisabled( $state ) {
+ parent::setDisabled( $state );
+ if ( isset( $this->input ) ) {
+ if ( $this->isDisabled() ) {
+ $this->input->setAttributes( [ 'disabled' => 'disabled' ] );
+ } else {
+ $this->input->removeAttributes( [ 'disabled' ] );
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Set the 'id' attribute of the `<input>` element.
+ *
+ * @param string $id The ID of the input element
+ * @return $this
+ */
+ public function setInputId( $id ) {
+ $this->input->setAttributes( [ 'id' => $id ] );
+ return $this;
+ }
+
+ public function getConfig( &$config ) {
+ $name = $this->input->getAttribute( 'name' );
+ if ( $name !== null ) {
+ $config['name'] = $name;
+ }
+ if ( $this->value !== '' ) {
+ $config['value'] = $this->value;
+ }
+ $id = $this->input->getAttribute( 'id' );
+ if ( $id !== null ) {
+ $config['inputId'] = $id;
+ }
+ return parent::getConfig( $config );
+ }
+}