├── src ├── kits │ └── default │ │ ├── src │ │ ├── sass │ │ │ ├── base │ │ │ │ ├── .gitkeep │ │ │ │ ├── _mixins.scss │ │ │ │ ├── _functions.scss │ │ │ │ ├── _helpers.scss │ │ │ │ ├── _typography.scss │ │ │ │ ├── _elements.scss │ │ │ │ └── _variables.scss │ │ │ ├── block │ │ │ │ └── _block.scss │ │ │ ├── content │ │ │ │ ├── .gitkeep │ │ │ │ ├── _node.page.scss │ │ │ │ └── _node.article.scss │ │ │ ├── layout │ │ │ │ ├── .gitkeep │ │ │ │ ├── _page.footer.scss │ │ │ │ ├── _page.header.scss │ │ │ │ └── _page.content.scss │ │ │ └── default.style.scss │ │ ├── components │ │ │ └── node │ │ │ │ ├── _node.scss │ │ │ │ └── node.twig │ │ └── js │ │ │ └── default.script.js │ │ ├── templates │ │ ├── form │ │ │ └── README.txt │ │ ├── menu │ │ │ └── README.txt │ │ ├── block │ │ │ └── README.txt │ │ ├── content │ │ │ ├── README.txt │ │ │ └── node.html.twig │ │ ├── field │ │ │ └── README.txt │ │ ├── system │ │ │ └── README.txt │ │ ├── views │ │ │ └── README.txt │ │ ├── comment │ │ │ └── README.txt │ │ ├── page │ │ │ └── README.txt │ │ ├── user │ │ │ └── README.txt │ │ └── README.txt │ │ ├── includes │ │ ├── theme.inc │ │ ├── form.inc │ │ ├── menu.inc │ │ ├── user.inc │ │ ├── view.inc │ │ ├── block.inc │ │ ├── comment.inc │ │ ├── content.inc │ │ └── field.inc │ │ ├── screenshot.png │ │ ├── .gitignore │ │ ├── config │ │ └── schema │ │ │ └── default.schema.yml │ │ ├── default.libraries.yml │ │ ├── default.theme │ │ ├── default.breakpoints.yml │ │ ├── default.info.yml │ │ ├── README.md │ │ ├── package.json │ │ └── webpack.mix.js ├── components │ ├── offcanvas │ │ └── _offcanvas.scss │ ├── forum │ │ └── _forum.scss │ ├── form │ │ └── _form.scss │ ├── card │ │ └── card.twig │ ├── navbar │ │ ├── _navbar.scss │ │ ├── navbar-brand.twig │ │ └── navbar.twig │ ├── figure │ │ └── figure.twig │ ├── image │ │ └── image.twig │ ├── button │ │ └── button.twig │ ├── breadcrumb │ │ └── breadcrumb.twig │ ├── dropdown │ │ └── dropdown-menu.twig │ ├── field │ │ └── field.twig │ ├── block │ │ └── block.twig │ ├── badge │ │ └── badge.twig │ ├── alert │ │ └── alert.twig │ ├── table │ │ └── table.twig │ ├── nav │ │ └── nav.twig │ └── pagination │ │ └── pagination.twig ├── sass │ ├── radix.style.scss │ └── radix.bootstrap.scss └── SubThemeGenerator.php ├── screenshot.png ├── templates ├── menu │ ├── menu.html.twig │ ├── menu--main.html.twig │ ├── menu--account.html.twig │ ├── menu-local-task.html.twig │ └── menu-local-tasks.html.twig ├── block │ ├── block--system-main-block.html.twig │ ├── block.html.twig │ ├── block--system-menu-block.html.twig │ ├── block--local-tasks-block.html.twig │ └── block--system-branding-block.html.twig ├── region │ └── region.html.twig ├── form │ ├── input--radio.html.twig │ ├── input--checkbox.html.twig │ ├── textarea.html.twig │ ├── form--search-block-form.html.twig │ ├── radios.html.twig │ ├── form.html.twig │ ├── input--submit.html.twig │ ├── input.html.twig │ ├── details.html.twig │ ├── select.html.twig │ ├── form-element--radio.html.twig │ ├── form-element--checkbox.html.twig │ ├── fieldset.html.twig │ └── form-element.html.twig ├── field │ ├── image.html.twig │ ├── filter-caption.html.twig │ ├── field--field-tags.html.twig │ ├── field--comment.html.twig │ └── field.html.twig ├── navigation │ ├── breadcrumb.html.twig │ ├── pager.html.twig │ ├── menu-local-action.html.twig │ ├── links.html.twig │ └── links--dropbutton.html.twig ├── views │ ├── views-mini-pager.html.twig │ └── views-view-table.html.twig ├── content │ ├── page-title.html.twig │ ├── node--forum--full.html.twig │ ├── node.html.twig │ └── comment.html.twig ├── user │ ├── user.html.twig │ └── forum-submitted.html.twig ├── misc │ └── status-messages.html.twig ├── page │ └── page.html.twig └── dataset │ ├── table.html.twig │ └── forum-list.html.twig ├── .gitignore ├── assets ├── mix-manifest.json └── css │ └── radix.style.css ├── config └── schema │ └── radix.schema.yml ├── drush.services.yml ├── radix.theme ├── includes ├── user.inc ├── suggestions.inc ├── view.inc ├── field.inc ├── block.inc ├── form.inc └── menu.inc ├── radix.libraries.yml ├── radix.info.yml ├── composer.json ├── package.json ├── webpack.mix.js ├── README.md ├── CHANGELOG.txt ├── radix.drush.inc └── Commands └── radix └── SubThemeCommands.php /src/kits/default/src/sass/base/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/base/_mixins.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/block/_block.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/content/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/layout/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/base/_functions.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/base/_helpers.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/base/_typography.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/kits/default/templates/form/README.txt: -------------------------------------------------------------------------------- 1 | Place form template files here. 2 | -------------------------------------------------------------------------------- /src/kits/default/templates/menu/README.txt: -------------------------------------------------------------------------------- 1 | Place menu template files here. 2 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radixtheme/radix/HEAD/screenshot.png -------------------------------------------------------------------------------- /src/kits/default/templates/block/README.txt: -------------------------------------------------------------------------------- 1 | Place block template files here. 2 | -------------------------------------------------------------------------------- /src/kits/default/templates/content/README.txt: -------------------------------------------------------------------------------- 1 | Place node template files here. 2 | -------------------------------------------------------------------------------- /src/kits/default/templates/field/README.txt: -------------------------------------------------------------------------------- 1 | Place field template files here. 2 | -------------------------------------------------------------------------------- /src/kits/default/templates/system/README.txt: -------------------------------------------------------------------------------- 1 | Place system template files here. 2 | -------------------------------------------------------------------------------- /src/kits/default/templates/views/README.txt: -------------------------------------------------------------------------------- 1 | Place views template files here. 2 | -------------------------------------------------------------------------------- /src/kits/default/templates/comment/README.txt: -------------------------------------------------------------------------------- 1 | Place comment template files here. 2 | -------------------------------------------------------------------------------- /src/kits/default/templates/page/README.txt: -------------------------------------------------------------------------------- 1 | Place page and region template files here. 2 | -------------------------------------------------------------------------------- /src/kits/default/templates/user/README.txt: -------------------------------------------------------------------------------- 1 | Place user and profile template files here. 2 | -------------------------------------------------------------------------------- /src/components/offcanvas/_offcanvas.scss: -------------------------------------------------------------------------------- 1 | #drupal-off-canvas { 2 | box-sizing: initial; 3 | } 4 | -------------------------------------------------------------------------------- /src/kits/default/templates/README.txt: -------------------------------------------------------------------------------- 1 | 2 | This directory should be used to place template files. 3 | -------------------------------------------------------------------------------- /src/kits/default/includes/theme.inc: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /templates/form/input--checkbox.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a checkbox input. 5 | */ 6 | #} 7 | 8 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/layout/_page.footer.scss: -------------------------------------------------------------------------------- 1 | // Page: Footer 2 | // ----------------------------------------------------------------------------- 3 | .page__footer { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/layout/_page.header.scss: -------------------------------------------------------------------------------- 1 | // Page: Header 2 | // ----------------------------------------------------------------------------- 3 | .page__header { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/layout/_page.content.scss: -------------------------------------------------------------------------------- 1 | // Page: Content 2 | // ----------------------------------------------------------------------------- 3 | .page__content { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/kits/default/templates/content/node.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Node. 5 | */ 6 | #} 7 | {% extends '@RADIX_SUBTHEME_MACHINE_NAME/node/node.twig' %} 8 | 9 | -------------------------------------------------------------------------------- /templates/block/block.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a block. 5 | */ 6 | #} 7 | {% include '@radix/block/block.twig' with { 8 | html_tag: 'div', 9 | } %} 10 | -------------------------------------------------------------------------------- /src/components/forum/_forum.scss: -------------------------------------------------------------------------------- 1 | .forum { 2 | 3 | &__last-reply { 4 | width: 20%; 5 | } 6 | } 7 | 8 | .forum-list { 9 | 10 | &__forum { 11 | width: 60%; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/kits/default/src/components/node/_node.scss: -------------------------------------------------------------------------------- 1 | // Custom style for the Node component. 2 | // ----------------------------------------------------------------------------- 3 | .node { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /templates/field/image.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for an image field. 5 | */ 6 | #} 7 | {% include '@radix/image/image.twig' with { 8 | responsive: true, 9 | } %} 10 | -------------------------------------------------------------------------------- /templates/form/textarea.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a textarea form element. 5 | */ 6 | #} 7 | {{ value }} 8 | -------------------------------------------------------------------------------- /templates/menu/menu--main.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * Template for the main menu. 4 | */ 5 | #} 6 | {% include '@radix/nav/nav.twig' with { 7 | utility_classes: [ 8 | 'navbar-nav', 9 | ], 10 | } %} 11 | -------------------------------------------------------------------------------- /templates/block/block--system-menu-block.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for the system menu block. 5 | */ 6 | #} 7 | {% include '@radix/block/block.twig' with { 8 | html_tag: 'div' 9 | } %} 10 | -------------------------------------------------------------------------------- /templates/form/form--search-block-form.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for the Search block form. 5 | */ 6 | #} 7 | 8 | {{ children }} 9 | 10 | -------------------------------------------------------------------------------- /templates/menu/menu--account.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * Template for the account menu. 4 | */ 5 | #} 6 | {% include '@radix/nav/nav.twig' with { 7 | utility_classes: [ 8 | 'navbar-nav', 9 | ], 10 | } %} 11 | -------------------------------------------------------------------------------- /templates/navigation/breadcrumb.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for the breadcrumb. 5 | */ 6 | #} 7 | {% include '@radix/breadcrumb/breadcrumb.twig' with { 8 | breadcrumb: breadcrumb, 9 | } %} 10 | -------------------------------------------------------------------------------- /templates/navigation/pager.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a pager. 5 | */ 6 | #} 7 | {% include '@radix/pagination/pagination.twig' with { 8 | items: items, 9 | alignment: 'center' 10 | } %} 11 | -------------------------------------------------------------------------------- /src/kits/default/config/schema/default.schema.yml: -------------------------------------------------------------------------------- 1 | # Schema for the configuration files of the RADIX_SUBTHEME_NAME theme. 2 | 3 | RADIX_SUBTHEME_MACHINE_NAME.settings: 4 | type: theme_settings 5 | label: 'RADIX_SUBTHEME_NAME settings' 6 | -------------------------------------------------------------------------------- /src/components/form/_form.scss: -------------------------------------------------------------------------------- 1 | fieldset.card { 2 | 3 | legend { 4 | font-size: 1rem; 5 | } 6 | } 7 | 8 | .form-check { 9 | margin-bottom: 1rem; 10 | 11 | .form-radios &, 12 | .form-checkboxes & { 13 | margin-bottom: 0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /templates/field/filter-caption.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Figure. 5 | */ 6 | #} 7 | {% include '@radix/figure/figure.twig' with { 8 | image: node, 9 | caption: caption, 10 | utility_classes: classes|split(' '), 11 | } %} 12 | -------------------------------------------------------------------------------- /src/components/card/card.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Card component. 5 | */ 6 | #} 7 |
8 | 9 |
10 | {% block body %} 11 | {{ body }} 12 | {% endblock %} 13 |
14 |
15 | -------------------------------------------------------------------------------- /templates/block/block--local-tasks-block.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for local tasks block. 5 | */ 6 | #} 7 | {% include '@radix/block/block.twig' with { 8 | html_tag: 'div', 9 | utility_classes: [ 10 | 'my-3', 11 | ], 12 | }%} 13 | -------------------------------------------------------------------------------- /templates/views/views-mini-pager.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a mini pager. 5 | */ 6 | #} 7 | {% include '@radix/pagination/pagination.twig' with { 8 | items: items, 9 | alignment: 'center', 10 | utility_classes: ['mt-3'], 11 | } %} 12 | -------------------------------------------------------------------------------- /templates/content/page-title.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for the page title. 5 | */ 6 | #} 7 | {{ title_prefix }} 8 | {% if title %} 9 | {{ title }} 10 | {% endif %} 11 | {{ title_suffix }} 12 | -------------------------------------------------------------------------------- /templates/menu/menu-local-task.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a local task link. 5 | */ 6 | #} 7 | 8 | {{ link['#title'] }} 9 | 10 | -------------------------------------------------------------------------------- /src/sass/radix.style.scss: -------------------------------------------------------------------------------- 1 | // Components 2 | // ----------------------------------------------------------------------------- 3 | @import "../components/navbar/navbar"; 4 | @import "../components/form/form"; 5 | @import "../components/forum/forum"; 6 | @import "../components/offcanvas/offcanvas"; 7 | -------------------------------------------------------------------------------- /src/kits/default/default.libraries.yml: -------------------------------------------------------------------------------- 1 | style: 2 | version: VERSION 3 | css: 4 | theme: 5 | assets/css/RADIX_SUBTHEME_MACHINE_NAME.style.css: {} 6 | js: 7 | assets/js/RADIX_SUBTHEME_MACHINE_NAME.script.js: {} 8 | dependencies: 9 | - core/jquery 10 | - core/drupal 11 | -------------------------------------------------------------------------------- /src/kits/default/src/js/default.script.js: -------------------------------------------------------------------------------- 1 | import 'popper.js'; 2 | import 'bootstrap'; 3 | 4 | (function () { 5 | 6 | 'use strict'; 7 | 8 | Drupal.behaviors.helloWorld = { 9 | attach: function (context) { 10 | console.log('Hello World'); 11 | } 12 | }; 13 | 14 | })(jQuery, Drupal); 15 | -------------------------------------------------------------------------------- /templates/field/field--field-tags.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for field_tags. 5 | */ 6 | #} 7 | {% for item in items %} 8 | {% include '@radix/badge/badge.twig' with { 9 | type: 'light', 10 | content: item.content['#title'], 11 | url: item.content['#url'], 12 | } %} 13 | {% endfor %} 14 | -------------------------------------------------------------------------------- /radix.theme: -------------------------------------------------------------------------------- 1 | 12 | {% block content %} 13 | {{- content|without('summary') -}} 14 | {% endblock %} 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/components/navbar/_navbar.scss: -------------------------------------------------------------------------------- 1 | .navbar { 2 | 3 | .form-inline { 4 | 5 | .form-actions { 6 | display: none; 7 | } 8 | } 9 | } 10 | 11 | .toolbar-oriented .toolbar-bar { 12 | z-index: 1200; 13 | } 14 | 15 | .toolbar-horizontal { 16 | 17 | .toolbar-menu { 18 | 19 | &.nav { 20 | float: left; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /assets/css/radix.style.css: -------------------------------------------------------------------------------- 1 | .navbar .form-inline .form-actions{display:none}.toolbar-oriented .toolbar-bar{z-index:1200}.toolbar-horizontal .toolbar-menu.nav{float:left}fieldset.card legend{font-size:1rem}.form-check{margin-bottom:1rem}.form-checkboxes .form-check,.form-radios .form-check{margin-bottom:0}.forum__last-reply{width:20%}.forum-list__forum{width:60%}#drupal-off-canvas{box-sizing:initial} -------------------------------------------------------------------------------- /templates/navigation/menu-local-action.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Theme override for a single local action link. 5 | * 6 | * Available variables: 7 | * - attributes: HTML attributes for the wrapper element. 8 | * - link: A rendered link element. 9 | * 10 | * @see template_preprocess_menu_local_action() 11 | */ 12 | #} 13 |
14 | {{ link }} 15 |
16 | -------------------------------------------------------------------------------- /templates/form/radios.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Theme override for a 'radios' #type form element. 5 | * 6 | * Available variables 7 | * - attributes: A list of HTML attributes for the wrapper element. 8 | * - children: The rendered radios. 9 | * 10 | * @see template_preprocess_radios() 11 | */ 12 | #} 13 | {{ children }} 14 | -------------------------------------------------------------------------------- /templates/form/form.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a 'form' element. 5 | * 6 | * Available variables 7 | * - attributes: A list of HTML attributes for the wrapper element. 8 | * - children: The child elements of the form. 9 | * 10 | * @see template_preprocess_form() 11 | * 12 | * @ingroup themeable 13 | */ 14 | #} 15 | 16 | {{ children }} 17 | 18 | -------------------------------------------------------------------------------- /templates/menu/menu-local-tasks.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template primary and secondary local tasks. 5 | */ 6 | #} 7 | {% if primary %} 8 |

{{ 'Primary tabs'|t }}

9 | 10 | {% endif %} 11 | {% if secondary %} 12 |

{{ 'Secondary tabs'|t }}

