├── .babelrc ├── .gitignore ├── LICENCE ├── README.md ├── dist ├── ReactBootstrapRibbon.js ├── ReactBootstrapRibbonButton.js ├── ReactBootstrapRibbonGroup.js ├── ReactBootstrapRibbonGroupItem.js └── react-bootstrap-ribbon.css ├── docs ├── CNAME ├── android-icon-144x144.png ├── android-icon-192x192.png ├── android-icon-36x36.png ├── android-icon-48x48.png ├── android-icon-72x72.png ├── android-icon-96x96.png ├── apple-icon-114x114.png ├── apple-icon-120x120.png ├── apple-icon-144x144.png ├── apple-icon-152x152.png ├── apple-icon-180x180.png ├── apple-icon-57x57.png ├── apple-icon-60x60.png ├── apple-icon-72x72.png ├── apple-icon-76x76.png ├── apple-icon-precomposed.png ├── apple-icon.png ├── browserconfig.xml ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png ├── favicon.ico ├── index.html ├── manifest.json ├── ms-icon-144x144.png ├── ms-icon-150x150.png ├── ms-icon-310x310.png ├── ms-icon-70x70.png ├── public │ ├── dark.css │ ├── main.css │ └── main.js └── src │ ├── ExampleRibbon.js │ ├── LgkLogo.js │ ├── _dark-theme.scss │ ├── dark.scss │ ├── index.js │ └── main.scss ├── index.js ├── package-lock.json ├── package.json ├── preview_desktop.jpg ├── preview_desktop.png ├── preview_mobile.jpg ├── preview_mobile.png ├── src ├── ReactBootstrapRibbon.js ├── ReactBootstrapRibbonButton.js ├── ReactBootstrapRibbonGroup.js ├── ReactBootstrapRibbonGroupItem.js └── react-bootstrap-ribbon.css └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/env", 5 | { 6 | "modules": false 7 | } 8 | ], 9 | "@babel/react" 10 | ] 11 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | src/client/public/ 3 | *.tgz 4 | docs/public/dark.js -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Lars Gerrit Kliesing (LGK) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Bootstrap Ribbon 2 | 3 | Get a Microsoft inspired Ribbon menu for your React app. It uses Bootstrap 4 components.\ 4 | [Find React Bootstrap Ribbon on NPM.](https://www.npmjs.com/package/react-bootstrap-ribbon) 5 | 6 | [![npm version](https://img.shields.io/npm/v/react-bootstrap-ribbon.svg)](https://www.npmjs.com/package/react-bootstrap-ribbon) 7 | 8 |

Desktop preview

9 | Ribbon menu on desktop 10 | 11 |

Mobile preview

12 | Ribbon menu on mobile 13 | 14 |

Installation

15 | 16 |

17 | Add it with NPM:
18 | npm i -S react-bootstrap-ribbon 19 |

20 | 21 |

22 | After that you can import the components:
23 | import {Ribbon, RibbonGroup, RibbonGroupItem, RibbonButton} from "react-bootstrap-ribbon"; 24 |

25 | 26 |

27 | Make sure you also embed the CSS:
28 | import "react-bootstrap-ribbon/dist/react-bootstrap-ribbon.css"; 29 |

30 | 31 | 32 |

Usage

33 | 34 | Your code could look like this: 35 | 36 | ```javascript 37 | import React, { Component } from "react"; 38 | import { Ribbon, RibbonGroup, RibbonGroupItem, RibbonButton } from "react-bootstrap-ribbon"; 39 | 40 | // In this example Bootsrap is installed via NPM. Here it gets imported from the "./node_modules" folder: 41 | import "bootstrap/dist/css/bootstrap.css"; 42 | import "react-bootstrap-ribbon/dist/react-bootstrap-ribbon.css"; 43 | 44 | class App extends Component { 45 | render() { 46 | return ( 47 |
48 | {/* 49 | `breakpoint` prop is optional and defines when to switch between mobile and desktop view. 50 | Possible values: "sm", "md", "lg", "xl", default: "md" 51 | `height` is also optional. Default is "8rem". 52 | */} 53 | 54 | 55 | alert("Hello from Ribbon button!")}> 56 | 57 | ✏️ 58 |
Edit
59 |
60 |
61 | 62 | {/* more Ribbon group items */} 63 |
64 | 65 | {/* more Ribbon groups */} 66 |
67 |
68 | ); 69 | } 70 | } 71 | 72 | export default App; 73 | ``` 74 | 75 |

Run an example

