32 | -------------------------------------------------------------------------------- /wp-dsfr-theme/home.php: -------------------------------------------------------------------------------- 1 | 4 |
5 | 8 |
9 | Beapi\Theme\Dsfr\Helpers\Misc\get_archive_tags_group_arg( 'category' ), 15 | ] 16 | ); 17 | ?> 18 |
19 | 2 ] ); 27 | endwhile; 28 | endif; 29 | ?> 30 |
31 | 32 | 33 |
34 |
35 | register_service( $name ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /wp-dsfr-theme/inc/Helpers/Custom_Menu_Walker.php: -------------------------------------------------------------------------------- 1 | classes, true ) ) { 24 | $sub_menu_id = 'menu-' . $item->ID; 25 | 26 | // replace the last link by a button 27 | $output = preg_replace( 28 | '/((.*)?<\/a>)$/', 29 | sprintf( '', $sub_menu_id ), 30 | $output 31 | ); 32 | 33 | $output .= sprintf( '
', esc_attr( $sub_menu_id ) ); 34 | $output .= '
    '; 35 | } 36 | } 37 | 38 | /** 39 | * @param $output 40 | * @param int $depth 41 | * @param array $args 42 | */ 43 | public function end_lvl( &$output, $depth = 0, $args = [] ) { 44 | $output .= '
'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /wp-dsfr-theme/inc/Helpers/DSFR.php: -------------------------------------------------------------------------------- 1 | __( 'Tilleul verveine', 'wp-dsfr-theme' ), 14 | 'green-bourgeon' => __( 'Bourgeon', 'wp-dsfr-theme' ), 15 | 'green-emeraude' => __( 'Émeraude', 'wp-dsfr-theme' ), 16 | 'green-menthe' => __( 'Menthe', 'wp-dsfr-theme' ), 17 | 'green-archipel' => __( 'Archipel', 'wp-dsfr-theme' ), 18 | 'blue-ecume' => __( 'Écume', 'wp-dsfr-theme' ), 19 | 'blue-cumulus' => __( 'Cumulus', 'wp-dsfr-theme' ), 20 | 'purple-glycine' => __( 'Glycine', 'wp-dsfr-theme' ), 21 | 'pink-macaron' => __( 'Macaron', 'wp-dsfr-theme' ), 22 | 'pink-tuile' => __( 'Tuile', 'wp-dsfr-theme' ), 23 | 'yellow-tournesol' => __( 'Tournesol', 'wp-dsfr-theme' ), 24 | 'yellow-moutarde' => __( 'Moutarde', 'wp-dsfr-theme' ), 25 | 'orange-terre-battue' => __( 'Terre battue', 'wp-dsfr-theme' ), 26 | 'brown-cafe-creme' => __( 'Café crème', 'wp-dsfr-theme' ), 27 | 'brown-caramel' => __( 'Caramel', 'wp-dsfr-theme' ), 28 | 'brown-opera' => __( 'Opéra', 'wp-dsfr-theme' ), 29 | 'beige-gris-galet' => __( 'Gris galet', 'wp-dsfr-theme' ), 30 | ]; 31 | 32 | if ( ! empty( $prefix ) ) { 33 | foreach ( $colors as $key => $color ) { 34 | $colors[ $prefix . $key ] = $colors[ $key ]; 35 | unset( $colors[ $key ] ); 36 | } 37 | } 38 | 39 | return $colors; 40 | } 41 | 42 | /** 43 | * Get dsfr colors 44 | * 45 | * @param string $prefix 46 | * 47 | * @return array $colors 48 | */ 49 | function get_dsfr_colors( string $prefix = '' ): array { 50 | return array_keys( get_dsfr_colors_with_label( $prefix ) ); 51 | } 52 | -------------------------------------------------------------------------------- /wp-dsfr-theme/inc/Helpers/Formatting/Escape.php: -------------------------------------------------------------------------------- 1 | absint( $term->term_id ), 20 | 'taxonomy' => esc_attr( $taxonomy ), 21 | ]; 22 | return wp_json_encode( $data ); 23 | } 24 | -------------------------------------------------------------------------------- /wp-dsfr-theme/inc/Helpers/Svg.php: -------------------------------------------------------------------------------- 1 | get_service( 'svg' ); 19 | return false !== $svg ? $svg->get_the_icon( $icon_class, $additionnal_classes ) : ''; 20 | } 21 | 22 | /** 23 | * @usage Beapi\Theme\Dsfr\Helpers\Svg\the_icon( 'like' ); 24 | * 25 | * @param string $icon_class 26 | * @param array $additionnal_classes 27 | */ 28 | function the_icon( string $icon_class, $additionnal_classes = [] ): void { 29 | /** 30 | * @var Svg $svg 31 | */ 32 | $svg = \Beapi\Theme\Dsfr\Framework::get_container()->get_service( 'svg' ); 33 | false !== $svg ? $svg->the_icon( $icon_class, $additionnal_classes ) : ''; 34 | } 35 | -------------------------------------------------------------------------------- /wp-dsfr-theme/inc/Interface_Module.php: -------------------------------------------------------------------------------- 1 | after_setup_theme(); 21 | } 22 | 23 | /** 24 | * @return string 25 | */ 26 | public function get_service_name(): string { 27 | return 'theme'; 28 | } 29 | 30 | /** 31 | * After setup theme 32 | */ 33 | public function after_setup_theme(): void { 34 | /** 35 | * Init the supports. 36 | */ 37 | $this->add_theme_supports(); 38 | $this->remove_theme_supports(); 39 | 40 | /** 41 | * Load translations. 42 | */ 43 | $this->i18n(); 44 | } 45 | 46 | /** 47 | * Set theme supports 48 | */ 49 | private function add_theme_supports(): void { 50 | // Add the theme support basic elements 51 | add_theme_support( 'align-wide' ); 52 | add_theme_support( 'responsive-embeds' ); 53 | add_theme_support( 'editor-styles' ); 54 | add_theme_support( 'wp-block-styles' ); 55 | add_theme_support( 'post-thumbnails' ); 56 | add_theme_support( 'html5', [ 'comment-list', 'comment-form', 'search-form', 'gallery', 'caption', 'script', 'style' ] ); 57 | add_theme_support( 'title-tag' ); 58 | add_theme_support( 'async-js' ); 59 | add_theme_support( 'yoast-seo-breadcrumbs' ); 60 | } 61 | 62 | /** 63 | * Remove theme supports 64 | */ 65 | private function remove_theme_supports(): void { 66 | // remove the theme support basic elements 67 | remove_theme_support( 'core-block-patterns' ); 68 | } 69 | 70 | /** 71 | * i18n 72 | */ 73 | private function i18n(): void { 74 | // Load theme texdomain 75 | load_theme_textdomain( 'framework-textdomain', \get_theme_file_path( '/languages' ) ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /wp-dsfr-theme/inc/Tools/Assets.php: -------------------------------------------------------------------------------- 1 | 8 |
9 | 10 |
11 | 12 |
13 | 14 |
15 | 8 |
9 | 10 |
11 | 12 |
13 | 14 |
15 | 9 | 10 |
11 | 12 |

13 | 14 | 15 | 16 |
17 | 18 | 19 |
20 | 21 |
22 | 23 | 24 | 25 |

26 | 27 | 28 | 29 |

30 | 31 |
32 | 33 | 34 |
35 | 36 |
37 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/arguments.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |

13 | 14 | 15 | 16 |
17 | 18 | 19 |
20 | 21 |
22 | 23 | 24 | 25 |

26 | 27 | 28 | 29 |

30 | 31 |
32 | 33 | 34 |
35 | 36 |
37 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-alert-sm.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |

13 | 14 |
15 | 16 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-alert.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |

13 | 14 | 15 | 16 |

17 | 18 |
19 | 20 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-badge.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |

11 | 12 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-badges-group.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
    11 | 12 |
  • 13 | 14 | 15 | 16 |
  • 17 | 18 | 19 | 20 |
  • 21 | 22 |
23 | 24 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-btn-arrow-left.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-btn-arrow-right.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-btn-download-left.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-btn-download-right.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-callout.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |

13 | 14 | 15 | 16 |

17 | 18 | 19 | 20 |
21 | 22 |
23 | 24 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-highlight-informations.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |

13 | 14 | 15 | 16 |

17 | 18 | 19 | 24 | 25 |

:

26 | 27 | 28 | 29 |
30 | 31 |

32 | 33 |
34 | 35 | 38 |
39 | 40 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-highlight.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |

13 | 14 |
15 | 16 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-link-arrow-left.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-link-arrow-right.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-link-download-left.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-link-download-right.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/fr-table-informations.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |

13 | 14 | 15 | 16 |

17 | 18 | 19 | 24 | 25 |

:

26 | 27 | 28 | 29 |
30 | 31 | 34 |
35 | 36 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/hero-front-page-with-background.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |
13 | 14 |
15 | 16 |

17 | 18 | 19 | 20 |

21 | 22 | 23 | 24 |
25 | 26 | 27 |
28 | 29 |
30 | 31 | 32 | 33 |
34 | 35 |
36 | 37 |
38 | 39 |
40 | 41 |
42 | 43 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/hero-front-page.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |
13 | 14 |
15 | 16 |

17 | 18 | 19 | 20 |

21 | 22 | 23 | 24 |
25 | 26 | 27 |
28 | 29 |
30 | 31 | 32 | 33 |
34 | 35 |
36 | 37 |
38 | 39 |
40 | 41 |
42 | 43 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/hero-title-image-with-background.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |
13 | 14 |

15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | -------------------------------------------------------------------------------- /wp-dsfr-theme/patterns/hero-title-image.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |
13 | 14 |

15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | -------------------------------------------------------------------------------- /wp-dsfr-theme/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeAPI/wp-dsfr/a2047ca452bf05cea6f858f1d9548e1140aee480/wp-dsfr-theme/screenshot.png -------------------------------------------------------------------------------- /wp-dsfr-theme/search.php: -------------------------------------------------------------------------------- 1 | 4 |
5 |
6 |
7 |

8 | 17 |

18 |
19 |
20 |
21 |
22 |
23 | 24 |
25 |
26 | 36 | 37 |
38 |
39 |
40 |
41 | 7 | 25 | -------------------------------------------------------------------------------- /wp-dsfr-theme/single.php: -------------------------------------------------------------------------------- 1 | 8 |
9 | 10 |
11 | 12 |
13 | 16 |
17 | ' 22 | 23 | if (detail) { 24 | html += ' ' + detail.outerHTML 25 | } 26 | 27 | el.innerHTML = html 28 | el.classList.add('has-js-fr-download-link-icon') 29 | } 30 | } 31 | } 32 | 33 | // ---- 34 | // init 35 | // ---- 36 | FrLinkDownload.init('.fr-link--download, .wp-block-file a:first-child') 37 | 38 | // ---- 39 | // export 40 | // ---- 41 | export default FrLinkDownload 42 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/js/classes/HeaderSearch.js: -------------------------------------------------------------------------------- 1 | import AbstractDomElement from './AbstractDomElement' 2 | 3 | // ---- 4 | // class 5 | // ---- 6 | class HeaderSearch extends AbstractDomElement { 7 | constructor(element, options) { 8 | const instance = super(element, options) 9 | 10 | // avoid double init : 11 | if (!instance.isNewInstance()) { 12 | return instance 13 | } 14 | 15 | this._onFocus = () => { 16 | this._element.querySelector('input[type="search"]').focus() 17 | } 18 | 19 | this._element.addEventListener('focus', this._onFocus) 20 | } 21 | 22 | destroy() { 23 | super.destroy() 24 | this._element.removeEventListener('focus', this._onFocus) 25 | } 26 | } 27 | 28 | // ---- 29 | // init 30 | // ---- 31 | HeaderSearch.init('#header-search[tabindex="-1"]') 32 | 33 | // ---- 34 | // export 35 | // ---- 36 | export default HeaderSearch 37 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/js/classes/Overflow.js: -------------------------------------------------------------------------------- 1 | import AbstractDomElement from './AbstractDomElement' 2 | import { ThrottledEvent } from 'oneloop.js' 3 | 4 | // ---- 5 | // class 6 | // ---- 7 | class Overflow extends AbstractDomElement { 8 | constructor(element, options) { 9 | const instance = super(element, options) 10 | 11 | // avoid double init : 12 | if (!instance.isNewInstance()) { 13 | return instance 14 | } 15 | 16 | const scroll = new ThrottledEvent(this._element, 'scroll') 17 | const resize = ThrottledEvent.getInstance(window, 'resize') 18 | const onEvent = this.checkScrollPosition.bind(this) 19 | 20 | scroll.add('scroll', onEvent) 21 | resize.add('resize', onEvent) 22 | 23 | this.checkScrollPosition() 24 | } 25 | 26 | checkScrollPosition() { 27 | const el = this._element 28 | 29 | el.style.setProperty('--s', el.scrollLeft + 'px') 30 | el.classList.toggle('has-hidden-content-left', el.scrollLeft > 0) 31 | el.classList.toggle('has-hidden-content-right', el.scrollLeft < el.scrollWidth - el.offsetWidth) 32 | } 33 | } 34 | 35 | // ---- 36 | // init 37 | // ---- 38 | Overflow.init('.wp-block-table') 39 | 40 | // ---- 41 | // export 42 | // ---- 43 | export default Overflow 44 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/js/index.js: -------------------------------------------------------------------------------- 1 | import './classes/Overflow' 2 | import './classes/HeaderSearch' 3 | import './classes/FrLinkDownload' 4 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/js/post-build.js: -------------------------------------------------------------------------------- 1 | function requireAll(r) { 2 | r.keys().forEach(r) 3 | } 4 | 5 | // SVG 6 | requireAll(require.context('../img/icons', true, /\.svg$/)) 7 | 8 | // STATIC 9 | requireAll(require.context('../img/static', true, /\.(png|jpe?g|gif)$/)) 10 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/js/utils/each.js: -------------------------------------------------------------------------------- 1 | export default function (array, callback) { 2 | const l = array.length 3 | var i 4 | 5 | for (i = 0; i < l; i++) { 6 | callback(array[i], i, l) 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/js/utils/extend.js: -------------------------------------------------------------------------------- 1 | import isPlainObject from './isPlainObject' 2 | 3 | export default function extend() { 4 | const args = arguments 5 | const firstArgIsBool = typeof args[0] === 'boolean' 6 | const deep = firstArgIsBool ? args[0] : false 7 | const start = firstArgIsBool ? 1 : 0 8 | const rt = isPlainObject(args[start]) ? args[start] : {} 9 | var i 10 | var prop 11 | 12 | for (i = start + 1; i < args.length; i++) { 13 | for (prop in args[i]) { 14 | if (deep && isPlainObject(args[i][prop])) { 15 | rt[prop] = extend(true, {}, rt[prop], args[i][prop]) 16 | } else if (typeof args[i][prop] !== 'undefined') { 17 | rt[prop] = args[i][prop] 18 | } 19 | } 20 | } 21 | 22 | return rt 23 | } 24 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/js/utils/isPlainObject.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * is-plain-object 3 | * 4 | * Copyright (c) 2014-2017, Jon Schlinkert. 5 | * Released under the MIT License. 6 | */ 7 | 8 | function isObject(o) { 9 | return Object.prototype.toString.call(o) === '[object Object]' 10 | } 11 | 12 | export default function isPlainObject(o) { 13 | let ctor, prot 14 | 15 | if (isObject(o) === false) { 16 | return false 17 | } 18 | 19 | // If has modified constructor 20 | ctor = o.constructor 21 | if (ctor === undefined) { 22 | return true 23 | } 24 | 25 | // If has modified prototype 26 | prot = ctor.prototype 27 | if (isObject(prot) === false) { 28 | return false 29 | } 30 | 31 | // If constructor does not have an Object-specific method 32 | // eslint-disable-next-line no-prototype-builtins 33 | if (prot.hasOwnProperty('isPrototypeOf') === false) { 34 | return false 35 | } 36 | 37 | // Most likely a plain Object 38 | return true 39 | } 40 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/01-abstract/_constants.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants 3 | */ 4 | 5 | // ========== 6 | // Easings - Author: Scotty Vernon - Licensed under a MIT License 7 | // ========== 8 | $ease-in-sine: cubic-bezier(.47, 0, .745, .715); 9 | $ease-out-sine: cubic-bezier(.39, .575, .565, 1); 10 | $ease-in-out-sine: cubic-bezier(.37, 0, .63, 1); 11 | 12 | $ease-in-quad: cubic-bezier(.55, .085, .68, .53); 13 | $ease-out-quad: cubic-bezier(.25, .46, .45, .94); 14 | $ease-in-out-quad: cubic-bezier(.45, 0, .55, 1); 15 | 16 | $ease-in-cubic: cubic-bezier(.55, .055, .675, .19); 17 | $ease-out-cubic: cubic-bezier(.215, .61, .355, 1); 18 | $ease-in-out-cubic: cubic-bezier(.65, 0, .35, 1); 19 | 20 | $ease-in-quart: cubic-bezier(.895, .03, .685, .22); 21 | $ease-out-quart: cubic-bezier(.165, .84, .44, 1); 22 | $ease-in-out-quart: cubic-bezier(.76, 0, .24, 1); 23 | 24 | $ease-in-quint: cubic-bezier(.755, .05, .855, .06); 25 | $ease-out-quint: cubic-bezier(.23, 1, .32, 1); 26 | $ease-in-out-quint: cubic-bezier(.83, 0, .17, 1); 27 | 28 | $ease-in-expo: cubic-bezier(.95, .05, .795, .035); 29 | $ease-out-expo: cubic-bezier(.19, 1, .22, 1); 30 | $ease-in-out-expo: cubic-bezier(.87, 0, .13, 1); 31 | 32 | $ease-in-circ: cubic-bezier(.6, .04, .98, .335); 33 | $ease-out-circ: cubic-bezier(.075, .82, .165, 1); 34 | $ease-in-out-circ: cubic-bezier(.85, 0, .15, 1); 35 | 36 | $ease-in-back: cubic-bezier(.6, -.28, .735, .045); 37 | $ease-out-back: cubic-bezier(.175, .885, .32, 1.275); 38 | $ease-in-out-back: cubic-bezier(.68, -.55, .265, 1.55); 39 | 40 | $ease-in-out-fast: cubic-bezier(1, 0, 0, 1); 41 | 42 | $authentic-motion: cubic-bezier(.4, 0, .2, 1); 43 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/01-abstract/abstract.scss: -------------------------------------------------------------------------------- 1 | @import "./constants"; 2 | @import "./variables"; 3 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_f-assign-inputs.scss: -------------------------------------------------------------------------------- 1 | @use "sass:list"; 2 | @use "sass:string"; 3 | 4 | /** 5 | * Assign inputs 6 | */ 7 | 8 | @function assign-inputs($inputs, $pseudo: null) { 9 | $list: (); 10 | 11 | @each $input in $inputs { 12 | $input: string.unquote($input); 13 | $input: if($pseudo, $input + ":" + $pseudo, $input); 14 | $list: list.append($list, $input, comma); 15 | } 16 | 17 | @return $list; 18 | } 19 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_f-context-align.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Align 3 | * 4 | * examples : 5 | * 6 | * #{ context-align("wide") } .block#{ context-align() } { 7 | * ... your css 8 | * } 9 | * 10 | * return for style.scss : 11 | * .block.alignwide { 12 | * ... your css 13 | * } 14 | * 15 | * return for editor.scss : 16 | * [data-align="wide"] > .block { 17 | * ... your css 18 | * } 19 | * 20 | */ 21 | 22 | $function-context-align-last-value: ""; 23 | 24 | @function context-align($value: null, $suffix: " > ") { 25 | @if not $value { 26 | @if ($entry-file-name == "style") { 27 | @return ".align" + $function-context-align-last-value; 28 | } 29 | } @else { 30 | $function-context-align-last-value: $value !global; 31 | 32 | @if ($entry-file-name == "editor") { 33 | @return "[data-align=\"" + $value + "\"]" + $suffix; 34 | } 35 | } 36 | 37 | @return ""; 38 | } 39 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_f-em.scss: -------------------------------------------------------------------------------- 1 | @use "sass:math"; 2 | 3 | /** 4 | * Em 5 | * 6 | * convert value from px to em 7 | */ 8 | 9 | @function em($pxval, $base: $font-size-base) { 10 | 11 | @if not unitless($pxval) { 12 | $pxval: strip-units($pxval); 13 | } 14 | 15 | @if not unitless($base) { 16 | $base: strip-units($base); 17 | } 18 | 19 | @return math.div($pxval, $base) * 1em; 20 | } 21 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_f-get-gutter-width.scss: -------------------------------------------------------------------------------- 1 | @use "sass:map"; 2 | 3 | /** 4 | * Get Gutter width 5 | * 6 | * get the value of gutter according to the preset 7 | */ 8 | 9 | @function get-gutter($preset: d) { 10 | @return map.get(map.get($column-preset, $preset), gutter-width); 11 | } 12 | 13 | @function get-gutter-width($preset: d) { 14 | @return get-gutter($preset) * 1px; 15 | } 16 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_f-get-svg-url.scss: -------------------------------------------------------------------------------- 1 | @use "sass:map"; 2 | 3 | /** 4 | * get-svg-url 5 | * 6 | * examples : 7 | * get-svg-url("arrow") 8 | * get-svg-url("arrow", $color-primary) 9 | * 10 | */ 11 | 12 | @function get-svg-url($name: null, $fill: $color-dark, $opacity: 1, $style: "") { 13 | 14 | $svgs: ( 15 | // name-of-the-svg: (viewBox, content of the svg element) 16 | "arrow": ("0 0 18 14", "%3Cpath d='M17.25 7 10.37.12l-.96.97 5.2 5.22H.76V7.7h13.87L9.4 12.9l.96.96L17.25 7Z'/%3E"), 17 | "down": ("0 0 11.2 6.7", "3Cpath d='M0 .5C0 .4.1.2.2.1c.2-.2.5-.1.7.1l4.6 5.3.1.1s.1 0 .1-.1L10.3.1c.2-.1.5-.2.7 0 .2.2.2.5.1.7L6.5 6.2c-.2.3-.5.5-.9.5s-.7-.2-.9-.6L.1.8C0 .7 0 .6 0 .5z'/%3E"), 18 | "download": ("0 0 24 24","%3Cpath d='M3 19h18v2H3v-2Zm10-5.8L19 7l1.5 1.4L12 17 3.5 8.5 5 7.1l6.1 6V2h2v11.2Z'/%3E") 19 | ); 20 | 21 | @if not map-has-key($svgs, $name) { 22 | @return ""; 23 | } 24 | 25 | @if ($style != "") { 26 | $style: " style='" + $style + "'"; 27 | } 28 | 29 | @if ($fill != "") { 30 | $fill: " fill='rgba(#{red($fill), green($fill), blue($fill), $opacity})'"; 31 | } 32 | 33 | @return url("data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg'" + $fill + $style + " viewBox='" + nth(map.get($svgs, $name), 1) + "'%3E%" + nth(map.get($svgs, $name), 2) + "%3C/svg%3E"); /* stylelint-disable-line */ 34 | } 35 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_f-strip-units.scss: -------------------------------------------------------------------------------- 1 | @use "sass:math"; 2 | 3 | /** 4 | * Strip units 5 | */ 6 | 7 | @function strip-units($value) { 8 | 9 | @return math.div($value, ($value * 0 + 1)); 10 | } 11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_f-to-number.scss: -------------------------------------------------------------------------------- 1 | @use "sass:map"; 2 | @use "sass:math"; 3 | @use "sass:string"; 4 | 5 | /** 6 | * To number - convert string to number 7 | * 8 | * @author: Stackoverflow - https://stackoverflow.com/questions/47630616/scss-arithmetic-operation-with-string 9 | * 10 | * @param string $value 11 | * 12 | * Examples : 13 | * @for (dollar)i from 1 through 6 { 14 | * &[data-per-line="#{(dollar)i}"] { 15 | * .card { 16 | * width: column(to-number(#{math(dot)div(12, (dollar)i + 1)})); 17 | * } 18 | * } 19 | * } 20 | */ 21 | 22 | @function to-number($value) { 23 | @if type-of($value) == "number" { 24 | @return $value; 25 | } @else if type-of($value) != "string" { 26 | @error "Value for `to-number` should be a number or a string."; 27 | } 28 | 29 | $result: 0; 30 | $digits: 0; 31 | $minus: string.slice($value, 1, 1) == "-"; 32 | $numbers: ("0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9); 33 | 34 | @for $i from if($minus, 2, 1) through str-length($value) { 35 | $character: string.slice($value, $i, $i); 36 | 37 | @if (index(map-keys($numbers), $character) or $character == ".") { 38 | @if $character == "." { 39 | $digits: 1; 40 | } @else if $digits == 0 { 41 | $result: $result * 10 + map.get($numbers, $character); 42 | } @else { 43 | $digits: $digits * 10; 44 | $result: $result + math.div(map.get($numbers, $character), $digits); 45 | } 46 | } 47 | } 48 | 49 | @return if($minus, -$result, $result); 50 | } 51 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-align.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Align 3 | * 4 | * default: float left 5 | */ 6 | 7 | @mixin align($direction: left) { 8 | float: $direction; 9 | 10 | @if ($direction == left) { 11 | margin-right: $spacing-5; 12 | } @else { 13 | margin-left: $spacing-5; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-autofill.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Autofill 3 | * 4 | * webkit autofill 5 | */ 6 | 7 | @mixin autofill { 8 | &:-webkit-autofill, 9 | &:-webkit-autofill:hover, 10 | &:-webkit-autofill:focus { 11 | @content; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-background-static.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Background retina 3 | * Use with caution 4 | * 5 | * examples : 6 | * @include background-static("your-image"); 7 | * 8 | */ 9 | 10 | @mixin background-static($filename, $retina: true, $position: center center, $size: auto 100%, $type: "png" ) { 11 | background-image: url(../img/static/#{$filename}.#{$type}); 12 | background-repeat: no-repeat; 13 | background-position: $position; 14 | background-size: $size; 15 | 16 | @if ($retina) { 17 | @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 18 | background-image: url(../img/static/#{$filename}@2x.#{$type}); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-bg-fullwidth.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Background fullwidth mixin in a container 3 | */ 4 | 5 | @mixin bg-fullwidth($color: $color-grey-100) { 6 | position: relative; 7 | 8 | &::before { 9 | position: absolute; 10 | top: 0; 11 | left: 50%; 12 | width: 100vw; 13 | height: 100%; 14 | pointer-events: none; 15 | content: ""; 16 | background-color: $color; 17 | transform: translate3d(-50%, 0, 0); 18 | 19 | @include style-only { 20 | z-index: -1; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-block-vertical-spacing.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Block vertical spacing 3 | */ 4 | 5 | @mixin block-vertical-spacing($type : margin, $spacing : $spacing-9) { 6 | #{context-selector(".blocks-container > &", ".is-root-container &")} { 7 | #{$type}-top: $spacing; 8 | #{$type}-bottom: $spacing; 9 | 10 | @if $type == padding { 11 | margin-top: 0; 12 | margin-bottom: 0; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-breakpoint.scss: -------------------------------------------------------------------------------- 1 | @use "sass:map"; 2 | 3 | /** 4 | * Breakpoints 5 | * 6 | * examples : 7 | * 8 | * @include breakpoints(sm, md) { ... } 9 | * return @media screen and (min-width: 768px) and (max-width: 1024px) { ... } 10 | * 11 | * @include breakpoints(sm, max) { ... } 12 | * return @media screen and (max-width: 767px) { ... } 13 | * 14 | * @include breakpoints(sm) or @include breakpoints(sm, min) { ... } 15 | * return @media screen and (min-width: 768px) { ... } 16 | * 17 | */ 18 | 19 | @mixin breakpoints($breakpoint, $min-or-max-or-breakpoint: min) { 20 | $font-size: 16px; // don't use em function whitout param, $font-size-base can be modified 21 | 22 | @if (type-of(map.get($breakpoints, $min-or-max-or-breakpoint)) == "number") { 23 | 24 | @media screen and (min-width: em(map.get($breakpoints, $breakpoint), $font-size)) and (max-width: em(map.get($breakpoints, $min-or-max-or-breakpoint) - 1, $font-size)) { 25 | @content; 26 | } 27 | } @else if ($min-or-max-or-breakpoint == max) { 28 | 29 | @media screen and (max-width: em(map.get($breakpoints, $breakpoint) - 1, $font-size)) { 30 | @content; 31 | } 32 | } @else { 33 | 34 | @media screen and (min-width: em(map.get($breakpoints, $breakpoint), $font-size)) { 35 | @content; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-checkbox-custom.scss: -------------------------------------------------------------------------------- 1 | @use "sass:math"; 2 | 3 | /** 4 | * Checkbox custom 5 | */ 6 | 7 | @mixin checkbox-custom($color: $color-primary, $size: 18px, $border-width: 1px) { 8 | @include sr-only; 9 | 10 | + label { 11 | position: relative; 12 | display: block; 13 | padding-left: $size + 20; 14 | cursor: pointer; 15 | 16 | &::before { 17 | position: absolute; 18 | top: 1px; 19 | left: 0; 20 | width: $size; 21 | height: $size; 22 | margin: 0; 23 | content: ""; 24 | background-color: $color-light; 25 | border: $border-width solid $color; 26 | } 27 | 28 | &::after { 29 | position: absolute; 30 | top: 7px; 31 | left: math.round(math.div($size, 2)); 32 | width: math.round(math.div($size, 1.5)); 33 | height: math.round(math.div($size, 2.5)); 34 | content: ""; 35 | border-color: $color; 36 | border-style: solid; 37 | border-width: 0 0 2px 2px; 38 | opacity: 0; 39 | transition: opacity .2s; 40 | transform: translate(-50%, -50%) rotate(-45deg); 41 | } 42 | } 43 | } 44 | 45 | @mixin checkbox-custom-checked { 46 | + label { 47 | &::after { 48 | opacity: 1; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-clearflex.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Clearflex : clear:left for flexbox 3 | */ 4 | 5 | @mixin clearflex { 6 | &::after { 7 | display: flex; 8 | margin-left: auto; 9 | content: ""; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-container-query.scss: -------------------------------------------------------------------------------- 1 | @use "sass:map"; 2 | 3 | /** 4 | * Container Query 5 | * 6 | * examples : 7 | * 8 | * @include container-query(sm, md, name) { ... } 9 | * return @container name (min-width: 768px) and (max-width: 1024px) { ... } 10 | * 11 | * @include container-query(sm, max, name) { ... } 12 | * return @container (max-width: 767px) { ... } 13 | * 14 | * @include container-query(sm, min, name) { ... } 15 | * return @container name (min-width: 768px) { ... } 16 | * 17 | */ 18 | 19 | @mixin container-query($breakpoint, $min-or-max-or-breakpoint: min, $container-name: "") { 20 | $font-size: 16px; // don't use em function whitout param, $font-size-base can be modified 21 | 22 | @if (type-of(map.get($breakpoints, $min-or-max-or-breakpoint)) == "number") { 23 | 24 | @container #{$container-name} (min-width: #{em(map.get($breakpoints, $breakpoint), $font-size)}) and (max-width: #{em(map.get($breakpoints, $min-or-max-or-breakpoint) - 1, $font-size)}) { 25 | 26 | @content; 27 | } 28 | } @else if ($min-or-max-or-breakpoint == max) { 29 | 30 | @container #{$container-name} (max-width: #{em(map.get($breakpoints, $breakpoint) - 1, $font-size)}) { 31 | 32 | @content; 33 | } 34 | } @else { 35 | 36 | @container #{$container-name} (min-width: #{em(map.get($breakpoints, $breakpoint), $font-size)}) { 37 | 38 | @content; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-container.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Container 3 | */ 4 | 5 | @mixin container { 6 | width: $container-wide; 7 | max-width: calc(100% - var(--external-gutter) * 2); 8 | margin-right: auto; 9 | margin-left: auto; 10 | } 11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-declare-font-face.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Declare font face 3 | * 4 | * used in base/_fonts.scss 5 | */ 6 | 7 | @mixin declare-font-face($font-family, $font-filename, $font-weight : normal, $font-style : normal, $font-stretch : normal, $font-format : "woff2") { 8 | 9 | @font-face { 10 | font-family: "#{$font-family}"; 11 | font-style: $font-style; 12 | font-weight: $font-weight; 13 | font-stretch: $font-stretch; 14 | src: url(#{$font-filename}.woff2) format("#{$font-format}"); 15 | font-display: swap; 16 | unicode-range: U+0-10FFFF; /* cutting of the font file for better loading */ 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-editor-only.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor style only 3 | * 4 | * Style inside the mixin while be writed only for editor.scss 5 | * 6 | * @include editor-only { 7 | * ... css only for the gutenberg editor 8 | * } 9 | * 10 | * the variable $entry-file-name is defined in style.scss and editor.scss 11 | */ 12 | 13 | @mixin editor-only { 14 | @if ($entry-file-name == "editor") { 15 | @content; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-heading.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Heading mixins 3 | */ 4 | 5 | @mixin heading($name: h1, $style: default) { 6 | margin-bottom: $title-spacing; 7 | font-size: var(--title--font-size-#{$name}); 8 | font-weight: 700; 9 | line-height: var(--title--line-height-#{$name}); 10 | color: var(--text-title-grey); 11 | } 12 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-hover.scss: -------------------------------------------------------------------------------- 1 | @use "sass:list"; 2 | 3 | /** 4 | * Add active, focus and hover pseudo selectors to element 5 | * @param {string||list} $additionalSelectors 6 | * List of additional selectors 7 | * 8 | * @param {boolean} $onlyNoTouch 9 | * The hover style will only work when the user is using a tool device like a mouse or a trackpad. 10 | * https://defensivecss.dev/tip/hover-media/ 11 | * https://developer.mozilla.org/fr/docs/Web/CSS/@media/hover 12 | */ 13 | @mixin hover($onlyNoTouch: null, $additionalSelectors: null) { 14 | $selectors: "&:hover", "&:active", "&:focus"; 15 | 16 | @if ($additionalSelectors) { 17 | @if (type-of($additionalSelectors) == "string") { 18 | $selectors: $selectors "," $additionalSelectors; 19 | } 20 | @else if (type-of($additionalSelectors) == "list") { 21 | $selectors: list.join($selectors, $additionalSelectors, comma); 22 | } 23 | } 24 | 25 | @if $onlyNoTouch { 26 | @media (hover: hover) { 27 | #{$selectors} { 28 | @content; 29 | } 30 | } 31 | } @else { 32 | #{$selectors} { 33 | @content; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-invisible-scrollbar.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Invisible scrollbar 3 | * 4 | * /!\ ALERT : Don't use this mixin neither on the html element, nor on the body element to avoid deteriorating the accessibility 5 | */ 6 | 7 | @mixin invisible-scrollbar { 8 | -ms-overflow-style: none; /* IE and Edge */ 9 | scrollbar-width: none; /* Firefox */ 10 | 11 | &::-webkit-scrollbar { 12 | display: none; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-line-clamp.scss: -------------------------------------------------------------------------------- 1 | /// Truncates text at a specific number of lines. 2 | /// https://css-tricks.com/almanac/properties/l/line-clamp/ 3 | /// 4 | /// @param {number} $lines 5 | /// The number of lines for the text. 6 | @mixin line-clamp($lines: 2) { 7 | display: -webkit-box; 8 | overflow: hidden; 9 | -webkit-line-clamp: #{$lines}; 10 | -webkit-box-orient: vertical; 11 | } 12 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-not-acf.scss: -------------------------------------------------------------------------------- 1 | // Not apply style to ACF fields 2 | @mixin not-acf() { 3 | #{context-selector(":where(body)", ":where(*:not([class*="acf-"])) >")} { 4 | @content; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-placeholder-media.scss: -------------------------------------------------------------------------------- 1 | @use "sass:math"; 2 | 3 | /** 4 | * Placeholder media 5 | */ 6 | 7 | @mixin placeholder-media($width, $height, $targets: "img", $object-fit: "") { 8 | position: relative; 9 | 10 | &::before { 11 | @include placeholder-media-size($width, $height); 12 | 13 | display: block; 14 | content: ""; 15 | } 16 | 17 | .lazyload, 18 | .lazyloading { 19 | height: 0; 20 | } 21 | 22 | #{$targets} { 23 | position: absolute; 24 | top: 0; 25 | left: 0; 26 | width: 100%; 27 | height: 100%; 28 | } 29 | 30 | @if ($object-fit != "") { 31 | img { 32 | display: block; 33 | width: 100%; 34 | height: 100%; 35 | object-fit: $object-fit; 36 | } 37 | } 38 | } 39 | 40 | @mixin placeholder-media-size($width, $height) { 41 | padding-bottom: math.div($height, $width) * 100%; 42 | } 43 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-radio-custom.scss: -------------------------------------------------------------------------------- 1 | @use "sass:math"; 2 | 3 | /** 4 | * Radio custom, must be used with checkbox custom 5 | */ 6 | 7 | @mixin radio-custom($include-checkbox-style: false, $color: $color-primary, $size: 18px, $border-width: 1px) { 8 | @if ($include-checkbox-style) { 9 | @include checkbox-custom($color, $size, $border-width); 10 | } 11 | 12 | + label { 13 | &::before { 14 | border-radius: 50%; 15 | } 16 | 17 | &::after { 18 | top: #{1px + math.div($size, 2)}; 19 | width: math.div($size, 2); 20 | height: math.div($size, 2); 21 | background: $color; 22 | border: none; 23 | border-radius: 50%; 24 | } 25 | } 26 | } 27 | 28 | @mixin radio-custom-checked() { 29 | @include checkbox-custom-checked; 30 | } 31 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-reduced-motion.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Reduced-motion 3 | * 4 | * exemples : 5 | * 6 | * @include reduced-motion { ... } 7 | * return @media screen and (prefers-reduced-motion : reduce) { ... } 8 | * 9 | * you can add heavy animation using : 10 | * 11 | * @include reduced-motion (false) { ... } 12 | * return @media screen and (prefers-reduced-motion : no-preference) { ... } 13 | */ 14 | 15 | @mixin reduced-motion ($reduce: true) { 16 | 17 | @if ($reduce == true) { 18 | 19 | @media screen and (prefers-reduced-motion: reduce) { 20 | @content; 21 | } 22 | } @else { 23 | 24 | @media screen and (prefers-reduced-motion: no-preference) { 25 | @content; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-row-fullwidth.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Row fullwidth 3 | */ 4 | 5 | @mixin row-fullwidth($position: relative) { 6 | position: $position; 7 | left: 50%; 8 | z-index: 1; 9 | width: 100vw; 10 | margin-left: -50vw; 11 | } 12 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-scrollbar.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Scrollbar invisible 3 | * 4 | * /!\ ALERT : Don't use this mixin neither on the html element, nor on the body element to avoid deteriorating accessibility 5 | */ 6 | 7 | @mixin scrollbar-invisible { 8 | -ms-overflow-style: none; /* IE and Edge */ 9 | scrollbar-width: none; /* Firefox */ 10 | 11 | &::-webkit-scrollbar { 12 | display: none; 13 | } 14 | } 15 | 16 | /** 17 | * Scrollbar color 18 | */ 19 | 20 | @mixin scrollbar-color($size, $scrollbar-color, $track-color) { 21 | &::-webkit-scrollbar { 22 | display: none; 23 | width: $size; 24 | height: $size; 25 | } 26 | 27 | &::-webkit-scrollbar-thumb { 28 | background: $scrollbar-color; 29 | border-radius: 20px; 30 | } 31 | 32 | &::-webkit-scrollbar-track { 33 | background: $track-color; 34 | border-radius: 20px; 35 | } 36 | 37 | @include hover { 38 | &::-webkit-scrollbar { 39 | display: block; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-select-custom.scss: -------------------------------------------------------------------------------- 1 | @use "sass:color"; 2 | 3 | /** 4 | * Select custom 5 | */ 6 | 7 | @mixin select-custom { 8 | display: block; 9 | width: 100%; 10 | max-width: 100%; /* useful when width is set to anything other than 100% */ 11 | padding: 15px 25px; 12 | margin: 0; 13 | font-size: 16px; // prevent iOS zoom 14 | line-height: 1.15; 15 | color: $color-text; 16 | background-color: $color-light; 17 | background-image: get-svg-url("down"), linear-gradient(to bottom, $color-light 0%, $color-light 100%); 18 | background-repeat: no-repeat, repeat; 19 | background-position: right 10px top 50%, 0 0; 20 | background-size: 10px auto, 100%; 21 | border: 1px solid $color-grey-500; 22 | border-radius: 10px; 23 | appearance: none; 24 | 25 | // Set options to normal weight 26 | option { 27 | font-weight: 400; 28 | } 29 | 30 | // Hide arrow icon in IE browsers 31 | &::-ms-expand { 32 | display: none; 33 | } 34 | 35 | // Hover style 36 | &:hover { 37 | border-color: color.adjust($color-grey-500, $lightness: -10%); 38 | } 39 | 40 | // Focus style 41 | &:focus { 42 | color: color.adjust($color-text, $lightness: -10%); 43 | border-color: color.adjust($color-grey-500, $lightness: -20%); 44 | outline: none; 45 | box-shadow: 0 0 1px 3px rgba(59, 153, 252, .7); 46 | box-shadow: 0 0 0 3px -moz-mac-focusring; 47 | 48 | option { 49 | outline: none; 50 | } 51 | } 52 | 53 | // Support for rtl text, explicit support for Arabic and Hebrew 54 | *[dir="rtl"] &, 55 | :root:lang(ar) &, 56 | :root:lang(iw) & { 57 | background-position: left 10px top 50%, 0 0; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/_m-style-only.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Style only 3 | * 4 | * Style inside the mixin while be writed only for style.scss 5 | * 6 | * @include style-only { 7 | * ... css only for the front office 8 | * } 9 | * 10 | * the variable $entry-file-name is defined in style.scss and editor.scss 11 | */ 12 | 13 | @mixin style-only { 14 | @if ($entry-file-name == "style") { 15 | @content; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/02-tools/tools.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Abstract folder entry file 3 | */ 4 | 5 | @import "./f-assign-inputs"; 6 | @import "./f-column"; 7 | @import "./f-context-align"; 8 | @import "./f-context-selector"; 9 | @import "./f-easings"; 10 | @import "./f-em"; 11 | @import "./f-get-gutter-width"; 12 | @import "./f-get-svg-url"; 13 | @import "./f-strip-units"; 14 | @import "./f-to-number"; 15 | @import "./m-align"; 16 | @import "./m-autofill"; 17 | @import "./m-breakpoint"; 18 | @import "./m-checkbox-custom"; 19 | @import "./m-clearflex"; 20 | @import "./m-container"; 21 | @import "./m-container-query"; 22 | @import "./m-declare-font-face"; 23 | @import "./m-editor-only"; 24 | @import "./m-fr-btn"; 25 | @import "./m-fr-link"; 26 | @import "./m-heading"; 27 | @import "./m-hover"; 28 | @import "./m-line-clamp"; 29 | @import "./m-placeholder-media"; 30 | @import "./m-radio-custom"; 31 | @import "./m-row-fullwidth"; 32 | @import "./m-scrollbar"; 33 | @import "./m-select-custom"; 34 | @import "./m-sr-only"; 35 | @import "./m-style-only"; 36 | @import "./m-reduced-motion"; 37 | @import "./m-bg-fullwidth"; 38 | @import "./m-block-vertical-spacing"; 39 | @import "./m-background-static"; 40 | @import "./m-invisible-scrollbar"; 41 | @import "./m-not-acf"; 42 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/03-base/_media.scss: -------------------------------------------------------------------------------- 1 | embed, 2 | iframe, 3 | object, 4 | video { 5 | max-width: 100%; 6 | } 7 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/03-base/_print.scss: -------------------------------------------------------------------------------- 1 | @media print { 2 | * { 3 | font-family: Arial, Helvetica, sans-serif !important; 4 | color: $color-dark !important; 5 | text-decoration: none; 6 | text-shadow: none !important; 7 | background: transparent !important; 8 | filter: none !important; 9 | }/* Black prints faster: h5bp.com/s */ 10 | a, 11 | a:visited { 12 | text-decoration: none; 13 | } 14 | 15 | a[href]::after { 16 | content: " (" attr(href) ")"; 17 | } 18 | 19 | abbr[title]::after { 20 | content: " (" attr(title) ")"; 21 | } 22 | 23 | .ir a::after, 24 | a[href^="javascript:"]::after, 25 | a[href^="#"]::after { 26 | content: ""; 27 | }/* Don't show links for images, or javascript/internal links */ 28 | pre, 29 | blockquote { 30 | border: 0; 31 | page-break-inside: avoid; 32 | } 33 | 34 | thead { 35 | display: table-header-group; 36 | }/* h5bp.com/t */ 37 | tr, 38 | img { 39 | page-break-inside: avoid; 40 | } 41 | 42 | img { 43 | max-width: 100% !important; 44 | } 45 | 46 | @page { 47 | margin: .5cm; 48 | } 49 | 50 | p, 51 | h2, 52 | h3 { 53 | orphans: 3; 54 | widows: 3; 55 | } 56 | 57 | h2, 58 | h3 { 59 | page-break-after: avoid; 60 | } 61 | 62 | .inline-element-with-padding { 63 | padding: 0; 64 | } 65 | 66 | /* remove useless content */ 67 | .fr-header, 68 | .fr-footer, 69 | .widget-area, 70 | .breadcrumb, 71 | .wp-pagenavi { 72 | display: none !important; 73 | } 74 | 75 | /* reset width */ 76 | .content { 77 | width: 100% !important; 78 | padding: 10px 0 !important; 79 | margin: 10px 0 !important; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/03-base/_reset.scss: -------------------------------------------------------------------------------- 1 | html { 2 | // Scroll resets 3 | -webkit-overflow-scrolling: touch; 4 | scroll-behavior: smooth; 5 | } 6 | 7 | *[id] { 8 | scroll-margin-top: $spacing-6; 9 | } 10 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/03-base/_svg-icons.scss: -------------------------------------------------------------------------------- 1 | .icon { 2 | display: inline-block; 3 | width: 16px; 4 | height: 16px; 5 | vertical-align: middle; 6 | fill: currentColor; 7 | } 8 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/03-base/_text.scss: -------------------------------------------------------------------------------- 1 | %figcaption { 2 | @extend %text-xs; 3 | 4 | max-width: $container-wide; 5 | margin-top: 12px; 6 | margin-right: auto; 7 | margin-left: auto; 8 | text-align: left; 9 | } 10 | 11 | figcaption { 12 | @extend %figcaption; 13 | } 14 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/03-base/base.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Base folder entry file 3 | */ 4 | 5 | @import "./variables-css"; 6 | @import "./reset"; 7 | @import "./svg-icons"; 8 | @import "./media"; 9 | @import "./print"; 10 | @import "./text"; 11 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/04-utilities/_palette.scss: -------------------------------------------------------------------------------- 1 | @use "sass:map"; 2 | 3 | $palette-slugs: ( 4 | "text-title-grey", 5 | "text-default-grey", 6 | "background-action-high-blue-france", 7 | "background-alt-blue-france", 8 | ); 9 | 10 | @each $slug in $palette-slugs { 11 | $color: var(--#{$slug}); 12 | 13 | .has-#{$slug}-color { 14 | color: $color; 15 | } 16 | 17 | .has-#{$slug}-background-color { 18 | background-color: $color; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/04-utilities/_seo.scss: -------------------------------------------------------------------------------- 1 | %seo-container { 2 | position: relative; 3 | z-index: 1; 4 | cursor: pointer; 5 | } 6 | 7 | %seo-target { 8 | &::before { 9 | position: absolute; 10 | top: 0; 11 | right: 0; 12 | bottom: 0; 13 | left: 0; 14 | z-index: 100; 15 | content: ""; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/04-utilities/_wp-admin-bar.scss: -------------------------------------------------------------------------------- 1 | #wpadminbar { 2 | @include breakpoints(sm, max) { 3 | overflow: scroll; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/04-utilities/utilities.scss: -------------------------------------------------------------------------------- 1 | @import "./wp-admin-bar"; 2 | @import "./seo"; 3 | @import "./palette"; 4 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-accordion.scss: -------------------------------------------------------------------------------- 1 | .fr-accordion { 2 | .fr-collapse { 3 | > div { 4 | > :last-child { 5 | margin-bottom: 0; 6 | } 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-accordions-group.scss: -------------------------------------------------------------------------------- 1 | .fr-accordions-group { 2 | margin-bottom: $text-spacing; 3 | } 4 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-btn.scss: -------------------------------------------------------------------------------- 1 | %fr-btn { 2 | @include fr-btn; 3 | } 4 | 5 | %fr-btn-secondary { 6 | @include fr-btn-secondary; 7 | } 8 | 9 | %fr-btn-tertiary { 10 | @include fr-btn-tertiary; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-callout.scss: -------------------------------------------------------------------------------- 1 | .fr-callout { 2 | :last-child { 3 | margin-bottom: 0; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-card.scss: -------------------------------------------------------------------------------- 1 | .fr-card { 2 | // add svg support for fr-card__header 3 | &__img { 4 | display: flex; 5 | align-items: center; 6 | justify-content: center; 7 | 8 | svg { 9 | width: 80%; 10 | height: auto; 11 | aspect-ratio: 16/9; 12 | object-fit: contain; 13 | fill: var(--artwork-major-red-marianne); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-highlight.scss: -------------------------------------------------------------------------------- 1 | .fr-highlight { 2 | :last-child { 3 | margin-bottom: 0; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-link.scss: -------------------------------------------------------------------------------- 1 | %fr-link { 2 | @include fr-link; 3 | } 4 | 5 | %fr-link-download { 6 | @extend %fr-link-download-fix; 7 | @include fr-link-download; 8 | } 9 | 10 | %fr-link-download-fix { 11 | &.has-js-fr-download-link-icon { 12 | &::after { 13 | content: none; 14 | } 15 | } 16 | 17 | .fr-link__icon { 18 | --icon-size: 1rem; 19 | display: inline-block; 20 | width: var(--icon-size); 21 | height: var(--icon-size); 22 | margin: 0 -.125rem 0 0; 23 | vertical-align: calc((.75em - var(--icon-size)) * .5); 24 | content: ""; 25 | background-color: currentColor; 26 | mask-size: 100% 100%; 27 | mask-image: get-svg-url(download, ""); 28 | } 29 | } 30 | 31 | // fix for download link 32 | // see FRLinkDownload.js and https://github.com/GouvernementFR/dsfr/issues/902 33 | .fr-link--download { 34 | @extend %fr-link-download-fix; 35 | } 36 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-pagination.scss: -------------------------------------------------------------------------------- 1 | .fr-pagination { 2 | $el: &; 3 | 4 | margin-top: $spacing-8; 5 | 6 | &__list { 7 | justify-content: center; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-quote.scss: -------------------------------------------------------------------------------- 1 | .fr-quote { 2 | $el: &; 3 | 4 | @extend %block-spacing-md; 5 | 6 | figcaption { 7 | margin-bottom: 0 !important; 8 | margin-left: 0; 9 | } 10 | 11 | #{$el}__author { 12 | color: var(--text-default-grey); 13 | } 14 | 15 | #{$el}__source { 16 | margin-bottom: 0; 17 | } 18 | 19 | #{$el}__image { 20 | aspect-ratio: 1; 21 | } 22 | 23 | @include breakpoints(sm) { 24 | &--column { 25 | padding-left: 248px; 26 | background-position: 216px top; 27 | } 28 | 29 | #{$el}__image { 30 | left: 0; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-ratio.scss: -------------------------------------------------------------------------------- 1 | [class^="fr-ratio"], 2 | [class*=" fr-ratio"] { 3 | height: auto; 4 | } 5 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/_fr-tabs.scss: -------------------------------------------------------------------------------- 1 | .fr-tabs { 2 | margin-bottom: $text-spacing; 3 | 4 | &__panel { 5 | > div { 6 | @extend %no-first-and-last-child-vertical-margin; 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/05-components/components.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Elements folder entry file 3 | */ 4 | 5 | @import "./fr-accordion"; 6 | @import "./fr-accordions-group"; 7 | @import "./fr-btn"; 8 | @import "./fr-callout"; 9 | @import "./fr-card"; 10 | @import "./fr-highlight"; 11 | @import "./fr-link"; 12 | @import "./fr-pagination"; 13 | @import "./fr-quote"; 14 | @import "./fr-ratio"; 15 | @import "./fr-tabs"; 16 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/blocks.scss: -------------------------------------------------------------------------------- 1 | // Blocks 2 | // - These styles replace key Gutenberg Block styles with font, color, and 3 | // spacing with CSS-variables overrides 4 | // - In the future the Block styles may get compiled to individual .css 5 | // files and conditionally loaded 6 | 7 | @import "./core/audio"; 8 | @import "./core/buttons"; 9 | @import "./core/columns"; 10 | @import "./core/cover"; 11 | @import "./core/embed"; 12 | @import "./core/file"; 13 | @import "./core/gallery"; 14 | @import "./core/group"; 15 | @import "./core/heading"; 16 | @import "./core/image"; 17 | @import "./core/list"; 18 | @import "./core/media-text"; 19 | @import "./core/paragraph"; 20 | @import "./core/separator"; 21 | @import "./core/table"; 22 | @import "./core/video"; 23 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_audio.scss: -------------------------------------------------------------------------------- 1 | .wp-block-audio { 2 | @extend %block-spacing-xs; 3 | } 4 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_buttons.scss: -------------------------------------------------------------------------------- 1 | .wp-block { 2 | &-buttons { 3 | gap: 16px; 4 | margin-bottom: $text-spacing; 5 | } 6 | 7 | // ---- 8 | // button 9 | // ---- 10 | &-button { 11 | position: relative; 12 | 13 | .wp-block-button__link { 14 | display: inline; 15 | padding: 0; 16 | font: inherit; 17 | color: inherit; 18 | background: none; 19 | border: none; 20 | border-radius: 0; 21 | } 22 | 23 | a::before { 24 | position: absolute; 25 | top: 0; 26 | left: 0; 27 | width: 100%; 28 | height: 100%; 29 | content: ""; 30 | } 31 | 32 | &.has-custom-font-size .wp-block-button__link { 33 | font-size: inherit; 34 | } 35 | 36 | // style button block 37 | &:is( 38 | :not([class*="is-style"]), 39 | .is-style-fill, 40 | .is-style-secondary, 41 | .is-style-tertiary) { 42 | @extend %fr-btn; 43 | } 44 | 45 | &.is-style-secondary { 46 | @extend %fr-btn-secondary; 47 | } 48 | 49 | &.is-style-tertiary { 50 | @extend %fr-btn-tertiary; 51 | } 52 | 53 | // style link 54 | &.is-style-link { 55 | @extend %fr-link; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_columns.scss: -------------------------------------------------------------------------------- 1 | .wp-block-columns { 2 | gap: var(--row-gap) var(--column-gap); 3 | 4 | justify-content: space-between; 5 | margin-right: auto; 6 | margin-left: auto; 7 | 8 | #{context-selector("&.alignwide", "[data-align='wide'] > &")} { 9 | @extend %block-spacing-md; 10 | } 11 | 12 | #{context-selector("&.alignfull", "[data-align='full'] > &")} { 13 | @extend %block-spacing-lg; 14 | } 15 | 16 | @include breakpoints(md, max) { 17 | &:not(.is-not-stacked-on-mobile) { 18 | flex-wrap: wrap !important; 19 | 20 | .wp-block-column { 21 | flex-basis: 100% !important; 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_embed.scss: -------------------------------------------------------------------------------- 1 | .wp-block-embed { 2 | @extend %block-spacing-sm; 3 | 4 | #{context-selector("&.alignwide", "[data-align='wide'] > &")} { 5 | @extend %block-spacing-md; 6 | } 7 | 8 | #{context-selector("&.alignfull", "[data-align='full'] > &")} { 9 | @extend %block-spacing-lg; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_file.scss: -------------------------------------------------------------------------------- 1 | .wp-block-file { 2 | $el: &; 3 | 4 | @extend %block-spacing-xs; 5 | 6 | a { 7 | @extend %fr-link; 8 | @extend %fr-link-download; 9 | 10 | @include editor-only { 11 | &::before { 12 | @include fr-link-download-detail; 13 | 14 | content: "Type de fichier – poids"; 15 | } 16 | } 17 | } 18 | 19 | #{$el}__button { 20 | display: none; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_gallery.scss: -------------------------------------------------------------------------------- 1 | .wp-block-gallery { 2 | --wp--style--unstable-gallery-gap: var(--column-gap) !important; 3 | 4 | @extend %block-spacing-sm; 5 | 6 | gap: var(--row-gap) var(--column-gap) !important; 7 | 8 | #{context-selector("&.alignwide", "[data-align='wide'] > &")} { 9 | @extend %block-spacing-md; 10 | } 11 | 12 | #{context-selector("&.alignfull", "[data-align='full'] > &")} { 13 | @extend %block-spacing-lg; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_group.scss: -------------------------------------------------------------------------------- 1 | .wp-block-group { 2 | $el: &; 3 | 4 | display: flow-root; 5 | 6 | &.has-background { 7 | padding: $spacing-6 var(--external-gutter); 8 | } 9 | 10 | #{$el}__inner-container { 11 | > * { 12 | max-width: none; 13 | } 14 | } 15 | 16 | #{context-selector("&.alignfull", "[data-align='full'] > &")} { 17 | padding-right: 0; 18 | padding-left: 0; 19 | 20 | &.has-background { 21 | @extend %block-spacing-lg; 22 | 23 | & + & { 24 | @extend %block-spacing-lg-reverse; 25 | } 26 | } 27 | 28 | #{$el}__inner-container { 29 | @include container; 30 | } 31 | } 32 | 33 | @include breakpoints(md) { 34 | &.has-background { 35 | padding-top: $spacing-14; 36 | padding-bottom: $spacing-14; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_heading.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Headings 3 | */ 4 | %title-base-style { 5 | margin-bottom: $title-spacing; 6 | font-family: $font-family-title; 7 | font-weight: 700; 8 | color: var(--text-title-grey); 9 | } 10 | 11 | @for $i from 1 through 6 { 12 | %title-h#{$i} { 13 | @extend %title-base-style; 14 | 15 | font-size: var(--title--font-size-h#{$i}); 16 | line-height: var(--title--line-height-h#{$i}); 17 | } 18 | 19 | .has-h-#{$i}-font-size { 20 | @extend %title-h#{$i}; 21 | } 22 | } 23 | 24 | %display-base-style { 25 | margin-bottom: $display-spacing; 26 | font-family: $font-family-title; 27 | font-weight: 700; 28 | color: var(--text-title-grey); 29 | } 30 | 31 | @each $size in (xl, lg, md, sm, xs) { 32 | %display-#{$size} { 33 | @extend %display-base-style; 34 | 35 | font-size: var(--display--font-size-#{$size}); 36 | line-height: var(--display--line-height-#{$size}); 37 | } 38 | 39 | .has-display-#{$size}-font-size { 40 | @extend %display-#{$size}; 41 | } 42 | } 43 | 44 | .is-style-flag-fr { 45 | &::before { 46 | display: block; 47 | width: 114px; 48 | height: 5px; 49 | margin-bottom: $text-spacing; 50 | content: ""; 51 | background: linear-gradient(to right, var(--blue-france-sun-113-625) 33.33%, var(--grey-950-125) 33.33%, var(--grey-950-125) 66.66%, var(--red-marianne-main-472) 66.66%); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_html.scss: -------------------------------------------------------------------------------- 1 | @include editor-only { 2 | [data-type="core/html"] textarea { 3 | // style 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_image.scss: -------------------------------------------------------------------------------- 1 | .wp-block-image { 2 | @extend %block-spacing-sm; 3 | 4 | > img { 5 | max-width: 100%; 6 | height: auto; 7 | } 8 | 9 | #{context-selector("&.alignwide", "[data-align='wide'] > &")} { 10 | @extend %block-spacing-md; 11 | } 12 | 13 | #{context-selector("&.alignfull", "[data-align='full'] > &")} { 14 | @extend %block-spacing-lg; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_list.scss: -------------------------------------------------------------------------------- 1 | #{context-selector('.blocks-container', '.is-root-container')} { 2 | ul:where(:not([class*="fr-"])), 3 | ol:where(:not([class*="fr-"])) { 4 | margin-bottom: $text-spacing; 5 | 6 | // Utility classes 7 | &.aligncenter { 8 | padding: 0; 9 | list-style-position: inside; 10 | } 11 | 12 | &.alignright { 13 | padding: 0; 14 | text-align: right; 15 | list-style-position: inside; 16 | } 17 | } 18 | 19 | ul { 20 | &:not([class*="is-style-"], .no-list-style, [class*="fr-"]) { 21 | list-style-type: disc; 22 | } 23 | } 24 | 25 | ol { 26 | &:not([class*="is-style-"], .no-list-style, [class*="fr-"]) { 27 | list-style-type: decimal; 28 | } 29 | } 30 | 31 | dd { 32 | margin: 0; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_paragraph.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Paragraph 3 | */ 4 | %text-base-style { 5 | margin-bottom: $text-spacing; 6 | font-family: $font-family-title; 7 | font-weight: normal; 8 | color: var(--text-default-grey); 9 | } 10 | 11 | %text-xs { 12 | @extend %text-base-style; 13 | 14 | font-size: $paragraph-xs-font-size; 15 | line-height: $paragraph-xs-line-height; 16 | color: var(--text-mention-grey); 17 | } 18 | 19 | %text-sm { 20 | @extend %text-base-style; 21 | 22 | font-size: $paragraph-sm-font-size; 23 | line-height: $paragraph-sm-line-height; 24 | } 25 | 26 | %text-md { 27 | @extend %text-base-style; 28 | 29 | font-size: $paragraph-md-font-size; 30 | line-height: $paragraph-md-line-height; 31 | } 32 | 33 | %text-lg { 34 | @extend %text-base-style; 35 | 36 | font-size: $paragraph-lg-font-size; 37 | line-height: $paragraph-lg-line-height; 38 | } 39 | 40 | %text-xl { 41 | @extend %text-base-style; 42 | 43 | font-size: $paragraph-xl-font-size; 44 | line-height: $paragraph-xl-line-height; 45 | } 46 | 47 | p { 48 | &.has-background { 49 | padding: 20px; 50 | } 51 | } 52 | 53 | .has-xs-font-size { 54 | @extend %text-xs; 55 | } 56 | 57 | .has-sm-font-size { 58 | @extend %text-sm; 59 | } 60 | 61 | .has-md-font-size { 62 | @extend %text-md; 63 | } 64 | 65 | .has-lg-font-size { 66 | @extend %text-lg; 67 | } 68 | 69 | .has-xl-font-size { 70 | @extend %text-xl; 71 | } 72 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_separator.scss: -------------------------------------------------------------------------------- 1 | .wp-block-separator { 2 | width: auto !important; 3 | margin: 0 auto; 4 | border: none; 5 | } 6 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/core/_video.scss: -------------------------------------------------------------------------------- 1 | .wp-block-video { 2 | @extend %block-spacing-sm; 3 | 4 | #{context-selector("&.alignwide", "[data-align='wide'] > &")} { 5 | @extend %block-spacing-md; 6 | } 7 | 8 | #{context-selector("&.alignfull", "[data-align='full'] > &")} { 9 | @extend %block-spacing-lg; 10 | } 11 | } 12 | 13 | * > figure > video { 14 | vertical-align: middle; 15 | } 16 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/06-blocks/custom/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BeAPI/wp-dsfr/a2047ca452bf05cea6f858f1d9548e1140aee480/wp-dsfr-theme/src/scss/06-blocks/custom/.gitkeep -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/07-patterns/_wp-block-group--arguments.scss: -------------------------------------------------------------------------------- 1 | .wp-block-group { 2 | $el: &; 3 | 4 | &#{$el}--arguments { 5 | @extend %block-spacing-lg; 6 | 7 | .wp-block-heading { 8 | margin-bottom: 40px; 9 | } 10 | 11 | &.has-background { 12 | @extend %block-inner-spacing-md; 13 | } 14 | 15 | .wp-block-columns { 16 | margin-top: 0; 17 | 18 | .wp-block-image { 19 | margin-bottom: $spacing-5; 20 | } 21 | 22 | .wp-block-heading { 23 | margin-bottom: $spacing-5; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/07-patterns/_wp-block-group--hero.scss: -------------------------------------------------------------------------------- 1 | .wp-block-group { 2 | $el: &; 3 | 4 | &--hero { 5 | @extend %block-spacing-lg; 6 | 7 | #{context-selector('&.alignfull.has-background', '[data-align="full"] > &.has-background')} { 8 | padding-top: $spacing-12; 9 | padding-bottom: $spacing-12; 10 | } 11 | 12 | @include style-only { 13 | body:not(.single) .blocks-container > &.alignfull.has-background:first-child { 14 | position: relative; 15 | padding-top: 0; 16 | 17 | &::before { 18 | position: absolute; 19 | bottom: 0; 20 | left: 0; 21 | z-index: -1; 22 | width: 100%; 23 | height: calc(100% + 500px); 24 | content: ""; 25 | background: inherit; 26 | } 27 | } 28 | } 29 | 30 | .wp-block-columns { 31 | row-gap: $spacing-9; 32 | } 33 | 34 | @include breakpoints(md, max) { 35 | #{$el}__inner-container > .wp-block-image:last-child, 36 | &:not(.wp-block-group--hero-icon) .wp-block-column:last-child:has(.wp-block-image) { 37 | margin: 0 calc(var(--external-gutter) * -1) -#{$spacing-12} calc(var(--external-gutter) * -1) !important; 38 | } 39 | 40 | &.wp-block-group--hero-icon .wp-block-column:last-child:has(.wp-block-image) { 41 | margin-bottom: -#{$spacing-8} !important; 42 | } 43 | } 44 | 45 | @include breakpoints(md) { 46 | #{context-selector('&.alignfull.has-background', '[data-align="full"] > &.has-background')} { 47 | padding-top: $spacing-14; 48 | padding-bottom: $spacing-14; 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/07-patterns/_wp-block-group--how-to-use.scss: -------------------------------------------------------------------------------- 1 | .wp-block-group { 2 | $el: &; 3 | 4 | &--how-to-use { 5 | @extend %block-spacing-sm; 6 | 7 | padding: 24px; 8 | background: var(--background-raised-grey); 9 | border: 1px solid var(--grey-625-425); 10 | 11 | &:focus::after { 12 | content: none !important; 13 | } 14 | 15 | &::before { 16 | margin-bottom: 12px; 17 | } 18 | 19 | p { 20 | code { 21 | display: inline-block; 22 | padding: 2px 5px; 23 | font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; 24 | font-size: .75em; 25 | color: #000; 26 | vertical-align: middle; 27 | background: #eee; 28 | border-radius: 5px; 29 | } 30 | 31 | span[class*="fr-icon"] + code { 32 | margin-bottom: 4px; 33 | vertical-align: middle; 34 | 35 | } 36 | } 37 | 38 | .list-icons { 39 | p { 40 | columns: 2; 41 | column-gap: 12px; 42 | } 43 | } 44 | 45 | p.fr-badge { 46 | --text-spacing: 0 0 1.5rem; 47 | } 48 | 49 | @include style-only { 50 | h1, 51 | h2, 52 | h3, 53 | h4, 54 | h5, 55 | h6 { 56 | &:empty { 57 | &::before { 58 | content: "Titre"; 59 | } 60 | } 61 | } 62 | 63 | p, 64 | th, 65 | td { 66 | &:empty { 67 | &::before { 68 | content: "Texte"; 69 | } 70 | } 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/07-patterns/_wp-block-group-fr-alert.scss: -------------------------------------------------------------------------------- 1 | .wp-block-group { 2 | $el: &; 3 | 4 | &.fr-alert { 5 | @extend %block-spacing-sm; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/07-patterns/_wp-block-group-fr-callout.scss: -------------------------------------------------------------------------------- 1 | .wp-block-group { 2 | $el: &; 3 | 4 | &.fr-callout { 5 | @extend %block-spacing-sm; 6 | 7 | #{$el}__inner-container { 8 | @extend %no-first-and-last-child-vertical-margin; 9 | 10 | p { 11 | margin-bottom: 8px; 12 | } 13 | 14 | .wp-block-buttons { 15 | margin-top: 16px; 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/07-patterns/_wp-block-group-fr-highlight.scss: -------------------------------------------------------------------------------- 1 | .wp-block-group { 2 | $el: &; 3 | 4 | &.fr-highlight { 5 | --wp-block-group-fr-highlight-width: var(--responsive--aligndefault-width); 6 | 7 | @extend %block-spacing-sm; 8 | 9 | position: relative; 10 | left: 16px; 11 | max-width: calc(var(--wp-block-group-fr-highlight-width) - 32px); 12 | 13 | #{$el}__inner-container { 14 | @extend %no-first-and-last-child-vertical-margin; 15 | } 16 | 17 | #{context-selector("&.alignwide", "[data-align='wide'] &")} { 18 | --wp-block-group-fr-highlight-width: var(--responsive--alignwide-width); 19 | } 20 | 21 | #{context-selector("&.alignfull", "[data-align='full'] &")} { 22 | --wp-block-group-fr-highlight-width: var(--responsive--alignfull-width); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/07-patterns/_wp-block-media-text--description.scss: -------------------------------------------------------------------------------- 1 | .wp-block-media-text { 2 | $el: &; 3 | 4 | &--description { 5 | @include breakpoints(md) { 6 | .wp-block-buttons:last-child { 7 | margin-top: $spacing-8; 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/07-patterns/patterns.scss: -------------------------------------------------------------------------------- 1 | // @import "./my-pattern"; 2 | @import "./wp-block-group--arguments"; 3 | @import "./wp-block-group--hero"; 4 | @import "./wp-block-group--how-to-use"; 5 | @import "./wp-block-group-fr-alert"; 6 | @import "./wp-block-group-fr-callout"; 7 | @import "./wp-block-group-fr-highlight"; 8 | @import "./wp-block-media-text--description"; 9 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/08-template-parts/_grid.scss: -------------------------------------------------------------------------------- 1 | .grid { 2 | display: grid; 3 | grid-template-columns: 1fr; 4 | gap: var(--row-gap) var(--column-gap); 5 | 6 | > * { 7 | width: 100%; 8 | min-width: 0; 9 | } 10 | 11 | .fr-tags-group + & { 12 | margin-top: $spacing-10; 13 | } 14 | 15 | @include breakpoints(xs, sm) { 16 | &[data-grid-size]:not([data-grid-size="1"]) { 17 | grid-template-columns: repeat(2, 1fr); 18 | 19 | .fr-tile--horizontal { 20 | grid-column: 1/3; 21 | } 22 | } 23 | } 24 | 25 | @include breakpoints(sm, md) { 26 | &[data-grid-size]:not([data-grid-size="1"]) { 27 | grid-template-columns: repeat(2, 1fr); 28 | } 29 | 30 | &--fr-card-post { 31 | .fr-card--horizontal { 32 | grid-column: 1/3; 33 | } 34 | } 35 | } 36 | 37 | @include breakpoints(md) { 38 | @for $i from 2 through 6 { 39 | &[data-grid-size="#{$i}"] { 40 | grid-template-columns: repeat(#{$i}, 1fr); 41 | } 42 | } 43 | 44 | &--fr-card-post { 45 | .fr-card--horizontal { 46 | grid-column: 1/4; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/08-template-parts/_latest-posts.scss: -------------------------------------------------------------------------------- 1 | .latest-posts { 2 | padding-top: 56px; 3 | padding-bottom: 56px; 4 | 5 | &__title { 6 | margin-bottom: $spacing-8; 7 | } 8 | 9 | &__link { 10 | margin-top: -$spacing-8; 11 | margin-bottom: $spacing-8; 12 | } 13 | 14 | &__grid { 15 | display: grid; 16 | grid-template-columns: 1fr; 17 | gap: var(--row-gap) var(--column-gap); 18 | } 19 | 20 | @include breakpoints(sm) { 21 | &__grid { 22 | grid-template-columns: 1fr 1fr; 23 | } 24 | } 25 | 26 | @include breakpoints(md) { 27 | padding-top: 72px; 28 | padding-bottom: 72px; 29 | 30 | .fr-container { 31 | display: flex; 32 | flex-wrap: wrap; 33 | align-items: flex-end; 34 | justify-content: space-between; 35 | } 36 | 37 | &__title { 38 | width: column(8); 39 | } 40 | 41 | &__link { 42 | max-width: column(4); 43 | margin-top: 0; 44 | margin-bottom: #{$spacing-8 + 2}; 45 | } 46 | 47 | &__grid { 48 | grid-template-columns: repeat(4, 1fr); 49 | width: 100%; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/08-template-parts/_page-top.scss: -------------------------------------------------------------------------------- 1 | .page-top { 2 | > div { 3 | @include container; 4 | 5 | max-width: var(--responsive--aligndefault-width); 6 | margin-top: $spacing-10; 7 | 8 | @include breakpoints(md) { 9 | margin-top: $spacing-12; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/08-template-parts/template-parts.scss: -------------------------------------------------------------------------------- 1 | // import template-parts 2 | @import "./grid"; 3 | @import "./hero"; 4 | @import "./latest-posts"; 5 | @import "./page-top"; 6 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/09-templates/_search.scss: -------------------------------------------------------------------------------- 1 | /* Search Page 2 | -------------------------------------------------------------- */ 3 | .search { 4 | &__columns { 5 | > div { 6 | &:first-child { 7 | > *:not(:last-child) { 8 | margin-bottom: 32px; 9 | } 10 | } 11 | } 12 | } 13 | 14 | @include breakpoints(md) { 15 | &__columns { 16 | display: flex; 17 | align-items: flex-start; 18 | justify-content: space-between; 19 | 20 | > div { 21 | &:first-child { 22 | position: sticky; 23 | top: 72px; 24 | width: column(3, 3); 25 | } 26 | 27 | &:last-child { 28 | width: column(8); 29 | } 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/09-templates/templates.scss: -------------------------------------------------------------------------------- 1 | @import "./search"; 2 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/10-vendor/vendor.scss: -------------------------------------------------------------------------------- 1 | // @import vendor styles here 2 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/editor.scss: -------------------------------------------------------------------------------- 1 | $entry-file-name: "editor"; 2 | 3 | /** 4 | * Abstract 5 | * == Contain SCSS and CSS variables and webfonts declarations. 6 | */ 7 | 8 | @import "./01-abstract/abstract"; 9 | 10 | /** 11 | * Tools 12 | * == Contains functions and mixins. 13 | */ 14 | 15 | @import "./02-tools/tools"; 16 | 17 | /** 18 | * Base 19 | * == Contain generic styles such as normalize or reset. 20 | */ 21 | 22 | @import "./03-base/variables-css"; 23 | @import "./03-base/svg-icons"; 24 | @import "./03-base/text"; 25 | 26 | /** 27 | * Utilities 28 | * == Utility classes that are not assigned to a specific component. 29 | */ 30 | 31 | // @import "./04-utilities/utilities"; 32 | 33 | /** 34 | * Blocks 35 | * == Gutenberg core blocks styles, style for front-end layout and editor. 36 | */ 37 | 38 | @import "./05-components/components"; 39 | 40 | /** 41 | * Gutenberg 42 | * == Gutenberg core/custom blocks and patterns styles, style for front-end layout and editor. 43 | */ 44 | 45 | @import "./06-blocks/gutenberg"; 46 | @import "./06-blocks/blocks"; 47 | 48 | /** 49 | * Patterns 50 | * == Contains styles for gutenberg patterns. 51 | */ 52 | 53 | @import "./07-patterns/patterns"; 54 | 55 | /** 56 | * Template parts 57 | * == If you want to add custom styles for specific page templates parts. 58 | */ 59 | 60 | @import "./08-template-parts/grid"; 61 | 62 | /** 63 | * Vendor 64 | * == Plugins or libraries custom styles. 65 | */ 66 | 67 | // @import "./10-vendor/vendor"; 68 | -------------------------------------------------------------------------------- /wp-dsfr-theme/src/scss/style.scss: -------------------------------------------------------------------------------- 1 | $entry-file-name: "style"; 2 | 3 | /** 4 | * Abstract 5 | * == Contain SCSS and CSS variables and webfonts declarations. 6 | */ 7 | 8 | @import "./01-abstract/abstract"; 9 | 10 | /** 11 | * Tools 12 | * == Contains functions and mixins. 13 | */ 14 | 15 | @import "./02-tools/tools"; 16 | 17 | /** 18 | * Base 19 | * == Contain generic styles such as normalize or reset. 20 | */ 21 | 22 | @import "./03-base/base"; 23 | 24 | /** 25 | * Utilities 26 | * == Utility classes that are not assigned to a specific component. 27 | */ 28 | 29 | @import "./04-utilities/utilities"; 30 | 31 | /** 32 | * Components 33 | * == Contain any default component. Just give the components some basic styles. 34 | */ 35 | 36 | @import "./05-components/components"; 37 | 38 | /** 39 | * Gutenberg 40 | * == Gutenberg core/custom blocks and patterns styles, style for front-end layout and editor. 41 | */ 42 | 43 | @import "./06-blocks/gutenberg"; 44 | @import "./06-blocks/blocks"; 45 | 46 | /** 47 | * Patterns 48 | * == Contains styles for gutenberg patterns. 49 | */ 50 | 51 | @import "./07-patterns/patterns"; 52 | 53 | /** 54 | * Template parts 55 | * == If you want to add custom styles for specific page templates parts. 56 | */ 57 | 58 | @import "./08-template-parts/template-parts"; 59 | 60 | /** 61 | * Pages 62 | * == If you want to add custom styles for specific page templates. 63 | */ 64 | 65 | @import "./09-templates/templates"; 66 | 67 | /** 68 | * Vendor 69 | * == Plugins or libraries custom styles. 70 | */ 71 | 72 | // @import "./10-vendor/vendor"; 73 | -------------------------------------------------------------------------------- /wp-dsfr-theme/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | Theme Name: WP DSFR Theme 3 | Theme URI: https://github.com/BeAPI/dsfr 4 | Description: WordPress DSFR theme 5 | Version: 1.0.0 6 | Author: BeAPI 7 | Author URI: http://www.beapi.fr 8 | Text Domain: wp-dsfr-theme 9 | Requires at least: 5.9 10 | Requires PHP: 7.4 11 | */ 12 | -------------------------------------------------------------------------------- /wp-dsfr-theme/templates/empty-page.php: -------------------------------------------------------------------------------- 1 | 11 |
12 |
13 | 14 |
15 |
16 |