13 | 14 | {% endif %} 15 | -------------------------------------------------------------------------------- /radix.libraries.yml: -------------------------------------------------------------------------------- 1 | bootstrap: 2 | version: VERSION 3 | js: 4 | node_modules/popper.js/dist/umd/popper.min.js: {} 5 | node_modules/bootstrap/dist/js/bootstrap.min.js: {} 6 | css: 7 | theme: 8 | assets/css/radix.bootstrap.css: {} 9 | dependencies: 10 | - core/jquery 11 | 12 | style: 13 | version: VERSION 14 | css: 15 | theme: 16 | assets/css/radix.style.css: {} 17 | dependencies: 18 | - core/jquery 19 | - core/drupal 20 | -------------------------------------------------------------------------------- /templates/form/input--submit.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Theme override for an 'input' #type form element. 5 | * 6 | * Available variables: 7 | * - attributes: A list of HTML attributes for the input element. 8 | * - children: Optional additional rendered elements. 9 | * 10 | * @see template_preprocess_input() 11 | */ 12 | #} 13 | {% include '@radix/button/button.twig' with { 14 | type: 'primary', 15 | tag: 'input', 16 | attributes: attributes, 17 | } %} 18 | -------------------------------------------------------------------------------- /templates/form/input.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Theme override for an 'input' #type form element. 5 | * 6 | * Available variables: 7 | * - attributes: A list of HTML attributes for the input element. 8 | * - children: Optional additional rendered elements. 9 | * 10 | * @see template_preprocess_input() 11 | */ 12 | #} 13 | {% if type != 'file' %} 14 | {% set css_classes = ['form-control'] %} 15 | {% endif %} 16 | 17 | {{ children }} 18 | -------------------------------------------------------------------------------- /templates/block/block--system-branding-block.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for the branding block. 5 | */ 6 | #} 7 | {% embed '@radix/block/block.twig' with { 8 | html_tag: 'div', 9 | } %} 10 | 11 | {% block content %} 12 | {% include '@radix/navbar/navbar-brand.twig' with { 13 | text: site_name, 14 | image: site_logo, 15 | width: 30, 16 | height: 'auto', 17 | path: path(''), 18 | alt: elements.content.site_name['#markup'] ~ ' logo' , 19 | } %} 20 | {% endblock %} 21 | 22 | {% endembed %} 23 | -------------------------------------------------------------------------------- /src/components/figure/figure.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Figure component. 5 | * 6 | * Available config: 7 | * - utility_classes: An array of utility classes. 8 | * - align: left|right|center 9 | * - responsive: true|false 10 | */ 11 | #} 12 | {% set classes = [ 13 | 'figure', 14 | ]|merge(utility_classes ? utility_classes : []) %} 15 | 16 | 17 | {{ image }} 18 | 19 | {% if caption %} 20 |
{{ caption }}
21 | {% endif %} 22 | 23 | -------------------------------------------------------------------------------- /src/components/image/image.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for an Image component. 5 | * 6 | * Available config: 7 | * - utility_classes: An array of utility classes. 8 | * - align: left|right|center 9 | * - responsive: true|false 10 | */ 11 | #} 12 | {% set classes = [ 13 | responsive ? 'img-fluid' : 'img-thumbnail', 14 | align == 'left' ? 'float-left', 15 | align == 'right' ? 'float-right', 16 | align == 'center' ? 'mx-auto d-block', 17 | ]|merge(utility_classes ? utility_classes : []) %} 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/components/button/button.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a button component. 5 | * 6 | * Available config: 7 | * - type: primary | secondary | success | danger | warning | info | light | dark 8 | * - outline: true | false 9 | * - tag: button, a, input 10 | * - value: string 11 | * - attributes: Attributes array. 12 | */ 13 | #} 14 | {% set css_classes = [ 15 | 'btn', 16 | type ? 'btn-' ~ type 17 | ] %} 18 | {% if tag == 'input' %} 19 | 20 | {% else %} 21 | <{{ tag }}>{{ value }} 22 | {% endif %} 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/kits/default/src/components/node/node.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Node component. 5 | */ 6 | #} 7 | {% 8 | set classes = [ 9 | 'node', 10 | node.isPromoted() ? 'node--promoted', 11 | node.isSticky() ? 'node--sticky', 12 | not node.isPublished() ? 'node--unpublished', 13 | node.bundle|clean_class, 14 | node.bundle|clean_class ~ '--' ~ view_mode|clean_class, 15 | ] 16 | %} 17 | 18 | {{ title_prefix }} 19 | {{ title_suffix }} 20 | 21 | {% block content %} 22 | {{ content }} 23 | {% endblock %} 24 | 25 | -------------------------------------------------------------------------------- /templates/field/field--comment.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for the comment field. 5 | */ 6 | #} 7 | 8 | {{ title_prefix }} 9 | {{ title_suffix }} 10 | 11 | {{ comments }} 12 | 13 | {% if comment_form %} 14 |
15 |
16 |
17 |
18 |
19 | {{ 'Add new comment'|t }} 20 |
21 |
22 | {{ comment_form }} 23 |
24 |
25 |
26 |
27 | {% endif %} 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/kits/default/default.breakpoints.yml: -------------------------------------------------------------------------------- 1 | default.xs: 2 | label: XS 3 | mediaQuery: '(max-width: 575px)' 4 | weight: 0 5 | multipliers: 6 | - 1x 7 | default.sm: 8 | label: SM 9 | mediaQuery: '(min-width: 576px) and (max-width: 767px)' 10 | weight: 1 11 | multipliers: 12 | - 1x 13 | default.md: 14 | label: MD 15 | mediaQuery: '(min-width: 768px) and (max-width: 991px)' 16 | weight: 2 17 | multipliers: 18 | - 1x 19 | default.lg: 20 | label: LG 21 | mediaQuery: '(min-width: 992px) and (max-width: 1199px)' 22 | weight: 3 23 | multipliers: 24 | - 1x 25 | default.xl: 26 | label: XL 27 | mediaQuery: '(min-width: 1200px)' 28 | weight: 4 29 | multipliers: 30 | - 1x 31 | -------------------------------------------------------------------------------- /src/components/breadcrumb/breadcrumb.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Breadcrumb component. 5 | * 6 | * Available config: 7 | * - utility_classes: An array of utility classes. 8 | */ 9 | #} 10 | {% if breadcrumb %} 11 | 24 | {% endif %} 25 | -------------------------------------------------------------------------------- /radix.info.yml: -------------------------------------------------------------------------------- 1 | name: Radix 2 | type: theme 3 | base theme: false 4 | description: Responsive base theme for Drupal. 5 | screenshot: screenshot.png 6 | core_version_requirement: ^8.7.7 || ^9.0 7 | 8 | stylesheets-remove: 9 | - system.theme.css 10 | - system.menus.css 11 | - system.admin.css 12 | 13 | libraries: 14 | - radix/bootstrap 15 | - radix/style 16 | 17 | libraries-override: 18 | seven/global-styling: false 19 | 20 | regions: 21 | navbar_branding: Navbar branding 22 | navbar_left: Navbar left 23 | navbar_right: Navbar right 24 | header: Header 25 | content: Content 26 | page_bottom: Page bottom 27 | footer: Footer 28 | 29 | components: 30 | namespaces: 31 | radix: src/components 32 | -------------------------------------------------------------------------------- /templates/navigation/links.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for links. 5 | */ 6 | #} 7 | {% embed '@radix/nav/nav.twig' with { 8 | items: links, 9 | } %} 10 | 11 | {% block items %} 12 | {%- for item in links -%} 13 | 14 | {%- if item.link -%} 15 | {{ item.link['#title'] }} 16 | {%- elseif item.text_attributes -%} 17 | {{ item.text }} 18 | {%- else -%} 19 | {{ item.text }} 20 | {%- endif -%} 21 | 22 | {%- endfor -%} 23 | {% endblock %} 24 | 25 | {% endembed %} 26 | -------------------------------------------------------------------------------- /src/components/dropdown/dropdown-menu.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Dropdown menu component. 5 | */ 6 | #} 7 | 21 | -------------------------------------------------------------------------------- /templates/user/forum-submitted.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Theme override for a forum post submission string. 5 | * 6 | * The submission string indicates when and by whom a topic was submitted. 7 | * 8 | * Available variables: 9 | * - author: The author of the post. 10 | * - time: How long ago the post was created. 11 | * - topic: An object with the raw data of the post. Potentially unsafe. Be 12 | * sure to clean this data before printing. 13 | * 14 | * @see template_preprocess_forum_submitted() 15 | */ 16 | #} 17 | {% if time %} 18 | {% trans %}{{ author }} {{ time }} ago{% endtrans %} 19 | 20 | {% else %} 21 | {{ 'n/a'|t }} 22 | {% endif %} 23 | -------------------------------------------------------------------------------- /templates/form/details.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Theme override for a details element. 5 | */ 6 | #} 7 | {% set css_classes = [ 8 | 'card', 9 | 'mb-3', 10 | ] %} 11 | 12 | 13 | {% 14 | set summary_classes = [ 15 | 'card-header', 16 | required ? 'js-form-required', 17 | required ? 'form-required', 18 | ] 19 | %} 20 | {%- if title -%} 21 | 22 | {{ title }} 23 | 24 | {%- endif -%} 25 | 26 | {% if errors %} 27 |
28 | {{ errors }} 29 |
30 | {% endif %} 31 | 32 |
33 | {{ description }} 34 | {{ children }} 35 | {{ value }} 36 |
37 | 38 | -------------------------------------------------------------------------------- /src/kits/default/default.info.yml: -------------------------------------------------------------------------------- 1 | name: RADIX_SUBTHEME_NAME 2 | description: RADIX_SUBTHEME_DESCRIPTION 3 | screenshot: screenshot.png 4 | core_version_requirement: ^8.7.7 || ^9.0 5 | version: VERSION 6 | engine: twig 7 | type: theme 8 | base theme: radix 9 | hidden: true 10 | 11 | regions: 12 | navbar_branding: Navbar branding 13 | navbar_left: Navbar left 14 | navbar_right: Navbar right 15 | header: Header 16 | content: Content 17 | page_bottom: Page bottom 18 | footer: Footer 19 | 20 | libraries: 21 | - radix/style 22 | - RADIX_SUBTHEME_MACHINE_NAME/style 23 | 24 | libraries-override: 25 | radix/bootstrap: false 26 | 27 | ckeditor_stylesheets: 28 | - assets/css/RADIX_SUBTHEME_MACHINE_NAME.style.css 29 | 30 | components: 31 | namespaces: 32 | RADIX_SUBTHEME_MACHINE_NAME: src/components 33 | -------------------------------------------------------------------------------- /src/kits/default/README.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | RADIX_SUBTHEME_NAME theme uses [Webpack](https://webpack.js.org) to compile and 4 | bundle SASS and JS. 5 | 6 | #### Step 1 7 | Make sure you have Node and npm installed. 8 | You can read a guide on how to install node here: 9 | https://docs.npmjs.com/getting-started/installing-node 10 | 11 | If you prefer to use [Yarn](https://yarnpkg.com) instead of npm, install Yarn by 12 | following the guide [here](https://yarnpkg.com/docs/install). 13 | 14 | #### Step 2 15 | Go to the root of RADIX_SUBTHEME_NAME theme and run the following commands: `npm 16 | install` or `yarn install`. 17 | 18 | #### Step 3 19 | Update `proxy` in **webpack.mix.json**. 20 | 21 | #### Step 4 22 | Run the following command to compile Sass and watch for changes: `npm run watch` 23 | or `yarn watch`. 24 | -------------------------------------------------------------------------------- /src/components/field/field.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a field. 5 | */ 6 | #} 7 | 8 | {% if label_hidden %} 9 | {% if multiple %} 10 | 11 | {% for item in items %} 12 | {{ item.content }} 13 | {% endfor %} 14 | 15 | {% else %} 16 | {% for item in items %} 17 | {{ item.content }} 18 | {% endfor %} 19 | {% endif %} 20 | {% else %} 21 | 22 | {{ label }} 23 | {% if multiple %} 24 |
25 | {% endif %} 26 | {% for item in items %} 27 | {{ item.content }}
28 | {% endfor %} 29 | {% if multiple %} 30 | 31 | {% endif %} 32 | 33 | {% endif %} 34 | -------------------------------------------------------------------------------- /src/components/block/block.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Block component. 5 | * 6 | * Available config: 7 | * - html_tag: The HTML tag for the block. 8 | * - utility_classes: An array of utility classes. 9 | */ 10 | #} 11 | {% set classes = [ 12 | 'block', 13 | bundle ? 'block--' ~ bundle|clean_class, 14 | id ? 'block--' ~ id|replace({"_": "-"})|clean_class, 15 | ]|merge(utility_classes ? utility_classes : []) %} 16 | 17 | {% if html_tag %} 18 | <{{ html_tag }}{{ attributes|without('id').addClass(classes) }}> 19 | {% endif %} 20 | 21 | {{ title_prefix }} 22 | {% if label %} 23 | {% block label %} 24 | {{ label }} 25 | {% endblock %} 26 | {% endif %} 27 | {{ title_suffix }} 28 | 29 | {% block content %} 30 | {{ content }} 31 | {% endblock %} 32 | 33 | {% if html_tag %} 34 | 35 | {% endif %} 36 | -------------------------------------------------------------------------------- /templates/content/node--forum--full.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a forum node in full display mode. 5 | */ 6 | #} 7 | {% extends 'node.html.twig' %} 8 | {% block content %} 9 |
10 |
11 | {% if display_submitted %} 12 |
13 | 14 | {% trans %}Posted by {{ author_name }} on {{ date }}{% endtrans %} 15 | {{ metadata }} 16 |
17 | 18 | {% endif %} 19 | 20 | {% if content.taxonomy_forums %} 21 |
22 | {{ content.taxonomy_forums }} 23 |
24 | {% endif %} 25 | 26 | {{ content|without('taxonomy_forums', 'comment_forum') }} 27 | 28 |
29 | 30 | {{ content.comment_forum }} 31 |
32 | 33 | {% endblock %} 34 | -------------------------------------------------------------------------------- /includes/suggestions.inc: -------------------------------------------------------------------------------- 1 | getParameter('node')) { 17 | if (is_numeric($node)) { 18 | $node = Node::load($node); 19 | } 20 | 21 | $suggestions[] = 'page__node__' . $node->bundle(); 22 | } 23 | } 24 | 25 | /** 26 | * Implements hook_theme_suggestions_hook_alter(). 27 | */ 28 | function radix_theme_suggestions_user_alter(array &$suggestions, array $variables) { 29 | // Add a suggestion based on the view mode. 30 | $suggestions[] = $variables['theme_hook_original'] . '__' . $variables['elements']['#view_mode']; 31 | } 32 | -------------------------------------------------------------------------------- /src/components/badge/badge.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Badge component. 5 | * 6 | * Available config: 7 | * - html_tag: The HTML tag to use for the bade. Defaults to span. 8 | * - type: primary | secondary | success | danger | warning | info | light | dark 9 | * - utility_classes: An array of utility classes. 10 | * - content: The content of the badge. 11 | * - url: if anchor add a url, html_tag will be set to a automatically. 12 | */ 13 | #} 14 | {% set classes = [ 15 | 'badge', 16 | type ? 'badge-' ~ type, 17 | ]|merge(utility_classes ? utility_classes : []) %} 18 | 19 | {% set html_tag = html_tag ?? 'span' %} 20 | 21 | {% if url %} 22 | {% set html_tag = 'a' %} 23 | {% set url = url|render %} 24 | {% endif %} 25 | 26 | {% if content %} 27 | <{{ html_tag }} {{ url ? 'href=' ~ url }} class="{{ classes|join(' ') }}"> 28 | 29 | {% block content %} 30 | {{ content }} 31 | {% endblock %} 32 | 33 | 34 | {% endif %} 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/components/alert/alert.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for Alert component. 5 | * 6 | * Available config: 7 | * - type: primary | secondary | success | danger | warning | info | light | dark 8 | * - heading: string, 9 | * - dimissible: true | false 10 | * - utility_classes: An array of utility classes. 11 | */ 12 | #} 13 | {% set dismissible = dismissible ?? true %} 14 | {% set classes = [ 15 | 'alert', 16 | type ? 'alert-' ~ type, 17 | dismissible ? 'alert-dismissible', 18 | ]|merge(utility_classes ? utility_classes : []) %} 19 | 20 | 35 | -------------------------------------------------------------------------------- /templates/form/select.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Theme override for a select element. 5 | * 6 | * Available variables: 7 | * - attributes: HTML attributes for the select tag. 8 | * - options: The option element children. 9 | * 10 | * @see template_preprocess_select() 11 | */ 12 | #} 13 | {% spaceless %} 14 | 15 | {% for option in options %} 16 | {% if option.type == 'optgroup' %} 17 | 18 | {% for sub_option in option.options %} 19 | 20 | {% endfor %} 21 | 22 | {% elseif option.type == 'option' %} 23 | 24 | {% endif %} 25 | {% endfor %} 26 | 27 | {% endspaceless %} 28 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/base/_elements.scss: -------------------------------------------------------------------------------- 1 | // Headings 2 | // ----------------------------------------------------------------------------- 3 | h1, h2, h3, h4, h5, h6 { 4 | 5 | } 6 | 7 | // Text 8 | // ----------------------------------------------------------------------------- 9 | p { 10 | 11 | } 12 | 13 | // Links 14 | // ----------------------------------------------------------------------------- 15 | a { 16 | 17 | @include hover { 18 | 19 | } 20 | } 21 | 22 | // Lists 23 | // ----------------------------------------------------------------------------- 24 | ol, 25 | ul, 26 | dl { 27 | 28 | } 29 | 30 | // Image 31 | // ----------------------------------------------------------------------------- 32 | img { 33 | 34 | } 35 | 36 | figure { 37 | 38 | } 39 | 40 | figcaption { 41 | 42 | } 43 | 44 | // Other 45 | // ----------------------------------------------------------------------------- 46 | blockquote { 47 | 48 | } 49 | 50 | strong { 51 | 52 | } 53 | 54 | small { 55 | 56 | } 57 | -------------------------------------------------------------------------------- /includes/view.inc: -------------------------------------------------------------------------------- 1 | id(); 15 | $display = $view->current_display; 16 | $suggestions[] = 'views_view__' . $name; 17 | $suggestions[] = 'views_view__' . $name . '__' . $display; 18 | } 19 | 20 | /** 21 | * Implements hook_theme_suggestions_HOOK_alter(). 22 | */ 23 | function radix_theme_suggestions_views_view_unformatted_alter(array &$suggestions, array $variables) { 24 | // Add a suggestion based on the view name and the current display. 25 | $view = $variables['view']; 26 | $name = $view->id(); 27 | $display = $view->current_display; 28 | $suggestions[] = 'views_view_unformatted__' . $name . '__' . $display; 29 | } 30 | -------------------------------------------------------------------------------- /templates/misc/status-messages.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for status messages. 5 | */ 6 | #} 7 | {% set types = { 8 | status: 'success', 9 | warning: 'warning', 10 | error: 'danger', 11 | info: 'info', 12 | } %} 13 | 14 | {% for type, messages in message_list %} 15 |
16 | {% embed '@radix/alert/alert.twig' with { 17 | type: types[type], 18 | } %} 19 | {% block content %} 20 | {% if status_headings[type] %} 21 |

{{ status_headings[type] }}

22 | {% endif %} 23 | {% if messages|length > 1 %} 24 |
    25 | {% for message in messages %} 26 |
  • {{ message }}
  • 27 | {% endfor %} 28 |
29 | {% else %} 30 | {{ messages|first }} 31 | {% endif %} 32 | {% endblock %} 33 | {% endembed %} 34 |
35 | {% endfor %} 36 | -------------------------------------------------------------------------------- /templates/navigation/links--dropbutton.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for links within a dropbutton. 5 | */ 6 | #} 7 |
8 | {% if split %} 9 | {{ button }} 10 | {% endif %} 11 | 12 | {% if links %} 13 | 20 | 31 | {% endif %} 32 |
33 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "drupal/radix", 3 | "description": "Radix is a base theme for Drupal. It has Bootstrap, Sass, BrowserSync and Font Awesome built-in.", 4 | "type": "drupal-theme", 5 | "homepage": "https://www.drupal.org/project/radix", 6 | "authors": [ 7 | { 8 | "name": "Arshad Chummun", 9 | "email": "arshad@chummun.com", 10 | "homepage": "https://arshad.io", 11 | "role": "Maintainer" 12 | }, 13 | { 14 | "name": "Ng Chin Kiong", 15 | "email": "ck@o8.agency", 16 | "homepage": "https://www.o8.agency", 17 | "role": "Maintainer" 18 | } 19 | ], 20 | "support": { 21 | "issues": "https://www.drupal.org/project/issues/radix" 22 | }, 23 | "license": "GPL-2.0-or-later", 24 | "minimum-stability": "dev", 25 | "require": { 26 | "drupal/components": "^2.1" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "Drush\\Commands\\radix\\": "Commands/radix/" 31 | } 32 | }, 33 | "extra": { 34 | "drush": { 35 | "services": { 36 | "drush.services.yml": "^9" 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /templates/content/node.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Node. 5 | */ 6 | #} 7 | {% 8 | set classes = [ 9 | 'node', 10 | node.isPromoted() ? 'node--promoted', 11 | node.isSticky() ? 'node--sticky', 12 | not node.isPublished() ? 'node--unpublished', 13 | node.bundle|clean_class, 14 | node.bundle|clean_class ~ '--' ~ view_mode|clean_class, 15 | ] 16 | %} 17 | 18 | {{ title_prefix }} 19 | {{ title_suffix }} 20 | 21 | {% block content %} 22 | {% if not page %} 23 | 24 | {{ label }} 25 | 26 | {% endif %} 27 | 28 | {% if display_submitted %} 29 |
30 | {{ author_picture }} 31 | 32 | {% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %} 33 | {{ metadata }} 34 | 35 |
36 | {% endif %} 37 | 38 | 39 | {{ content }} 40 | 41 | {% endblock %} 42 | 43 | -------------------------------------------------------------------------------- /templates/form/form-element--radio.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a radio form element. 5 | * 6 | * @ingroup themeable 7 | */ 8 | #} 9 | {% 10 | set classes = [ 11 | 'js-form-item', 12 | 'form-item', 13 | 'js-form-type-' ~ type|clean_class, 14 | 'form-item-' ~ name|clean_class, 15 | 'js-form-item-' ~ name|clean_class, 16 | title_display not in ['after', 'before'] ? 'form-no-label', 17 | disabled == 'disabled' ? 'form-disabled', 18 | errors ? 'form-item--error', 19 | 'form-check', 20 | ] 21 | %} 22 | {% 23 | set description_classes = [ 24 | 'description', 25 | 'form-text', 26 | 'text-muted', 27 | description_display == 'invisible' ? 'visually-hidden', 28 | ] 29 | %} 30 | 31 | {{ children }} 32 | 33 | {{ label }} 34 | 35 | {% if errors %} 36 |
37 | {{ errors }} 38 |
39 | {% endif %} 40 | 41 | {% if description.content %} 42 | 43 | {{ description.content }} 44 | 45 | {% endif %} 46 | 47 | -------------------------------------------------------------------------------- /templates/form/form-element--checkbox.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a checkbox form element. 5 | * 6 | * @ingroup themeable 7 | */ 8 | #} 9 | {% 10 | set classes = [ 11 | 'js-form-item', 12 | 'form-item', 13 | 'js-form-type-' ~ type|clean_class, 14 | 'form-item-' ~ name|clean_class, 15 | 'js-form-item-' ~ name|clean_class, 16 | title_display not in ['after', 'before'] ? 'form-no-label', 17 | disabled == 'disabled' ? 'form-disabled', 18 | errors ? 'form-item--error', 19 | 'form-check', 20 | ] 21 | %} 22 | {% 23 | set description_classes = [ 24 | 'description', 25 | 'form-text', 26 | 'text-muted', 27 | description_display == 'invisible' ? 'visually-hidden', 28 | ] 29 | %} 30 | 31 | {{ children }} 32 | 33 | {{ label }} 34 | 35 | {% if errors %} 36 |
37 | {{ errors }} 38 |
39 | {% endif %} 40 | 41 | {% if description.content %} 42 | 43 | {{ description.content }} 44 | 45 | {% endif %} 46 | 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "radix", 3 | "description": "Responsive base theme for Drupal.", 4 | "private": true, 5 | "scripts": { 6 | "postinstall": "find node_modules/ -name '*.info' -type f -delete", 7 | "dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 8 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "hot": "cross-env NODE_ENV=development webpack-dev-server --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "bootstrap": "4.3.1", 14 | "browser-sync": "^2.26.14", 15 | "browser-sync-webpack-plugin": "^2.0.1", 16 | "cross-env": "^5.2.1", 17 | "laravel-mix": "^5.0.9", 18 | "node-sass": "^4.14.1", 19 | "popper.js": "^1.14.7", 20 | "resolve-url-loader": "^3.1.2", 21 | "sass": "^1.32.11", 22 | "sass-loader": "^8.0.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/kits/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RADIX_SUBTHEME_MACHINE_NAME", 3 | "description": "RADIX_SUBTHEME_DESCRIPTION", 4 | "private": true, 5 | "scripts": { 6 | "postinstall": "find node_modules/ -name '*.info' -type f -delete", 7 | "dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 8 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "hot": "cross-env NODE_ENV=development webpack-dev-server --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "bootstrap": "4.3.1", 14 | "browser-sync": "^2.26.14", 15 | "browser-sync-webpack-plugin": "^2.0.1", 16 | "cross-env": "^5.2.1", 17 | "laravel-mix": "^5.0.9", 18 | "node-sass": "^4.14.1", 19 | "popper.js": "^1.14.7", 20 | "resolve-url-loader": "^3.1.2", 21 | "sass": "^1.32.11", 22 | "sass-loader": "^8.0.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /includes/field.inc: -------------------------------------------------------------------------------- 1 | loadHTML($variables['node']); 37 | if ($image = $doc->getElementsByTagName('img')->item(0)) { 38 | $image->setAttribute('class', 'figure-img img-fluid'); 39 | $variables['node'] = [ 40 | '#markup' => $image->ownerDocument->saveHTML($image), 41 | ]; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/components/navbar/navbar-brand.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for Navbar brand component. 5 | * 6 | * Available config: 7 | * - text: the text to use for the brand. 8 | * - path: the path for the link. Leave blank for no link. 9 | * - image: 10 | * - src: The source of the image 11 | * - width: The width of the image 12 | * - height: The height of the image 13 | * - alt: The alternative text of the image 14 | * - utility_classes: An array of utility classes. 15 | */ 16 | #} 17 | {% import _self as navbar_brand %} 18 | {% set utility_classes = utility_classes|join(' ') %} 19 | 20 | {% if path %} 21 | 22 | {% if image %} 23 | {{ navbar_brand.image(image, width, height, alt) }} 24 | {% endif %} 25 | {{ text }} 26 | 27 | {% else %} 28 | 29 | {% if image %} 30 | {{ navbar_brand.image(image, alt) }} 31 | {% endif %} 32 | {{ text }} 33 | 34 | {% endif %} 35 | 36 | {% macro image(src, width, height, alt) %} 37 | {{ alt|default('') }} 38 | {% endmacro %} 39 | -------------------------------------------------------------------------------- /templates/field/field.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Default template for a field. 5 | */ 6 | #} 7 | {% 8 | set classes = [ 9 | bundle|clean_class ~ '__' ~ field_name_clean|clean_class, 10 | label_display == 'inline' ? 'd-flex', 11 | ] 12 | %} 13 | {% 14 | set title_classes = [ 15 | 'field__label', 16 | 'font-weight-bold', 17 | label_display == 'visually_hidden' ? 'visually-hidden', 18 | ] 19 | %} 20 | 21 | {% if label_hidden %} 22 | {% if multiple %} 23 | 24 | {% for item in items %} 25 | {{ item.content }} 26 | {% endfor %} 27 | 28 | {% else %} 29 | {% for item in items %} 30 | {{ item.content }} 31 | {% endfor %} 32 | {% endif %} 33 | {% else %} 34 | 35 | 36 | {{ label }}{% if label_display == 'inline' %}:{% endif %} 37 | 38 | {% if multiple %} 39 |
40 | {% endif %} 41 | {% for item in items %} 42 | {{ item.content }}
43 | {% endfor %} 44 | {% if multiple %} 45 | 46 | {% endif %} 47 | 48 | {% endif %} 49 | -------------------------------------------------------------------------------- /src/sass/radix.bootstrap.scss: -------------------------------------------------------------------------------- 1 | // Bootstrap 2 | // ----------------------------------------------------------------------------- 3 | @import "~bootstrap/scss/functions"; 4 | @import "~bootstrap/scss/variables"; 5 | @import "~bootstrap/scss/mixins"; 6 | @import "~bootstrap/scss/print"; 7 | @import "~bootstrap/scss/reboot"; 8 | @import "~bootstrap/scss/type"; 9 | @import "~bootstrap/scss/images"; 10 | @import "~bootstrap/scss/code"; 11 | @import "~bootstrap/scss/grid"; 12 | @import "~bootstrap/scss/tables"; 13 | @import "~bootstrap/scss/forms"; 14 | @import "~bootstrap/scss/buttons"; 15 | @import "~bootstrap/scss/transitions"; 16 | @import "~bootstrap/scss/dropdown"; 17 | @import "~bootstrap/scss/button-group"; 18 | @import "~bootstrap/scss/input-group"; 19 | @import "~bootstrap/scss/custom-forms"; 20 | @import "~bootstrap/scss/nav"; 21 | @import "~bootstrap/scss/navbar"; 22 | @import "~bootstrap/scss/card"; 23 | @import "~bootstrap/scss/breadcrumb"; 24 | @import "~bootstrap/scss/pagination"; 25 | @import "~bootstrap/scss/badge"; 26 | @import "~bootstrap/scss/jumbotron"; 27 | @import "~bootstrap/scss/alert"; 28 | @import "~bootstrap/scss/progress"; 29 | @import "~bootstrap/scss/media"; 30 | @import "~bootstrap/scss/list-group"; 31 | @import "~bootstrap/scss/close"; 32 | @import "~bootstrap/scss/modal"; 33 | @import "~bootstrap/scss/tooltip"; 34 | @import "~bootstrap/scss/popover"; 35 | @import "~bootstrap/scss/carousel"; 36 | @import "~bootstrap/scss/utilities"; 37 | -------------------------------------------------------------------------------- /src/components/navbar/navbar.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for Navbar component. 5 | * 6 | * Available config: 7 | * - container: fixed | fluid. 8 | * - placement: default | fixed-top | fixed-bottom | sticky-top 9 | * - color: light | dark 10 | * - navbar_expand: sm | md | lg | xl 11 | * - utility_classes: An array of utility classes. 12 | * 13 | * Available blocks: 14 | * - branding 15 | * - left 16 | * - right 17 | */ 18 | #} 19 | {{ attach_library('radix/navbar') }} 20 | 21 | {% set container = container == 'fixed' ? 'container' : false %} 22 | {% set placement = placement ?? '' %} 23 | {% set color = color ?? 'light' %} 24 | {% set navbar_expand = navbar_expand ?? 'lg' %} 25 | 26 | 53 | -------------------------------------------------------------------------------- /templates/content/comment.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a comment. 5 | */ 6 | #} 7 | 8 | {# 9 | Hide the "new" indicator by default, let a piece of JavaScript ask the 10 | server which comments are new for the user. Rendering the final "new" 11 | indicator here would break the render cache. 12 | #} 13 | 14 | 15 |
16 |
17 | {{ user_picture }} 18 |
19 | 20 |
21 | 22 |
23 | {{ submitted }} 24 | {{ permalink }} 25 |
26 | 27 |
28 | {% if title %} 29 | {{ title_prefix }} 30 | {{ title }} 31 | {{ title_suffix }} 32 | {% endif %} 33 | {{ content }} 34 |
35 |
36 |
37 | 38 | 39 |
40 | {# 41 | Indicate the semantic relationship between parent and child comments for 42 | accessibility. The list is difficult to navigate in a screen reader 43 | without this information. 44 | #} 45 | {% if parent %} 46 |

{{ parent }}

47 | {% endif %} 48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | /* 2 | |-------------------------------------------------------------------------- 3 | | Mix Asset Management 4 | |-------------------------------------------------------------------------- 5 | | 6 | | Mix provides a clean, fluent API for defining some Webpack build steps 7 | | for your application. See https://github.com/JeffreyWay/laravel-mix. 8 | | 9 | */ 10 | const proxy = 'http://drupal.local'; 11 | const mix = require('laravel-mix'); 12 | 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | Configuration 16 | |-------------------------------------------------------------------------- 17 | */ 18 | mix 19 | .webpackConfig({ 20 | // Use the jQuery shipped with Drupal to avoid conflicts. 21 | externals: { 22 | jquery: 'jQuery' 23 | } 24 | }) 25 | .setPublicPath('assets') 26 | .disableNotifications() 27 | .options({ 28 | processCssUrls: false 29 | }); 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Browsersync 34 | |-------------------------------------------------------------------------- 35 | */ 36 | mix.browserSync({ 37 | proxy: proxy, 38 | files: ['assets/js/**/*.js', 'assets/css/**/*.css'], 39 | stream: true, 40 | }); 41 | 42 | /* 43 | |-------------------------------------------------------------------------- 44 | | SASS 45 | |-------------------------------------------------------------------------- 46 | */ 47 | mix 48 | .sass('src/sass/radix.bootstrap.scss', 'css') 49 | .sass('src/sass/radix.style.scss', 'css'); 50 | -------------------------------------------------------------------------------- /templates/page/page.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for the main page. 5 | */ 6 | #} 7 |
8 | {% embed '@radix/navbar/navbar.twig' with { 9 | placement: 'sticky-top', 10 | container: 'fixed', 11 | color: 'light', 12 | utility_classes: ['bg-light'], 13 | } %} 14 | 15 | {% block branding %} 16 | {% if page.navbar_branding %} 17 | {{ page.navbar_branding }} 18 | {% endif %} 19 | {% endblock %} 20 | 21 | {% block left %} 22 | {% if page.navbar_left %} 23 |
24 | {{ page.navbar_left }} 25 |
26 | {% endif %} 27 | {% endblock %} 28 | 29 | {% block right %} 30 | {% if page.navbar_right %} 31 | {{ page.navbar_right }} 32 | {% endif %} 33 | {% endblock %} 34 | {% endembed %} 35 | 36 |
37 | {# link is in html.html.twig #} 38 | 39 | {% if page.header %} 40 | 45 | {% endif %} 46 | 47 | {% if page.content %} 48 |
49 |
50 | {{ page.content }} 51 |
52 |
53 | {% endif %} 54 |
55 | 56 | {% if page.footer %} 57 |
58 |
59 |
60 | {{ page.footer }} 61 |
62 |
63 |
64 | {% endif %} 65 |
66 | -------------------------------------------------------------------------------- /src/kits/default/webpack.mix.js: -------------------------------------------------------------------------------- 1 | /* 2 | |-------------------------------------------------------------------------- 3 | | Mix Asset Management 4 | |-------------------------------------------------------------------------- 5 | | 6 | | Mix provides a clean, fluent API for defining some Webpack build steps 7 | | for your application. See https://github.com/JeffreyWay/laravel-mix. 8 | | 9 | */ 10 | const proxy = 'http://drupal.local'; 11 | const mix = require('laravel-mix'); 12 | 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | Configuration 16 | |-------------------------------------------------------------------------- 17 | */ 18 | mix 19 | .webpackConfig({ 20 | // Use the jQuery shipped with Drupal to avoid conflicts. 21 | externals: { 22 | jquery: 'jQuery' 23 | } 24 | }) 25 | .setPublicPath('assets') 26 | .disableNotifications() 27 | .options({ 28 | processCssUrls: false 29 | }); 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Browsersync 34 | |-------------------------------------------------------------------------- 35 | */ 36 | mix.browserSync({ 37 | proxy: proxy, 38 | files: ['assets/js/**/*.js', 'assets/css/**/*.css'], 39 | stream: true, 40 | }); 41 | 42 | /* 43 | |-------------------------------------------------------------------------- 44 | | SASS 45 | |-------------------------------------------------------------------------- 46 | */ 47 | mix.sass('src/sass/RADIX_SUBTHEME_MACHINE_NAME.style.scss', 'css'); 48 | 49 | /* 50 | |-------------------------------------------------------------------------- 51 | | JS 52 | |-------------------------------------------------------------------------- 53 | */ 54 | mix.js('src/js/RADIX_SUBTHEME_MACHINE_NAME.script.js', 'js'); 55 | -------------------------------------------------------------------------------- /includes/block.inc: -------------------------------------------------------------------------------- 1 | bundle(); 22 | 23 | // Add to theme suggestions. 24 | $suggestions[] = 'block__block_content__' . $bundle; 25 | } 26 | 27 | /** 28 | * Implements hook_preprocess_block(). 29 | */ 30 | function radix_preprocess_block(&$variables) { 31 | // Add id to template. 32 | if (isset($variables['elements']['#id'])) { 33 | $variables['id'] = str_replace('_', '-', $variables['elements']['#id']); 34 | } 35 | 36 | // Check for BlockContent. 37 | if ($variables['elements']['#configuration']['provider'] != 'block_content' || empty($variables['elements']['content']['#block_content'])) { 38 | return; 39 | } 40 | 41 | // Get the block bundle. 42 | $block_content = $variables['elements']['content']['#block_content']; 43 | 44 | // Add bundle to template. 45 | $variables['bundle'] = $block_content->bundle(); 46 | } 47 | 48 | /** 49 | * Implements template_preprocess_block_content(). 50 | */ 51 | function radix_preprocess_block_content(&$variables) { 52 | // Helpful $content variable for templates. 53 | $variables += ['content' => []]; 54 | foreach (Element::children($variables['elements']) as $key) { 55 | $variables['content'][$key] = $variables['elements'][$key]; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /includes/form.inc: -------------------------------------------------------------------------------- 1 | tag. 8 | * - caption: A localized string for the tag. 9 | * - colgroups: Column groups. Each group contains the following properties: 10 | * - attributes: HTML attributes to apply to the tag. 11 | * Note: Drupal currently supports only one table header row, see 12 | * https://www.drupal.org/node/893530 and 13 | * http://api.drupal.org/api/drupal/includes!theme.inc/function/theme_table/7#comment-5109. 14 | * - header: Table header cells. Each cell contains the following properties: 15 | * - tag: The HTML tag name to use; either 'th' or 'td'. 16 | * - attributes: HTML attributes to apply to the tag. 17 | * - content: A localized string for the title of the column. 18 | * - field: Field name (required for column sorting). 19 | * - sort: Default sort order for this column ("asc" or "desc"). 20 | * - sticky: A flag indicating whether to use a "sticky" table header. 21 | * - rows: Table rows. Each row contains the following properties: 22 | * - attributes: HTML attributes to apply to the tag. 23 | * - data: Table cells. 24 | * - no_striping: A flag indicating that the row should receive no 25 | * 'even / odd' styling. Defaults to FALSE. 26 | * - cells: Table cells of the row. Each cell contains the following keys: 27 | * - tag: The HTML tag name to use; either 'th' or 'td'. 28 | * - attributes: Any HTML attributes, such as "colspan", to apply to the 29 | * table cell. 30 | * - content: The string to display in the table cell. 31 | * - active_table_sort: A boolean indicating whether the cell is the active 32 | table sort. 33 | * - footer: Table footer rows, in the same format as the rows variable. 34 | * - empty: The message to display in an extra row if table does not have 35 | * any rows. 36 | * - no_striping: A boolean indicating that the row should receive no striping. 37 | * - header_columns: The number of columns in the header. 38 | * 39 | * @see template_preprocess_table() 40 | */ 41 | #} 42 | {% include '@radix/table/table.twig' %} 43 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/default.style.scss: -------------------------------------------------------------------------------- 1 | // Bootstrap 2 | // ----------------------------------------------------------------------------- 3 | @import "~bootstrap/scss/functions"; 4 | @import "base/variables"; 5 | @import "~bootstrap/scss/mixins"; 6 | @import "~bootstrap/scss/print"; 7 | @import "~bootstrap/scss/reboot"; 8 | @import "~bootstrap/scss/type"; 9 | @import "~bootstrap/scss/images"; 10 | @import "~bootstrap/scss/code"; 11 | @import "~bootstrap/scss/grid"; 12 | @import "~bootstrap/scss/tables"; 13 | @import "~bootstrap/scss/forms"; 14 | @import "~bootstrap/scss/buttons"; 15 | @import "~bootstrap/scss/transitions"; 16 | @import "~bootstrap/scss/dropdown"; 17 | @import "~bootstrap/scss/button-group"; 18 | @import "~bootstrap/scss/input-group"; 19 | @import "~bootstrap/scss/custom-forms"; 20 | @import "~bootstrap/scss/nav"; 21 | @import "~bootstrap/scss/navbar"; 22 | @import "~bootstrap/scss/card"; 23 | @import "~bootstrap/scss/breadcrumb"; 24 | @import "~bootstrap/scss/pagination"; 25 | @import "~bootstrap/scss/badge"; 26 | @import "~bootstrap/scss/jumbotron"; 27 | @import "~bootstrap/scss/alert"; 28 | @import "~bootstrap/scss/progress"; 29 | @import "~bootstrap/scss/media"; 30 | @import "~bootstrap/scss/list-group"; 31 | @import "~bootstrap/scss/close"; 32 | @import "~bootstrap/scss/modal"; 33 | @import "~bootstrap/scss/tooltip"; 34 | @import "~bootstrap/scss/popover"; 35 | @import "~bootstrap/scss/carousel"; 36 | @import "~bootstrap/scss/utilities"; 37 | 38 | // Base 39 | // ----------------------------------------------------------------------------- 40 | @import "base/mixins"; 41 | @import "base/functions"; 42 | @import "base/helpers"; 43 | @import "base/elements"; 44 | @import "base/typography"; 45 | 46 | // Layout 47 | // ----------------------------------------------------------------------------- 48 | @import "layout/page.header"; 49 | @import "layout/page.content"; 50 | @import "layout/page.footer"; 51 | 52 | // Component 53 | // ----------------------------------------------------------------------------- 54 | @import "../components/node/node"; 55 | 56 | // Other 57 | // ----------------------------------------------------------------------------- 58 | @import "block/block"; 59 | @import "content/node.page"; 60 | @import "content/node.article"; 61 | -------------------------------------------------------------------------------- /src/components/table/table.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Table component. 5 | * 6 | * Available config: 7 | * - utility_classes: An array of utility classes. 8 | */ 9 | #} 10 | 11 | {% set classes = [ 12 | 'table', 13 | ]|merge(utility_classes ? utility_classes : []) %} 14 | 15 | 16 | {% if caption %} 17 | {{ caption }} 18 | {% endif %} 19 | 20 | {% for colgroup in colgroups %} 21 | {% if colgroup.cols %} 22 | 23 | {% for col in colgroup.cols %} 24 | 25 | {% endfor %} 26 | 27 | {% else %} 28 | 29 | {% endif %} 30 | {% endfor %} 31 | 32 | {% if header %} 33 | 34 | 35 | {% for cell in header %} 36 | {% 37 | set cell_classes = [ 38 | cell.active_table_sort ? 'is-active', 39 | ] 40 | %} 41 | <{{ cell.tag }}{{ cell.attributes.addClass(cell_classes) }}> 42 | {{- cell.content -}} 43 | 44 | {% endfor %} 45 | 46 | 47 | {% endif %} 48 | 49 | {% if rows %} 50 | 51 | {% for row in rows %} 52 | {% 53 | set row_classes = [ 54 | not no_striping ? cycle(['odd', 'even'], loop.index0), 55 | ] 56 | %} 57 | 58 | {% for cell in row.cells %} 59 | <{{ cell.tag }}{{ cell.attributes }}> 60 | {{- cell.content -}} 61 | 62 | {% endfor %} 63 | 64 | {% endfor %} 65 | 66 | {% elseif empty %} 67 | 68 | 69 | {{ empty }} 70 | 71 | 72 | {% endif %} 73 | {% if footer %} 74 | 75 | {% for row in footer %} 76 | 77 | {% for cell in row.cells %} 78 | <{{ cell.tag }}{{ cell.attributes }}> 79 | {{- cell.content -}} 80 | 81 | {% endfor %} 82 | 83 | {% endfor %} 84 | 85 | {% endif %} 86 | 87 | -------------------------------------------------------------------------------- /src/components/nav/nav.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Nav component. 5 | * 6 | * Available config: 7 | * - alignment: left | right | center | vertical. 8 | * - style: tabs | pills 9 | * - fill: fill | justify 10 | * - utility_classes: An array of utility classes. 11 | */ 12 | #} 13 | {% import _self as menus %} 14 | 15 | {% if alignment == 'right' %} 16 | {% set alignment = 'justify-content-end' %} 17 | {% elseif alignment == 'center' %} 18 | {% set alignment = 'justify-content-center' %} 19 | {% elseif alignment == 'vertical' %} 20 | {% set alignment = 'flex-column' %} 21 | {% else %} 22 | {% set alignment = '' %} 23 | {% endif %} 24 | 25 | {% set style = style ? 'nav-' ~ style : '' %} 26 | {% set fill = fill ? 'nav-' ~ fill : '' %} 27 | 28 | {% set nav_classes = [ 'nav', style, alignment, fill]|merge(utility_classes ? utility_classes : []) %} 29 | 30 | {% if items %} 31 | 32 | {% block items %} 33 | {% for item in items %} 34 | {% set nav_item_classes = [ 35 | 'nav-item', 36 | item.in_active_trail ? 'active', 37 | item.is_expanded and item.below ? 'dropdown' 38 | ] %} 39 | {% set nav_link_classes = ['nav-link'] %} 40 | {% if item.url.options.attributes.class is iterable %} 41 | {% set nav_link_classes = nav_link_classes|merge(item.url.options.attributes.class) %} 42 | {% elseif item.url.options.attributes.class %} 43 | {% set nav_link_classes = nav_link_classes|merge([item.url.options.attributes.class]) %} 44 | {% endif %} 45 | 57 | {% endfor %} 58 | {% endblock %} 59 | 60 | {% endif %} 61 | 62 | -------------------------------------------------------------------------------- /templates/form/fieldset.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Theme override for a fieldset element and its children. 5 | * 6 | * Available variables: 7 | * - attributes: HTML attributes for the fieldset element. 8 | * - errors: (optional) Any errors for this fieldset element, may not be set. 9 | * - required: Boolean indicating whether the fieldeset element is required. 10 | * - legend: The legend element containing the following properties: 11 | * - title: Title of the fieldset, intended for use as the text of the legend. 12 | * - attributes: HTML attributes to apply to the legend. 13 | * - description: The description element containing the following properties: 14 | * - content: The description content of the fieldset. 15 | * - attributes: HTML attributes to apply to the description container. 16 | * - children: The rendered child elements of the fieldset. 17 | * - prefix: The content to add before the fieldset children. 18 | * - suffix: The content to add after the fieldset children. 19 | * 20 | * @see template_preprocess_fieldset() 21 | */ 22 | #} 23 | {% 24 | set classes = [ 25 | 'js-form-item', 26 | 'form-item', 27 | 'js-form-wrapper', 28 | 'form-wrapper', 29 | 'card', 30 | 'mb-3', 31 | ] 32 | %} 33 | 34 | {% 35 | set legend_span_classes = [ 36 | 'fieldset-legend', 37 | required ? 'js-form-required', 38 | required ? 'form-required', 39 | ] 40 | %} 41 | {# Always wrap fieldset legends in a SPAN for CSS positioning. #} 42 |
43 | 44 | {{ legend.title }} 45 | 46 |
47 |
48 | {% if errors %} 49 |
50 | {{ errors }} 51 |
52 | {% endif %} 53 | {% if prefix %} 54 | {{ prefix }} 55 | {% endif %} 56 | {{ children }} 57 | {% if suffix %} 58 | {{ suffix }} 59 | {% endif %} 60 | {% if description.content %} 61 | {{ description.content }} 62 | {% endif %} 63 |
64 | 65 | -------------------------------------------------------------------------------- /includes/menu.inc: -------------------------------------------------------------------------------- 1 | getRequestUri(); 19 | 20 | $items = $variables['items']; 21 | foreach ($items as $key => $item) { 22 | // If path is current_path, set active to li. 23 | if ($item['url']->toString() == $current_path) { 24 | // Add active link. 25 | $variables['items'][$key]['attributes']['class'] = 'active'; 26 | } 27 | } 28 | } 29 | 30 | /** 31 | * Implements template_preprocess_menu_local_action(). 32 | */ 33 | function radix_preprocess_menu_local_action(&$variables) { 34 | // Add button classes. 35 | $variables['link']['#options']['attributes']['class'][] = 'btn'; 36 | $variables['link']['#options']['attributes']['class'][] = 'btn-sm'; 37 | $variables['link']['#options']['attributes']['class'][] = 'btn-primary'; 38 | } 39 | 40 | /** 41 | * Implements template_preprocess_links__dropbutton(). 42 | */ 43 | function radix_preprocess_links__dropbutton(&$variables) { 44 | $links = &$variables['links']; 45 | 46 | // Do nothing if we have no links. 47 | if (!count($links)) { 48 | return; 49 | } 50 | 51 | // Get the first link and use it for the dropbutton. 52 | $link = reset($links); 53 | 54 | /** @var \Drupal\Core\Url $url */ 55 | $variables['split'] = FALSE; 56 | if (isset($link['link']) && ($url = $link['link']['#url'])) { 57 | $button = $link['link']; 58 | 59 | if ($variables['split'] = $url->getRouteName() !== '') { 60 | $button['#options']['attributes']['class'][] = 'btn'; 61 | $button['#options']['attributes']['class'][] = 'btn-sm'; 62 | $button['#options']['attributes']['class'][] = 'btn-outline-dark'; 63 | } 64 | 65 | $variables['button'] = $button; 66 | 67 | // Remove first link from links. 68 | array_shift($links); 69 | } 70 | 71 | // Add required classes. 72 | foreach ($links as $key => $link) { 73 | $links[$key]['link']['#options']['attributes']['class'][] = 'dropdown-item'; 74 | 75 | if (isset($links[$key]['text_attributes'])) { 76 | $links[$key]['text_attributes']->addClass('dropdown-item'); 77 | } 78 | 79 | if (isset($links[$key]['attributes'])) { 80 | $links[$key]['attributes']->addClass('dropdown-item'); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /templates/views/views-view-table.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a views table. 5 | */ 6 | #} 7 | 8 | {% set classes = [ 9 | 'cols-' ~ header|length, 10 | responsive ? 'responsive-enabled', 11 | sticky ? 'sticky-enabled', 12 | 'table', 13 | 'table-bordered', 14 | ] %} 15 |
16 | 17 | {% if caption_needed %} 18 | 19 | {% if caption %} 20 | {{ caption }} 21 | {% else %} 22 | {{ title }} 23 | {% endif %} 24 | {% if (summary is not empty) or (description is not empty) %} 25 |
26 | {% if summary is not empty %} 27 | {{ summary }} 28 | {% endif %} 29 | {% if description is not empty %} 30 | {{ description }} 31 | {% endif %} 32 |
33 | {% endif %} 34 | 35 | {% endif %} 36 | {% if header %} 37 | 38 | 39 | {% for key, column in header %} 40 | {% if column.default_classes %} 41 | {% set column_classes = [ 42 | 'views-field', 43 | 'views-field-' ~ fields[key], 44 | ] %} 45 | {% endif %} 46 | 47 | {%- if column.wrapper_element -%} 48 | <{{ column.wrapper_element }}> 49 | {%- if column.url -%} 50 | {{ column.content }}{{ column.sort_indicator }} 52 | {%- else -%} 53 | {{ column.content }}{{ column.sort_indicator }} 54 | {%- endif -%} 55 | 56 | {%- else -%} 57 | {%- if column.url -%} 58 | {{ column.content }}{{ column.sort_indicator }} 60 | {%- else -%} 61 | {{- column.content }}{{ column.sort_indicator }} 62 | {%- endif -%} 63 | {%- endif -%} 64 | 65 | {% endfor %} 66 | 67 | 68 | {% endif %} 69 | 70 | {% for row in rows %} 71 | 72 | {% for key, column in row.columns %} 73 | {% if column.default_classes %} 74 | {% set column_classes = [ 75 | 'views-field' 76 | ] %} 77 | {% for field in column.fields %} 78 | {% set column_classes = column_classes|merge(['views-field-' ~ field]) %} 79 | {% endfor %} 80 | {% endif %} 81 | 82 | {%- if column.wrapper_element -%} 83 | <{{ column.wrapper_element }}> 84 | {% for content in column.content %} 85 | {{ content.separator }}{{ content.field_output }} 86 | {% endfor %} 87 | 88 | {%- else -%} 89 | {% for content in column.content %} 90 | {{- content.separator }}{{ content.field_output -}} 91 | {% endfor %} 92 | {%- endif %} 93 | 94 | {% endfor %} 95 | 96 | {% endfor %} 97 | 98 | 99 |
100 | -------------------------------------------------------------------------------- /templates/dataset/forum-list.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Theme override to display a list of forums and containers. 5 | * 6 | * Available variables: 7 | * - forums: A collection of forums and containers to display. It is keyed to 8 | * the numeric IDs of all child forums and containers. Each forum in forums 9 | * contains: 10 | * - is_container: A flag indicating if the forum can contain other 11 | * forums. Otherwise, the forum can only contain topics. 12 | * - depth: How deep the forum is in the current hierarchy. 13 | * - zebra: 'even' or 'odd', used for row class. 14 | * - icon_class: 'default' or 'new', used for forum icon class. 15 | * - icon_title: Text alternative for the forum icon. 16 | * - name: The name of the forum. 17 | * - link: The URL to link to this forum. 18 | * - description: The description field for the forum, containing: 19 | * - value: The descriptive text for the forum. 20 | * - new_topics: A flag indicating if the forum contains unread posts. 21 | * - new_url: A URL to the forum's unread posts. 22 | * - new_text: Text for the above URL, which tells how many new posts. 23 | * - old_topics: A count of posts that have already been read. 24 | * - num_posts: The total number of posts in the forum. 25 | * - last_reply: Text representing the last time a forum was posted or 26 | * commented in. 27 | * - forum_id: Forum ID for the current forum. Parent to all items within the 28 | * forums array. 29 | * 30 | * @see template_preprocess_forum_list() 31 | */ 32 | #} 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | {% for child_id, forum in forums %} 44 | 45 | 70 | {% if forum.is_container == false %} 71 | 74 | 75 | 76 | {% endif %} 77 | 78 | {% endfor %} 79 | 80 |
{{ 'Forum'|t }}{{ 'Topics'|t }}{{ 'Posts'|t }}{{ 'Last post'|t }}
50 | {# 51 | Enclose the contents of this cell with X divs, where X is the 52 | depth this forum resides at. This will allow us to use CSS 53 | left-margin for indenting. 54 | #} 55 | {% for i in 1..forum.depth if forum.depth > 0 %}
{% endfor %} 56 |
57 | {{ forum.icon_title }} 58 |
59 |
60 |

{{ forum.label }}

61 | {% if forum.new_topics == true %} 62 | {{ forum.new_text }} 63 | {% endif %} 64 |
65 | {% if forum.description.value %} 66 |
{{ forum.description.value }}
67 | {% endif %} 68 | {% for i in 1..forum.depth if forum.depth > 0 %}
{% endfor %} 69 |
72 | {{ forum.num_topics }} 73 | {{ forum.num_posts }}{{ forum.last_reply }}
81 | -------------------------------------------------------------------------------- /templates/form/form-element.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Default theme implementation for a form element. 5 | * 6 | * Available variables: 7 | * - attributes: HTML attributes for the containing element. 8 | * - errors: (optional) Any errors for this form element, may not be set. 9 | * - prefix: (optional) The form element prefix, may not be set. 10 | * - suffix: (optional) The form element suffix, may not be set. 11 | * - required: The required marker, or empty if the associated form element is 12 | * not required. 13 | * - type: The type of the element. 14 | * - name: The name of the element. 15 | * - label: A rendered label element. 16 | * - label_display: Label display setting. It can have these values: 17 | * - before: The label is output before the element. This is the default. 18 | * The label includes the #title and the required marker, if #required. 19 | * - after: The label is output after the element. For example, this is used 20 | * for radio and checkbox #type elements. If the #title is empty but the 21 | * field is #required, the label will contain only the required marker. 22 | * - invisible: Labels are critical for screen readers to enable them to 23 | * properly navigate through forms but can be visually distracting. This 24 | * property hides the label for everyone except screen readers. 25 | * - attribute: Set the title attribute on the element to create a tooltip but 26 | * output no label element. This is supported only for checkboxes and radios 27 | * in \Drupal\Core\Render\Element\CompositeFormElementTrait::preRenderCompositeFormElement(). 28 | * It is used where a visual label is not needed, such as a table of 29 | * checkboxes where the row and column provide the context. The tooltip will 30 | * include the title and required marker. 31 | * - description: (optional) A list of description properties containing: 32 | * - content: A description of the form element, may not be set. 33 | * - attributes: (optional) A list of HTML attributes to apply to the 34 | * description content wrapper. Will only be set when description is set. 35 | * - description_display: Description display setting. It can have these values: 36 | * - before: The description is output before the element. 37 | * - after: The description is output after the element. This is the default 38 | * value. 39 | * - invisible: The description is output after the element, hidden visually 40 | * but available to screen readers. 41 | * - disabled: True if the element is disabled. 42 | * - title_display: Title display setting. 43 | * 44 | * @see template_preprocess_form_element() 45 | * 46 | * @ingroup themeable 47 | */ 48 | #} 49 | {% 50 | set classes = [ 51 | 'js-form-item', 52 | 'form-item', 53 | 'js-form-type-' ~ type|clean_class, 54 | 'form-item-' ~ name|clean_class, 55 | 'js-form-item-' ~ name|clean_class, 56 | title_display not in ['after', 'before'] ? 'form-no-label', 57 | disabled == 'disabled' ? 'form-disabled', 58 | errors ? 'form-item--error', 59 | 'form-group', 60 | ] 61 | %} 62 | {% 63 | set description_classes = [ 64 | 'description', 65 | 'form-text', 66 | 'text-muted', 67 | description_display == 'invisible' ? 'visually-hidden', 68 | ] 69 | %} 70 | 71 | {% if label_display in ['before', 'invisible'] %} 72 | {{ label }} 73 | {% endif %} 74 | {% if prefix is not empty %} 75 | {{ prefix }} 76 | {% endif %} 77 | {% if description_display == 'before' and description.content %} 78 | 79 | {{ description.content }} 80 | 81 | {% endif %} 82 | {{ children }} 83 | {% if suffix is not empty %} 84 | {{ suffix }} 85 | {% endif %} 86 | {% if label_display == 'after' %} 87 | {{ label }} 88 | {% endif %} 89 | {% if errors %} 90 |
91 | {{ errors }} 92 |
93 | {% endif %} 94 | {% if description_display in ['after', 'invisible'] and description.content %} 95 | 96 | {{ description.content }} 97 | 98 | {% endif %} 99 | 100 | -------------------------------------------------------------------------------- /src/components/pagination/pagination.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Template for a Pagination components. 5 | * 6 | * Available config: 7 | * - utility_classes: An array of utility classes. 8 | * - size: sm, md, lg 9 | * - alignment: left | right | center | vertical. 10 | */ 11 | */ 12 | #} 13 | 14 | {% if alignment == 'right' %} 15 | {% set alignment = 'justify-content-end' %} 16 | {% elseif alignment == 'center' %} 17 | {% set alignment = 'justify-content-center' %} 18 | {% else %} 19 | {% set alignment = '' %} 20 | {% endif %} 21 | 22 | {% if items %} 23 | 98 | {% endif %} 99 | -------------------------------------------------------------------------------- /src/SubThemeGenerator.php: -------------------------------------------------------------------------------- 1 | dir; 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | * 53 | * @param string $dir 54 | * Directory where a Radix starter kit already copied to. 55 | * 56 | * @return $this 57 | */ 58 | public function setDir(string $dir) { 59 | $this->dir = $dir; 60 | 61 | return $this; 62 | } 63 | 64 | /** 65 | * {@inheritdoc} 66 | * 67 | * @var string 68 | */ 69 | protected $machineName = ''; 70 | 71 | /** 72 | * {@inheritdoc} 73 | */ 74 | public function getMachineName(): string { 75 | if (!$this->machineName) { 76 | return basename($this->getDir()); 77 | } 78 | 79 | return $this->machineName; 80 | } 81 | 82 | /** 83 | * {@inheritdoc} 84 | */ 85 | public function setMachineName(string $machineName) { 86 | $this->machineName = $machineName; 87 | 88 | return $this; 89 | } 90 | 91 | /** 92 | * {@inheritdoc} 93 | * 94 | * @var string 95 | */ 96 | protected $name = ''; 97 | 98 | /** 99 | * {@inheritdoc} 100 | */ 101 | public function getName(): string { 102 | return $this->name; 103 | } 104 | 105 | /** 106 | * {@inheritdoc} 107 | * 108 | * @return $this 109 | */ 110 | public function setName(string $name) { 111 | $this->name = $name; 112 | 113 | return $this; 114 | } 115 | 116 | /** 117 | * {@inheritdoc} 118 | */ 119 | protected $description = ''; 120 | 121 | /** 122 | * {@inheritdoc} 123 | */ 124 | public function getDescription(): string { 125 | return $this->description; 126 | } 127 | 128 | /** 129 | * {@inheritdoc} 130 | */ 131 | public function setDescription(string $description) { 132 | $this->description = $description; 133 | 134 | return $this; 135 | } 136 | 137 | /** 138 | * {@inheritdoc} 139 | */ 140 | public function __construct() { 141 | $this->fs = new Filesystem(); 142 | $this->finder = new Finder(); 143 | } 144 | 145 | /** 146 | * {@inheritdoc} 147 | * 148 | * @return $this 149 | */ 150 | public function generate() { 151 | return $this 152 | ->initMachineNameOld() 153 | ->modifyFileContents() 154 | ->renameFiles(); 155 | } 156 | 157 | /** 158 | * {@inheritdoc} 159 | * 160 | * @return $this 161 | */ 162 | protected function initMachineNameOld() { 163 | $dstDir = $this->getDir(); 164 | $infoFiles = glob("$dstDir/*.info.yml"); 165 | 166 | $this->machineNameOld = basename(reset($infoFiles), '.info.yml'); 167 | 168 | return $this; 169 | } 170 | 171 | /** 172 | * {@inheritdoc} 173 | * 174 | * @return $this 175 | */ 176 | protected function modifyFileContents() { 177 | $replacementPairs = $this->getFileContentReplacementPairs(); 178 | foreach ($this->getFilesToMakeReplacements() as $fileName) { 179 | $this->modifyFileContent($fileName, $replacementPairs); 180 | } 181 | 182 | return $this; 183 | } 184 | 185 | /** 186 | * {@inheritdoc} 187 | * 188 | * @return $this 189 | */ 190 | protected function renameFiles() { 191 | $machineNameNew = $this->getMachineName(); 192 | if ($this->machineNameOld === $machineNameNew) { 193 | return $this; 194 | } 195 | 196 | foreach ($this->getFileNamesToRename() as $fileName) { 197 | $this->fs->rename($fileName, str_replace($this->machineNameOld, $machineNameNew, $fileName)); 198 | } 199 | 200 | return $this; 201 | } 202 | 203 | /** 204 | * {@inheritdoc} 205 | * 206 | * @return $this 207 | */ 208 | protected function modifyFileContent(string $fileName, array $replacementPairs) { 209 | if (!$this->fs->exists($fileName)) { 210 | return $this; 211 | } 212 | 213 | $this->fs->dumpFile( 214 | $fileName, 215 | strtr($this->fileGetContents($fileName), $replacementPairs) 216 | ); 217 | 218 | return $this; 219 | } 220 | 221 | /** 222 | * {@inheritdoc} 223 | * 224 | * @return string[] 225 | * Returns file names. 226 | */ 227 | protected function getFileNamesToRename(): array { 228 | // Find all files within the theme that match *{KIT_NAME}*. 229 | return array_keys(iterator_to_array($this->finder->files()->name("*{$this->machineNameOld}*")->in($this->getDir()))); 230 | } 231 | 232 | /** 233 | * {@inheritdoc} 234 | * 235 | * @return string[] 236 | * Returns replacement pairs. 237 | */ 238 | protected function getFileContentReplacementPairs(): array { 239 | return [ 240 | 'RADIX_SUBTHEME_NAME' => $this->getName(), 241 | 'RADIX_SUBTHEME_DESCRIPTION' => $this->getDescription(), 242 | 'RADIX_SUBTHEME_MACHINE_NAME' => $this->getMachineName(), 243 | "\nhidden: true\n" => "\n", 244 | ]; 245 | } 246 | 247 | /** 248 | * {@inheritdoc} 249 | * 250 | * @return string[] 251 | * Returns files to make replacements. 252 | */ 253 | public function getFilesToMakeReplacements(): array { 254 | return array_keys(iterator_to_array($this->finder->files()->in($this->getDir()))); 255 | } 256 | 257 | /** 258 | * {@inheritdoc} 259 | */ 260 | protected function fileGetContents(string $fileName): string { 261 | $content = file_get_contents($fileName); 262 | if ($content === FALSE) { 263 | throw new \RuntimeException("Could not read file '$fileName'", 1); 264 | } 265 | 266 | return $content; 267 | } 268 | 269 | } 270 | -------------------------------------------------------------------------------- /CHANGELOG.txt: -------------------------------------------------------------------------------- 1 | Radix 8.x-4.10, 2020-09-30 2 | ================== 3 | - Update npm packages: browser-sync, laravel-mix and node-sass 4 | 5 | Radix 8.x-4.9, 2020-09-28 6 | ================== 7 | - Issue #3152030 by Cellar Door, JohanFeuillet, arshadcn: Radix Sub theme is not Compatible with Drupal 9.0 8 | 9 | Radix 8.x-4.8, 2020-03-17 10 | ================== 11 | - Issue #3120205 by arshadcn: Update npm packages 12 | 13 | Radix 8.x-4.7, 2020-01-26 14 | ================== 15 | - Issue #3097873: Pin dependencies for the default kit 16 | - Issue #3081833 by sgammon, stefan.korn: dropdown-menu.twig: Array to string conversion 17 | - Issue #3086685 by stefan.korn: Issue after upgrading theme to 4.6 18 | - Issue #3079855 by stefan.korn: Issue with Drupal off-canvas dialog resizing (for example using Layout Builder) 19 | 20 | Radix 8.x-4.6, 2019-10-07 21 | ================== 22 | - Issue #3081150 by arshadcn, Jacine: Drush subtheme generator expects the kit to be located in Radix 23 | - Issue #3081166 by arshadcn, Jacine: Provide a means to rename other additional configuration files 24 | - Issue #3082593 by arshadcn, diqidoq, stefan.korn, tstermitz: Radix creates html class attribute "img-thumbnail" for all images 25 | - Issue #3084620 by stefan.korn: Views Mini pager should not show if there is only one page of items 26 | - Issue #3074568 by semiaddict, charlieweb82, sgammon: nav.twig: Array to string conversion in Drupal\Core\Template\AttributeArray->__toString() 27 | 28 | Radix 8.x-4.5, 2019-09-08 29 | ================== 30 | - Issue #2933383 by Sweetchuck: Convert radix drush command to drush 9 31 | 32 | Radix 8.x-4.4, 2019-07-23 33 | ================== 34 | - Issue #3063109 by Jacine: Site logo should have an alt attribute 35 | - Issue #3008219 by hctom, jwilson3: Call to a member function bundle() on string in radix_theme_suggestions_page_alter() 36 | - Issue #3053875 by jwilson3: dismissible alerts syntax is confusing, missing alert-dismissible 37 | 38 | Radix 8.x-4.3, 2019-05-04 39 | --------------------------------------- 40 | - Issue #3052101 by arshadcn: Add cross-env to theme for Windows support 41 | - Issue #3008488 by neubreed, scoff, Morbus Iff: Fix logo width and height in navbar/navbar-brand.twig 42 | - Issue #3051644: Nav twig file doesn't allow the class override by third-party modules 43 | - Issue #3049513 by sgammon, Morbus Iff, arshadcn: Menu block nav container and id/classes are not included 44 | - Issue #3048201: Use dropdowns for dropbutton 45 | - Issue #3028359 by kevinfunk, crs1138: Missing Sass variables in the subtheme 46 | 47 | Radix 8.x-4.2, 2019-04-06 48 | --------------------------------------- 49 | - Added template suggestions for user entity. 50 | - Issue #3046104 by doxigo, arshadcn: radix_preprocess_filter_caption overrides the output of image HTML with captions 51 | - Issue #3045895: Call to a member function setAttribute() on null in radix_preprocess_filter_caption 52 | - Fixed an issue with missing attributes in nav template. 53 | - Issue #3026552: set processCSSUrls to false by default 54 | 55 | Radix 8.x-4.1, 2019-03-25 56 | --------------------------------------- 57 | - Issue #3042502 by kevinfunk, arshadcn: Update Bootstrap to 4.3.1 58 | - Update npm packages in default kit 59 | - Add a theme schema 60 | - Add template for forum and comment 61 | 62 | Radix 8.x-4.0, 2018-08-03 63 | --------------------------------------- 64 | - Upgrade Bootstrap to Bootstrap 4 65 | - Add Twig components support 66 | - Add drupal/components as a composer dependency 67 | - Replace Gulp with Laravel Mix 68 | 69 | Radix 8.x-3.1, 2017-02-01 70 | --------------------------------------- 71 | - Remove unused menu template files. 72 | - Fixed drop-downs not showing in main navigation. 73 | - Add contextual links back to system-menu-block. 74 | - Allow kits to be created from any branch. 75 | - Add support for Yarn package manager. 76 | - Update npm dependencies. 77 | - Update bower dependencies. 78 | - Add bootstrap styles to Radix base theme. 79 | 80 | Radix 8.x-3.0, 2016-12-22 81 | --------------------------------------- 82 | - No changes 83 | 84 | Radix 8.x-3.0-beta1, 2016-11-28 85 | --------------------------------------- 86 | - Issue #2824400 by Laubi, arshadcn: Radix is spamming notice messages. 87 | - Remove comment.inc file. 88 | - Update the list of files to make replacement on drush. 89 | 90 | Radix 8.x-3.0-alpha4, 2016-06-15 91 | --------------------------------------- 92 | - Restore previous field.html.twig and add a field-no-wrapper.html.twig template 93 | - Clean up radix template files 94 | - Rename default files in the default kit 95 | - Move scss and js directories under assets 96 | - Issue #2711987 by jday: Minor issues in _mixins.scss calls 97 | - Remove compass from style.scss 98 | - Rename breakpoints.yml file when creating a subtheme 99 | 100 | Radix 8.x-3.0-alpha3, 2016-05-14 101 | --------------------------------------- 102 | - Add breakpoints file to default kit 103 | - Updates for multiple templates: views, html, feed-icon, field and block 104 | - Update template for views and nodes 105 | - Update template for block 106 | - Remove theme_views_mini_pager 107 | - Remove bootstrapcdn js 108 | - Update block template 109 | - Remove seven/global-styling library 110 | - Issue #2699605: Undefined index: id in radix_preprocess_block() 111 | - Remove gulp-compass from default kit 112 | 113 | Radix 8.x-3.0-alpha2, 2016-05-14 114 | --------------------------------------- 115 | - Fix template for checkboxes and radios 116 | - Update template for form-element 117 | - Add template for page-title 118 | - Add radix scss partial to main theme 119 | - Remove unused radix_theme hook 120 | - Remove system.admin.css 121 | - Add template for local action 122 | - Move radix scss partials out of the default/subtheme kit 123 | 124 | Radix 8.x-3.0-alpha1, 2016-02-08 125 | --------------------------------------- 126 | - Remove id from main nav template 127 | - Update region template 128 | - Update main page template 129 | - Update branding block template 130 | - Use site-logo and site-name classes instead of ids 131 | - Remove stylesheets and add regions and libraries to info file 132 | - Update template of search form 133 | - Update z-index of navbar 134 | - Remove alter hooks from .theme file 135 | - Update default logos 136 | - Update default template for blocks 137 | - Remove bower_components under gitignore 138 | - Fix info and libraries files for latest version 139 | -------------------------------------------------------------------------------- /radix.drush.inc: -------------------------------------------------------------------------------- 1 | 'Create a Radix subtheme.', 18 | 'arguments' => [ 19 | 'name' => 'The name of your subtheme.', 20 | ], 21 | 'options' => [ 22 | 'machine_name' => 'The machine-readable name of your subtheme. This will be auto-generated from the human-readable name if ommited.', 23 | 'description' => 'The description of your subtheme', 24 | 'destination' => 'The destination of your subtheme. Defaults to "./themes".', 25 | 'kit' => 'The name or url of the starter kit to use. Defaults to "default".', 26 | ], 27 | 'examples' => [ 28 | 'drush radix "My Theme"' => 'Creates a Radix subtheme called "My Theme", using the default options.', 29 | 'drush radix "My Theme" --machine_name=my_theme' => 'Creates a Radix subtheme called "My Theme" with a specific machine name.', 30 | ], 31 | ]; 32 | 33 | return $items; 34 | } 35 | 36 | /** 37 | * Implements hook_drush_help(). 38 | */ 39 | function radix_drush_help($section) { 40 | switch ($section) { 41 | case 'drush:radix': 42 | return dt('This command will create a Radix subtheme. See examples to get started.'); 43 | 44 | break; 45 | } 46 | } 47 | 48 | /** 49 | * Implements drush_hook_COMMAND(). 50 | */ 51 | function drush_radix($name = NULL, $machine_name = NULL) { 52 | 53 | // If no $name provided, abort. 54 | if (!$name) { 55 | drush_print(dt('Theme name missing. See help using drush radix --help.')); 56 | return; 57 | } 58 | 59 | // Determine the theme name. 60 | if (!isset($name)) { 61 | $name = drush_get_option('name'); 62 | } 63 | 64 | // Determine the machine name. 65 | if (!isset($machine_name)) { 66 | $machine_name = drush_get_option('machine_name'); 67 | } 68 | if (!$machine_name) { 69 | $machine_name = $name; 70 | } 71 | $machine_name = str_replace(' ', '_', strtolower($machine_name)); 72 | $search = [ 73 | // Remove characters not valid in function names. 74 | '/[^a-z0-9_]/', 75 | // Functions must begin with an alpha character. 76 | '/^[^a-z]+/', 77 | ]; 78 | $machine_name = preg_replace($search, '', $machine_name); 79 | 80 | // Description of subtheme. 81 | $description = (drush_get_option('description')) ? trim(drush_get_option('description')) : 'A theme based on Radix.'; 82 | 83 | // Determine the path to the new subtheme. 84 | $subtheme_path = 'themes'; 85 | if ($path = drush_get_option('path')) { 86 | $subtheme_path = drush_trim_path($path); 87 | } 88 | $subtheme_path = drush_normalize_path(drush_get_context('DRUSH_DRUPAL_ROOT') . '/' . $subtheme_path . '/' . $machine_name); 89 | 90 | // Determine the kit to use. 91 | $kit = (drush_get_option('kit')) ? drush_trim_path(drush_get_option('kit')) : 'default'; 92 | 93 | // Make a fresh copy of the kit. 94 | $kit_path = drush_normalize_path(drush_get_context('DRUSH_DRUPAL_ROOT') . '/' . drupal_get_path('theme', 'radix') . '/src/kits/' . $kit); 95 | 96 | // Allow kits to be pulled from external urls. 97 | if (UrlHelper::isValid($kit, TRUE)) { 98 | $kit_url = $kit; 99 | $kit_name = 'kit'; 100 | 101 | // Get kit name from kit url. 102 | if (preg_match("/\/radix\-kit\-([a-z0-9\_]*)\//", $kit_url, $matches)) { 103 | $kit_name = $kit = $matches[1]; 104 | } 105 | 106 | // Switch to a temp directory. 107 | $current_dir = getcwd(); 108 | chdir(drush_tempdir()); 109 | 110 | drush_print(dt('Downloading @kit_name from @kit_url...', [ 111 | '@kit_name' => (!empty($kit_name)) ? $kit_name . ' kit' : $kit_name, 112 | '@kit_url' => $kit_url, 113 | ])); 114 | if ($filepath = drush_download_file($kit_url)) { 115 | $filename = basename($filepath); 116 | 117 | // Decompress the zip archive. 118 | $files = drush_tarball_extract($filename, getcwd(), TRUE); 119 | 120 | // Re-index array. 121 | // This fixes an issue where a .tag.gz tarball returns a non-zero array. 122 | $files = array_values($files); 123 | $kit_path = getcwd() . '/' . $files[0]; 124 | 125 | // Set working directory back to the previous working directory. 126 | chdir($current_dir); 127 | } 128 | } 129 | 130 | if (!is_dir(dirname($subtheme_path))) { 131 | drush_die(dt('The directory "!directory" was not found.', ['!directory' => dirname($subtheme_path)])); 132 | } 133 | drush_op('drush_copy_dir', $kit_path, $subtheme_path); 134 | 135 | // Alter the contents of the .info file based on the command options. 136 | $alterations = [ 137 | 'RADIX_SUBTHEME_NAME' => $name, 138 | 'RADIX_SUBTHEME_DESCRIPTION' => $description, 139 | 'RADIX_SUBTHEME_MACHINE_NAME' => $machine_name, 140 | 'hidden: true' => '', 141 | ]; 142 | 143 | // Replace all occurrences of '{{machine_name}}' with the machine name of our sub theme. 144 | $files_to_replace = radix_get_files_to_make_replacements($kit); 145 | foreach ($files_to_replace as $file_to_replace) { 146 | drush_op('radix_file_str_replace', $subtheme_path . '/' . $file_to_replace, array_keys($alterations), $alterations); 147 | } 148 | 149 | // Rename files. 150 | $files_to_rename = [ 151 | '{{kit}}.info.yml', 152 | '{{kit}}.libraries.yml', 153 | '{{kit}}.breakpoints.yml', 154 | '{{kit}}.theme', 155 | 'config/schema/{{kit}}.schema.yml', 156 | 'src/sass/{{kit}}.style.scss', 157 | 'src/js/{{kit}}.script.js', 158 | ]; 159 | foreach ($files_to_rename as $file_to_rename_path) { 160 | $file_original_path = $subtheme_path . '/' . str_replace('{{kit}}', $kit, $file_to_rename_path); 161 | $file_new_path = $subtheme_path . '/' . str_replace('{{kit}}', $machine_name, $file_to_rename_path); 162 | drush_op('rename', drush_normalize_path($file_original_path), drush_normalize_path($file_new_path)); 163 | } 164 | 165 | // Notify user of the newly created theme. 166 | $message = 'Successfully created the Radix subtheme "!name" in "!path" using the "!kit" kit'; 167 | 168 | $message = dt($message . '.', [ 169 | '!name' => $name, 170 | '!path' => $subtheme_path, 171 | '!kit' => $kit, 172 | ]); 173 | drush_print($message); 174 | } 175 | 176 | /** 177 | * Replace strings in a file. 178 | */ 179 | function radix_file_str_replace($file_path, $find, $replace) { 180 | $file_path = drush_normalize_path($file_path); 181 | $file_contents = file_get_contents($file_path); 182 | $file_contents = str_replace($find, $replace, $file_contents); 183 | file_put_contents($file_path, $file_contents); 184 | } 185 | 186 | /** 187 | * Returns an array of files to make string replacements. 188 | */ 189 | function radix_get_files_to_make_replacements($kit = 'default') { 190 | return [ 191 | $kit . '.info.yml', 192 | $kit . '.libraries.yml', 193 | $kit . '.theme', 194 | 'package.json', 195 | 'package-lock.json', 196 | 'webpack.mix.js', 197 | 'README.md', 198 | 'templates/content/node.html.twig', 199 | 'config/schema/' . $kit . '.schema.yml', 200 | ]; 201 | } 202 | -------------------------------------------------------------------------------- /Commands/radix/SubThemeCommands.php: -------------------------------------------------------------------------------- 1 | subThemeCreator = $subThemeCreator ?: new SubThemeGenerator(); 49 | $this->fs = $fs ?: new Filesystem(); 50 | 51 | parent::__construct(); 52 | } 53 | 54 | /** 55 | * Creates a Radix sub-theme. 56 | * 57 | * @command radix:create 58 | * @aliases radix 59 | * 60 | * @bootstrap full 61 | * 62 | * @option string $machine-name 63 | * The machine-readable name of your sub-theme. This will be auto-generated 64 | * from the human-readable name if omitted. 65 | * @option string $description 66 | * The description of your sub-theme 67 | * @option string $destination 68 | * The destination of your sub-theme. 69 | * @option string $kit 70 | * The name or url of the starter kit to use. 71 | * 72 | * @usage drush radix:create 'My Theme' 73 | * Creates a Radix sub-theme called "My Theme", using the default options. 74 | * @usage drush radix:create 'My Theme' --machine_name=my_theme 75 | * Creates a Radix sub-theme called "My Theme" with a specific machine name. 76 | * 77 | * @radixArgLabel name 78 | * @radixOptionMachineName machine-name 79 | */ 80 | public function generateSubTheme( 81 | string $name, 82 | array $options = [ 83 | 'machine-name' => '', 84 | 'description' => '', 85 | 'destination' => '', 86 | 'kit' => 'default', 87 | ] 88 | ) { 89 | $kit = $options['kit']; 90 | 91 | // @todo Use extension service. 92 | $radixDir = drupal_get_path('theme', 'radix'); 93 | $srcDir = "$radixDir/src/kits/{$kit}"; 94 | 95 | // Find kit from other active themes. 96 | /** @var \Drupal\Core\Extension\Extension[] $themes */ 97 | foreach (\Drupal::service('theme_handler')->listInfo() as $theme) { 98 | $path = "{$theme->getPath()}/src/kits/{$kit}"; 99 | if ($this->fs->exists($path)) { 100 | $srcDir = $path; 101 | } 102 | } 103 | 104 | $dstDir = "{$options['destination']}/{$options['machine-name']}"; 105 | 106 | $cb = $this->collectionBuilder(); 107 | $cb->getState()->offsetSet('srcDir', $srcDir); 108 | 109 | if (UrlHelper::isValid($kit, TRUE)) { 110 | $kitUrl = $kit; 111 | $cb->addTask($this->taskTmpDir()); 112 | 113 | $cb->addCode(function (RoboStateData $data) use ($kitUrl): int { 114 | $logger = $this->logger(); 115 | $logger->debug( 116 | 'download Radix starter kit from {kitUrl}', 117 | [ 118 | 'kitUrl' => $kitUrl, 119 | ] 120 | ); 121 | 122 | $fileName = $this->getFileNameFromUrl($kitUrl); 123 | $packDir = "{$data['path']}/pack"; 124 | $data['packPath'] = "$packDir/$fileName"; 125 | 126 | try { 127 | $this->fs->mkdir($packDir); 128 | $this->fs->copy($kitUrl, $data['packPath']); 129 | } 130 | catch (\Exception $e) { 131 | $logger->error($e->getMessage()); 132 | 133 | return 1; 134 | } 135 | 136 | return 0; 137 | }); 138 | 139 | $cb->addCode(function (RoboStateData $data): int { 140 | $logger = $this->logger(); 141 | $logger->debug( 142 | 'extract downloaded Radix starter kit from {packPath} to {srcDir}', 143 | [ 144 | 'packPath' => $data['packPath'], 145 | 'srcDir' => $data['srcDir'], 146 | ] 147 | ); 148 | 149 | $data['srcDir'] = "{$data['path']}/kit"; 150 | 151 | /** @var \Drupal\Core\Archiver\ArchiverManager $extractorManager */ 152 | $extractorManager = \Drupal::service('plugin.manager.archiver'); 153 | 154 | try { 155 | /** @var \Drupal\Core\Archiver\ArchiverInterface $extractorInstance */ 156 | $extractorInstance = $extractorManager->getInstance(['filepath' => $data['packPath']]); 157 | $extractorInstance->extract($data['srcDir']); 158 | } 159 | catch (Exception $e) { 160 | $this->logger()->error($e->getMessage()); 161 | 162 | return 1; 163 | } 164 | 165 | $topLevelDir = $this->getTopLevelDir($data['srcDir']); 166 | if ($topLevelDir) { 167 | $data['srcDir'] = $topLevelDir; 168 | } 169 | 170 | return 0; 171 | }); 172 | } 173 | 174 | $cb->addCode(function (RoboStateData $data) use ($dstDir): int { 175 | $logger = $this->logger(); 176 | $logger->debug( 177 | 'copy Radix starter kit from {srcDir} to {dstDir}', 178 | [ 179 | 'srcDir' => $data['srcDir'], 180 | 'dstDir' => $dstDir, 181 | ] 182 | ); 183 | 184 | try { 185 | $this->fs->mirror($data['srcDir'], $dstDir); 186 | } 187 | catch (\Exception $e) { 188 | $this->logger()->error($e->getMessage()); 189 | 190 | return 1; 191 | } 192 | 193 | return 0; 194 | }); 195 | 196 | $cb->addCode(function () use ($name, $options, $dstDir): int { 197 | $logger = $this->logger(); 198 | $logger->debug( 199 | 'customize Radix starter kit in {dstDir} directory', 200 | [ 201 | 'dstDir' => $dstDir, 202 | ] 203 | ); 204 | 205 | $this 206 | ->subThemeCreator 207 | ->setDir($dstDir) 208 | ->setMachineName($options['machine-name']) 209 | ->setName($name) 210 | ->setDescription($options['description']) 211 | ->generate(); 212 | 213 | return 0; 214 | }); 215 | 216 | return $cb; 217 | } 218 | 219 | /** 220 | * {@inheritdoc} 221 | * 222 | * @hook validate radix:create 223 | */ 224 | public function onHookValidateRadixGenerateSubTheme(CommandData $commandData): ?CommandError { 225 | $input = $commandData->input(); 226 | 227 | if (!$input->getOption('kit')) { 228 | $input->setOption('kit', 'default'); 229 | } 230 | 231 | if (!$input->getOption('description')) { 232 | $input->setOption('description', $this->getDefaultDescription()); 233 | } 234 | 235 | $machineName = $input->getOption('machine-name'); 236 | if (!$machineName) { 237 | $machineName = $this->convertLabelToMachineName($input->getArgument('name')); 238 | $input->setOption('machine-name', $machineName); 239 | } 240 | 241 | $destination = $input->getOption('destination'); 242 | if (!$destination) { 243 | $destination = $this->getDefaultDestination(); 244 | $input->setOption('destination', $destination); 245 | } 246 | 247 | $dstDir = "$destination/$machineName"; 248 | if ($this->fs->exists($dstDir) && !$this->isDirEmpty($dstDir)) { 249 | return new CommandError("Destination directory '$dstDir' not empty", 1); 250 | } 251 | 252 | return NULL; 253 | } 254 | 255 | /** 256 | * {@inheritdoc} 257 | * 258 | * @hook validate @radixArgLabel 259 | * 260 | * @return null|\Consolidation\AnnotatedCommand\CommandError 261 | * Returns null or CommandError. 262 | */ 263 | public function onHookValidateRadixArgLabel(CommandData $commandData): ?CommandError { 264 | $annotationKey = 'radixArgLabel'; 265 | $annotationData = $commandData->annotationData(); 266 | if (!$annotationData->has($annotationKey)) { 267 | return NULL; 268 | } 269 | 270 | $commandErrors = []; 271 | $argNames = $this->parseMultiValueAnnotation($annotationData->get($annotationKey)); 272 | foreach ($argNames as $argName) { 273 | $commandErrors[] = $this->onHookValidateRadixArgLabelSingle($commandData, $argName); 274 | } 275 | 276 | return $this->aggregateCommandErrors($commandErrors); 277 | } 278 | 279 | /** 280 | * {@inheritdoc} 281 | */ 282 | protected function onHookValidateRadixArgLabelSingle(CommandData $commandData, string $argName): ?CommandError { 283 | $label = $commandData->input()->getArgument($argName); 284 | if (strlen($label) === 0) { 285 | return NULL; 286 | } 287 | 288 | if (!preg_match('/^[^\t\r\n]+$/ui', $label)) { 289 | return new CommandError("Tabs and new line characters are not allowed in argument '$argName'."); 290 | } 291 | 292 | return NULL; 293 | } 294 | 295 | /** 296 | * {@inheritdoc} 297 | * 298 | * @hook validate @radixOptionMachineName 299 | */ 300 | public function onHookValidateRadixOptionMachineName(CommandData $commandData) { 301 | $annotationKey = 'radixOptionMachineName'; 302 | $annotationData = $commandData->annotationData(); 303 | if (!$annotationData->has($annotationKey)) { 304 | return NULL; 305 | } 306 | 307 | $commandErrors = []; 308 | $optionNames = $this->parseMultiValueAnnotation($annotationData->get($annotationKey)); 309 | foreach ($optionNames as $optionName) { 310 | $commandErrors[] = $this->onHookValidateRadixOptionMachineNameSingle($commandData, $optionName); 311 | } 312 | 313 | return $this->aggregateCommandErrors($commandErrors); 314 | } 315 | 316 | /** 317 | * {@inheritdoc} 318 | */ 319 | protected function onHookValidateRadixOptionMachineNameSingle(CommandData $commandData, $optionName): ?CommandError { 320 | $machineNames = $commandData->input()->getOption($optionName); 321 | if (!is_array($machineNames)) { 322 | $machineNames = strlen($machineNames) !== 0 ? [$machineNames] : []; 323 | } 324 | 325 | $invalidMachineNames = []; 326 | foreach ($machineNames as $machineName) { 327 | if (!preg_match('/^[a-z][a-z0-9_]*$/', $machineName)) { 328 | $invalidMachineNames[] = $machineName; 329 | } 330 | } 331 | 332 | if ($invalidMachineNames) { 333 | return new CommandError("Following machine-names are invalid in option '$optionName': " . implode(', ', $invalidMachineNames)); 334 | } 335 | 336 | return NULL; 337 | } 338 | 339 | /** 340 | * {@inheritdoc} 341 | */ 342 | protected function parseMultiValueAnnotation(string $value): array { 343 | return $this->explodeCommaSeparatedList($value); 344 | } 345 | 346 | /** 347 | * {@inheritdoc} 348 | */ 349 | protected function explodeCommaSeparatedList(string $items): array { 350 | return array_filter( 351 | preg_split('/\s*,\s*/', trim($items)), 352 | 'mb_strlen' 353 | ); 354 | } 355 | 356 | /** 357 | * {@inheritdoc} 358 | * 359 | * @param \Consolidation\AnnotatedCommand\CommandError[] $commandErrors 360 | * Command errors. 361 | */ 362 | protected function aggregateCommandErrors(array $commandErrors): ?CommandError { 363 | $errorCode = 0; 364 | $messages = []; 365 | /** @var \Consolidation\AnnotatedCommand\CommandError $commandError */ 366 | foreach (array_filter($commandErrors) as $commandError) { 367 | $messages[] = $commandError->getOutputData(); 368 | $errorCode = max($errorCode, $commandError->getExitCode()); 369 | } 370 | 371 | if ($messages) { 372 | return new CommandError(implode(PHP_EOL, $messages), $errorCode); 373 | } 374 | 375 | return NULL; 376 | } 377 | 378 | /** 379 | * {@inheritdoc} 380 | */ 381 | protected function convertLabelToMachineName(string $label): string { 382 | return mb_strtolower(preg_replace('/[^a-z0-9_]+/ui', '_', $label)); 383 | } 384 | 385 | /** 386 | * {@inheritdoc} 387 | */ 388 | protected function getDefaultDestination(): string { 389 | if ($this->fs->exists('./themes/contrib') || $this->fs->exists('./themes/custom')) { 390 | return './themes/custom'; 391 | } 392 | 393 | return './themes'; 394 | } 395 | 396 | /** 397 | * {@inheritdoc} 398 | */ 399 | protected function getDefaultDescription(): string { 400 | return 'A theme based on Radix.'; 401 | } 402 | 403 | /** 404 | * {@inheritdoc} 405 | */ 406 | protected function isDirEmpty(string $dir): bool { 407 | return !(new \FilesystemIterator($dir))->valid(); 408 | } 409 | 410 | /** 411 | * {@inheritdoc} 412 | */ 413 | protected function getDirectDescendants(string $dir): Finder { 414 | return (new Finder()) 415 | ->in($dir) 416 | ->depth('0'); 417 | } 418 | 419 | /** 420 | * {@inheritdoc} 421 | */ 422 | protected function getFileNameFromUrl(string $url): string { 423 | return pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_BASENAME); 424 | } 425 | 426 | /** 427 | * {@inheritdoc} 428 | */ 429 | protected function getTopLevelDir(string $parentDir): string { 430 | $directDescendants = $this->getDirectDescendants($parentDir); 431 | $iterator = $directDescendants->getIterator(); 432 | $iterator->rewind(); 433 | /** @var \Symfony\Component\Finder\SplFileInfo $firstFile */ 434 | $firstFile = $iterator->current(); 435 | if ($directDescendants->count() === 1 && $firstFile->isDir()) { 436 | return $firstFile->getPathname(); 437 | } 438 | 439 | return ''; 440 | } 441 | 442 | } 443 | -------------------------------------------------------------------------------- /src/kits/default/src/sass/base/_variables.scss: -------------------------------------------------------------------------------- 1 | // Variables 2 | // 3 | // Variables should follow the `$component-state-property-size` formula for 4 | // consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs. 5 | 6 | // Color system 7 | 8 | $white: #fff !default; 9 | $gray-100: #f8f9fa !default; 10 | $gray-200: #e9ecef !default; 11 | $gray-300: #dee2e6 !default; 12 | $gray-400: #ced4da !default; 13 | $gray-500: #adb5bd !default; 14 | $gray-600: #6c757d !default; 15 | $gray-700: #495057 !default; 16 | $gray-800: #343a40 !default; 17 | $gray-900: #212529 !default; 18 | $black: #000 !default; 19 | 20 | $grays: () !default; 21 | // stylelint-disable-next-line scss/dollar-variable-default 22 | $grays: map-merge( 23 | ( 24 | "100": $gray-100, 25 | "200": $gray-200, 26 | "300": $gray-300, 27 | "400": $gray-400, 28 | "500": $gray-500, 29 | "600": $gray-600, 30 | "700": $gray-700, 31 | "800": $gray-800, 32 | "900": $gray-900 33 | ), 34 | $grays 35 | ); 36 | 37 | $blue: #007bff !default; 38 | $indigo: #6610f2 !default; 39 | $purple: #6f42c1 !default; 40 | $pink: #e83e8c !default; 41 | $red: #dc3545 !default; 42 | $orange: #fd7e14 !default; 43 | $yellow: #ffc107 !default; 44 | $green: #28a745 !default; 45 | $teal: #20c997 !default; 46 | $cyan: #17a2b8 !default; 47 | 48 | $colors: () !default; 49 | // stylelint-disable-next-line scss/dollar-variable-default 50 | $colors: map-merge( 51 | ( 52 | "blue": $blue, 53 | "indigo": $indigo, 54 | "purple": $purple, 55 | "pink": $pink, 56 | "red": $red, 57 | "orange": $orange, 58 | "yellow": $yellow, 59 | "green": $green, 60 | "teal": $teal, 61 | "cyan": $cyan, 62 | "white": $white, 63 | "gray": $gray-600, 64 | "gray-dark": $gray-800 65 | ), 66 | $colors 67 | ); 68 | 69 | $primary: $blue !default; 70 | $secondary: $gray-600 !default; 71 | $success: $green !default; 72 | $info: $cyan !default; 73 | $warning: $yellow !default; 74 | $danger: $red !default; 75 | $light: $gray-100 !default; 76 | $dark: $gray-800 !default; 77 | 78 | $theme-colors: () !default; 79 | // stylelint-disable-next-line scss/dollar-variable-default 80 | $theme-colors: map-merge( 81 | ( 82 | "primary": $primary, 83 | "secondary": $secondary, 84 | "success": $success, 85 | "info": $info, 86 | "warning": $warning, 87 | "danger": $danger, 88 | "light": $light, 89 | "dark": $dark 90 | ), 91 | $theme-colors 92 | ); 93 | 94 | // Set a specific jump point for requesting color jumps 95 | $theme-color-interval: 8% !default; 96 | 97 | // The yiq lightness value that determines when the lightness of color changes from "dark" to "light". Acceptable values are between 0 and 255. 98 | $yiq-contrasted-threshold: 150 !default; 99 | 100 | // Customize the light and dark text colors for use in our YIQ color contrast function. 101 | $yiq-text-dark: $gray-900 !default; 102 | $yiq-text-light: $white !default; 103 | 104 | 105 | // Options 106 | // 107 | // Quickly modify global styling by enabling or disabling optional features. 108 | 109 | $enable-caret: true !default; 110 | $enable-rounded: true !default; 111 | $enable-shadows: false !default; 112 | $enable-gradients: false !default; 113 | $enable-transitions: true !default; 114 | $enable-prefers-reduced-motion-media-query: true !default; 115 | $enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS 116 | $enable-grid-classes: true !default; 117 | $enable-pointer-cursor-for-buttons: true !default; 118 | $enable-print-styles: true !default; 119 | $enable-responsive-font-sizes: false !default; 120 | $enable-validation-icons: true !default; 121 | $enable-deprecation-messages: true !default; 122 | 123 | 124 | // Spacing 125 | // 126 | // Control the default styling of most Bootstrap elements by modifying these 127 | // variables. Mostly focused on spacing. 128 | // You can add more entries to the $spacers map, should you need more variation. 129 | 130 | $spacer: 1rem !default; 131 | $spacers: () !default; 132 | // stylelint-disable-next-line scss/dollar-variable-default 133 | $spacers: map-merge( 134 | ( 135 | 0: 0, 136 | 1: ($spacer * .25), 137 | 2: ($spacer * .5), 138 | 3: $spacer, 139 | 4: ($spacer * 1.5), 140 | 5: ($spacer * 3) 141 | ), 142 | $spacers 143 | ); 144 | 145 | // This variable affects the `.h-*` and `.w-*` classes. 146 | $sizes: () !default; 147 | // stylelint-disable-next-line scss/dollar-variable-default 148 | $sizes: map-merge( 149 | ( 150 | 25: 25%, 151 | 50: 50%, 152 | 75: 75%, 153 | 100: 100%, 154 | auto: auto 155 | ), 156 | $sizes 157 | ); 158 | 159 | 160 | // Body 161 | // 162 | // Settings for the `` element. 163 | 164 | $body-bg: $white !default; 165 | $body-color: $gray-900 !default; 166 | 167 | 168 | // Links 169 | // 170 | // Style anchor elements. 171 | 172 | $link-color: theme-color("primary") !default; 173 | $link-decoration: none !default; 174 | $link-hover-color: darken($link-color, 15%) !default; 175 | $link-hover-decoration: underline !default; 176 | // Darken percentage for links with `.text-*` class (e.g. `.text-success`) 177 | $emphasized-link-hover-darken-percentage: 15% !default; 178 | 179 | // Paragraphs 180 | // 181 | // Style p element. 182 | 183 | $paragraph-margin-bottom: 1rem !default; 184 | 185 | 186 | // Grid breakpoints 187 | // 188 | // Define the minimum dimensions at which your layout will change, 189 | // adapting to different screen sizes, for use in media queries. 190 | 191 | $grid-breakpoints: ( 192 | xs: 0, 193 | sm: 576px, 194 | md: 768px, 195 | lg: 992px, 196 | xl: 1200px 197 | ) !default; 198 | 199 | @include _assert-ascending($grid-breakpoints, "$grid-breakpoints"); 200 | @include _assert-starts-at-zero($grid-breakpoints, "$grid-breakpoints"); 201 | 202 | 203 | // Grid containers 204 | // 205 | // Define the maximum width of `.container` for different screen sizes. 206 | 207 | $container-max-widths: ( 208 | sm: 540px, 209 | md: 720px, 210 | lg: 960px, 211 | xl: 1140px 212 | ) !default; 213 | 214 | @include _assert-ascending($container-max-widths, "$container-max-widths"); 215 | 216 | 217 | // Grid columns 218 | // 219 | // Set the number of columns and specify the width of the gutters. 220 | 221 | $grid-columns: 12 !default; 222 | $grid-gutter-width: 30px !default; 223 | 224 | 225 | // Components 226 | // 227 | // Define common padding and border radius sizes and more. 228 | 229 | $line-height-lg: 1.5 !default; 230 | $line-height-sm: 1.5 !default; 231 | 232 | $border-width: 1px !default; 233 | $border-color: $gray-300 !default; 234 | 235 | $border-radius: .25rem !default; 236 | $border-radius-lg: .3rem !default; 237 | $border-radius-sm: .2rem !default; 238 | 239 | $rounded-pill: 50rem !default; 240 | 241 | $box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default; 242 | $box-shadow: 0 .5rem 1rem rgba($black, .15) !default; 243 | $box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default; 244 | 245 | $component-active-color: $white !default; 246 | $component-active-bg: theme-color("primary") !default; 247 | 248 | $caret-width: .3em !default; 249 | $caret-vertical-align: $caret-width * .85 !default; 250 | $caret-spacing: $caret-width * .85 !default; 251 | 252 | $transition-base: all .2s ease-in-out !default; 253 | $transition-fade: opacity .15s linear !default; 254 | $transition-collapse: height .35s ease !default; 255 | 256 | $embed-responsive-aspect-ratios: () !default; 257 | // stylelint-disable-next-line scss/dollar-variable-default 258 | $embed-responsive-aspect-ratios: join( 259 | ( 260 | (21 9), 261 | (16 9), 262 | (4 3), 263 | (1 1), 264 | ), 265 | $embed-responsive-aspect-ratios 266 | ); 267 | 268 | // Typography 269 | // 270 | // Font, line-height, and color for body text, headings, and more. 271 | 272 | // stylelint-disable value-keyword-case 273 | $font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default; 274 | $font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default; 275 | $font-family-base: $font-family-sans-serif !default; 276 | // stylelint-enable value-keyword-case 277 | 278 | $font-size-base: 1rem !default; // Assumes the browser default, typically `16px` 279 | $font-size-lg: $font-size-base * 1.25 !default; 280 | $font-size-sm: $font-size-base * .875 !default; 281 | 282 | $font-weight-lighter: lighter !default; 283 | $font-weight-light: 300 !default; 284 | $font-weight-normal: 400 !default; 285 | $font-weight-bold: 700 !default; 286 | $font-weight-bolder: bolder !default; 287 | 288 | $font-weight-base: $font-weight-normal !default; 289 | $line-height-base: 1.5 !default; 290 | 291 | $h1-font-size: $font-size-base * 2.5 !default; 292 | $h2-font-size: $font-size-base * 2 !default; 293 | $h3-font-size: $font-size-base * 1.75 !default; 294 | $h4-font-size: $font-size-base * 1.5 !default; 295 | $h5-font-size: $font-size-base * 1.25 !default; 296 | $h6-font-size: $font-size-base !default; 297 | 298 | $headings-margin-bottom: $spacer / 2 !default; 299 | $headings-font-family: null !default; 300 | $headings-font-weight: 500 !default; 301 | $headings-line-height: 1.2 !default; 302 | $headings-color: null !default; 303 | 304 | $display1-size: 6rem !default; 305 | $display2-size: 5.5rem !default; 306 | $display3-size: 4.5rem !default; 307 | $display4-size: 3.5rem !default; 308 | 309 | $display1-weight: 300 !default; 310 | $display2-weight: 300 !default; 311 | $display3-weight: 300 !default; 312 | $display4-weight: 300 !default; 313 | $display-line-height: $headings-line-height !default; 314 | 315 | $lead-font-size: $font-size-base * 1.25 !default; 316 | $lead-font-weight: 300 !default; 317 | 318 | $small-font-size: 80% !default; 319 | 320 | $text-muted: $gray-600 !default; 321 | 322 | $blockquote-small-color: $gray-600 !default; 323 | $blockquote-small-font-size: $small-font-size !default; 324 | $blockquote-font-size: $font-size-base * 1.25 !default; 325 | 326 | $hr-border-color: rgba($black, .1) !default; 327 | $hr-border-width: $border-width !default; 328 | 329 | $mark-padding: .2em !default; 330 | 331 | $dt-font-weight: $font-weight-bold !default; 332 | 333 | $kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default; 334 | $nested-kbd-font-weight: $font-weight-bold !default; 335 | 336 | $list-inline-padding: .5rem !default; 337 | 338 | $mark-bg: #fcf8e3 !default; 339 | 340 | $hr-margin-y: $spacer !default; 341 | 342 | 343 | // Tables 344 | // 345 | // Customizes the `.table` component with basic values, each used across all table variations. 346 | 347 | $table-cell-padding: .75rem !default; 348 | $table-cell-padding-sm: .3rem !default; 349 | 350 | $table-color: $body-color !default; 351 | $table-bg: null !default; 352 | $table-accent-bg: rgba($black, .05) !default; 353 | $table-hover-color: $table-color !default; 354 | $table-hover-bg: rgba($black, .075) !default; 355 | $table-active-bg: $table-hover-bg !default; 356 | 357 | $table-border-width: $border-width !default; 358 | $table-border-color: $border-color !default; 359 | 360 | $table-head-bg: $gray-200 !default; 361 | $table-head-color: $gray-700 !default; 362 | 363 | $table-dark-color: $white !default; 364 | $table-dark-bg: $gray-800 !default; 365 | $table-dark-accent-bg: rgba($white, .05) !default; 366 | $table-dark-hover-color: $table-dark-color !default; 367 | $table-dark-hover-bg: rgba($white, .075) !default; 368 | $table-dark-border-color: lighten($table-dark-bg, 7.5%) !default; 369 | $table-dark-color: $white !default; 370 | 371 | $table-striped-order: odd !default; 372 | 373 | $table-caption-color: $text-muted !default; 374 | 375 | $table-bg-level: -9 !default; 376 | $table-border-level: -6 !default; 377 | 378 | 379 | // Buttons + Forms 380 | // 381 | // Shared variables that are reassigned to `$input-` and `$btn-` specific variables. 382 | 383 | $input-btn-padding-y: .375rem !default; 384 | $input-btn-padding-x: .75rem !default; 385 | $input-btn-font-family: null !default; 386 | $input-btn-font-size: $font-size-base !default; 387 | $input-btn-line-height: $line-height-base !default; 388 | 389 | $input-btn-focus-width: .2rem !default; 390 | $input-btn-focus-color: rgba($component-active-bg, .25) !default; 391 | $input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default; 392 | 393 | $input-btn-padding-y-sm: .25rem !default; 394 | $input-btn-padding-x-sm: .5rem !default; 395 | $input-btn-font-size-sm: $font-size-sm !default; 396 | $input-btn-line-height-sm: $line-height-sm !default; 397 | 398 | $input-btn-padding-y-lg: .5rem !default; 399 | $input-btn-padding-x-lg: 1rem !default; 400 | $input-btn-font-size-lg: $font-size-lg !default; 401 | $input-btn-line-height-lg: $line-height-lg !default; 402 | 403 | $input-btn-border-width: $border-width !default; 404 | 405 | 406 | // Buttons 407 | // 408 | // For each of Bootstrap's buttons, define text, background, and border color. 409 | 410 | $btn-padding-y: $input-btn-padding-y !default; 411 | $btn-padding-x: $input-btn-padding-x !default; 412 | $btn-font-family: $input-btn-font-family !default; 413 | $btn-font-size: $input-btn-font-size !default; 414 | $btn-line-height: $input-btn-line-height !default; 415 | 416 | $btn-padding-y-sm: $input-btn-padding-y-sm !default; 417 | $btn-padding-x-sm: $input-btn-padding-x-sm !default; 418 | $btn-font-size-sm: $input-btn-font-size-sm !default; 419 | $btn-line-height-sm: $input-btn-line-height-sm !default; 420 | 421 | $btn-padding-y-lg: $input-btn-padding-y-lg !default; 422 | $btn-padding-x-lg: $input-btn-padding-x-lg !default; 423 | $btn-font-size-lg: $input-btn-font-size-lg !default; 424 | $btn-line-height-lg: $input-btn-line-height-lg !default; 425 | 426 | $btn-border-width: $input-btn-border-width !default; 427 | 428 | $btn-font-weight: $font-weight-normal !default; 429 | $btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default; 430 | $btn-focus-width: $input-btn-focus-width !default; 431 | $btn-focus-box-shadow: $input-btn-focus-box-shadow !default; 432 | $btn-disabled-opacity: .65 !default; 433 | $btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default; 434 | 435 | $btn-link-disabled-color: $gray-600 !default; 436 | 437 | $btn-block-spacing-y: .5rem !default; 438 | 439 | // Allows for customizing button radius independently from global border radius 440 | $btn-border-radius: $border-radius !default; 441 | $btn-border-radius-lg: $border-radius-lg !default; 442 | $btn-border-radius-sm: $border-radius-sm !default; 443 | 444 | $btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; 445 | 446 | 447 | // Forms 448 | 449 | $label-margin-bottom: .5rem !default; 450 | 451 | $input-padding-y: $input-btn-padding-y !default; 452 | $input-padding-x: $input-btn-padding-x !default; 453 | $input-font-family: $input-btn-font-family !default; 454 | $input-font-size: $input-btn-font-size !default; 455 | $input-font-weight: $font-weight-base !default; 456 | $input-line-height: $input-btn-line-height !default; 457 | 458 | $input-padding-y-sm: $input-btn-padding-y-sm !default; 459 | $input-padding-x-sm: $input-btn-padding-x-sm !default; 460 | $input-font-size-sm: $input-btn-font-size-sm !default; 461 | $input-line-height-sm: $input-btn-line-height-sm !default; 462 | 463 | $input-padding-y-lg: $input-btn-padding-y-lg !default; 464 | $input-padding-x-lg: $input-btn-padding-x-lg !default; 465 | $input-font-size-lg: $input-btn-font-size-lg !default; 466 | $input-line-height-lg: $input-btn-line-height-lg !default; 467 | 468 | $input-bg: $white !default; 469 | $input-disabled-bg: $gray-200 !default; 470 | 471 | $input-color: $gray-700 !default; 472 | $input-border-color: $gray-400 !default; 473 | $input-border-width: $input-btn-border-width !default; 474 | $input-box-shadow: inset 0 1px 1px rgba($black, .075) !default; 475 | 476 | $input-border-radius: $border-radius !default; 477 | $input-border-radius-lg: $border-radius-lg !default; 478 | $input-border-radius-sm: $border-radius-sm !default; 479 | 480 | $input-focus-bg: $input-bg !default; 481 | $input-focus-border-color: lighten($component-active-bg, 25%) !default; 482 | $input-focus-color: $input-color !default; 483 | $input-focus-width: $input-btn-focus-width !default; 484 | $input-focus-box-shadow: $input-btn-focus-box-shadow !default; 485 | 486 | $input-placeholder-color: $gray-600 !default; 487 | $input-plaintext-color: $body-color !default; 488 | 489 | $input-height-border: $input-border-width * 2 !default; 490 | 491 | $input-height-inner: calc(#{$input-line-height * 1em} + #{$input-padding-y * 2}) !default; 492 | $input-height-inner-half: calc(#{$input-line-height * .5em} + #{$input-padding-y}) !default; 493 | $input-height-inner-quarter: calc(#{$input-line-height * .25em} + #{$input-padding-y / 2}) !default; 494 | 495 | $input-height: calc(#{$input-line-height * 1em} + #{$input-padding-y * 2} + #{$input-height-border}) !default; 496 | $input-height-sm: calc(#{$input-line-height-sm * 1em} + #{$input-btn-padding-y-sm * 2} + #{$input-height-border}) !default; 497 | $input-height-lg: calc(#{$input-line-height-lg * 1em} + #{$input-btn-padding-y-lg * 2} + #{$input-height-border}) !default; 498 | 499 | $input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; 500 | 501 | $form-text-margin-top: .25rem !default; 502 | 503 | $form-check-input-gutter: 1.25rem !default; 504 | $form-check-input-margin-y: .3rem !default; 505 | $form-check-input-margin-x: .25rem !default; 506 | 507 | $form-check-inline-margin-x: .75rem !default; 508 | $form-check-inline-input-margin-x: .3125rem !default; 509 | 510 | $form-grid-gutter-width: 10px !default; 511 | $form-group-margin-bottom: 1rem !default; 512 | 513 | $input-group-addon-color: $input-color !default; 514 | $input-group-addon-bg: $gray-200 !default; 515 | $input-group-addon-border-color: $input-border-color !default; 516 | 517 | $custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; 518 | 519 | $custom-control-gutter: .5rem !default; 520 | $custom-control-spacer-x: 1rem !default; 521 | 522 | $custom-control-indicator-size: 1rem !default; 523 | $custom-control-indicator-bg: $input-bg !default; 524 | 525 | $custom-control-indicator-bg-size: 50% 50% !default; 526 | $custom-control-indicator-box-shadow: $input-box-shadow !default; 527 | $custom-control-indicator-border-color: $gray-500 !default; 528 | $custom-control-indicator-border-width: $input-border-width !default; 529 | 530 | $custom-control-indicator-disabled-bg: $input-disabled-bg !default; 531 | $custom-control-label-disabled-color: $gray-600 !default; 532 | 533 | $custom-control-indicator-checked-color: $component-active-color !default; 534 | $custom-control-indicator-checked-bg: $component-active-bg !default; 535 | $custom-control-indicator-checked-disabled-bg: rgba(theme-color("primary"), .5) !default; 536 | $custom-control-indicator-checked-box-shadow: none !default; 537 | $custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default; 538 | 539 | $custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default; 540 | $custom-control-indicator-focus-border-color: $input-focus-border-color !default; 541 | 542 | $custom-control-indicator-active-color: $component-active-color !default; 543 | $custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default; 544 | $custom-control-indicator-active-box-shadow: none !default; 545 | $custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default; 546 | 547 | $custom-checkbox-indicator-border-radius: $border-radius !default; 548 | $custom-checkbox-indicator-icon-checked: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e"), "#", "%23") !default; 549 | 550 | $custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default; 551 | $custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default; 552 | $custom-checkbox-indicator-icon-indeterminate: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/%3e%3c/svg%3e"), "#", "%23") !default; 553 | $custom-checkbox-indicator-indeterminate-box-shadow: none !default; 554 | $custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default; 555 | 556 | $custom-radio-indicator-border-radius: 50% !default; 557 | $custom-radio-indicator-icon-checked: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$custom-control-indicator-checked-color}'/%3e%3c/svg%3e"), "#", "%23") !default; 558 | 559 | $custom-switch-width: $custom-control-indicator-size * 1.75 !default; 560 | $custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default; 561 | $custom-switch-indicator-size: calc(#{$custom-control-indicator-size} - #{$custom-control-indicator-border-width * 4}) !default; 562 | 563 | $custom-select-padding-y: $input-padding-y !default; 564 | $custom-select-padding-x: $input-padding-x !default; 565 | $custom-select-font-family: $input-font-family !default; 566 | $custom-select-font-size: $input-font-size !default; 567 | $custom-select-height: $input-height !default; 568 | $custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator 569 | $custom-select-font-weight: $input-font-weight !default; 570 | $custom-select-line-height: $input-line-height !default; 571 | $custom-select-color: $input-color !default; 572 | $custom-select-disabled-color: $gray-600 !default; 573 | $custom-select-bg: $input-bg !default; 574 | $custom-select-disabled-bg: $gray-200 !default; 575 | $custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions 576 | $custom-select-indicator-color: $gray-800 !default; 577 | $custom-select-indicator: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e"), "#", "%23") !default; 578 | $custom-select-background: $custom-select-indicator no-repeat right $custom-select-padding-x center / $custom-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon) 579 | 580 | $custom-select-feedback-icon-padding-right: calc((1em + #{2 * $custom-select-padding-y}) * 3 / 4 + #{$custom-select-padding-x + $custom-select-indicator-padding}) !default; 581 | $custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default; 582 | $custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default; 583 | 584 | $custom-select-border-width: $input-border-width !default; 585 | $custom-select-border-color: $input-border-color !default; 586 | $custom-select-border-radius: $border-radius !default; 587 | $custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default; 588 | 589 | $custom-select-focus-border-color: $input-focus-border-color !default; 590 | $custom-select-focus-width: $input-focus-width !default; 591 | $custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default; 592 | 593 | $custom-select-padding-y-sm: $input-padding-y-sm !default; 594 | $custom-select-padding-x-sm: $input-padding-x-sm !default; 595 | $custom-select-font-size-sm: $input-font-size-sm !default; 596 | $custom-select-height-sm: $input-height-sm !default; 597 | 598 | $custom-select-padding-y-lg: $input-padding-y-lg !default; 599 | $custom-select-padding-x-lg: $input-padding-x-lg !default; 600 | $custom-select-font-size-lg: $input-font-size-lg !default; 601 | $custom-select-height-lg: $input-height-lg !default; 602 | 603 | $custom-range-track-width: 100% !default; 604 | $custom-range-track-height: .5rem !default; 605 | $custom-range-track-cursor: pointer !default; 606 | $custom-range-track-bg: $gray-300 !default; 607 | $custom-range-track-border-radius: 1rem !default; 608 | $custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default; 609 | 610 | $custom-range-thumb-width: 1rem !default; 611 | $custom-range-thumb-height: $custom-range-thumb-width !default; 612 | $custom-range-thumb-bg: $component-active-bg !default; 613 | $custom-range-thumb-border: 0 !default; 614 | $custom-range-thumb-border-radius: 1rem !default; 615 | $custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default; 616 | $custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default; 617 | $custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge 618 | $custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default; 619 | $custom-range-thumb-disabled-bg: $gray-500 !default; 620 | 621 | $custom-file-height: $input-height !default; 622 | $custom-file-height-inner: $input-height-inner !default; 623 | $custom-file-focus-border-color: $input-focus-border-color !default; 624 | $custom-file-focus-box-shadow: $input-focus-box-shadow !default; 625 | $custom-file-disabled-bg: $input-disabled-bg !default; 626 | 627 | $custom-file-padding-y: $input-padding-y !default; 628 | $custom-file-padding-x: $input-padding-x !default; 629 | $custom-file-line-height: $input-line-height !default; 630 | $custom-file-font-family: $input-font-family !default; 631 | $custom-file-font-weight: $input-font-weight !default; 632 | $custom-file-color: $input-color !default; 633 | $custom-file-bg: $input-bg !default; 634 | $custom-file-border-width: $input-border-width !default; 635 | $custom-file-border-color: $input-border-color !default; 636 | $custom-file-border-radius: $input-border-radius !default; 637 | $custom-file-box-shadow: $input-box-shadow !default; 638 | $custom-file-button-color: $custom-file-color !default; 639 | $custom-file-button-bg: $input-group-addon-bg !default; 640 | $custom-file-text: ( 641 | en: "Browse" 642 | ) !default; 643 | 644 | 645 | // Form validation 646 | 647 | $form-feedback-margin-top: $form-text-margin-top !default; 648 | $form-feedback-font-size: $small-font-size !default; 649 | $form-feedback-valid-color: theme-color("success") !default; 650 | $form-feedback-invalid-color: theme-color("danger") !default; 651 | 652 | $form-feedback-icon-valid-color: $form-feedback-valid-color !default; 653 | $form-feedback-icon-valid: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"), "#", "%23") !default; 654 | $form-feedback-icon-invalid-color: $form-feedback-invalid-color !default; 655 | $form-feedback-icon-invalid: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$form-feedback-icon-invalid-color}' viewBox='-2 -2 7 7'%3e%3cpath stroke='#{$form-feedback-icon-invalid-color}' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E"), "#", "%23") !default; 656 | 657 | $form-validation-states: () !default; 658 | // stylelint-disable-next-line scss/dollar-variable-default 659 | $form-validation-states: map-merge( 660 | ( 661 | "valid": ( 662 | "color": $form-feedback-valid-color, 663 | "icon": $form-feedback-icon-valid 664 | ), 665 | "invalid": ( 666 | "color": $form-feedback-invalid-color, 667 | "icon": $form-feedback-icon-invalid 668 | ), 669 | ), 670 | $form-validation-states 671 | ); 672 | 673 | // Z-index master list 674 | // 675 | // Warning: Avoid customizing these values. They're used for a bird's eye view 676 | // of components dependent on the z-axis and are designed to all work together. 677 | 678 | $zindex-dropdown: 1000 !default; 679 | $zindex-sticky: 1020 !default; 680 | $zindex-fixed: 1030 !default; 681 | $zindex-modal-backdrop: 1040 !default; 682 | $zindex-modal: 1050 !default; 683 | $zindex-popover: 1060 !default; 684 | $zindex-tooltip: 1070 !default; 685 | 686 | 687 | // Navs 688 | 689 | $nav-link-padding-y: .5rem !default; 690 | $nav-link-padding-x: 1rem !default; 691 | $nav-link-disabled-color: $gray-600 !default; 692 | 693 | $nav-tabs-border-color: $gray-300 !default; 694 | $nav-tabs-border-width: $border-width !default; 695 | $nav-tabs-border-radius: $border-radius !default; 696 | $nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default; 697 | $nav-tabs-link-active-color: $gray-700 !default; 698 | $nav-tabs-link-active-bg: $body-bg !default; 699 | $nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default; 700 | 701 | $nav-pills-border-radius: $border-radius !default; 702 | $nav-pills-link-active-color: $component-active-color !default; 703 | $nav-pills-link-active-bg: $component-active-bg !default; 704 | 705 | $nav-divider-color: $gray-200 !default; 706 | $nav-divider-margin-y: $spacer / 2 !default; 707 | 708 | 709 | // Navbar 710 | 711 | $navbar-padding-y: $spacer / 2 !default; 712 | $navbar-padding-x: $spacer !default; 713 | 714 | $navbar-nav-link-padding-x: .5rem !default; 715 | 716 | $navbar-brand-font-size: $font-size-lg !default; 717 | // Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link 718 | $nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default; 719 | $navbar-brand-height: $navbar-brand-font-size * $line-height-base !default; 720 | $navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default; 721 | 722 | $navbar-toggler-padding-y: .25rem !default; 723 | $navbar-toggler-padding-x: .75rem !default; 724 | $navbar-toggler-font-size: $font-size-lg !default; 725 | $navbar-toggler-border-radius: $btn-border-radius !default; 726 | 727 | $navbar-dark-color: rgba($white, .5) !default; 728 | $navbar-dark-hover-color: rgba($white, .75) !default; 729 | $navbar-dark-active-color: $white !default; 730 | $navbar-dark-disabled-color: rgba($white, .25) !default; 731 | $navbar-dark-toggler-icon-bg: str-replace(url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='#{$navbar-dark-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"), "#", "%23") !default; 732 | $navbar-dark-toggler-border-color: rgba($white, .1) !default; 733 | 734 | $navbar-light-color: rgba($black, .5) !default; 735 | $navbar-light-hover-color: rgba($black, .7) !default; 736 | $navbar-light-active-color: rgba($black, .9) !default; 737 | $navbar-light-disabled-color: rgba($black, .3) !default; 738 | $navbar-light-toggler-icon-bg: str-replace(url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"), "#", "%23") !default; 739 | $navbar-light-toggler-border-color: rgba($black, .1) !default; 740 | 741 | $navbar-light-brand-color: $navbar-light-active-color !default; 742 | $navbar-light-brand-hover-color: $navbar-light-active-color !default; 743 | $navbar-dark-brand-color: $navbar-dark-active-color !default; 744 | $navbar-dark-brand-hover-color: $navbar-dark-active-color !default; 745 | 746 | 747 | // Dropdowns 748 | // 749 | // Dropdown menu container and contents. 750 | 751 | $dropdown-min-width: 10rem !default; 752 | $dropdown-padding-y: .5rem !default; 753 | $dropdown-spacer: .125rem !default; 754 | $dropdown-font-size: $font-size-base !default; 755 | $dropdown-color: $body-color !default; 756 | $dropdown-bg: $white !default; 757 | $dropdown-border-color: rgba($black, .15) !default; 758 | $dropdown-border-radius: $border-radius !default; 759 | $dropdown-border-width: $border-width !default; 760 | $dropdown-inner-border-radius: calc(#{$dropdown-border-radius} - #{$dropdown-border-width}) !default; 761 | $dropdown-divider-bg: $gray-200 !default; 762 | $dropdown-divider-margin-y: $nav-divider-margin-y !default; 763 | $dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default; 764 | 765 | $dropdown-link-color: $gray-900 !default; 766 | $dropdown-link-hover-color: darken($gray-900, 5%) !default; 767 | $dropdown-link-hover-bg: $gray-100 !default; 768 | 769 | $dropdown-link-active-color: $component-active-color !default; 770 | $dropdown-link-active-bg: $component-active-bg !default; 771 | 772 | $dropdown-link-disabled-color: $gray-600 !default; 773 | 774 | $dropdown-item-padding-y: .25rem !default; 775 | $dropdown-item-padding-x: 1.5rem !default; 776 | 777 | $dropdown-header-color: $gray-600 !default; 778 | 779 | 780 | // Pagination 781 | 782 | $pagination-padding-y: .5rem !default; 783 | $pagination-padding-x: .75rem !default; 784 | $pagination-padding-y-sm: .25rem !default; 785 | $pagination-padding-x-sm: .5rem !default; 786 | $pagination-padding-y-lg: .75rem !default; 787 | $pagination-padding-x-lg: 1.5rem !default; 788 | $pagination-line-height: 1.25 !default; 789 | 790 | $pagination-color: $link-color !default; 791 | $pagination-bg: $white !default; 792 | $pagination-border-width: $border-width !default; 793 | $pagination-border-color: $gray-300 !default; 794 | 795 | $pagination-focus-box-shadow: $input-btn-focus-box-shadow !default; 796 | $pagination-focus-outline: 0 !default; 797 | 798 | $pagination-hover-color: $link-hover-color !default; 799 | $pagination-hover-bg: $gray-200 !default; 800 | $pagination-hover-border-color: $gray-300 !default; 801 | 802 | $pagination-active-color: $component-active-color !default; 803 | $pagination-active-bg: $component-active-bg !default; 804 | $pagination-active-border-color: $pagination-active-bg !default; 805 | 806 | $pagination-disabled-color: $gray-600 !default; 807 | $pagination-disabled-bg: $white !default; 808 | $pagination-disabled-border-color: $gray-300 !default; 809 | 810 | 811 | // Jumbotron 812 | 813 | $jumbotron-padding: 2rem !default; 814 | $jumbotron-color: null !default; 815 | $jumbotron-bg: $gray-200 !default; 816 | 817 | 818 | // Cards 819 | 820 | $card-spacer-y: .75rem !default; 821 | $card-spacer-x: 1.25rem !default; 822 | $card-border-width: $border-width !default; 823 | $card-border-radius: $border-radius !default; 824 | $card-border-color: rgba($black, .125) !default; 825 | $card-inner-border-radius: calc(#{$card-border-radius} - #{$card-border-width}) !default; 826 | $card-cap-bg: rgba($black, .03) !default; 827 | $card-cap-color: null !default; 828 | $card-color: null !default; 829 | $card-bg: $white !default; 830 | 831 | $card-img-overlay-padding: 1.25rem !default; 832 | 833 | $card-group-margin: $grid-gutter-width / 2 !default; 834 | $card-deck-margin: $card-group-margin !default; 835 | 836 | $card-columns-count: 3 !default; 837 | $card-columns-gap: 1.25rem !default; 838 | $card-columns-margin: $card-spacer-y !default; 839 | 840 | 841 | // Tooltips 842 | 843 | $tooltip-font-size: $font-size-sm !default; 844 | $tooltip-max-width: 200px !default; 845 | $tooltip-color: $white !default; 846 | $tooltip-bg: $black !default; 847 | $tooltip-border-radius: $border-radius !default; 848 | $tooltip-opacity: .9 !default; 849 | $tooltip-padding-y: .25rem !default; 850 | $tooltip-padding-x: .5rem !default; 851 | $tooltip-margin: 0 !default; 852 | 853 | $tooltip-arrow-width: .8rem !default; 854 | $tooltip-arrow-height: .4rem !default; 855 | $tooltip-arrow-color: $tooltip-bg !default; 856 | 857 | // Form tooltips must come after regular tooltips 858 | $form-feedback-tooltip-padding-y: $tooltip-padding-y !default; 859 | $form-feedback-tooltip-padding-x: $tooltip-padding-x !default; 860 | $form-feedback-tooltip-font-size: $tooltip-font-size !default; 861 | $form-feedback-tooltip-line-height: $line-height-base !default; 862 | $form-feedback-tooltip-opacity: $tooltip-opacity !default; 863 | $form-feedback-tooltip-border-radius: $tooltip-border-radius !default; 864 | 865 | 866 | // Popovers 867 | 868 | $popover-font-size: $font-size-sm !default; 869 | $popover-bg: $white !default; 870 | $popover-max-width: 276px !default; 871 | $popover-border-width: $border-width !default; 872 | $popover-border-color: rgba($black, .2) !default; 873 | $popover-border-radius: $border-radius-lg !default; 874 | $popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default; 875 | 876 | $popover-header-bg: darken($popover-bg, 3%) !default; 877 | $popover-header-color: $headings-color !default; 878 | $popover-header-padding-y: .5rem !default; 879 | $popover-header-padding-x: .75rem !default; 880 | 881 | $popover-body-color: $body-color !default; 882 | $popover-body-padding-y: $popover-header-padding-y !default; 883 | $popover-body-padding-x: $popover-header-padding-x !default; 884 | 885 | $popover-arrow-width: 1rem !default; 886 | $popover-arrow-height: .5rem !default; 887 | $popover-arrow-color: $popover-bg !default; 888 | 889 | $popover-arrow-outer-color: fade-in($popover-border-color, .05) !default; 890 | 891 | 892 | // Toasts 893 | 894 | $toast-max-width: 350px !default; 895 | $toast-padding-x: .75rem !default; 896 | $toast-padding-y: .25rem !default; 897 | $toast-font-size: .875rem !default; 898 | $toast-color: null !default; 899 | $toast-background-color: rgba($white, .85) !default; 900 | $toast-border-width: 1px !default; 901 | $toast-border-color: rgba(0, 0, 0, .1) !default; 902 | $toast-border-radius: .25rem !default; 903 | $toast-box-shadow: 0 .25rem .75rem rgba($black, .1) !default; 904 | 905 | $toast-header-color: $gray-600 !default; 906 | $toast-header-background-color: rgba($white, .85) !default; 907 | $toast-header-border-color: rgba(0, 0, 0, .05) !default; 908 | 909 | 910 | // Badges 911 | 912 | $badge-font-size: 75% !default; 913 | $badge-font-weight: $font-weight-bold !default; 914 | $badge-padding-y: .25em !default; 915 | $badge-padding-x: .4em !default; 916 | $badge-border-radius: $border-radius !default; 917 | 918 | $badge-transition: $btn-transition !default; 919 | $badge-focus-width: $input-btn-focus-width !default; 920 | 921 | $badge-pill-padding-x: .6em !default; 922 | // Use a higher than normal value to ensure completely rounded edges when 923 | // customizing padding or font-size on labels. 924 | $badge-pill-border-radius: 10rem !default; 925 | 926 | 927 | // Modals 928 | 929 | // Padding applied to the modal body 930 | $modal-inner-padding: 1rem !default; 931 | 932 | $modal-dialog-margin: .5rem !default; 933 | $modal-dialog-margin-y-sm-up: 1.75rem !default; 934 | 935 | $modal-title-line-height: $line-height-base !default; 936 | 937 | $modal-content-color: null !default; 938 | $modal-content-bg: $white !default; 939 | $modal-content-border-color: rgba($black, .2) !default; 940 | $modal-content-border-width: $border-width !default; 941 | $modal-content-border-radius: $border-radius-lg !default; 942 | $modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default; 943 | $modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default; 944 | 945 | $modal-backdrop-bg: $black !default; 946 | $modal-backdrop-opacity: .5 !default; 947 | $modal-header-border-color: $border-color !default; 948 | $modal-footer-border-color: $modal-header-border-color !default; 949 | $modal-header-border-width: $modal-content-border-width !default; 950 | $modal-footer-border-width: $modal-header-border-width !default; 951 | $modal-header-padding-y: 1rem !default; 952 | $modal-header-padding-x: 1rem !default; 953 | $modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility 954 | 955 | $modal-xl: 1140px !default; 956 | $modal-lg: 800px !default; 957 | $modal-md: 500px !default; 958 | $modal-sm: 300px !default; 959 | 960 | $modal-fade-transform: translate(0, -50px) !default; 961 | $modal-show-transform: none !default; 962 | $modal-transition: transform .3s ease-out !default; 963 | 964 | 965 | // Alerts 966 | // 967 | // Define alert colors, border radius, and padding. 968 | 969 | $alert-padding-y: .75rem !default; 970 | $alert-padding-x: 1.25rem !default; 971 | $alert-margin-bottom: 1rem !default; 972 | $alert-border-radius: $border-radius !default; 973 | $alert-link-font-weight: $font-weight-bold !default; 974 | $alert-border-width: $border-width !default; 975 | 976 | $alert-bg-level: -10 !default; 977 | $alert-border-level: -9 !default; 978 | $alert-color-level: 6 !default; 979 | 980 | 981 | // Progress bars 982 | 983 | $progress-height: 1rem !default; 984 | $progress-font-size: $font-size-base * .75 !default; 985 | $progress-bg: $gray-200 !default; 986 | $progress-border-radius: $border-radius !default; 987 | $progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default; 988 | $progress-bar-color: $white !default; 989 | $progress-bar-bg: theme-color("primary") !default; 990 | $progress-bar-animation-timing: 1s linear infinite !default; 991 | $progress-bar-transition: width .6s ease !default; 992 | 993 | 994 | // List group 995 | 996 | $list-group-color: null !default; 997 | $list-group-bg: $white !default; 998 | $list-group-border-color: rgba($black, .125) !default; 999 | $list-group-border-width: $border-width !default; 1000 | $list-group-border-radius: $border-radius !default; 1001 | 1002 | $list-group-item-padding-y: .75rem !default; 1003 | $list-group-item-padding-x: 1.25rem !default; 1004 | 1005 | $list-group-hover-bg: $gray-100 !default; 1006 | $list-group-active-color: $component-active-color !default; 1007 | $list-group-active-bg: $component-active-bg !default; 1008 | $list-group-active-border-color: $list-group-active-bg !default; 1009 | 1010 | $list-group-disabled-color: $gray-600 !default; 1011 | $list-group-disabled-bg: $list-group-bg !default; 1012 | 1013 | $list-group-action-color: $gray-700 !default; 1014 | $list-group-action-hover-color: $list-group-action-color !default; 1015 | 1016 | $list-group-action-active-color: $body-color !default; 1017 | $list-group-action-active-bg: $gray-200 !default; 1018 | 1019 | 1020 | // Image thumbnails 1021 | 1022 | $thumbnail-padding: .25rem !default; 1023 | $thumbnail-bg: $body-bg !default; 1024 | $thumbnail-border-width: $border-width !default; 1025 | $thumbnail-border-color: $gray-300 !default; 1026 | $thumbnail-border-radius: $border-radius !default; 1027 | $thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default; 1028 | 1029 | 1030 | // Figures 1031 | 1032 | $figure-caption-font-size: 90% !default; 1033 | $figure-caption-color: $gray-600 !default; 1034 | 1035 | 1036 | // Breadcrumbs 1037 | 1038 | $breadcrumb-padding-y: .75rem !default; 1039 | $breadcrumb-padding-x: 1rem !default; 1040 | $breadcrumb-item-padding: .5rem !default; 1041 | 1042 | $breadcrumb-margin-bottom: 1rem !default; 1043 | 1044 | $breadcrumb-bg: $gray-200 !default; 1045 | $breadcrumb-divider-color: $gray-600 !default; 1046 | $breadcrumb-active-color: $gray-600 !default; 1047 | $breadcrumb-divider: quote("/") !default; 1048 | 1049 | $breadcrumb-border-radius: $border-radius !default; 1050 | 1051 | 1052 | // Carousel 1053 | 1054 | $carousel-control-color: $white !default; 1055 | $carousel-control-width: 15% !default; 1056 | $carousel-control-opacity: .5 !default; 1057 | $carousel-control-hover-opacity: .9 !default; 1058 | $carousel-control-transition: opacity .15s ease !default; 1059 | 1060 | $carousel-indicator-width: 30px !default; 1061 | $carousel-indicator-height: 3px !default; 1062 | $carousel-indicator-hit-area-height: 10px !default; 1063 | $carousel-indicator-spacer: 3px !default; 1064 | $carousel-indicator-active-bg: $white !default; 1065 | $carousel-indicator-transition: opacity .6s ease !default; 1066 | 1067 | $carousel-caption-width: 70% !default; 1068 | $carousel-caption-color: $white !default; 1069 | 1070 | $carousel-control-icon-width: 20px !default; 1071 | 1072 | $carousel-control-prev-icon-bg: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e"), "#", "%23") !default; 1073 | $carousel-control-next-icon-bg: str-replace(url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e"), "#", "%23") !default; 1074 | 1075 | $carousel-transition-duration: .6s !default; 1076 | $carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`) 1077 | 1078 | 1079 | // Spinners 1080 | 1081 | $spinner-width: 2rem !default; 1082 | $spinner-height: $spinner-width !default; 1083 | $spinner-border-width: .25em !default; 1084 | 1085 | $spinner-width-sm: 1rem !default; 1086 | $spinner-height-sm: $spinner-width-sm !default; 1087 | $spinner-border-width-sm: .2em !default; 1088 | 1089 | 1090 | // Close 1091 | 1092 | $close-font-size: $font-size-base * 1.5 !default; 1093 | $close-font-weight: $font-weight-bold !default; 1094 | $close-color: $black !default; 1095 | $close-text-shadow: 0 1px 0 $white !default; 1096 | 1097 | 1098 | // Code 1099 | 1100 | $code-font-size: 87.5% !default; 1101 | $code-color: $pink !default; 1102 | 1103 | $kbd-padding-y: .2rem !default; 1104 | $kbd-padding-x: .4rem !default; 1105 | $kbd-font-size: $code-font-size !default; 1106 | $kbd-color: $white !default; 1107 | $kbd-bg: $gray-900 !default; 1108 | 1109 | $pre-color: $gray-900 !default; 1110 | $pre-scrollable-max-height: 340px !default; 1111 | 1112 | 1113 | // Utilities 1114 | 1115 | $displays: none, inline, inline-block, block, table, table-row, table-cell, flex, inline-flex !default; 1116 | $overflows: auto, hidden !default; 1117 | $positions: static, relative, absolute, fixed, sticky !default; 1118 | 1119 | 1120 | // Printing 1121 | 1122 | $print-page-size: a3 !default; 1123 | $print-body-min-width: map-get($grid-breakpoints, "lg") !default; 1124 | --------------------------------------------------------------------------------