76 | Clone this repo on your PC. After that install all dependencies with npm i.
77 | Then run npm start and you should see the example in your browser. You can see the code under ./docs/src/index.js. 78 | -------------------------------------------------------------------------------- /dist/ReactBootstrapRibbon.js: -------------------------------------------------------------------------------- 1 | function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 2 | 3 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4 | 5 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 6 | 7 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 8 | 9 | function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } 10 | 11 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 12 | 13 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 14 | 15 | function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } 16 | 17 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 18 | 19 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 20 | 21 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 22 | 23 | import React from "react"; 24 | import PropTypes from "prop-types"; 25 | 26 | var ReactBootstrapRibbon = /*#__PURE__*/function (_React$Component) { 27 | _inherits(ReactBootstrapRibbon, _React$Component); 28 | 29 | var _super = _createSuper(ReactBootstrapRibbon); 30 | 31 | function ReactBootstrapRibbon() { 32 | var _this; 33 | 34 | _classCallCheck(this, ReactBootstrapRibbon); 35 | 36 | _this = _super.call(this); 37 | _this.state = { 38 | mobileCurrentGroup: 0 39 | }; 40 | return _this; 41 | } 42 | 43 | _createClass(ReactBootstrapRibbon, [{ 44 | key: "handleChange", 45 | value: function handleChange(event) { 46 | this.setState({ 47 | mobileCurrentGroup: event.target.value * 1 48 | }); 49 | } 50 | }, { 51 | key: "render", 52 | value: function render() { 53 | var _this2 = this; 54 | 55 | var children = Array.isArray(this.props.children) ? this.props.children : [this.props.children]; 56 | return /*#__PURE__*/React.createElement("div", { 57 | className: "bg-light" 58 | }, /*#__PURE__*/React.createElement("div", { 59 | className: "d-".concat(this.props.breakpoint, "-none") 60 | }, /*#__PURE__*/React.createElement("div", { 61 | className: "mobile-ribbon ribbon" 62 | }, /*#__PURE__*/React.createElement("div", { 63 | className: "ribbon-group-content" 64 | }, /*#__PURE__*/React.createElement("select", { 65 | className: "mobile-ribbon-select form-control", 66 | onChange: function onChange(event) { 67 | return _this2.handleChange(event); 68 | } 69 | }, children.map(function (item, index) { 70 | return /*#__PURE__*/React.createElement("option", { 71 | key: index, 72 | value: index 73 | }, item.props.title); 74 | }))), children.map(function (item, index) { 75 | return /*#__PURE__*/React.createElement("div", { 76 | key: index, 77 | className: "ribbon-group-content " + (index === _this2.state.mobileCurrentGroup ? "d-block" : "d-none") 78 | }, /*#__PURE__*/React.createElement("div", { 79 | className: "row no-gutters" 80 | }, item.props.children)); 81 | }))), /*#__PURE__*/React.createElement("div", { 82 | className: "d-none d-".concat(this.props.breakpoint, "-block") 83 | }, /*#__PURE__*/React.createElement("div", { 84 | className: "ribbon d-flex", 85 | style: { 86 | height: this.props.height 87 | } 88 | }, /*#__PURE__*/React.createElement("div", { 89 | className: "row no-gutters w-100" 90 | }, this.props.children)))); 91 | } 92 | }], [{ 93 | key: "defaultProps", 94 | get: function get() { 95 | return { 96 | height: "8rem", 97 | breakpoint: "md" 98 | }; 99 | } 100 | }]); 101 | 102 | return ReactBootstrapRibbon; 103 | }(React.Component); 104 | 105 | ReactBootstrapRibbon.propTypes = { 106 | height: PropTypes.string, 107 | breakpoint: PropTypes.oneOf(["sm", "md", "lg", "xl"]) 108 | }; 109 | export default ReactBootstrapRibbon; 110 | -------------------------------------------------------------------------------- /dist/ReactBootstrapRibbonButton.js: -------------------------------------------------------------------------------- 1 | function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 2 | 3 | function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } 4 | 5 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 6 | 7 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 8 | 9 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 10 | 11 | function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } 12 | 13 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 14 | 15 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 16 | 17 | function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } 18 | 19 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 20 | 21 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 22 | 23 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 24 | 25 | import React from "react"; 26 | 27 | var ReactBootstrapRibbonButton = /*#__PURE__*/function (_React$Component) { 28 | _inherits(ReactBootstrapRibbonButton, _React$Component); 29 | 30 | var _super = _createSuper(ReactBootstrapRibbonButton); 31 | 32 | function ReactBootstrapRibbonButton() { 33 | _classCallCheck(this, ReactBootstrapRibbonButton); 34 | 35 | return _super.apply(this, arguments); 36 | } 37 | 38 | _createClass(ReactBootstrapRibbonButton, [{ 39 | key: "render", 40 | value: function render() { 41 | return /*#__PURE__*/React.createElement("button", _extends({ 42 | type: "button", 43 | className: "btn btn-light btn-block text-nowrap" 44 | }, this.props), this.props.children); 45 | } 46 | }]); 47 | 48 | return ReactBootstrapRibbonButton; 49 | }(React.Component); 50 | 51 | export default ReactBootstrapRibbonButton; 52 | -------------------------------------------------------------------------------- /dist/ReactBootstrapRibbonGroup.js: -------------------------------------------------------------------------------- 1 | function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 2 | 3 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4 | 5 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 6 | 7 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 8 | 9 | function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } 10 | 11 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 12 | 13 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 14 | 15 | function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } 16 | 17 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 18 | 19 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 20 | 21 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 22 | 23 | import React from "react"; 24 | 25 | var ReactBootstrapRibbonGroup = /*#__PURE__*/function (_React$Component) { 26 | _inherits(ReactBootstrapRibbonGroup, _React$Component); 27 | 28 | var _super = _createSuper(ReactBootstrapRibbonGroup); 29 | 30 | function ReactBootstrapRibbonGroup() { 31 | _classCallCheck(this, ReactBootstrapRibbonGroup); 32 | 33 | return _super.apply(this, arguments); 34 | } 35 | 36 | _createClass(ReactBootstrapRibbonGroup, [{ 37 | key: "render", 38 | value: function render() { 39 | return /*#__PURE__*/React.createElement("div", { 40 | className: "ribbon-col h-100 " + (this.props.colClass ? this.props.colClass : "col-sm-6") 41 | }, /*#__PURE__*/React.createElement("div", { 42 | className: "ribbon-group h-100 d-flex flex-column" 43 | }, /*#__PURE__*/React.createElement("div", { 44 | className: "ribbon-group-content h-100 flex-fill" 45 | }, /*#__PURE__*/React.createElement("div", { 46 | className: "row no-gutters row-2px h-100 p-1" 47 | }, this.props.children)), /*#__PURE__*/React.createElement("div", { 48 | className: "ribbon-group-title text-center" 49 | }, this.props.title))); 50 | } 51 | }]); 52 | 53 | return ReactBootstrapRibbonGroup; 54 | }(React.Component); 55 | 56 | export default ReactBootstrapRibbonGroup; 57 | -------------------------------------------------------------------------------- /dist/ReactBootstrapRibbonGroupItem.js: -------------------------------------------------------------------------------- 1 | function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 2 | 3 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4 | 5 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 6 | 7 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 8 | 9 | function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } 10 | 11 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 12 | 13 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 14 | 15 | function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } 16 | 17 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 18 | 19 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 20 | 21 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 22 | 23 | import React from "react"; 24 | 25 | var ReactBootstrapRibbonGroupItem = /*#__PURE__*/function (_React$Component) { 26 | _inherits(ReactBootstrapRibbonGroupItem, _React$Component); 27 | 28 | var _super = _createSuper(ReactBootstrapRibbonGroupItem); 29 | 30 | function ReactBootstrapRibbonGroupItem() { 31 | _classCallCheck(this, ReactBootstrapRibbonGroupItem); 32 | 33 | return _super.apply(this, arguments); 34 | } 35 | 36 | _createClass(ReactBootstrapRibbonGroupItem, [{ 37 | key: "render", 38 | value: function render() { 39 | return /*#__PURE__*/React.createElement("div", { 40 | className: "d-md-flex " + (this.props.colClass ? this.props.colClass : "col-6") 41 | }, this.props.children); 42 | } 43 | }]); 44 | 45 | return ReactBootstrapRibbonGroupItem; 46 | }(React.Component); 47 | 48 | export default ReactBootstrapRibbonGroupItem; 49 | -------------------------------------------------------------------------------- /dist/react-bootstrap-ribbon.css: -------------------------------------------------------------------------------- 1 | .ribbon-col:not(:last-child) .ribbon-group { 2 | box-shadow: inset -1px 0 1px rgba(0,0,0,.1); 3 | } 4 | 5 | .ribbon-group-title { 6 | background-color: rgba(0,0,0,.1); 7 | } -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | ribbon.lgk.io -------------------------------------------------------------------------------- /docs/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/android-icon-144x144.png -------------------------------------------------------------------------------- /docs/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/android-icon-192x192.png -------------------------------------------------------------------------------- /docs/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/android-icon-36x36.png -------------------------------------------------------------------------------- /docs/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/android-icon-48x48.png -------------------------------------------------------------------------------- /docs/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/android-icon-72x72.png -------------------------------------------------------------------------------- /docs/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/android-icon-96x96.png -------------------------------------------------------------------------------- /docs/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon-114x114.png -------------------------------------------------------------------------------- /docs/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon-120x120.png -------------------------------------------------------------------------------- /docs/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon-144x144.png -------------------------------------------------------------------------------- /docs/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon-152x152.png -------------------------------------------------------------------------------- /docs/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon-180x180.png -------------------------------------------------------------------------------- /docs/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon-57x57.png -------------------------------------------------------------------------------- /docs/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon-60x60.png -------------------------------------------------------------------------------- /docs/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon-72x72.png -------------------------------------------------------------------------------- /docs/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon-76x76.png -------------------------------------------------------------------------------- /docs/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon-precomposed.png -------------------------------------------------------------------------------- /docs/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/apple-icon.png -------------------------------------------------------------------------------- /docs/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /docs/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/favicon-16x16.png -------------------------------------------------------------------------------- /docs/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/favicon-32x32.png -------------------------------------------------------------------------------- /docs/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/favicon-96x96.png -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/favicon.ico -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | React Bootstrap Ribbon 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
53 | 54 |
55 |
56 | 57 |
58 |
59 | 60 |
61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /docs/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /docs/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/ms-icon-144x144.png -------------------------------------------------------------------------------- /docs/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/ms-icon-150x150.png -------------------------------------------------------------------------------- /docs/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/ms-icon-310x310.png -------------------------------------------------------------------------------- /docs/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/docs/ms-icon-70x70.png -------------------------------------------------------------------------------- /docs/src/ExampleRibbon.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import Ribbon from "../../src/ReactBootstrapRibbon"; 4 | import RibbonGroup from "../../src/ReactBootstrapRibbonGroup"; 5 | import RibbonGroupItem from "../../src/ReactBootstrapRibbonGroupItem"; 6 | import RibbonButton from "../../src/ReactBootstrapRibbonButton"; 7 | 8 | export const ExampleRibbon = () => ( 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Edit
18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
Copy
28 |
29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
Paste
38 |
39 |
40 |
41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
New folder
51 |
52 |
53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | New file 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Easy access 71 | 72 | 73 |
74 |
75 |
76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
Properties
88 |
89 |
90 | 91 |
92 | 93 | 94 | 95 | 96 | 97 | Open file 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | History 108 | 109 | 110 |
111 |
112 |
113 | 114 | 115 | 116 |
117 | 118 | 119 | 120 | 121 | Select all 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | Toggle selection 130 | 131 | 132 |
133 |
134 |
135 |
136 | ); -------------------------------------------------------------------------------- /docs/src/LgkLogo.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export function LgkLogo() { 4 | return ( 5 | 6 | 14 | 15 | 19 | 20 | ); 21 | } -------------------------------------------------------------------------------- /docs/src/_dark-theme.scss: -------------------------------------------------------------------------------- 1 | // Open the following link to edit this config on Customize Bootstrap 2 | // https://colorganize.com/customize-bootstrap/index.html#%7B%22btHashVars%22%3A%7B%22%24gray-900%22%3A%22%23121212%22%2C%22%24white%22%3A%22%23fff%22%2C%22%24gray-800%22%3A%22%23232323%22%2C%22%24blue%22%3A%22lighten(%23096EB0%2C%2025%25)%22%2C%22%24primary%22%3A%22%24blue%22%2C%22%24gray-700%22%3A%22%23333333%22%2C%22%24pink%22%3A%22%23ff6caf%22%2C%22%24gray-400%22%3A%22%23ced4da%22%2C%22%24gray-500%22%3A%22%23adb5bd%22%2C%22%24black%22%3A%22%23000%22%2C%22%24gray-200%22%3A%22%23e9ecef%22%2C%22%24gray-300%22%3A%22%23dee2e6%22%2C%22%24gray-600%22%3A%22%236c757d%22%2C%22%24body-bg%22%3A%22%24gray-900%22%2C%22%24body-color%22%3A%22%24white%22%2C%22%24link-color%22%3A%22%24primary%22%2C%22%24link-hover-color%22%3A%22lighten(%24link-color%2C%2015%25)%22%2C%22%24table-bg%22%3A%22%24gray-800%22%2C%22%24table-border-color%22%3A%22%24gray-700%22%2C%22%24input-color%22%3A%22%24body-color%22%2C%22%24input-placeholder-color%22%3A%22%24gray-400%22%2C%22%24input-disabled-bg%22%3A%22%24gray-500%22%2C%22%24input-border-color%22%3A%22%24gray-600%22%2C%22%24input-group-addon-bg%22%3A%22%24gray-700%22%2C%22%24input-bg%22%3A%22rgba(%24white%2C%20.125)%22%2C%22%24card-bg%22%3A%22%24gray-800%22%2C%22%24nav-tabs-link-active-color%22%3A%22%24gray-300%22%2C%22%24nav-tabs-border-color%22%3A%22%24gray-700%22%2C%22%24nav-tabs-link-active-border-color%22%3A%22%24nav-tabs-border-color%20%24nav-tabs-border-color%20transparent%22%2C%22%24nav-tabs-link-active-bg%22%3A%22%24gray-700%22%2C%22%24nav-tabs-link-hover-border-color%22%3A%22%24gray-800%20%24gray-800%20transparent%22%2C%22%24modal-content-bg%22%3A%22%24gray-800%22%2C%22%24modal-header-border-color%22%3A%22%24gray-700%22%2C%22%24jumbotron-bg%22%3A%22%24gray-700%22%2C%22%24list-group-border-color%22%3A%22rgba(%24white%2C%20.125)%22%2C%22%24list-group-bg%22%3A%22%24gray-700%22%2C%22%24list-group-hover-bg%22%3A%22%24gray-600%22%2C%22%24list-group-action-color%22%3A%22%24gray-200%22%2C%22%24list-group-action-active-bg%22%3A%22%24gray-500%22%2C%22%24light%22%3A%22%24gray-700%22%2C%22%24navbar-light-color%22%3A%22rgba(%24white%2C%20.5)%22%2C%22%24navbar-light-hover-color%22%3A%22rgba(%24white%2C%20.7)%22%2C%22%24navbar-light-active-color%22%3A%22rgba(%24white%2C%20.9)%22%2C%22%24navbar-light-disabled-color%22%3A%22rgba(%24white%2C%20.3)%22%2C%22%24navbar-light-toggler-border-color%22%3A%22rgba(%24white%2C%20.1)%22%2C%22%24card-cap-bg%22%3A%22rgba(%24white%2C%20.03)%22%2C%22%24close-color%22%3A%22%24body-color%22%2C%22%24close-text-shadow%22%3A%220%201px%200%20%24black%22%2C%22%24card-border-color%22%3A%22rgba(%24white%2C%20.125)%22%2C%22%24thumbnail-border-color%22%3A%22%24gray-700%22%2C%22%24pagination-bg%22%3A%22%24body-bg%22%2C%22%24pagination-border-color%22%3A%22%24gray-700%22%2C%22%24pagination-hover-bg%22%3A%22%24gray-800%22%2C%22%24pagination-hover-border-color%22%3A%22%24gray-700%22%2C%22%24pagination-disabled-border-color%22%3A%22%24gray-700%22%2C%22%24pagination-disabled-bg%22%3A%22%24body-bg%22%2C%22%24pagination-disabled-color%22%3A%22%24gray-400%22%2C%22%24custom-control-indicator-bg%22%3A%22%24body-color%22%7D%7D 3 | 4 | 5 | 6 | // Color system 7 | // 8 | 9 | $gray-900: #121212; 10 | $white: #fff; 11 | $gray-800: #232323; 12 | $blue: lighten(#096EB0, 25%); 13 | $primary: $blue; 14 | $gray-700: #333333; 15 | $pink: #ff6caf; 16 | $gray-400: #ced4da; 17 | $gray-500: #adb5bd; 18 | $black: #000; 19 | $gray-200: #e9ecef; 20 | $gray-300: #dee2e6; 21 | $gray-600: #6c757d; 22 | $light: $gray-700; 23 | 24 | 25 | // Body 26 | // 27 | 28 | $body-bg: $gray-900; 29 | $body-color: $white; 30 | 31 | 32 | // Links 33 | // 34 | 35 | $link-color: $primary; 36 | $link-hover-color: lighten($link-color, 15%); 37 | 38 | 39 | // Tables 40 | // 41 | 42 | $table-bg: $gray-800; 43 | $table-border-color: $gray-700; 44 | 45 | 46 | // Forms 47 | // 48 | 49 | $input-color: $body-color; 50 | $input-placeholder-color: $gray-400; 51 | $input-disabled-bg: $gray-500; 52 | $input-border-color: $gray-600; 53 | $input-group-addon-bg: $gray-700; 54 | $input-bg: rgba($white, .125); 55 | $custom-control-indicator-bg: $body-color; 56 | 57 | 58 | // Navs 59 | // 60 | 61 | $nav-tabs-link-active-color: $gray-300; 62 | $nav-tabs-border-color: $gray-700; 63 | $nav-tabs-link-active-border-color: $nav-tabs-border-color $nav-tabs-border-color transparent; 64 | $nav-tabs-link-active-bg: $gray-700; 65 | $nav-tabs-link-hover-border-color: $gray-800 $gray-800 transparent; 66 | 67 | 68 | // Navbar 69 | // 70 | 71 | $navbar-light-color: rgba($white, .5); 72 | $navbar-light-hover-color: rgba($white, .7); 73 | $navbar-light-active-color: rgba($white, .9); 74 | $navbar-light-disabled-color: rgba($white, .3); 75 | $navbar-light-toggler-border-color: rgba($white, .1); 76 | 77 | 78 | // Pagination 79 | // 80 | 81 | $pagination-bg: $body-bg; 82 | $pagination-border-color: $gray-700; 83 | $pagination-hover-bg: $gray-800; 84 | $pagination-hover-border-color: $gray-700; 85 | $pagination-disabled-border-color: $gray-700; 86 | $pagination-disabled-bg: $body-bg; 87 | $pagination-disabled-color: $gray-400; 88 | 89 | 90 | // Jumbotron 91 | // 92 | 93 | $jumbotron-bg: $gray-700; 94 | 95 | 96 | // Cards 97 | // 98 | 99 | $card-bg: $gray-800; 100 | $card-cap-bg: rgba($white, .03); 101 | $card-border-color: rgba($white, .125); 102 | 103 | 104 | // Modals 105 | // 106 | 107 | $modal-content-bg: $gray-800; 108 | $modal-header-border-color: $gray-700; 109 | 110 | 111 | // List group 112 | // 113 | 114 | $list-group-border-color: rgba($white, .125); 115 | $list-group-bg: $gray-700; 116 | $list-group-hover-bg: $gray-600; 117 | $list-group-action-color: $gray-200; 118 | $list-group-action-active-bg: $gray-500; 119 | 120 | 121 | // Image thumbnails 122 | // 123 | 124 | $thumbnail-border-color: $gray-700; 125 | 126 | 127 | // Close 128 | // 129 | 130 | $close-color: $body-color; 131 | $close-text-shadow: 0 1px 0 $black; 132 | 133 | 134 | -------------------------------------------------------------------------------- /docs/src/dark.scss: -------------------------------------------------------------------------------- 1 | @import "./dark-theme"; 2 | @import "./main"; -------------------------------------------------------------------------------- /docs/src/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { render } from "react-dom"; 3 | import "babel-polyfill"; 4 | import ReactEmbedGist from "react-embed-gist"; 5 | 6 | import { Tabs, Tab, Form } from "react-bootstrap"; 7 | 8 | import "./main.scss"; 9 | import { ExampleRibbon } from "./ExampleRibbon"; 10 | import { LgkLogo } from "./LgkLogo"; 11 | 12 | import Ribbon from "../../src/ReactBootstrapRibbon"; 13 | import RibbonGroup from "../../src/ReactBootstrapRibbonGroup"; 14 | import RibbonGroupItem from "../../src/ReactBootstrapRibbonGroupItem"; 15 | import RibbonButton from "../../src/ReactBootstrapRibbonButton"; 16 | 17 | function App() { 18 | const [dark, setDark] = useState(false); 19 | const [showExampleCode, setShowExampleCode] = useState(false); 20 | const cssEmbed = document.getElementById("css-embed"); 21 | const lgkPillBtn = document.querySelector(".lgk-pill-btn"); 22 | 23 | const switchDark = () => { 24 | const _dark = !dark; 25 | setDark(_dark); 26 | 27 | cssEmbed.href = `public/${_dark === true ? "dark" : "main"}.css`; 28 | 29 | if (lgkPillBtn) { 30 | lgkPillBtn.classList.toggle("black"); 31 | } 32 | }; 33 | 34 | return ( 35 |
36 |
37 |
38 |

