├── test ├── TablePaginationSpec.js ├── index.js ├── innerText.js ├── TestWrapper.js ├── ModalBodySpec.js ├── NavbarBodySpec.js ├── FooterSpec.js ├── HeaderSpec.js ├── ModalFooterSpec.js ├── ModalTitleSpec.js ├── SidenavBodySpec.js ├── SidebarSpec.js ├── SidenavHeaderSpec.js ├── ContentSpec.js ├── utilsSpec.js ├── NavbarHeaderSpec.js ├── ContainerSpec.js ├── NavbarSpec.js ├── GridSpec.js ├── SidenavToggleSpec.js ├── ButtonToolbarSpec.js ├── IconButtonSpec.js ├── PopoverSpec.js ├── FlexboxGirdSpec.js ├── FlexboxGirdItemSpec.js ├── DividerSpec.js ├── RowSpec.js ├── ErrorMessageSpec.js ├── DrawerSpec.js ├── SafeAnchorSpec.js ├── ModalHeaderSpec.js ├── HelpBlockSpec.js ├── ModalDialogSpec.js ├── ControlLabelSpec.js ├── TooltipSpec.js ├── DropdownToggleSpec.js ├── LoaderSpec.js ├── UploadTriggerSpec.js └── PanelGroupSpec.js ├── styles └── less │ ├── index.less │ ├── mixins │ ├── modals.less │ ├── center-block.less │ ├── tooltip.less │ ├── popovers.less │ ├── uploader.less │ ├── labels.less │ ├── sidenavs.less │ ├── message.less │ ├── tables.less │ ├── nav-divider.less │ ├── input-numbers.less │ ├── radios.less │ ├── checkboxes.less │ ├── tags.less │ ├── pagination.less │ ├── nav-vertical-align.less │ ├── alerts.less │ ├── border-radius.less │ ├── notification.less │ ├── drawers.less │ ├── list-group.less │ ├── clearfix.less │ ├── button-groups.less │ ├── table-row.less │ ├── flexbox-grid.less │ ├── loaders.less │ ├── font-awesome.less │ ├── dropdown.less │ ├── palette.less │ └── toggle.less │ ├── fonts │ ├── rsuite-icon-font.eot │ ├── rsuite-icon-font.ttf │ └── rsuite-icon-font.woff │ ├── pickers │ ├── index.less │ ├── select-picker.less │ ├── cascader.less │ └── date-range-picker.less │ ├── help-block.less │ ├── auto-complete.less │ ├── component-animations.less │ ├── breadcrumbs.less │ ├── close.less │ ├── tags.less │ ├── container.less │ ├── utilities.less │ ├── divider.less │ ├── table-paginations.less │ ├── mixins.less │ ├── flexbox-grid.less │ ├── rsuite.less │ ├── scaffolding.less │ ├── timelines.less │ ├── toggle.less │ ├── input-numbers.less │ ├── grid.less │ ├── constants.less │ └── pagination.less ├── src ├── IntlProvider │ ├── index.js │ ├── locales │ │ ├── zh_TW.js │ │ ├── en_GB.js │ │ ├── en_US.js │ │ ├── zh_CN.js │ │ └── default.js │ ├── IntlProvider.js │ └── withLocale.js ├── DOMHelper.js ├── Portal.js ├── Animation.js ├── Cascader.js ├── TreePicker.js ├── DatePicker.js ├── SelectPicker.js ├── CheckPicker.js ├── Progress.js ├── CheckTreePicker.js ├── DateRangePicker.js ├── utils │ ├── isNullOrUndefined.js │ ├── isOneOf.js │ ├── previewFile.js │ ├── TypeDefinition.js │ ├── tplTransform.js │ ├── constants.js │ ├── prefix.js │ ├── index.js │ ├── getUnhandledProps.js │ ├── defaultProps.js │ ├── createChainedFunction.js │ ├── deprecationWarning.js │ ├── BrowserDetection.js │ ├── ReactChildren.js │ ├── lowPriorityWarning.js │ └── withStyleProps.js ├── Tree.js ├── CheckTree.js ├── IconFont.js ├── Whisper.js ├── Schema.js ├── Table.js ├── InputGroupAddon.js ├── ModalFooter.js ├── SidenavBody.js ├── NavbarHeader.js ├── SidenavHeader.js ├── ButtonToolbar.js ├── InputGroupButton.js ├── Content.js ├── Footer.js ├── Header.js ├── ModalTitle.js ├── ModalBody.js ├── NavbarBody.js ├── Grid.js ├── FlexboxGirdItem.js ├── Alert.js ├── ControlLabel.js ├── Container.js ├── Sidebar.js ├── FlexboxGird.js ├── Timeline.js ├── Divider.js ├── Notification.js ├── SidenavToggle.js ├── IconButton.js ├── SafeAnchor.js ├── BreadcrumbItem.js ├── DropdownToggle.js ├── Tag.js ├── ModalHeader.js ├── TimelineItem.js ├── Navbar.js ├── HelpBlock.js ├── ModalDialog.js ├── FormGroup.js ├── ButtonGroup.js ├── Row.js ├── ErrorMessage.js ├── PaginationButton.js ├── Drawer.js ├── AutoCompleteItem.js ├── Breadcrumb.js ├── RadioGroup.js ├── Popover.js ├── ProgressLine.js ├── Tooltip.js ├── InputGroup.js ├── Icon.js ├── StepItem.js ├── Button.js └── Col.js ├── .coveralls.yml ├── .prettierrc ├── .codecov.yml ├── .eslintignore ├── .flowconfig ├── .editorconfig ├── .github └── ISSUE_TEMPLATE.md ├── postcss.config.js ├── .travis.yml ├── .babelrc ├── flow-typed └── npm │ ├── classnames_v2.x.x.js │ └── prop-types_v15.x.x.js ├── .gitignore ├── CONTRIBUTING.zh-CN.md ├── LICENSE ├── .eslintrc.js ├── webpack.config.js ├── karma.conf.js ├── scripts └── gulpfile.js └── CONTRIBUTING.md /test/TablePaginationSpec.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /styles/less/index.less: -------------------------------------------------------------------------------- 1 | @import "rsuite"; 2 | -------------------------------------------------------------------------------- /src/IntlProvider/index.js: -------------------------------------------------------------------------------- 1 | export default from './IntlProvider'; 2 | -------------------------------------------------------------------------------- /src/IntlProvider/locales/zh_TW.js: -------------------------------------------------------------------------------- 1 | export default from './zh_CN'; 2 | -------------------------------------------------------------------------------- /src/IntlProvider/locales/en_GB.js: -------------------------------------------------------------------------------- 1 | export default from './default'; 2 | -------------------------------------------------------------------------------- /src/IntlProvider/locales/en_US.js: -------------------------------------------------------------------------------- 1 | export default from './default'; 2 | -------------------------------------------------------------------------------- /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci 2 | repo_token: 1Aagfc4r6UqD9M88fFI8XnBhr6Lr3Dy1o 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth":2, 4 | "singleQuote":true 5 | } 6 | -------------------------------------------------------------------------------- /src/DOMHelper.js: -------------------------------------------------------------------------------- 1 | import * as DOMHelper from 'dom-lib'; 2 | 3 | export default DOMHelper; 4 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | branch: master 3 | token: 261546c5-5861-481a-91c0-cbc564821496 4 | -------------------------------------------------------------------------------- /src/Portal.js: -------------------------------------------------------------------------------- 1 | import Portal from 'rsuite-utils/lib/Overlay/Portal'; 2 | 3 | export default Portal; 4 | -------------------------------------------------------------------------------- /src/Animation.js: -------------------------------------------------------------------------------- 1 | import * as Animation from 'rsuite-utils/lib/Animation'; 2 | 3 | export default Animation; 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | bin 2 | build 3 | lib 4 | tools 5 | node_modules 6 | coverage 7 | flow 8 | flow-typed 9 | /.git 10 | -------------------------------------------------------------------------------- /styles/less/mixins/modals.less: -------------------------------------------------------------------------------- 1 | .content-width(@width) { 2 | .@{ns}modal-dialog { 3 | width: @width; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /styles/less/fonts/rsuite-icon-font.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/rsuite/master/styles/less/fonts/rsuite-icon-font.eot -------------------------------------------------------------------------------- /styles/less/fonts/rsuite-icon-font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/rsuite/master/styles/less/fonts/rsuite-icon-font.ttf -------------------------------------------------------------------------------- /styles/less/fonts/rsuite-icon-font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/rsuite/master/styles/less/fonts/rsuite-icon-font.woff -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/build/.* 3 | [include] 4 | 5 | [libs] 6 | /flow-typed 7 | 8 | [lints] 9 | 10 | 11 | [options] 12 | 13 | [strict] 14 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | require('babel-polyfill'); 2 | 3 | function importAll(r) { 4 | r.keys().forEach(r); 5 | } 6 | 7 | importAll(require.context('.', true, /Spec.js$/)); 8 | -------------------------------------------------------------------------------- /src/Cascader.js: -------------------------------------------------------------------------------- 1 | import Cascader from 'rsuite-cascader'; 2 | import withLocale from './IntlProvider/withLocale'; 3 | 4 | 5 | export default withLocale(['Picker'])(Cascader); 6 | -------------------------------------------------------------------------------- /src/TreePicker.js: -------------------------------------------------------------------------------- 1 | import TreePicker from 'rsuite-treepicker'; 2 | import withLocale from './IntlProvider/withLocale'; 3 | 4 | export default withLocale(['Picker'])(TreePicker); 5 | -------------------------------------------------------------------------------- /src/DatePicker.js: -------------------------------------------------------------------------------- 1 | import DatePicker from 'rsuite-datepicker'; 2 | import withLocale from './IntlProvider/withLocale'; 3 | 4 | export default withLocale(['DatePicker'])(DatePicker); 5 | -------------------------------------------------------------------------------- /src/SelectPicker.js: -------------------------------------------------------------------------------- 1 | import SelctPicker from 'rsuite-selectpicker'; 2 | import withLocale from './IntlProvider/withLocale'; 3 | 4 | export default withLocale(['Picker'])(SelctPicker); 5 | -------------------------------------------------------------------------------- /styles/less/mixins/center-block.less: -------------------------------------------------------------------------------- 1 | // Center-align a block level element 2 | 3 | .center-block() { 4 | display: block; 5 | margin-left: auto; 6 | margin-right: auto; 7 | } 8 | -------------------------------------------------------------------------------- /src/CheckPicker.js: -------------------------------------------------------------------------------- 1 | import CheckPicker from 'rsuite-checkpicker'; 2 | import withLocale from './IntlProvider/withLocale'; 3 | 4 | 5 | export default withLocale(['Picker'])(CheckPicker); 6 | -------------------------------------------------------------------------------- /src/Progress.js: -------------------------------------------------------------------------------- 1 | import ProgressCircle from './ProgressCircle'; 2 | import ProgressLine from './ProgressLine'; 3 | 4 | export default { 5 | Line: ProgressLine, 6 | Circle: ProgressCircle 7 | }; 8 | -------------------------------------------------------------------------------- /styles/less/mixins/tooltip.less: -------------------------------------------------------------------------------- 1 | .set-translate(@translateX:0,@translateY:0) { 2 | transform: translate(0, 0); 3 | 4 | &.in { 5 | transform: translate(@translateX, @translateY); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/CheckTreePicker.js: -------------------------------------------------------------------------------- 1 | import CheckTreePicker from 'rsuite-checktreepicker'; 2 | import withLocale from './IntlProvider/withLocale'; 3 | 4 | 5 | export default withLocale(['Picker'])(CheckTreePicker); 6 | -------------------------------------------------------------------------------- /styles/less/mixins/popovers.less: -------------------------------------------------------------------------------- 1 | .set-translate(@translateX:0,@translateY:0) { 2 | transform: translate(0, 0); 3 | 4 | &.in { 5 | transform: translate(@translateX, @translateY); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/DateRangePicker.js: -------------------------------------------------------------------------------- 1 | import DateRangePicker from 'rsuite-daterangepicker'; 2 | import withLocale from './IntlProvider/withLocale'; 3 | 4 | export default withLocale(['DateRangePicker'])(DateRangePicker); 5 | -------------------------------------------------------------------------------- /src/utils/isNullOrUndefined.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import _ from 'lodash'; 4 | 5 | export default function isNullOrUndefined(value: any): boolean { 6 | return _.isNull(value) || _.isUndefined(value); 7 | } 8 | -------------------------------------------------------------------------------- /src/Tree.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import * as React from 'react'; 4 | import TreePicker from 'rsuite-treepicker'; 5 | 6 | const Tree = (props: any) => ; 7 | 8 | export default Tree; 9 | -------------------------------------------------------------------------------- /src/utils/isOneOf.js: -------------------------------------------------------------------------------- 1 | export default function isOneOf(one: string, ofTarget: Array) { 2 | if (Array.isArray(ofTarget)) { 3 | return ofTarget.indexOf(one) >= 0; 4 | } 5 | return one === ofTarget; 6 | } 7 | -------------------------------------------------------------------------------- /test/innerText.js: -------------------------------------------------------------------------------- 1 | export default function innerText(node) { 2 | 3 | if (window.navigator.userAgent.toLowerCase().indexOf('firefox') !== -1) { 4 | return node.textContent; 5 | } 6 | return node.innerText; 7 | } 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_style = space 9 | indent_size = 2 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | -------------------------------------------------------------------------------- /styles/less/mixins/uploader.less: -------------------------------------------------------------------------------- 1 | .img-cover() { 2 | width: 100%; 3 | height: auto; 4 | 5 | @supports (object-fit: cover) { 6 | & { 7 | height: 100%; 8 | object-fit: cover; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /styles/less/mixins/labels.less: -------------------------------------------------------------------------------- 1 | // Labels 2 | 3 | .label-variant(@color) { 4 | background-color: @color; 5 | 6 | &[href] { 7 | &:hover, 8 | &:focus { 9 | background-color: darken(@color, 10%); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | ### Bug, feature request, or proposal: 3 | 4 | 5 | 6 | ### What is the expected behavior? 7 | 8 | 9 | 10 | ### What is the current behavior? 11 | 12 | 13 | 14 | ### What are the steps to reproduce? 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/CheckTree.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import * as React from 'react'; 4 | import CheckTreePicker from 'rsuite-checktreepicker'; 5 | 6 | const CheckTree = (props: any) => ( 7 | 8 | ); 9 | 10 | export default CheckTree; 11 | -------------------------------------------------------------------------------- /styles/less/pickers/index.less: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | @import "calendar-picker"; 4 | @import "cascader"; 5 | @import "check-picker"; 6 | @import "check-tree-picker"; 7 | @import "date-range-picker"; 8 | @import "select-picker"; 9 | @import "tree-picker"; 10 | -------------------------------------------------------------------------------- /src/IconFont.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import Icon from './Icon'; 3 | import deprecationWarning from './utils/deprecationWarning'; 4 | 5 | export default deprecationWarning.wrapper(Icon, 6 | '``', 7 | '``', 8 | 'https://rsuitejs.com/components/icon' 9 | ); 10 | -------------------------------------------------------------------------------- /styles/less/mixins/sidenavs.less: -------------------------------------------------------------------------------- 1 | .reset-sidenav-dropdown-menu() { 2 | display: block; 3 | position: static; 4 | float: none; 5 | box-shadow: none; 6 | animation-name: none; 7 | padding: 0; 8 | background-color: transparent; 9 | border-radius: 0; 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/previewFile.js: -------------------------------------------------------------------------------- 1 | 2 | // @flow 3 | 4 | export default (file: File, callback: (result: string | ArrayBuffer) => void) => { 5 | const reader = new FileReader(); 6 | reader.onloadend = () => { 7 | callback(reader.result); 8 | }; 9 | reader.readAsDataURL(file); 10 | }; 11 | -------------------------------------------------------------------------------- /styles/less/help-block.less: -------------------------------------------------------------------------------- 1 | .help-block { 2 | &-success { 3 | color: @success-color; 4 | } 5 | 6 | &-warning { 7 | color: @warning-color; 8 | } 9 | 10 | &-danger { 11 | color: @error-color; 12 | } 13 | 14 | &-info { 15 | color: @info-color; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /styles/less/mixins/message.less: -------------------------------------------------------------------------------- 1 | // Messages 2 | 3 | .message-variant(@background; @icon-color) { 4 | background-color: @background; 5 | color: @text-color; 6 | 7 | .@{ns}message-icon-wrapper > .@{ns}icon, 8 | .@{ns}message-btn-close { 9 | color: @icon-color; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /styles/less/mixins/tables.less: -------------------------------------------------------------------------------- 1 | .column-resize-spanner() { 2 | height: 36px; 3 | width: @table-column-resize-spanner-width; 4 | z-index: @zindex-table-column-resize-spanner; 5 | position: absolute; 6 | cursor: ew-resize !important; 7 | outline: none; 8 | border-radius: 6px; 9 | } 10 | -------------------------------------------------------------------------------- /src/utils/TypeDefinition.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | export type Size = 'lg' | 'md' | 'sm' | 'xs'; 4 | export type Types = 'success' | 'warning' | 'error' | 'info'; 5 | export type Color = 'red' | 'orange' | 'yellow' | 'green' | 'cyan' | 'blue' | 'violet'; 6 | export type SVGIcon = { viewBox: string, id: string }; 7 | -------------------------------------------------------------------------------- /styles/less/mixins/nav-divider.less: -------------------------------------------------------------------------------- 1 | // Horizontal dividers 2 | // 3 | // Dividers (basically an hr) within dropdowns and nav lists 4 | 5 | .nav-divider(@color: #e5e5e5) { 6 | height: 1px; 7 | margin: @nav-divider-margin-vertical 0; 8 | overflow: hidden; 9 | background-color: @color; 10 | } 11 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const plugins = [ 2 | require('autoprefixer'), 3 | require('cssnano')({ 4 | preset: [ 5 | 'default', { 6 | discardComments: { 7 | removeAll: true 8 | } 9 | } 10 | ] 11 | }) 12 | ]; 13 | 14 | module.exports = { 15 | plugins 16 | }; 17 | -------------------------------------------------------------------------------- /styles/less/mixins/input-numbers.less: -------------------------------------------------------------------------------- 1 | .input-touchspin(@size) { 2 | @size-name: ~"input-height-@{size}"; 3 | @height: @@size-name/2; 4 | 5 | height: @height; 6 | 7 | > .@{ns}icon { 8 | height: @height; 9 | line-height: unit(@height/@number-input-touchspin-font-size); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Whisper.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from 'react'; 3 | import OverlayTrigger from 'rsuite-utils/lib/Overlay/OverlayTrigger'; 4 | 5 | const Whisper = ({ triggerRef, ...rest }: any) => ( 6 | 11 | ); 12 | 13 | export default Whisper; 14 | -------------------------------------------------------------------------------- /styles/less/mixins/radios.less: -------------------------------------------------------------------------------- 1 | .radio-inner-wrapper(@border-color:@radio-default-border-color) { 2 | border: 1px solid @border-color; 3 | background-color: @radio-bg; 4 | border-radius: @radio-border-radius; 5 | } 6 | 7 | .radio-inner-active-shadow(@shadow-color:@radio-default-border-color) { 8 | box-shadow: 0 0 0 2px fade(@shadow-color, 30%); 9 | } 10 | -------------------------------------------------------------------------------- /styles/less/mixins/checkboxes.less: -------------------------------------------------------------------------------- 1 | .checkbox-inner-wrap(@border-color:@checkbox-default-border-color) { 2 | border: 1px solid @border-color; 3 | background-color: @checkbox-bg; 4 | border-radius: @checkbox-border-radius; 5 | } 6 | 7 | .checkbox-inner-active-shadow(@shadow-color:@checkbox-default-border-color) { 8 | box-shadow: 0 0 0 2px fade(@shadow-color, 40%); 9 | } 10 | -------------------------------------------------------------------------------- /styles/less/mixins/tags.less: -------------------------------------------------------------------------------- 1 | .tag-variant(@background-color) { 2 | color: @B000; 3 | background-color: @background-color; 4 | } 5 | 6 | .generate-spectrum-tags(@i:length(@spectrum)) when (@i>0) { 7 | .generate-spectrum-tags(@i - 1); 8 | @name: extract(@spectrum, @i); 9 | @color: @@name; 10 | 11 | .@{ns}tag-@{name} { 12 | .tag-variant(@color); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Schema.js: -------------------------------------------------------------------------------- 1 | import { 2 | SchemaModel, 3 | StringType, 4 | NumberType, 5 | ArrayType, 6 | DateType, 7 | ObjectType, 8 | BooleanType 9 | } from 'rsuite-schema'; 10 | 11 | export default { 12 | Model: SchemaModel, 13 | Types: { 14 | StringType, 15 | NumberType, 16 | ArrayType, 17 | DateType, 18 | ObjectType, 19 | BooleanType 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /styles/less/mixins/pagination.less: -------------------------------------------------------------------------------- 1 | .pagination-active(@font-color) { 2 | .active() { 3 | color: @font-color; 4 | background-color: transparent; 5 | } 6 | .active; 7 | 8 | &:hover, 9 | &:focus, 10 | &.focus { 11 | .active; 12 | } 13 | 14 | &:active { 15 | &, 16 | &:hover, 17 | &:focus, 18 | &.focus { 19 | .active; 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 7.2.1 4 | 5 | env: 6 | - BROWSER=ChromeCi 7 | - BROWSER=Firefox 8 | 9 | cache: 10 | directories: 11 | - node_modules 12 | 13 | after_script: 14 | - npm run coveralls 15 | 16 | before_install: 17 | - export CHROME_BIN=chromium-browser 18 | - export DISPLAY=:99.0 19 | - sh -e /etc/init.d/xvfb start 20 | 21 | branches: 22 | only: 23 | - master 24 | -------------------------------------------------------------------------------- /styles/less/mixins/nav-vertical-align.less: -------------------------------------------------------------------------------- 1 | // Navbar vertical align 2 | // 3 | // Vertically center elements in the navbar. 4 | // Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin. 5 | 6 | .navbar-vertical-align(@element-height) { 7 | margin-top: ((@navbar-height - @element-height) / 2); 8 | margin-bottom: ((@navbar-height - @element-height) / 2); 9 | } 10 | -------------------------------------------------------------------------------- /styles/less/mixins/alerts.less: -------------------------------------------------------------------------------- 1 | .alert-variant(@background; @icon-color) { 2 | .@{notification-ns}-alert & { 3 | // Content 4 | .@{notification-ns}-notice-content { 5 | background-color: @background; 6 | color: @text-color; 7 | 8 | // Tip icon 9 | .@{ns}icon { 10 | color: @icon-color; 11 | } 12 | } 13 | 14 | // Close button 15 | .@{notification-ns}-notice-close { 16 | color: @icon-color; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "env", 5 | { 6 | "loose": true 7 | } 8 | ], 9 | "react", 10 | "stage-0" 11 | ], 12 | "plugins": [ 13 | "lodash", 14 | "transform-proto-to-assign", 15 | "flow-react-proptypes", 16 | "transform-react-flow-handled-props", 17 | "transform-class-properties", 18 | "transform-dev" 19 | ], 20 | "env": { 21 | "coverage": { 22 | "plugins": ["istanbul"] 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/utils/tplTransform.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import * as React from 'react'; 4 | 5 | const toJSX = (node, key) => (node ? {node} : null); 6 | 7 | /** 8 | * tplTransform('Show {0} data', 100); 9 | * output: 10 | * Show 100 data 11 | */ 12 | export default (pattern: string, ...data: Array) => 13 | pattern 14 | .split(/\{(\d+)\}/) 15 | .map((item, index) => (index % 2 ? toJSX(data[+item], index) : toJSX(item, index))) 16 | .filter(item => item !== ''); 17 | -------------------------------------------------------------------------------- /src/utils/constants.js: -------------------------------------------------------------------------------- 1 | export const STATUS_ICON_NAMES = { 2 | info: 'info', 3 | success: 'check-circle', 4 | error: 'close-circle', 5 | warning: 'remind' 6 | }; 7 | 8 | export const PAGINATION_ICON_NAMES = { 9 | more: 'more', 10 | prev: 'page-previous', 11 | next: 'page-next', 12 | first: 'page-top', 13 | last: 'page-end' 14 | }; 15 | 16 | export const SIZE = ['lg', 'md', 'sm', 'xs']; 17 | export const STATUS = ['success', 'warning', 'error', 'info']; 18 | export const COLOR = ['red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'violet']; 19 | -------------------------------------------------------------------------------- /src/utils/prefix.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import classNames from 'classnames'; 3 | 4 | export const globalKey = 'rs-'; 5 | export const defaultClassPrefix = name => `${globalKey}${name}`; 6 | 7 | function prefix(pre: string, className: string | Array): string { 8 | if (!pre || !className) { 9 | return ''; 10 | } 11 | 12 | if (_.isArray(className)) { 13 | return classNames(className.filter(name => !!name).map(name => `${pre}-${name}`)); 14 | } 15 | 16 | return `${pre}-${className}`; 17 | } 18 | 19 | export default _.curry(prefix); 20 | -------------------------------------------------------------------------------- /src/Table.js: -------------------------------------------------------------------------------- 1 | import setStatic from 'recompose/setStatic'; 2 | import { Table, Column, Cell, HeaderCell } from 'rsuite-table'; 3 | 4 | import withLocale from './IntlProvider/withLocale'; 5 | import TablePagination from './TablePagination'; 6 | 7 | const EnhancedLocaleTable = withLocale(['Table'])(Table); 8 | 9 | setStatic('Column', Column)(EnhancedLocaleTable); 10 | setStatic('Cell', Cell)(EnhancedLocaleTable); 11 | setStatic('HeaderCell', HeaderCell)(EnhancedLocaleTable); 12 | setStatic('Pagination', TablePagination)(EnhancedLocaleTable); 13 | 14 | export default EnhancedLocaleTable; 15 | -------------------------------------------------------------------------------- /styles/less/mixins/border-radius.less: -------------------------------------------------------------------------------- 1 | // Single side border-radius 2 | 3 | .border-top-radius(@radius) { 4 | border-top-right-radius: @radius; 5 | border-top-left-radius: @radius; 6 | } 7 | 8 | .border-right-radius(@radius) { 9 | border-bottom-right-radius: @radius; 10 | border-top-right-radius: @radius; 11 | } 12 | 13 | .border-bottom-radius(@radius) { 14 | border-bottom-right-radius: @radius; 15 | border-bottom-left-radius: @radius; 16 | } 17 | 18 | .border-left-radius(@radius) { 19 | border-bottom-left-radius: @radius; 20 | border-top-left-radius: @radius; 21 | } 22 | -------------------------------------------------------------------------------- /src/InputGroupAddon.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import * as React from 'react'; 4 | import classNames from 'classnames'; 5 | import { defaultProps } from './utils'; 6 | 7 | type Props = { 8 | className?: string, 9 | classPrefix?: string 10 | }; 11 | 12 | class InputGroupAddon extends React.Component { 13 | render() { 14 | const { className, classPrefix, ...props } = this.props; 15 | 16 | return ; 17 | } 18 | } 19 | 20 | export default defaultProps({ 21 | classPrefix: 'input-group-addon' 22 | })(InputGroupAddon); 23 | -------------------------------------------------------------------------------- /src/IntlProvider/IntlProvider.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import * as React from 'react'; 4 | import PropTypes from 'prop-types'; 5 | 6 | type Props = { 7 | locale: Object, 8 | children?: React.Node 9 | }; 10 | 11 | class IntlProvider extends React.Component { 12 | static childContextTypes = { 13 | rsuiteLocale: PropTypes.object 14 | }; 15 | 16 | getChildContext() { 17 | const { locale } = this.props; 18 | return { 19 | rsuiteLocale: locale 20 | }; 21 | } 22 | render() { 23 | return this.props.children; 24 | } 25 | } 26 | 27 | export default IntlProvider; 28 | -------------------------------------------------------------------------------- /src/ModalFooter.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import * as React from 'react'; 4 | import classNames from 'classnames'; 5 | import { defaultProps } from './utils'; 6 | 7 | type Props = { 8 | classPrefix?: string, 9 | className?: string 10 | }; 11 | 12 | class ModalFooter extends React.Component { 13 | render() { 14 | const { classPrefix, className, ...props } = this.props; 15 | let classes = classNames(classPrefix, className); 16 | return
; 17 | } 18 | } 19 | 20 | export default defaultProps({ 21 | classPrefix: 'modal-footer' 22 | })(ModalFooter); 23 | -------------------------------------------------------------------------------- /src/SidenavBody.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import * as React from 'react'; 4 | import classNames from 'classnames'; 5 | import { defaultProps } from './utils'; 6 | 7 | type Props = { 8 | classPrefix?: string, 9 | className?: string 10 | }; 11 | 12 | class SidenavBody extends React.Component { 13 | render() { 14 | const { classPrefix, className, ...props } = this.props; 15 | 16 | const classes = classNames(classPrefix, className); 17 | 18 | return
; 19 | } 20 | } 21 | 22 | export default defaultProps({ 23 | classPrefix: 'sidenav-body' 24 | })(SidenavBody); 25 | -------------------------------------------------------------------------------- /src/NavbarHeader.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import * as React from 'react'; 4 | import classNames from 'classnames'; 5 | 6 | import { defaultProps } from './utils'; 7 | 8 | type Props = { 9 | classPrefix?: string, 10 | className?: string 11 | }; 12 | 13 | class NavbarHeader extends React.Component { 14 | render() { 15 | const { className, classPrefix, ...props } = this.props; 16 | 17 | const classes = classNames(classPrefix, className); 18 | 19 | return
; 20 | } 21 | } 22 | 23 | export default defaultProps({ 24 | classPrefix: 'navbar-header' 25 | })(NavbarHeader); 26 | -------------------------------------------------------------------------------- /src/SidenavHeader.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import * as React from 'react'; 4 | import classNames from 'classnames'; 5 | import { defaultProps } from './utils'; 6 | 7 | type Props = { 8 | classPrefix?: string, 9 | className?: string 10 | }; 11 | 12 | class SidenavHeader extends React.Component { 13 | render() { 14 | const { className, classPrefix, ...props } = this.props; 15 | 16 | const classes = classNames(classPrefix, className); 17 | 18 | return
; 19 | } 20 | } 21 | 22 | export default defaultProps({ 23 | classPrefix: 'sidenav-header' 24 | })(SidenavHeader); 25 | -------------------------------------------------------------------------------- /styles/less/mixins/notification.less: -------------------------------------------------------------------------------- 1 | .notifocation-variant(@icon-color) { 2 | .@{notification-ns}-notify & { 3 | // Content 4 | .@{notification-ns}-notice-content { 5 | 6 | // Description 7 | // Has title and description need to ajust distance 8 | .@{notification-ns}-title + .@{notification-ns}-description { 9 | margin-left: @notify-title-icon-size+@notify-title-icon-margin; 10 | } 11 | 12 | // Tip icon 13 | .@{ns}icon { 14 | color: @icon-color; 15 | 16 | &::before { 17 | vertical-align: middle; 18 | } 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/ButtonToolbar.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import * as React from 'react'; 4 | import classNames from 'classnames'; 5 | 6 | import { defaultProps } from './utils'; 7 | 8 | type Props = { 9 | className?: string, 10 | classPrefix?: string 11 | }; 12 | 13 | class ButtonToolbar extends React.Component { 14 | render() { 15 | const { className, classPrefix, ...props } = this.props; 16 | const classes = classNames(classPrefix, className); 17 | return
; 18 | } 19 | } 20 | 21 | export default defaultProps({ 22 | classPrefix: 'btn-toolbar' 23 | })(ButtonToolbar); 24 | -------------------------------------------------------------------------------- /test/TestWrapper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * https://stackoverflow.com/questions/36682241/testing-functional-components-with-renderintodocument 3 | */ 4 | import React from 'react'; 5 | import { findDOMNode } from 'react-dom'; 6 | import ReactTestUtils from 'react-dom/test-utils'; 7 | 8 | class Wrapper extends React.Component { 9 | render() { 10 | return this.props.children; 11 | } 12 | } 13 | 14 | export function getInstance(children) { 15 | return ReactTestUtils.renderIntoDocument(children); 16 | } 17 | 18 | export function getDOMNode(children) { 19 | return findDOMNode(getInstance(children)); 20 | } 21 | 22 | export default Wrapper; 23 | -------------------------------------------------------------------------------- /src/InputGroupButton.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import * as React from 'react'; 4 | import classNames from 'classnames'; 5 | import { defaultProps } from './utils'; 6 | import Button from './Button'; 7 | 8 | type Props = { 9 | className?: string, 10 | classPrefix?: string 11 | }; 12 | 13 | class InputGroupButton extends React.Component { 14 | render() { 15 | const { className, classPrefix, ...props } = this.props; 16 | return