├── .babelrc ├── .eslintrc ├── .gitignore ├── .sass-lint.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs └── D3.md ├── gulpfile.js ├── karma.conf.js ├── package.json ├── services.js ├── src ├── framework │ ├── _index.scss │ ├── accordion │ │ ├── Accordion.jsx │ │ ├── Accordion.spec.jsx │ │ ├── _accordion.scss │ │ └── _index.scss │ ├── accordionItem │ │ ├── AccordionItem.jsx │ │ ├── AccordionItem.spec.jsx │ │ ├── _accordionItem.scss │ │ └── _index.scss │ ├── addOnControl │ │ ├── AddOnControl.jsx │ │ ├── AddOnControl.spec.jsx │ │ ├── _addOnControl.scss │ │ ├── _index.scss │ │ ├── dropdown │ │ │ ├── AddOnDropdown.jsx │ │ │ ├── AddOnDropdown.spec.jsx │ │ │ ├── AddOnDropdownOption.jsx │ │ │ ├── AddOnDropdownOption.spec.jsx │ │ │ ├── _addOnDropdown.scss │ │ │ └── _addOnDropdownOption.scss │ │ └── label │ │ │ ├── AddOnLabel.jsx │ │ │ ├── AddOnLabel.spec.jsx │ │ │ └── _addOnLabel.scss │ ├── alert │ │ ├── Alert.jsx │ │ ├── Alert.spec.jsx │ │ ├── _alert.scss │ │ └── _index.scss │ ├── appHeader │ │ ├── AppHeader.jsx │ │ ├── AppHeader.spec.jsx │ │ ├── _appHeader.scss │ │ ├── _index.scss │ │ ├── account │ │ │ ├── AccountNav.jsx │ │ │ ├── AccountNav.spec.jsx │ │ │ ├── AccountPicture.jsx │ │ │ ├── AccountPicture.spec.jsx │ │ │ ├── _accountNav.scss │ │ │ └── _accountPicture.scss │ │ ├── button │ │ │ ├── AppHeaderButton.jsx │ │ │ ├── AppHeaderButton.spec.jsx │ │ │ └── _appHeaderButton.scss │ │ ├── divider │ │ │ ├── AppHeaderDivider.jsx │ │ │ ├── AppHeaderDivider.spec.jsx │ │ │ └── _appHeaderDivider.scss │ │ ├── logo │ │ │ ├── AppLogo.jsx │ │ │ ├── AppLogo.spec.jsx │ │ │ └── _appLogo.scss │ │ ├── nav │ │ │ ├── AppNav.jsx │ │ │ ├── AppNav.spec.jsx │ │ │ └── _appNav.scss │ │ └── title │ │ │ ├── AppTitle.jsx │ │ │ ├── AppTitle.spec.jsx │ │ │ ├── AppTitleContainer.jsx │ │ │ ├── AppTitleContainer.spec.jsx │ │ │ ├── _appTitle.scss │ │ │ └── _appTitleContainer.scss │ ├── base │ │ ├── _index.scss │ │ └── dropdown │ │ │ ├── BaseDropdown.jsx │ │ │ ├── BaseDropdown.spec.jsx │ │ │ ├── BaseDropdownOption.jsx │ │ │ ├── BaseDropdownOption.spec.jsx │ │ │ └── _index.scss │ ├── body │ │ ├── Body.jsx │ │ ├── Body.spec.jsx │ │ ├── BodyMaxWidthLayout.jsx │ │ ├── BodyMaxWidthLayout.spec.jsx │ │ ├── BodyPanel.jsx │ │ ├── BodyPanel.spec.jsx │ │ ├── BodyPanelItem.jsx │ │ ├── BodyPanelItem.spec.jsx │ │ ├── _body.scss │ │ ├── _bodyMaxWidthLayout.scss │ │ ├── _bodyPanel.scss │ │ ├── _bodyPanelItem.scss │ │ └── _index.scss │ ├── box │ │ ├── Box.jsx │ │ ├── Box.spec.jsx │ │ ├── _box.scss │ │ └── _index.scss │ ├── button │ │ ├── AlertButton.jsx │ │ ├── AlertButton.spec.jsx │ │ ├── BasicButton.jsx │ │ ├── BasicButton.spec.jsx │ │ ├── Button.jsx │ │ ├── Button.spec.jsx │ │ ├── CallOutButton.jsx │ │ ├── CallOutButton.spec.jsx │ │ ├── GroupedButton.jsx │ │ ├── GroupedButton.spec.jsx │ │ ├── HollowButton.jsx │ │ ├── HollowButton.spec.jsx │ │ ├── PrimaryButton.jsx │ │ ├── PrimaryButton.spec.jsx │ │ ├── _button.scss │ │ ├── _index.scss │ │ └── index.jsx │ ├── buttonGroup │ │ ├── ButtonGroup.jsx │ │ ├── ButtonGroup.spec.jsx │ │ ├── _buttonGroup.scss │ │ └── _index.scss │ ├── card │ │ ├── Card.jsx │ │ ├── Card.spec.jsx │ │ ├── _card.scss │ │ └── _index.scss │ ├── cardHolder │ │ ├── CardHolder.jsx │ │ ├── CardHolder.spec.jsx │ │ ├── _cardHolder.scss │ │ └── _index.scss │ ├── changeLog │ │ ├── ChangeLogLink.jsx │ │ ├── ChangeLogLink.spec.jsx │ │ ├── ChangeLogModal.jsx │ │ ├── ChangeLogModal.spec.jsx │ │ ├── ChangeLogService.js │ │ ├── ChangeLogService.spec.js │ │ ├── _changeLogLink.scss │ │ ├── _changeLogModal.scss │ │ ├── _index.scss │ │ ├── helpers.js │ │ └── helpers.spec.js │ ├── chart │ │ ├── Chart.jsx │ │ ├── Chart.spec.jsx │ │ ├── LineChart.jsx │ │ ├── LineChart.spec.jsx │ │ ├── _chart.scss │ │ ├── _index.scss │ │ ├── _lineChart.scss │ │ └── chartDot │ │ │ ├── ChartDot.jsx │ │ │ ├── ChartDot.spec.jsx │ │ │ └── _chartDot.scss │ ├── checkBox │ │ ├── CheckBox.jsx │ │ ├── CheckBox.spec.jsx │ │ ├── _checkBox.scss │ │ └── _index.scss │ ├── columnLayout │ │ ├── Column.jsx │ │ ├── Column.spec.jsx │ │ ├── ColumnLayout.jsx │ │ ├── ColumnLayout.spec.jsx │ │ ├── _columnLayout.scss │ │ └── _index.scss │ ├── dropdown │ │ ├── Dropdown.jsx │ │ ├── Dropdown.spec.jsx │ │ ├── DropdownGroup.jsx │ │ ├── DropdownGroup.spec.jsx │ │ ├── DropdownOption.jsx │ │ ├── DropdownOption.spec.jsx │ │ ├── _dropdown.scss │ │ ├── _dropdownOption.scss │ │ ├── _index.scss │ │ └── dropdownDot │ │ │ ├── DropdownDot.jsx │ │ │ ├── DropdownDot.spec.jsx │ │ │ └── _index.scss │ ├── fieldMessage │ │ ├── FieldMessage.jsx │ │ ├── FieldMessage.spec.jsx │ │ └── _index.scss │ ├── filterControl │ │ ├── FilterControl.jsx │ │ ├── FilterControl.spec.jsx │ │ ├── FilterItem.jsx │ │ ├── FilterItem.spec.jsx │ │ ├── _filterControl.scss │ │ ├── _filterItem.scss │ │ ├── _index.scss │ │ ├── filterDropdown │ │ │ ├── FilterDropdown.jsx │ │ │ ├── FilterDropdown.spec.jsx │ │ │ ├── FilterDropdownButton.jsx │ │ │ ├── FilterDropdownButton.spec.jsx │ │ │ ├── FilterFormDropdown.jsx │ │ │ ├── FilterFormDropdown.spec.jsx │ │ │ ├── _filterDropdown.scss │ │ │ ├── _filterFormDropdown.scss │ │ │ └── filterOptions │ │ │ │ ├── FilterOptionList.jsx │ │ │ │ ├── FilterOptionList.spec.jsx │ │ │ │ └── _filterOptionList.scss │ │ └── forms │ │ │ ├── DateRangeFilterForm.jsx │ │ │ ├── DateRangeFilterForm.spec.jsx │ │ │ ├── FilterForm.jsx │ │ │ ├── FilterForm.spec.jsx │ │ │ ├── InputFilterForm.jsx │ │ │ ├── InputFilterForm.spec.jsx │ │ │ ├── MixedTypeValueFilterForm.jsx │ │ │ ├── MixedTypeValueFilterForm.spec.jsx │ │ │ ├── MultipleSelectFilterForm.jsx │ │ │ ├── MultipleSelectFilterForm.spec.jsx │ │ │ ├── SearchableMultipleSelectFilterForm.jsx │ │ │ ├── SearchableMultipleSelectFilterForm.spec.jsx │ │ │ ├── _filterForm.scss │ │ │ ├── _inputFilterForm.scss │ │ │ ├── _multipleSelectFilterForm.scss │ │ │ └── _searchableMultiSelectFilterForm.scss │ ├── form │ │ ├── Form.jsx │ │ ├── Form.spec.jsx │ │ ├── FormPanel.jsx │ │ ├── FormPanel.spec.jsx │ │ ├── _formPanel.scss │ │ ├── _index.scss │ │ └── footer │ │ │ ├── FormFooter.jsx │ │ │ ├── FormFooter.spec.jsx │ │ │ └── _formFooter.scss │ ├── framework.js │ ├── framework.spec.js │ ├── global │ │ ├── _blur.scss │ │ ├── _body.scss │ │ ├── _button.scss │ │ ├── _colors.scss │ │ ├── _cssIcons.scss │ │ ├── _fonts.scss │ │ ├── _footer.scss │ │ ├── _form.scss │ │ ├── _index.scss │ │ ├── _label.scss │ │ ├── _list.scss │ │ ├── _logo.scss │ │ ├── _misc.scss │ │ ├── _modal.scss │ │ └── _reset.scss │ ├── glossary │ │ ├── GlossaryItem.jsx │ │ ├── GlossaryProvider.jsx │ │ ├── GlossaryTooltip.jsx │ │ └── _index.scss │ ├── grid │ │ ├── Grid.jsx │ │ ├── Grid.spec.jsx │ │ ├── _index.scss │ │ ├── body │ │ │ ├── GridBody.jsx │ │ │ ├── GridBody.spec.jsx │ │ │ ├── GridBodyCell.jsx │ │ │ ├── GridBodyCell.spec.jsx │ │ │ ├── GridBodyEditableCell.jsx │ │ │ ├── GridBodyEditableCell.spec.jsx │ │ │ ├── GridFakeRow.jsx │ │ │ ├── GridFakeRow.spec.jsx │ │ │ ├── GridRow.jsx │ │ │ ├── GridRow.spec.jsx │ │ │ ├── _gridBody.scss │ │ │ ├── _gridBodyCell.scss │ │ │ ├── _gridRow.scss │ │ │ └── _index.scss │ │ ├── controls │ │ │ ├── GridControls.jsx │ │ │ ├── GridControls.spec.jsx │ │ │ ├── _gridControls.scss │ │ │ ├── _index.scss │ │ │ └── batch │ │ │ │ ├── _batch.scss │ │ │ │ └── _index.scss │ │ ├── empty │ │ │ ├── GridEmptyRow.jsx │ │ │ ├── GridEmptyRow.spec.jsx │ │ │ ├── _gridEmptyRow.scss │ │ │ └── _index.scss │ │ ├── footer │ │ │ ├── GridFooter.jsx │ │ │ ├── GridFooter.spec.jsx │ │ │ ├── GridFooterCell.jsx │ │ │ ├── GridFooterCell.spec.jsx │ │ │ ├── _gridFooter.scss │ │ │ └── _index.scss │ │ ├── header │ │ │ ├── GridHeader.jsx │ │ │ ├── GridHeader.spec.jsx │ │ │ ├── GridHeaderCell.jsx │ │ │ ├── GridHeaderCell.spec.jsx │ │ │ ├── GridHeaderSortableCell.jsx │ │ │ ├── GridHeaderSortableCell.spec.jsx │ │ │ ├── _gridHeader.scss │ │ │ └── _index.scss │ │ ├── icon │ │ │ ├── GridIcon.jsx │ │ │ ├── GridIcon.spec.jsx │ │ │ └── _index.scss │ │ ├── loading │ │ │ ├── GridLoadingRow.jsx │ │ │ ├── GridLoadingRow.spec.jsx │ │ │ ├── _gridLoadingRow.scss │ │ │ └── _index.scss │ │ └── stickyGrid │ │ │ ├── StickyGrid.jsx │ │ │ ├── StickyGrid.spec.jsx │ │ │ ├── _index.scss │ │ │ └── _stickyGrid.scss │ ├── horizontalLine │ │ ├── HorizontalLine.jsx │ │ ├── HorizontalLine.spec.jsx │ │ ├── _horizontalLine.scss │ │ └── _index.scss │ ├── imageUpload │ │ ├── ImagePreview.jsx │ │ ├── ImagePreview.spec.jsx │ │ ├── ImageUpload.jsx │ │ ├── ImageUpload.spec.jsx │ │ ├── _imageUpload.scss │ │ └── _index.scss │ ├── kpi │ │ ├── Kpi.jsx │ │ ├── Kpi.spec.jsx │ │ ├── KpiNegative.jsx │ │ ├── KpiNegative.spec.jsx │ │ ├── KpiPositive.jsx │ │ ├── KpiPositive.spec.jsx │ │ ├── _index.scss │ │ └── index.jsx │ ├── label │ │ ├── Label.jsx │ │ ├── Label.spec.jsx │ │ ├── SubLabel.jsx │ │ ├── SubLabel.spec.jsx │ │ ├── _index.scss │ │ ├── _label.scss │ │ └── _subLabel.scss │ ├── labeledField │ │ ├── LabeledField.jsx │ │ ├── LabeledField.spec.jsx │ │ ├── _index.scss │ │ └── _labeledField.scss │ ├── leftFixedLayout │ │ ├── LeftFixedLayout.jsx │ │ ├── LeftFixedLayout.spec.jsx │ │ ├── _index.scss │ │ └── _leftFixedLayout.scss │ ├── link │ │ ├── Link.jsx │ │ ├── Link.spec.jsx │ │ ├── _index.scss │ │ └── _link.scss │ ├── menu │ │ ├── Menu.jsx │ │ ├── Menu.spec.jsx │ │ ├── MenuItem.jsx │ │ ├── MenuItem.spec.jsx │ │ ├── _index.scss │ │ └── _menuItem.scss │ ├── modal │ │ ├── Modal.jsx │ │ ├── Modal.spec.jsx │ │ ├── ModalBody.jsx │ │ ├── ModalBody.spec.jsx │ │ ├── _index.scss │ │ ├── _modal.scss │ │ ├── confirmation │ │ │ ├── ModalConfirmationBody.jsx │ │ │ ├── ModalConfirmationBody.spec.jsx │ │ │ ├── ModalConfirmationFooter.jsx │ │ │ ├── ModalConfirmationFooter.spec.jsx │ │ │ └── _modalConfirmation.scss │ │ ├── footer │ │ │ ├── ModalFooter.jsx │ │ │ ├── ModalFooter.spec.jsx │ │ │ └── _modalFooter.scss │ │ ├── header │ │ │ ├── ModalCloseButton.jsx │ │ │ ├── ModalCloseButton.spec.jsx │ │ │ ├── ModalHeader.jsx │ │ │ ├── ModalHeader.spec.jsx │ │ │ └── _modalHeader.scss │ │ ├── overlay │ │ │ ├── ModalOverlay.jsx │ │ │ ├── ModalOverlay.spec.jsx │ │ │ └── _modalOverlay.scss │ │ └── stack │ │ │ ├── ModalStack.jsx │ │ │ ├── ModalStack.spec.jsx │ │ │ └── _modalStack.scss │ ├── organizationSwitcher │ │ ├── OrganizationSwitcher.jsx │ │ ├── OrganizationSwitcher.spec.jsx │ │ ├── OrganizationSwitcherItem.jsx │ │ ├── OrganizationSwitcherItem.spec.jsx │ │ ├── _index.scss │ │ ├── _organizationSwitcher.scss │ │ └── _organizationSwitcherItem.scss │ ├── pagination │ │ ├── Pagination.jsx │ │ ├── Pagination.spec.jsx │ │ ├── _index.scss │ │ └── _pagination.scss │ ├── panel │ │ ├── Panel.jsx │ │ ├── Panel.spec.jsx │ │ ├── PanelLayout.jsx │ │ ├── PanelLayout.spec.jsx │ │ ├── _index.scss │ │ ├── _panel.scss │ │ ├── _panelLayout.scss │ │ └── progress │ │ │ ├── PanelProgress.jsx │ │ │ ├── PanelProgress.spec.jsx │ │ │ └── _panelProgress.scss │ ├── pickedList │ │ ├── PickedList.jsx │ │ ├── PickedList.spec.jsx │ │ ├── PickedListItem.jsx │ │ ├── PickedListItem.spec.jsx │ │ ├── _index.scss │ │ ├── _pickedList.scss │ │ └── _pickedListItem.scss │ ├── pickedSummary │ │ ├── PickedSummary.jsx │ │ ├── PickedSummary.spec.jsx │ │ ├── _index.scss │ │ └── _pickedSummary.scss │ ├── progress │ │ ├── Progress.jsx │ │ ├── Progress.spec.jsx │ │ ├── ProgressModal.jsx │ │ ├── ProgressModal.spec.jsx │ │ ├── ProgressSuccess.jsx │ │ ├── ProgressSuccess.spec.jsx │ │ ├── _index.scss │ │ ├── _progress.scss │ │ ├── _progressModal.scss │ │ └── _progressSuccess.scss │ ├── radioButtonItem │ │ ├── RadioButtonItem.jsx │ │ ├── RadioButtonItem.spec.jsx │ │ ├── _index.scss │ │ └── _radioButtonItem.scss │ ├── radioButtons │ │ ├── RadioButtons.jsx │ │ └── RadioButtons.spec.jsx │ ├── recycledList │ │ ├── RecycledList.jsx │ │ └── RecycledList.spec.jsx │ ├── ribbon │ │ ├── Ribbon.jsx │ │ ├── Ribbon.spec.jsx │ │ ├── _index.scss │ │ └── _ribbon.scss │ ├── searchBox │ │ ├── SearchBox.jsx │ │ ├── SearchBox.spec.jsx │ │ ├── _index.scss │ │ └── _searchBox.scss │ ├── services.js │ ├── services.spec.js │ ├── services │ │ ├── event │ │ │ ├── EscapeKeyHandler.js │ │ │ ├── EscapeKeyHandler.spec.js │ │ │ ├── ThrottledEventDispatcher.js │ │ │ ├── ThrottledEventDispatcher.spec.js │ │ │ └── polyfillCustomEvent.js │ │ ├── filter │ │ │ ├── ComparisonTypes.js │ │ │ ├── Filter.js │ │ │ ├── Filter.spec.js │ │ │ ├── FilterOption.js │ │ │ ├── FilterOption.spec.js │ │ │ ├── FilterableItems.js │ │ │ ├── FilterableItems.spec.js │ │ │ ├── MixedTypeValueFilter.js │ │ │ ├── MixedTypeValueFilter.spec.js │ │ │ ├── OneOfOption.js │ │ │ └── OneOfOption.spec.js │ │ ├── grid │ │ │ └── GridStencil.js │ │ ├── number │ │ │ ├── Number.js │ │ │ └── Number.spec.js │ │ ├── object │ │ │ ├── ObjectUtil.js │ │ │ └── ObjectUtil.spec.js │ │ ├── scroll │ │ │ ├── ScrollPosition.js │ │ │ └── ScrollPosition.spec.js │ │ ├── sort │ │ │ ├── SortState.js │ │ │ ├── SortState.spec.js │ │ │ ├── Sorter.js │ │ │ └── Sorter.spec.js │ │ ├── string │ │ │ └── Entity.js │ │ └── test │ │ │ └── CommonAssertions.js │ ├── statusDropdown │ │ ├── StatusDropdown.jsx │ │ ├── StatusDropdown.spec.jsx │ │ ├── StatusDropdownOption.jsx │ │ ├── StatusDropdownOption.spec.jsx │ │ ├── _index.scss │ │ ├── _statusDropdown.scss │ │ ├── _statusDropdownOption.scss │ │ └── statusDropdownOptionIcon │ │ │ ├── StatusDropdownOptionIcon.jsx │ │ │ ├── StatusDropdownOptionIcon.spec.jsx │ │ │ └── _index.scss │ ├── summaryControl │ │ ├── SummaryControl.jsx │ │ ├── SummaryControl.spec.jsx │ │ ├── _index.scss │ │ └── _summaryControl.scss │ ├── text │ │ ├── DescriptionText.jsx │ │ ├── DescriptionText.spec.jsx │ │ ├── Heading.jsx │ │ ├── Heading.spec.jsx │ │ ├── Text.jsx │ │ ├── Text.spec.jsx │ │ ├── _descriptionText.scss │ │ ├── _heading.scss │ │ ├── _index.scss │ │ └── _text.scss │ ├── textArea │ │ ├── TextArea.jsx │ │ ├── TextArea.spec.jsx │ │ ├── _index.scss │ │ └── _textArea.scss │ ├── textInput │ │ ├── TextInput.jsx │ │ ├── TextInput.spec.jsx │ │ ├── _index.scss │ │ └── _textInput.scss │ ├── titleBar │ │ ├── TitleBar.jsx │ │ ├── TitleBar.spec.jsx │ │ ├── _index.scss │ │ └── _titleBar.scss │ ├── toggle │ │ ├── Toggle.jsx │ │ ├── Toggle.spec.jsx │ │ ├── _index.scss │ │ └── _toggle.scss │ ├── tooltip │ │ ├── Tooltip.jsx │ │ ├── Tooltip.spec.jsx │ │ ├── _index.scss │ │ └── _tooltip.scss │ ├── verticalLayout │ │ ├── VerticalLayout.jsx │ │ ├── VerticalLayout.spec.jsx │ │ ├── _index.scss │ │ └── _verticalLayout.scss │ └── viewHeader │ │ ├── ViewHeader.jsx │ │ ├── ViewHeader.spec.jsx │ │ ├── _index.scss │ │ ├── _viewHeader.scss │ │ ├── dateRange │ │ ├── DateRange.jsx │ │ └── _dateRange.scss │ │ └── nav │ │ ├── ViewHeaderNav.jsx │ │ ├── ViewHeaderNav.spec.jsx │ │ └── _viewHeaderNav.scss └── guide │ ├── components │ ├── navigation │ │ ├── NavItem.jsx │ │ ├── NavTitle.jsx │ │ ├── Navigation.jsx │ │ └── _navigation.scss │ ├── page │ │ ├── Example.jsx │ │ ├── Page.jsx │ │ ├── SubTitle.jsx │ │ ├── Text.jsx │ │ └── Title.jsx │ └── sourceCodeViewer │ │ ├── SourceCodeViewer.jsx │ │ └── _sourceCodeViewer.scss │ ├── index.jade │ ├── index.js │ ├── index.scss │ ├── services │ ├── route │ │ └── Route.js │ └── string │ │ └── Slug.js │ ├── store │ └── configureStore.js │ └── views │ ├── AppContainer.js │ ├── AppView.jsx │ ├── _app.scss │ ├── accordion │ └── AccordionExample.jsx │ ├── addOnControl │ └── AddOnControlExample.jsx │ ├── alert │ └── AlertExample.jsx │ ├── appHeader │ └── AppHeaderExample.jsx │ ├── body │ └── BodyExample.jsx │ ├── box │ └── BoxExample.jsx │ ├── button │ └── ButtonExample.jsx │ ├── buttonGroup │ └── ButtonGroupExample.jsx │ ├── card │ ├── CardExample.jsx │ ├── _cardExample.scss │ └── blueRibbon.png │ ├── chart │ ├── ChartExample.jsx │ └── chartExampleData.js │ ├── checkBox │ └── CheckBoxExample.jsx │ ├── columnLayout │ └── ColumnLayoutExample.jsx │ ├── dropdown │ └── DropdownExample.jsx │ ├── fieldMessage │ └── FieldMessageExample.jsx │ ├── form │ └── FormExample.jsx │ ├── grid │ ├── GridExample.jsx │ ├── createRows.js │ └── gridExampleFilterOptions.js │ ├── gridView │ ├── GridExample.jsx │ └── GridViewExample.jsx │ ├── home │ ├── HomeView.jsx │ └── _homeView.scss │ ├── horizontalLine │ └── HorizontalLineExample.jsx │ ├── htmlElements │ └── HtmlElementsExample.jsx │ ├── imageUpload │ └── ImageUploadExample.jsx │ ├── kpi │ └── KpiExample.jsx │ ├── label │ └── LabelExample.jsx │ ├── labeledField │ └── LabeledFieldExample.jsx │ ├── leftFixedLayout │ └── LeftFixedLayoutExample.jsx │ ├── link │ └── LinkExample.jsx │ ├── menu │ └── MenuExample.jsx │ ├── modal │ └── ModalExample.jsx │ ├── notFound │ └── NotFoundView.jsx │ ├── organizationSwitcher │ └── OrganizationSwitcherExample.jsx │ ├── pagination │ └── PaginationExample.jsx │ ├── panel │ └── PanelExample.jsx │ ├── pickedList │ └── PickedListExample.jsx │ ├── pickedSummary │ └── PickedSummaryExample.jsx │ ├── progress │ └── ProgressExample.jsx │ ├── radioButtons │ └── RadioButtonsExample.jsx │ ├── searchBox │ └── SearchBoxExample.jsx │ ├── statusDropdown │ └── StatusDropdownExample.jsx │ ├── summaryControl │ └── SummaryControlExample.jsx │ ├── text │ └── TextExample.jsx │ ├── textArea │ └── TextAreaExample.jsx │ ├── textInput │ └── TextInputExample.jsx │ ├── titleBar │ └── TitleBarExample.jsx │ ├── titledView │ └── TitledViewExample.jsx │ ├── toggle │ └── ToggleExample.jsx │ ├── tooltip │ └── TooltipExample.jsx │ ├── verticalLayout │ └── VerticalLayoutExample.jsx │ └── viewHeader │ └── ViewHeaderExample.jsx └── test └── assets └── img └── testImage.png /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "developmentWithHmr": { 4 | "plugins": [ 5 | "react-transform" 6 | ], 7 | "extra": { 8 | "react-transform": { 9 | "transforms": [{ 10 | "transform": "react-transform-hmr", 11 | "imports": ["react"], 12 | "locals": ["module"] 13 | }] 14 | } 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "smaato", 3 | "env": { 4 | "browser": true, 5 | }, 6 | "rules": { 7 | "class-methods-use-this": 0, 8 | "consistent-return": 0, 9 | "comma-dangle": [2, { 10 | "arrays": "always-multiline", 11 | "objects": "always-multiline", 12 | "imports": "always-multiline", 13 | "exports": "always-multiline", 14 | "functions": "ignore", 15 | }], 16 | "import/extensions": 0, 17 | "import/no-extraneous-dependencies": 0, 18 | "jsx-a11y/no-static-element-interactions": 0, 19 | "react/forbid-prop-types": 0, 20 | "react/jsx-filename-extension": 0, 21 | "react/no-array-index-key": 0, 22 | "react/no-string-refs": 0, 23 | "react/require-default-props": 0, 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .publish 2 | .sass-cache 3 | .DS_Store 4 | coverage 5 | node_modules 6 | dist 7 | reports 8 | *.log 9 | .idea/ 10 | *.iml 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This project is intended for internal use as Smaato and for sharing some of our 4 | development process with the community, but not for production use by the 5 | public. As such, we would appreciate any Pull Requests regarding bug fixes, 6 | but we won't be able to accept any Pull Requests for additional features or 7 | improvements, since there's no guarantee they'll align with our goals as a 8 | company. 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License 3 | 4 | Copyright (c) 2015-2016 Smaato Inc. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /services.js: -------------------------------------------------------------------------------- 1 | 2 | export * from './src/framework/services'; 3 | -------------------------------------------------------------------------------- /src/framework/accordion/Accordion.jsx: -------------------------------------------------------------------------------- 1 | 2 | import PropTypes from 'prop-types'; 3 | import React from 'react'; 4 | 5 | import AccordionItem from './../accordionItem/AccordionItem.jsx'; 6 | 7 | const Accordion = (props) => { 8 | const wrapperStyle = { 9 | width: props.width, 10 | }; 11 | 12 | return ( 13 |
14 | {props.children} 15 |
16 | ); 17 | }; 18 | 19 | Accordion.defaultProps = { 20 | width: '210px', 21 | }; 22 | 23 | Accordion.propTypes = { 24 | children: PropTypes.arrayOf(AccordionItem), 25 | width: PropTypes.string, 26 | }; 27 | 28 | export default Accordion; 29 | -------------------------------------------------------------------------------- /src/framework/accordion/_accordion.scss: -------------------------------------------------------------------------------- 1 | 2 | .accordion { 3 | border: 1px solid #d4d8db; 4 | } 5 | -------------------------------------------------------------------------------- /src/framework/accordion/_index.scss: -------------------------------------------------------------------------------- 1 | 2 | @import 'accordion'; 3 | -------------------------------------------------------------------------------- /src/framework/accordionItem/_accordionItem.scss: -------------------------------------------------------------------------------- 1 | 2 | .accordion__item { 3 | display: flex; 4 | flex-direction: column; 5 | height: 100%; 6 | overflow: hidden; 7 | 8 | &:not(:last-child) .accordion__item__title, 9 | &:not(:last-child) .accordion__item__content--active { 10 | border-bottom: 1px solid #d4d8db; 11 | } 12 | 13 | &:last-child .accordion__item__content--active { 14 | border-top: 1px solid #d4d8db; 15 | } 16 | 17 | &__title { 18 | align-items: center; 19 | background-color: #f6fafc; 20 | display: flex; 21 | flex: 0 0 auto; 22 | font-size: 13px; 23 | height: 30px; 24 | justify-content: space-between; 25 | line-height: $lineHeight; 26 | padding: 0 10px; 27 | cursor: pointer; 28 | } 29 | 30 | &__content { 31 | background-color: #ffffff; 32 | display: none; 33 | flex: 1 1 auto; 34 | line-height: $lineHeight; 35 | padding: 5px 10px; 36 | 37 | &--active { 38 | animation: display-none-transition 1s both; 39 | display: flex; 40 | opacity: 1; 41 | } 42 | 43 | @keyframes display-none-transition { 44 | 0% { 45 | opacity: 0; 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/framework/accordionItem/_index.scss: -------------------------------------------------------------------------------- 1 | 2 | @import 'accordionItem'; 3 | -------------------------------------------------------------------------------- /src/framework/addOnControl/AddOnControl.jsx: -------------------------------------------------------------------------------- 1 | 2 | import PropTypes from 'prop-types'; 3 | import React from 'react'; 4 | 5 | export { 6 | default as AddOnDropdown, 7 | } from './dropdown/AddOnDropdown.jsx'; 8 | 9 | export { 10 | default as AddOnDropdownOption, 11 | } from './dropdown/AddOnDropdownOption.jsx'; 12 | 13 | export { 14 | default as AddOnLabel, 15 | } from './label/AddOnLabel.jsx'; 16 | 17 | const AddOnControl = props => ( 18 |
19 | {props.children} 20 |
21 | ); 22 | 23 | AddOnControl.propTypes = { 24 | children: PropTypes.any, 25 | }; 26 | 27 | export default AddOnControl; 28 | -------------------------------------------------------------------------------- /src/framework/addOnControl/AddOnControl.spec.jsx: -------------------------------------------------------------------------------- 1 | 2 | import React from 'react'; 3 | import { TestCaseFactory } from 'react-test-kit'; 4 | import AddOnControl from './AddOnControl.jsx'; 5 | 6 | describe('AddOnControl', () => { 7 | describe('Props', () => { 8 | describe('children', () => { 9 | it('is rendered', () => { 10 | const props = { 11 | children:
test
, 12 | }; 13 | const testCase = TestCaseFactory.create( 14 | AddOnControl, 15 | props 16 | ); 17 | expect(testCase.first('#test').textContent).toBe('test'); 18 | }); 19 | }); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /src/framework/addOnControl/_addOnControl.scss: -------------------------------------------------------------------------------- 1 | 2 | @mixin addOnLabelStyle { 3 | display: flex; 4 | align-items: center; 5 | font-size: 12px; 6 | font-weight: 400; 7 | color: #52676f; 8 | border: 1px solid #c8cfd5; 9 | background-color: #f2f5f7; 10 | } 11 | 12 | /** 13 | * 1. Fix a bug in IE that prevented the left and right element widths from 14 | * being respected by the input. 15 | */ 16 | @mixin addOnLabelDimension { 17 | flex: 1 0 auto; /* 1 */ 18 | } 19 | 20 | $addOnLabelPadding: 9px; 21 | 22 | /** 23 | * 1. Implicitly set these styles on inputs only, because they'll be overridden 24 | * for the left and right elements. These styles fix a bug in IE, so 25 | * that the input will contract to respect the left and right elements' 26 | * widths. 27 | */ 28 | .addOnControl { 29 | display: flex; 30 | line-height: $lineHeight; 31 | 32 | > * { 33 | flex: 0 1 auto; /* 1 */ 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/framework/addOnControl/_index.scss: -------------------------------------------------------------------------------- 1 | 2 | @import 'addOnControl'; 3 | @import 'dropdown/addOnDropdown'; 4 | @import 'dropdown/addOnDropdownOption'; 5 | @import 'label/addOnLabel'; 6 | -------------------------------------------------------------------------------- /src/framework/addOnControl/dropdown/AddOnDropdown.jsx: -------------------------------------------------------------------------------- 1 | 2 | import classNames from 'classnames'; 3 | import PropTypes from 'prop-types'; 4 | import React from 'react'; 5 | 6 | import BaseDropdown from '../../base/dropdown/BaseDropdown.jsx'; 7 | import AddOnDropdownOption from './AddOnDropdownOption.jsx'; 8 | 9 | const AddOnDropdown = (props) => { 10 | const labelClasses = classNames(props.labelClasses, { 11 | 'addOnDropdownLabel--left': props.isLeftSide, 12 | 'addOnDropdownLabel--right': props.isRightSide, 13 | }); 14 | 15 | return ( 16 | 20 | ); 21 | }; 22 | 23 | AddOnDropdown.propTypes = Object.assign({}, BaseDropdown.propTypes, { 24 | isLeftSide: PropTypes.bool, 25 | isRightSide: PropTypes.bool, 26 | }); 27 | 28 | AddOnDropdown.defaultProps = Object.assign({}, BaseDropdown.defaultProps, { 29 | classes: 'addOnDropdown', 30 | labelClasses: 'addOnDropdownLabel', 31 | inputClasses: 'addOnDropdown__input', 32 | labelFocusClasses: 'is-add-on-dropdown-label-focus', 33 | optionListClasses: 'addOnDropdownOptionList', 34 | optionType: AddOnDropdownOption, 35 | }); 36 | 37 | export default AddOnDropdown; 38 | -------------------------------------------------------------------------------- /src/framework/addOnControl/dropdown/AddOnDropdownOption.jsx: -------------------------------------------------------------------------------- 1 | 2 | import React from 'react'; 3 | 4 | import BaseDropdownOption from '../../base/dropdown/BaseDropdownOption.jsx'; 5 | 6 | const AddOnDropdownOption = props => ( 7 | 10 | ); 11 | 12 | AddOnDropdownOption.propTypes = BaseDropdownOption.propTypes; 13 | 14 | AddOnDropdownOption.defaultProps = { 15 | classes: 'addOnDropdownOption', 16 | focusClasses: 'is-add-on-dropdown-option-focus', 17 | }; 18 | 19 | export default AddOnDropdownOption; 20 | -------------------------------------------------------------------------------- /src/framework/addOnControl/dropdown/AddOnDropdownOption.spec.jsx: -------------------------------------------------------------------------------- 1 | 2 | import { TestCaseFactory } from 'react-test-kit'; 3 | import AddOnDropdownOption from './AddOnDropdownOption.jsx'; 4 | import BaseDropdownOption from '../../base/dropdown/BaseDropdownOption.jsx'; 5 | 6 | describe('AddOnDropdownOption', () => { 7 | describe('DOM structure', () => { 8 | it('is a BaseDropdownOption', () => { 9 | const props = { 10 | onClick: () => undefined, 11 | onMouseOver: () => undefined, 12 | }; 13 | const testCase = TestCaseFactory.create(AddOnDropdownOption, props); 14 | expect(testCase.findComponents(BaseDropdownOption)).toBeDefined(); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/framework/addOnControl/dropdown/_addOnDropdownOption.scss: -------------------------------------------------------------------------------- 1 | 2 | .addOnDropdownOption { 3 | cursor: pointer; 4 | font-size: 12px; 5 | padding: 4px 8px; 6 | 7 | &.is-add-on-dropdown-option-focus { 8 | background-color: rgba(black, 0.05); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/framework/addOnControl/label/AddOnLabel.jsx: -------------------------------------------------------------------------------- 1 | 2 | import classNames from 'classnames'; 3 | import PropTypes from 'prop-types'; 4 | import React from 'react'; 5 | 6 | const AddOnLabel = (props) => { 7 | const classes = classNames('addOnLabel', { 8 | 'addOnLabel--left': props.isLeftSide, 9 | 'addOnLabel--right': props.isRightSide, 10 | }); 11 | 12 | return ( 13 |
14 | {props.children} 15 |
16 | ); 17 | }; 18 | 19 | AddOnLabel.propTypes = { 20 | children: PropTypes.any, 21 | isLeftSide: PropTypes.bool, 22 | isRightSide: PropTypes.bool, 23 | }; 24 | 25 | export default AddOnLabel; 26 | -------------------------------------------------------------------------------- /src/framework/addOnControl/label/_addOnLabel.scss: -------------------------------------------------------------------------------- 1 | 2 | .addOnLabel { 3 | @include addOnLabelStyle; 4 | @include addOnLabelDimension; 5 | padding: $addOnLabelPadding; 6 | white-space: nowrap; 7 | } 8 | 9 | .addOnLabel--left { 10 | border-right: 0; 11 | } 12 | 13 | .addOnLabel--right { 14 | border-left: 0; 15 | } 16 | -------------------------------------------------------------------------------- /src/framework/alert/Alert.jsx: -------------------------------------------------------------------------------- 1 | 2 | import classNames from 'classnames'; 3 | import keyMirror from 'keymirror'; 4 | import PropTypes from 'prop-types'; 5 | import React from 'react'; 6 | 7 | const Alert = (props) => { 8 | const typeToBackgroundColorClass = { 9 | [Alert.TYPE.ERROR]: 'alert--error', 10 | [Alert.TYPE.INFO]: 'alert--info', 11 | [Alert.TYPE.SUCCESS]: 'alert--success', 12 | [Alert.TYPE.WARNING]: 'alert--warning', 13 | }; 14 | 15 | const classes = classNames( 16 | 'alert', 17 | props.classes, 18 | typeToBackgroundColorClass[props.type] 19 | ); 20 | 21 | return ( 22 |
23 | {props.children} 24 |
25 | ); 26 | }; 27 | 28 | Alert.TYPE = keyMirror({ 29 | ERROR: null, 30 | INFO: null, 31 | SUCCESS: null, 32 | WARNING: null, 33 | }); 34 | 35 | Alert.propTypes = { 36 | children: PropTypes.any, 37 | classes: PropTypes.string, 38 | type: PropTypes.string.isRequired, 39 | }; 40 | 41 | export default Alert; 42 | -------------------------------------------------------------------------------- /src/framework/alert/_alert.scss: -------------------------------------------------------------------------------- 1 | 2 | .alert { 3 | color: $white; 4 | padding: 12px; 5 | text-align: center; 6 | width: 100%; 7 | 8 | &.alert--error { 9 | background-color: $lightRed; 10 | } 11 | 12 | &.alert--info { 13 | background-color: $blue; 14 | } 15 | 16 | &.alert--success { 17 | background-color: $green; 18 | } 19 | 20 | &.alert--warning { 21 | background-color: $yellow; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/framework/alert/_index.scss: -------------------------------------------------------------------------------- 1 | 2 | @import 'alert'; 3 | -------------------------------------------------------------------------------- /src/framework/appHeader/AppHeader.jsx: -------------------------------------------------------------------------------- 1 | 2 | import PropTypes from 'prop-types'; 3 | import React from 'react'; 4 | 5 | export { 6 | default as AccountNav, 7 | } from './account/AccountNav.jsx'; 8 | 9 | export { 10 | default as AccountPicture, 11 | } from './account/AccountPicture.jsx'; 12 | 13 | export { 14 | default as AppLogo, 15 | } from './logo/AppLogo.jsx'; 16 | 17 | export { 18 | default as AppNav, 19 | } from './nav/AppNav.jsx'; 20 | 21 | export { 22 | default as AppHeaderButton, 23 | } from './button/AppHeaderButton.jsx'; 24 | 25 | export { 26 | default as AppHeaderDivider, 27 | } from './divider/AppHeaderDivider.jsx'; 28 | 29 | export { 30 | default as AppTitle, 31 | } from './title/AppTitle.jsx'; 32 | 33 | export { 34 | default as AppTitleContainer, 35 | } from './title/AppTitleContainer.jsx'; 36 | 37 | const AppHeader = props => ( 38 |
39 |
40 | {props.left} 41 | {props.center} 42 | {props.right} 43 |
44 |
45 | ); 46 | 47 | AppHeader.propTypes = { 48 | left: PropTypes.element, 49 | center: PropTypes.element, 50 | right: PropTypes.element, 51 | }; 52 | 53 | export default AppHeader; 54 | -------------------------------------------------------------------------------- /src/framework/appHeader/_index.scss: -------------------------------------------------------------------------------- 1 | 2 | @import 'appHeader'; 3 | @import 'account/accountNav'; 4 | @import 'account/accountPicture'; 5 | @import 'logo/appLogo'; 6 | @import 'nav/appNav'; 7 | @import 'title/appTitle'; 8 | @import 'title/appTitleContainer'; 9 | @import 'button/appHeaderButton'; 10 | @import 'divider/appHeaderDivider'; 11 | -------------------------------------------------------------------------------- /src/framework/appHeader/account/AccountPicture.jsx: -------------------------------------------------------------------------------- 1 | 2 | import PropTypes from 'prop-types'; 3 | import React from 'react'; 4 | 5 | const AccountPicture = (props) => { 6 | const picture = props.url ? 7 | ( 8 | {props.title} 13 | ) : ( 14 | 18 | ); 19 | 20 | return ( 21 | 22 | {picture} 23 | 24 | ); 25 | }; 26 | 27 | AccountPicture.propTypes = { 28 | url: PropTypes.string, 29 | title: PropTypes.string, 30 | }; 31 | 32 | export default AccountPicture; 33 | -------------------------------------------------------------------------------- /src/framework/appHeader/account/_accountPicture.scss: -------------------------------------------------------------------------------- 1 | .accountPicture { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | width: $accountPicture_side; 6 | height: $accountPicture_side; 7 | border-radius: $accountPicture_side / 2; 8 | // Affects vertical-alignment. 9 | // Icon is 1px off in .exampleContainer, when this is not set, 10 | // but always fine inside .appHeader 11 | line-height: $accountPicture_side; 12 | overflow: hidden; 13 | background: scale-lightness($appHeaderNav_backgroundColor, 10%); 14 | } 15 | 16 | .accountPicture__icon { 17 | width: 10px; 18 | height: 10px; 19 | opacity: 0.5; 20 | } 21 | -------------------------------------------------------------------------------- /src/framework/appHeader/button/AppHeaderButton.jsx: -------------------------------------------------------------------------------- 1 | 2 | import classNames from 'classnames'; 3 | import PropTypes from 'prop-types'; 4 | import React from 'react'; 5 | 6 | import Button from '../../button/Button.jsx'; 7 | 8 | const AppHeaderButton = (props) => { 9 | const classes = classNames('appHeaderButton', props.classes); 10 | 11 | const extendedProps = Object.assign({}, props, { 12 | classes, 13 | }); 14 | 15 | return ( 16 |