39 | 40 |

41 |

React Bootstrap Ribbon

42 |

React Bootstrap Ribbon

43 |

A ribbon menu inspired by Microsoft for React using Bootstrap

44 |

45 |
46 |
47 | 48 | 71 | 72 |
73 |
74 |
75 |

76 | The ribbon will fit perfectly in your Bootstrap theme. Checkout how it will look with a dark theme: 77 |

78 | 85 |

86 | Do you like the dark theme? You can find it and many other themes on Colorganize: https://colorganize.com/webTheme/2 87 |

88 |
89 | 90 |

Simple ribbon

91 |

92 | { e.preventDefault(); setShowExampleCode(!showExampleCode); }}>Show example code 93 |

94 | {showExampleCode && 95 |
96 |
97 | {"ExampleRibbon.js"} 98 | 101 |
102 | 103 | 104 |
105 | } 106 | 107 | 108 | 109 | 110 |

Tabbed ribbons

111 | 112 |

113 | Use multiple ribbons and them into Bootstraps Tab components. You can do this with react-bootstrap 114 | {" "}or reactstrap. 115 |

116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 135 | 140 | 145 | 150 | 151 |
Share
152 |
153 |
154 | 155 | 156 | 157 | 165 | 170 | 175 | 176 | 177 |
Email
178 |
179 |
180 |
181 | 182 | 183 | 184 | 185 | 193 | 198 | 199 |
Close releasing
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 | 209 |
210 |
211 |
212 |

Getting started

213 | 214 |

Install with NPM

215 |

This is the recommended method. This way you'll always get the latest version.

216 | 217 |

218 | npm install --save react-bootstrap-ribbon 219 |

220 | 221 |

Download the latest release

222 | Get the latest release 228 |
229 | 230 |
231 |

Usage

232 | 233 | 234 |
235 |
236 |
237 | 238 | 258 |
259 | ); 260 | } 261 | 262 | render(, document.getElementById("app")); -------------------------------------------------------------------------------- /docs/src/main.scss: -------------------------------------------------------------------------------- 1 | $success: #26de81; 2 | 3 | @import "~bootstrap/scss/bootstrap"; 4 | @import "../../src/react-bootstrap-ribbon.css"; 5 | 6 | .nav-tabs, 7 | .nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { 8 | border-bottom-color: transparent; 9 | } 10 | 11 | .docs-first-section { 12 | background-image: linear-gradient(rgba($body-color,.03), rgba($body-color,.05)); 13 | } 14 | 15 | .gist-file { 16 | @extend .mb-0; 17 | } 18 | 19 | #lgk-link { 20 | color: #fba161; 21 | transition: color .15s ease-in-out; 22 | 23 | &:hover { 24 | color: lighten(#fba161, 6%); 25 | } 26 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | exports.Ribbon = require("./dist/ReactBootstrapRibbon.js")["default"]; 2 | exports.RibbonGroup = require("./dist/ReactBootstrapRibbonGroup.js")["default"]; 3 | exports.RibbonGroupItem = require("./dist/ReactBootstrapRibbonGroupItem.js")["default"]; 4 | exports.RibbonButton = require("./dist/ReactBootstrapRibbonButton.js")["default"]; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-bootstrap-ribbon", 3 | "version": "4.0.0", 4 | "description": "A ribbon menu for React using Bootstrap", 5 | "main": "index.js", 6 | "scripts": { 7 | "watch": "webpack -d --watch", 8 | "build": "webpack -p", 9 | "serve": "servor ./docs/ index.html 8080", 10 | "start": "concurrently \"npm run serve\" \"npm run watch\" ", 11 | "prepare1": "npx babel ./src/ReactBootstrapRibbon.js -o ./dist/ReactBootstrapRibbon.js", 12 | "prepare2": "npx babel ./src/ReactBootstrapRibbonGroup.js -o ./dist/ReactBootstrapRibbonGroup.js", 13 | "prepare3": "npx babel ./src/ReactBootstrapRibbonGroupItem.js -o ./dist/ReactBootstrapRibbonGroupItem.js", 14 | "prepare4": "npx babel ./src/ReactBootstrapRibbonButton.js -o ./dist/ReactBootstrapRibbonButton.js", 15 | "prepare5": "cpy ./src/react-bootstrap-ribbon.css ./dist", 16 | "dist": "npm run prepare1 | npm run prepare2 | npm run prepare3 | npm run prepare4 | npm run prepare5", 17 | "prepublish": "npm run dist" 18 | }, 19 | "files": [ 20 | "dist" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/lgkonline/react-bootstrap-ribbon.git" 25 | }, 26 | "author": { 27 | "name": "Lars Gerrit Kliesing // LGK", 28 | "url": "https://lgk.io" 29 | }, 30 | "keywords": [ 31 | "react", 32 | "bootstrap", 33 | "ribbon", 34 | "ribbon-interface", 35 | "ui", 36 | "bootstrap4", 37 | "css", 38 | "javascript", 39 | "ribbon-menu", 40 | "microsoft" 41 | ], 42 | "license": "MIT", 43 | "homepage": "https://ribbon.lgk.io", 44 | "dependencies": { 45 | "react": "^16.13.1", 46 | "react-dom": "^16.13.1" 47 | }, 48 | "peerDependencies": { 49 | "react-bootstrap": "^1.0.0", 50 | "bootstrap": "^4.4.1" 51 | }, 52 | "devDependencies": { 53 | "@babel/cli": "^7.8.4", 54 | "@babel/core": "^7.9.0", 55 | "@babel/preset-env": "^7.9.0", 56 | "@babel/preset-react": "^7.9.4", 57 | "babel-loader": "^8.1.0", 58 | "babel-polyfill": "^6.26.0", 59 | "bootstrap": "^4.4.1", 60 | "concurrently": "^5.1.0", 61 | "cpy-cli": "^3.1.0", 62 | "css-loader": "^3.4.2", 63 | "mini-css-extract-plugin": "^0.9.0", 64 | "node-sass": "^4.13.1", 65 | "optimize-css-assets-webpack-plugin": "^5.0.3", 66 | "prop-types": "^15.7.2", 67 | "react-bootstrap": "^1.0.0", 68 | "react-embed-gist": "^1.0.10", 69 | "sass-loader": "^8.0.2", 70 | "servor": "^3.2.0", 71 | "terser-webpack-plugin": "^2.3.5", 72 | "webpack": "^4.42.1", 73 | "webpack-cli": "^3.3.11" 74 | } 75 | } -------------------------------------------------------------------------------- /preview_desktop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/preview_desktop.jpg -------------------------------------------------------------------------------- /preview_desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/preview_desktop.png -------------------------------------------------------------------------------- /preview_mobile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/preview_mobile.jpg -------------------------------------------------------------------------------- /preview_mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lgkonline/react-bootstrap-ribbon/bca8125be14a7d77bcffce3d3fd9e088d41f63cc/preview_mobile.png -------------------------------------------------------------------------------- /src/ReactBootstrapRibbon.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | 4 | class ReactBootstrapRibbon extends React.Component { 5 | constructor() { 6 | super(); 7 | 8 | this.state = { 9 | mobileCurrentGroup: 0 10 | }; 11 | } 12 | 13 | static get defaultProps() { 14 | return { 15 | height: "8rem", 16 | breakpoint: "md" 17 | }; 18 | } 19 | 20 | handleChange(event) { 21 | this.setState({ mobileCurrentGroup: (event.target.value * 1) }); 22 | } 23 | 24 | render() { 25 | const children = Array.isArray(this.props.children) ? this.props.children : [this.props.children]; 26 | 27 | return ( 28 |
29 |
30 |
31 |
32 | 35 |
36 | 37 | {children.map((item, index) => { 38 | return ( 39 |
40 |
41 | {item.props.children} 42 |
43 |
44 | ); 45 | })} 46 |
47 |
48 | 49 |
50 |
51 |
52 | {this.props.children} 53 |
54 |
55 |
56 |
57 | ); 58 | } 59 | } 60 | 61 | ReactBootstrapRibbon.propTypes = { 62 | height: PropTypes.string, 63 | breakpoint: PropTypes.oneOf(["sm", "md", "lg", "xl"]) 64 | }; 65 | 66 | export default ReactBootstrapRibbon; -------------------------------------------------------------------------------- /src/ReactBootstrapRibbonButton.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | class ReactBootstrapRibbonButton extends React.Component { 4 | render() { 5 | return ( 6 | 9 | ); 10 | } 11 | } 12 | 13 | export default ReactBootstrapRibbonButton; -------------------------------------------------------------------------------- /src/ReactBootstrapRibbonGroup.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | class ReactBootstrapRibbonGroup extends React.Component { 4 | render() { 5 | return ( 6 |
7 |
8 |
9 |
10 | {this.props.children} 11 |
12 |
13 |
14 | {this.props.title} 15 |
16 |
17 |
18 | ); 19 | } 20 | } 21 | 22 | export default ReactBootstrapRibbonGroup; -------------------------------------------------------------------------------- /src/ReactBootstrapRibbonGroupItem.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | class ReactBootstrapRibbonGroupItem extends React.Component { 4 | render() { 5 | return ( 6 |
7 | {this.props.children} 8 |
9 | ); 10 | } 11 | } 12 | 13 | export default ReactBootstrapRibbonGroupItem; -------------------------------------------------------------------------------- /src/react-bootstrap-ribbon.css: -------------------------------------------------------------------------------- 1 | .ribbon-col:not(:last-child) .ribbon-group { 2 | box-shadow: inset -1px 0 1px rgba(0,0,0,.1); 3 | } 4 | 5 | .ribbon-group-title { 6 | background-color: rgba(0,0,0,.1); 7 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | // const globAll = require("glob-all"); 3 | const TerserJSPlugin = require("terser-webpack-plugin"); 4 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 5 | const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); 6 | // const PurgecssPlugin = require("purgecss-webpack-plugin"); 7 | 8 | const PATHS = { 9 | src: path.join(__dirname, "docs/src"), 10 | dist: path.join(__dirname, "docs/public") 11 | }; 12 | 13 | module.exports = { 14 | context: PATHS.src, 15 | entry: { 16 | "main": "./index.js", 17 | "dark": "./dark.scss" 18 | }, 19 | output: { 20 | path: PATHS.dist, 21 | filename: "[name].js", 22 | }, 23 | module: { 24 | rules: [ 25 | { 26 | test: /\.js$/, 27 | exclude: /node_modules/, 28 | use: [ 29 | "babel-loader", 30 | ], 31 | }, 32 | { 33 | test: /\.s?css$/i, 34 | use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], 35 | }, 36 | ], 37 | }, 38 | resolve: { 39 | modules: [ 40 | path.join(__dirname, "node_modules"), 41 | ], 42 | }, 43 | optimization: { 44 | minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})], 45 | }, 46 | plugins: [ 47 | new MiniCssExtractPlugin({ 48 | filename: "[name].css", 49 | chunkFilename: "[name].css" 50 | }), 51 | // new PurgecssPlugin({ 52 | // paths: globAll.sync([`${PATHS.src}/**/*`, `${PATHS.dist}/**/*`], { nodir: true }) 53 | // }) 54 | ] 55 | }; --------------------------------------------------------------------------------