@ulu/frontend 0.0.22 → 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/deprecated/js/drupal-programmatic-modal.js +91 -0
- package/{js/ui/modals.js → deprecated/js/micromodal-modals.js} +41 -67
- package/dist/ulu-frontend.min.css +1 -1
- package/dist/ulu-frontend.min.js +70 -1
- package/index.js +6 -1
- package/js/events/index.js +58 -7
- package/js/index.js +3 -7
- package/js/{helpers/css-breakpoint.js → ui/breakpoints.js} +9 -11
- package/js/ui/collapsible.js +195 -0
- package/js/ui/dialog.js +157 -0
- package/js/ui/dialog.todo +37 -0
- package/js/ui/flipcard.js +55 -11
- package/js/ui/grid.js +2 -47
- package/js/ui/index.js +21 -0
- package/js/ui/modal-builder.js +197 -0
- package/js/ui/overflow-scroller-pager.js +1 -1
- package/js/ui/overflow-scroller.js +8 -5
- package/js/ui/page.js +14 -0
- package/js/ui/popover.js +135 -0
- package/js/ui/print-details.js +44 -0
- package/js/ui/print.js +67 -0
- package/js/ui/programmatic-modal.js +79 -81
- package/js/ui/proxy-click.js +80 -0
- package/js/ui/resizer.js +3 -3
- package/js/ui/scroll-slider.js +56 -0
- package/js/ui/scrollpoint.js +300 -0
- package/js/ui/slider.js +72 -10
- package/js/ui/tabs.js +85 -58
- package/js/ui/theme-toggle.js +129 -0
- package/js/ui/tooltip.js +268 -67
- package/js/utils/{logger.js → class-logger.js} +6 -5
- package/js/utils/dom.js +122 -0
- package/js/utils/file-save.js +67 -0
- package/js/utils/floating-ui.js +83 -0
- package/js/utils/id.js +22 -0
- package/js/utils/index.js +7 -0
- package/js/{helpers → utils}/pause-youtube-video.js +1 -1
- package/package.json +32 -11
- package/resources/drupal/twig-macros/accordion.twig +99 -0
- package/resources/drupal/twig-macros/dropdown.twig +44 -0
- package/resources/drupal/twig-macros/flipcard.twig +69 -0
- package/resources/drupal/twig-macros/image.twig +30 -0
- package/resources/drupal/twig-macros/layout.twig +338 -0
- package/resources/drupal/twig-macros/slider.twig +214 -0
- package/resources/drupal/twig-macros/tabs.twig +84 -0
- package/scss/README.md +13 -1
- package/scss/_breakpoint.scss +69 -26
- package/scss/_button.scss +148 -57
- package/scss/_color.scss +46 -28
- package/scss/_cssvar.scss +103 -12
- package/scss/_element.scss +84 -67
- package/scss/_index.scss +0 -3
- package/scss/_layout.scss +71 -37
- package/scss/_path.scss +2 -2
- package/scss/_selector.scss +20 -11
- package/scss/_typography.scss +115 -82
- package/scss/_units.scss +14 -13
- package/scss/_utils.scss +280 -18
- package/scss/base/_color.scss +2 -1
- package/scss/base/_elements.scss +61 -35
- package/scss/base/_index.scss +60 -23
- package/scss/base/_keyframes.scss +115 -16
- package/scss/base/_layout.scss +10 -6
- package/scss/base/_normalize.scss +6 -122
- package/scss/base/_print.scss +49 -0
- package/scss/base/_root.scss +28 -0
- package/scss/base/_typography.scss +4 -1
- package/scss/components/_accordion.scss +217 -0
- package/scss/components/_adaptive-spacing.scss +148 -0
- package/scss/components/_badge.scss +17 -14
- package/scss/components/_button-verbose.scss +138 -0
- package/scss/components/_button.scss +9 -4
- package/scss/components/_callout.scss +175 -0
- package/scss/components/_captioned-figure.scss +173 -0
- package/scss/components/_card-grid.scss +75 -0
- package/scss/components/_card.scss +420 -0
- package/scss/components/_css-icon.scss +433 -0
- package/scss/{_grid.scss → components/_data-grid.scss} +100 -68
- package/scss/components/_data-table.scss +180 -0
- package/scss/components/_fill-context.scss +20 -22
- package/scss/components/_flipcard-grid.scss +66 -0
- package/scss/components/_flipcard.scss +304 -0
- package/scss/components/_form-theme.scss +633 -0
- package/scss/components/_hero.scss +183 -0
- package/scss/components/_horizontal-rule.scss +51 -0
- package/scss/components/_image-grid.scss +71 -0
- package/scss/components/_index.scss +276 -38
- package/scss/components/_links.scss +1 -1
- package/scss/components/_list-lines.scss +14 -3
- package/scss/components/_list-ordered.scss +3 -1
- package/scss/components/_list-unordered.scss +3 -1
- package/scss/components/_menu-stack.scss +245 -0
- package/scss/components/_modal.scss +495 -0
- package/scss/components/_nav-strip.scss +148 -0
- package/scss/components/_overlay-section.scss +122 -0
- package/scss/components/_pager.scss +168 -0
- package/scss/components/_placeholder-block.scss +121 -0
- package/scss/components/_popover.scss +263 -0
- package/scss/components/_pull-quote.scss +111 -0
- package/scss/components/_ratio-box.scss +64 -0
- package/scss/components/_rule.scss +12 -9
- package/scss/components/_scroll-slider.scss +204 -0
- package/scss/components/_skip-link.scss +92 -0
- package/scss/components/_slider.scss +241 -0
- package/scss/components/_spoke-spinner.scss +193 -0
- package/scss/components/_tabs.scss +179 -0
- package/scss/components/_tag.scss +142 -0
- package/scss/components/_tile-button.scss +131 -0
- package/scss/components/_tile-grid-overlay.scss +132 -0
- package/scss/components/_tile-grid.scss +172 -0
- package/scss/components/_vignette.scss +65 -0
- package/scss/components/_wysiwyg.scss +94 -0
- package/scss/helpers/_color.scss +1 -0
- package/scss/helpers/_display.scss +2 -1
- package/scss/helpers/_index.scss +45 -22
- package/scss/helpers/_print.scss +20 -43
- package/scss/helpers/_typography.scss +3 -0
- package/scss/helpers/_units.scss +10 -13
- package/scss/helpers/_utilities.scss +5 -1
- package/scss/stylesheets/base-styles.scss +7 -0
- package/scss/stylesheets/component-styles.scss +7 -0
- package/scss/stylesheets/helper-styles.scss +7 -0
- package/types/events/index.d.ts +1 -1
- package/types/events/index.d.ts.map +1 -1
- package/types/index.d.ts +2 -2
- package/types/{helpers/css-breakpoint.d.ts → ui/breakpoints.d.ts} +3 -3
- package/types/ui/breakpoints.d.ts.map +1 -0
- package/types/ui/collapsible.d.ts +67 -0
- package/types/ui/collapsible.d.ts.map +1 -0
- package/types/ui/dialog.d.ts +42 -0
- package/types/ui/dialog.d.ts.map +1 -0
- package/types/ui/flipcard.d.ts +8 -1
- package/types/ui/flipcard.d.ts.map +1 -1
- package/types/ui/grid.d.ts +0 -11
- package/types/ui/grid.d.ts.map +1 -1
- package/types/ui/index.d.ts +23 -0
- package/types/ui/index.d.ts.map +1 -0
- package/types/ui/modal-builder.d.ts +54 -0
- package/types/ui/modal-builder.d.ts.map +1 -0
- package/types/ui/overflow-scroller-pager.d.ts +1 -1
- package/types/ui/overflow-scroller-pager.d.ts.map +1 -1
- package/types/ui/overflow-scroller.d.ts +3 -1
- package/types/ui/overflow-scroller.d.ts.map +1 -1
- package/types/ui/page.d.ts +5 -0
- package/types/ui/page.d.ts.map +1 -0
- package/types/ui/popover.d.ts +40 -0
- package/types/ui/popover.d.ts.map +1 -0
- package/types/ui/print-details.d.ts +10 -0
- package/types/ui/print-details.d.ts.map +1 -0
- package/types/ui/print.d.ts +10 -0
- package/types/ui/print.d.ts.map +1 -0
- package/types/ui/programmatic-modal.d.ts +19 -1
- package/types/ui/programmatic-modal.d.ts.map +1 -1
- package/types/ui/proxy-click.d.ts +18 -0
- package/types/ui/proxy-click.d.ts.map +1 -0
- package/types/ui/resizer.d.ts +1 -1
- package/types/ui/resizer.d.ts.map +1 -1
- package/types/ui/scroll-slider.d.ts +13 -0
- package/types/ui/scroll-slider.d.ts.map +1 -0
- package/types/ui/scrollpoint.d.ts +133 -0
- package/types/ui/scrollpoint.d.ts.map +1 -0
- package/types/ui/slider.d.ts +14 -2
- package/types/ui/slider.d.ts.map +1 -1
- package/types/ui/tabs.d.ts +22 -0
- package/types/ui/tabs.d.ts.map +1 -1
- package/types/ui/theme-toggle.d.ts +14 -0
- package/types/ui/theme-toggle.d.ts.map +1 -0
- package/types/ui/tooltip.d.ts +92 -10
- package/types/ui/tooltip.d.ts.map +1 -1
- package/types/utils/{logger.d.ts → class-logger.d.ts} +1 -1
- package/types/utils/class-logger.d.ts.map +1 -0
- package/types/utils/dom.d.ts +48 -0
- package/types/utils/dom.d.ts.map +1 -0
- package/types/utils/file-save.d.ts +64 -0
- package/types/utils/file-save.d.ts.map +1 -0
- package/types/utils/floating-ui.d.ts +19 -0
- package/types/utils/floating-ui.d.ts.map +1 -0
- package/types/utils/id.d.ts +10 -0
- package/types/utils/id.d.ts.map +1 -0
- package/types/utils/index.d.ts +9 -0
- package/types/utils/index.d.ts.map +1 -0
- package/types/utils/pause-youtube-video.d.ts.map +1 -0
- package/js/helpers/file-save.js +0 -52
- package/js/helpers/scrollbar-width-property.js +0 -14
- package/project.todo +0 -22
- package/scss/_calculate.scss +0 -64
- package/scss/_utility.scss +0 -12
- package/types/helpers/css-breakpoint.d.ts.map +0 -1
- package/types/helpers/file-save.d.ts +0 -17
- package/types/helpers/file-save.d.ts.map +0 -1
- package/types/helpers/node-data-manager.d.ts +0 -45
- package/types/helpers/node-data-manager.d.ts.map +0 -1
- package/types/helpers/pause-youtube-video.d.ts.map +0 -1
- package/types/helpers/scrollbar-width-property.d.ts +0 -11
- package/types/helpers/scrollbar-width-property.d.ts.map +0 -1
- package/types/ui/modals.d.ts +0 -27
- package/types/ui/modals.d.ts.map +0 -1
- package/types/utils/logger.d.ts.map +0 -1
- package/vite.config.js +0 -36
- /package/{js/deprecated → deprecated/js}/doc-ready.js +0 -0
- /package/{js/deprecated → deprecated/js}/jquery-prototypes.js +0 -0
- /package/{js/deprecated → deprecated/js}/mini-collapsible-popper-positioning.js +0 -0
- /package/{js/deprecated → deprecated/js}/mini-collapsible.js +0 -0
- /package/{js/helpers → deprecated/js}/node-data-manager.js +0 -0
- /package/{js/deprecated → deprecated/js}/script-loader.js +0 -0
- /package/{js/deprecated → deprecated/js}/waypoints/README.md +0 -0
- /package/{js/deprecated → deprecated/js}/waypoints/anchor-menu.js +0 -0
- /package/{js/deprecated → deprecated/js}/waypoints/element-waypoint.js +0 -0
- /package/{js/deprecated → deprecated/js}/waypoints/examples/page-link-menu.md +0 -0
- /package/{js/deprecated → deprecated/js}/waypoints/state-in-attribute.js +0 -0
- /package/types/{helpers → utils}/pause-youtube-video.d.ts +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ulu/frontend",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
4
|
"description": "Modular Sass Theming Library",
|
|
5
5
|
"browser": "js/index.js",
|
|
6
6
|
"main": "index.js",
|
|
@@ -22,13 +22,14 @@
|
|
|
22
22
|
"type": "module",
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "vite build",
|
|
25
|
-
"
|
|
26
|
-
"docs
|
|
27
|
-
"docs:
|
|
28
|
-
"docs:
|
|
29
|
-
"docs:
|
|
30
|
-
"docs:
|
|
31
|
-
"
|
|
25
|
+
"types": "npx tsc",
|
|
26
|
+
"docs": "npx @11ty/eleventy --serve --config=docs.eleventy.js",
|
|
27
|
+
"docs:incremental": "npx @11ty/eleventy --serve --incremental --config=docs.eleventy.js",
|
|
28
|
+
"docs:nogen": "NO_DOC_GEN=true npx @11ty/eleventy --serve --incremental --config=docs.eleventy.js",
|
|
29
|
+
"docs:inspect": "node --inspect-brk ./node_modules/.bin/eleventy --serve --config=docs.eleventy.js",
|
|
30
|
+
"docs:build": "npx @11ty/eleventy --config=docs.eleventy.js",
|
|
31
|
+
"docs:assets": "vite --config docs.vite.config.js --force",
|
|
32
|
+
"docs:assets:build": "vite build --config docs.vite.config.js"
|
|
32
33
|
},
|
|
33
34
|
"repository": {
|
|
34
35
|
"type": "git",
|
|
@@ -54,19 +55,39 @@
|
|
|
54
55
|
},
|
|
55
56
|
"homepage": "https://github.com/Jscherbe/frontend#readme",
|
|
56
57
|
"devDependencies": {
|
|
58
|
+
"@11ty/eleventy": "^3.0.0-alpha.6",
|
|
59
|
+
"@11ty/eleventy-navigation": "^0.3.5",
|
|
60
|
+
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0",
|
|
61
|
+
"@fortawesome/fontawesome-free": "^6.5.2",
|
|
62
|
+
"@ulu/markdown-output-utils": "^0.0.6",
|
|
63
|
+
"@ulu/sassdoc-to-markdown": "^0.0.15",
|
|
64
|
+
"@ulu/vite-config-cms-theme": "^0.0.10",
|
|
57
65
|
"@ulu/vitepress-auto-menus": "^0.0.3",
|
|
58
66
|
"@ulu/vitepress-sassdoc": "^0.0.9",
|
|
67
|
+
"algoliasearch": "^4.23.3",
|
|
68
|
+
"chokidar": "^3.6.0",
|
|
69
|
+
"eleventy-plugin-nesting-toc": "^1.3.0",
|
|
59
70
|
"fs-extra": "^11.2.0",
|
|
71
|
+
"instantsearch.js": "^4.68.1",
|
|
60
72
|
"jsdoc": "^4.0.2",
|
|
61
73
|
"jsdoc-to-markdown": "^8.0.0",
|
|
62
|
-
"
|
|
74
|
+
"markdown-it-anchor": "^8.6.7",
|
|
75
|
+
"markdown-it-attrs": "^4.1.6",
|
|
76
|
+
"micromodal": "^0.4.10",
|
|
77
|
+
"sass-embedded": "^1.81.0",
|
|
78
|
+
"sharp": "^0.33.4",
|
|
79
|
+
"svgo": "^3.3.2",
|
|
63
80
|
"typescript": "^5.3.3",
|
|
64
81
|
"vitepress": "^1.0.0-rc.27"
|
|
65
82
|
},
|
|
66
83
|
"dependencies": {
|
|
67
|
-
"@
|
|
84
|
+
"@floating-ui/dom": "^1.6.5",
|
|
85
|
+
"@ulu/utils": "^0.0.17",
|
|
68
86
|
"aria-tablist": "^1.2.2",
|
|
69
87
|
"autoprefixer": "^10.4.16",
|
|
70
|
-
"vite": "^5.
|
|
88
|
+
"vite": "^5.4.11"
|
|
89
|
+
},
|
|
90
|
+
"optionalDependencies": {
|
|
91
|
+
"ally.js": "^1.4.1"
|
|
71
92
|
}
|
|
72
93
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{#
|
|
2
|
+
* ==============================================================================
|
|
3
|
+
* Accordion / Details
|
|
4
|
+
* ==============================================================================
|
|
5
|
+
*
|
|
6
|
+
* @version 1.0.1
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
{% import directory ~ '/templates/_macros/accordion.twig' as accordionMacros %}
|
|
10
|
+
|
|
11
|
+
* @param {Markup} toggle Markup to include in the toggle button
|
|
12
|
+
* @param {Markup} body Markup to include in the body (hidden area)
|
|
13
|
+
* @param {Object} options Configuration object
|
|
14
|
+
* @param {String} options.icon Add icon classes
|
|
15
|
+
* @param {Boolean} options.open Open by default
|
|
16
|
+
* @param {String} options.modifier Modifer class (needs to correspond with styling)
|
|
17
|
+
|
|
18
|
+
Notes:
|
|
19
|
+
- don't worry about headings in summary it doesn't work on screenreaders
|
|
20
|
+
- I wouldn't reset the headline order within (ie. no sectioning root, I think this will not work for SRs)
|
|
21
|
+
#}
|
|
22
|
+
|
|
23
|
+
{% macro accordion(toggle, body, options = {}) %}
|
|
24
|
+
{% set defaults = {
|
|
25
|
+
open: false,
|
|
26
|
+
modifier: "default",
|
|
27
|
+
icon: null,
|
|
28
|
+
attributes: null
|
|
29
|
+
} %}
|
|
30
|
+
{% set options = defaults|merge(options) %}
|
|
31
|
+
{% set classes = [
|
|
32
|
+
"site-details",
|
|
33
|
+
'site-details--' ~ options.modifier
|
|
34
|
+
] %}
|
|
35
|
+
{% set attributes = options.attributes ?: create_attribute() %}
|
|
36
|
+
<details {{ attributes.addClass(classes).setAttribute("open", options.open) }}>
|
|
37
|
+
<summary class="site-details__summary">
|
|
38
|
+
{{ toggle }}
|
|
39
|
+
<span class="site-details__icon {{ options.icon }}" aria-hidden="true"></span>
|
|
40
|
+
</summary>
|
|
41
|
+
<div class="site-details__content">
|
|
42
|
+
{{ body }}
|
|
43
|
+
</div>
|
|
44
|
+
</details>
|
|
45
|
+
{% endmacro %}
|
|
46
|
+
|
|
47
|
+
{% macro accordionGroup(title, accordions, options = {}) %}
|
|
48
|
+
{% set defaults = {
|
|
49
|
+
titleHidden: true,
|
|
50
|
+
modifier: "default",
|
|
51
|
+
textOpen: "Expand All",
|
|
52
|
+
textClose: "Close All",
|
|
53
|
+
icon: null
|
|
54
|
+
} %}
|
|
55
|
+
{% set uid = ctwig_uniqid("site-details-group") %}
|
|
56
|
+
{% set id = {
|
|
57
|
+
container: uid ~ '--container',
|
|
58
|
+
title: uid ~ '--title',
|
|
59
|
+
expand: uid ~ '--expand'
|
|
60
|
+
} %}
|
|
61
|
+
{% set options = defaults|merge(options) %}
|
|
62
|
+
|
|
63
|
+
<div class="site-details-group {{ 'site-details-group--' ~ options.modifier }}">
|
|
64
|
+
<h2
|
|
65
|
+
id="{{ id.title }}"
|
|
66
|
+
class="{{ options.titleHidden ? 'hidden-visually' : 'site-details-group__title' }}"
|
|
67
|
+
>
|
|
68
|
+
{{ title }}
|
|
69
|
+
</h2>
|
|
70
|
+
<div
|
|
71
|
+
id="{{ id.container }}"
|
|
72
|
+
class="site-details-group__inner"
|
|
73
|
+
aria-multiselectable="true"
|
|
74
|
+
>
|
|
75
|
+
<div class="site-details-group__controls">
|
|
76
|
+
<button
|
|
77
|
+
class="site-details-group__control"
|
|
78
|
+
id="{{ id.expand }}"
|
|
79
|
+
type="button"
|
|
80
|
+
aria-expanded="false"
|
|
81
|
+
aria-controls="{{ id.container }}"
|
|
82
|
+
aria-labelledby="{{ id.title }} {{ id.expand }}"
|
|
83
|
+
data-site-details-group="{{ {
|
|
84
|
+
textOpen: options.textOpen,
|
|
85
|
+
textClose: options.textClose
|
|
86
|
+
}|json_encode }}"
|
|
87
|
+
hidden
|
|
88
|
+
>
|
|
89
|
+
<span
|
|
90
|
+
class="site-details-group__controls-all-icon {{ options.icon }}"
|
|
91
|
+
aria-hidden="true"
|
|
92
|
+
></span>
|
|
93
|
+
{{ options.textOpen }}
|
|
94
|
+
</button>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
{% endmacro %}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{#
|
|
2
|
+
* ==============================================================================
|
|
3
|
+
* Dropdown
|
|
4
|
+
* ==============================================================================
|
|
5
|
+
*
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* {% import directory ~ '/templates/_macros/dropdown.twig' as dropdownMacros %}
|
|
10
|
+
#}
|
|
11
|
+
|
|
12
|
+
{#
|
|
13
|
+
* @param {Markup} toggle Markup to include in the toggle button
|
|
14
|
+
* @param {Markup} body Markup to include in the body (hidden area)
|
|
15
|
+
* @param {Object} options Configuration object
|
|
16
|
+
* @param {String} options.modifier Modifer class (needs to correspond with styling)
|
|
17
|
+
* @param {Boolean} options.isMenu The content of this dropdown should be styled as a menu
|
|
18
|
+
* @param {Boolean} options.placement Placement suggestion, possible values:
|
|
19
|
+
auto, auto-start, auto-end, top, top-start, top-end, bottom, bottom-start,
|
|
20
|
+
bottom-end, right, right-start, right-end, left, left-start, left-end
|
|
21
|
+
#}
|
|
22
|
+
|
|
23
|
+
{% macro dropdown(toggle, body, options = {}) %}
|
|
24
|
+
{% set defaults = {
|
|
25
|
+
isMenu: false,
|
|
26
|
+
modifier: "default",
|
|
27
|
+
placement: "bottom-end"
|
|
28
|
+
} %}
|
|
29
|
+
{% set options = defaults|merge(options) %}
|
|
30
|
+
<div
|
|
31
|
+
class="site-dropdown {{ 'site-dropdown--' ~ options.modifier }}"
|
|
32
|
+
data-cc-placement="{{ options.placement }}"
|
|
33
|
+
>
|
|
34
|
+
<button class="site-dropdown__toggle" type="button">
|
|
35
|
+
{{ toggle }}
|
|
36
|
+
<span class="site-dropdown__toggle-icon" aria-hidden="true"></span>
|
|
37
|
+
</button>
|
|
38
|
+
<div class="site-dropdown__content">
|
|
39
|
+
<div class="{{ options.isMenu ? 'site-dropdown__menu' : 'site-dropdown__content-inner' }}">
|
|
40
|
+
{{ body }}
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
{% endmacro %}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{#
|
|
2
|
+
* ==============================================================================
|
|
3
|
+
* Flipcard
|
|
4
|
+
* ==============================================================================
|
|
5
|
+
*
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* {% import directory ~ '/templates/_macros/flipcard.twig' as flipcardMacros %}
|
|
10
|
+
#}
|
|
11
|
+
|
|
12
|
+
{#
|
|
13
|
+
* @param {Array} flipcards Array of flipcards (markup from flipcard macro below)
|
|
14
|
+
#}
|
|
15
|
+
|
|
16
|
+
{% macro flipcardLayout(flipcards) %}
|
|
17
|
+
<div class="flipcard-grid">
|
|
18
|
+
{% for flipcard in flipcards %}
|
|
19
|
+
<div class="flipcard-grid__item">
|
|
20
|
+
{{ flipcard }}
|
|
21
|
+
</div>
|
|
22
|
+
{% endfor %}
|
|
23
|
+
</div>
|
|
24
|
+
{% endmacro %}
|
|
25
|
+
|
|
26
|
+
{#
|
|
27
|
+
* @param {Markup} front Markup for front
|
|
28
|
+
* @param {Markup} back Markup for back
|
|
29
|
+
* @param {Markup} image Image for the front
|
|
30
|
+
* @param {Object} options Configuration
|
|
31
|
+
* @param {Object} options.modifier Modifer class (needs to correspond with styling)
|
|
32
|
+
* @param {Boolean} options.frontOnBack Include a duplicate of the front content on back (no interactive elements, aria-hidden)
|
|
33
|
+
#}
|
|
34
|
+
|
|
35
|
+
{% macro flipcard(front, back, image = false, options = {}) %}
|
|
36
|
+
{% set var = value %}
|
|
37
|
+
{% set defaults = {
|
|
38
|
+
modifier: "default",
|
|
39
|
+
frontOnBack: false
|
|
40
|
+
} %}
|
|
41
|
+
{% set options = defaults|merge(options) %}
|
|
42
|
+
|
|
43
|
+
<div class="flipcard {{ image ? 'flipcard--w-image' }}" data-site-flipcard>
|
|
44
|
+
<h3 class="flipcard__front" data-site-flipcard-front>
|
|
45
|
+
{% if image %}
|
|
46
|
+
<span class="flipcard__front-image">{{ image }}</span>
|
|
47
|
+
{% endif %}
|
|
48
|
+
<span class="flipcard__front-content">
|
|
49
|
+
{{ front }}
|
|
50
|
+
<span class="flipcard__icon flipcard__icon--front" aria-hidden="true"></span>
|
|
51
|
+
</span>
|
|
52
|
+
</h3>
|
|
53
|
+
<div class="flipcard__back" data-site-flipcard-back>
|
|
54
|
+
{% if frontOnBack %}
|
|
55
|
+
<div class="flipcard__back-front-content" aria-hidden="true">
|
|
56
|
+
{{ front }}
|
|
57
|
+
</div>
|
|
58
|
+
{% endif %}
|
|
59
|
+
<div class="flipcard__back-content">
|
|
60
|
+
{{ back }}
|
|
61
|
+
</div>
|
|
62
|
+
<span class="flipcard__icon flipcard__icon--back" aria-hidden="true"></span>
|
|
63
|
+
</div>
|
|
64
|
+
{# Site styling can choose to use this if wanted or it can remain empty #}
|
|
65
|
+
<div class="flipcard__icon-footer">
|
|
66
|
+
<span class="flipcard__icon flipcard__icon--footer" aria-hidden="true"></span>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
{% endmacro %}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
{#
|
|
3
|
+
==================================================================================
|
|
4
|
+
Image Macros
|
|
5
|
+
==================================================================================
|
|
6
|
+
|
|
7
|
+
Version: 1.0.0
|
|
8
|
+
|
|
9
|
+
Description: Reusable interactive elements, correspond with styling and scripting
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
{% import directory ~ '/templates/_macros/image.twig' as imageMacros %}
|
|
13
|
+
|
|
14
|
+
#}
|
|
15
|
+
|
|
16
|
+
{#
|
|
17
|
+
* @param {Markup} field Image field
|
|
18
|
+
* @param {Markup} options Configruation
|
|
19
|
+
* @param {Markup} options.alt Custom alt text (default to field)
|
|
20
|
+
* @param {Markup} options.class (default to full-width-image)
|
|
21
|
+
#}
|
|
22
|
+
|
|
23
|
+
{% macro large(field, options = {}) %}
|
|
24
|
+
{% if field.value is not empty %}
|
|
25
|
+
{{ drupal_image(field.entity.uri.value, 'large', {
|
|
26
|
+
alt: options.alt|default(field.alt),
|
|
27
|
+
class: options.class|default("full-width-image")
|
|
28
|
+
}) }}
|
|
29
|
+
{% endif %}
|
|
30
|
+
{% endmacro %}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
{#
|
|
2
|
+
Usage:
|
|
3
|
+
{% import directory ~ '/templates/_macros/layout.twig' as layoutMacros %}
|
|
4
|
+
#}
|
|
5
|
+
|
|
6
|
+
{% macro quote(options) %}
|
|
7
|
+
{% set defaults = {
|
|
8
|
+
body: null,
|
|
9
|
+
author: null,
|
|
10
|
+
authorTitle: null,
|
|
11
|
+
authorPhoto: null,
|
|
12
|
+
bodyClasses: "type-large-x"
|
|
13
|
+
} %}
|
|
14
|
+
{% set options = defaults|merge(options) %}
|
|
15
|
+
<figure class="site-quote">
|
|
16
|
+
{# inline all was added incase editor field is output in here #}
|
|
17
|
+
<blockquote class="site-quote__body display-inline-all {{ options.bodyClasses }}">
|
|
18
|
+
{{ options.body }}
|
|
19
|
+
</blockquote>
|
|
20
|
+
{% if options.author %}
|
|
21
|
+
<figcaption class="site-quote__author">
|
|
22
|
+
{% if options.authorPhoto %}
|
|
23
|
+
<div class="site-quote__author-photo">
|
|
24
|
+
<div class="badge badge--small">
|
|
25
|
+
<div class="badge__inner">
|
|
26
|
+
{{ options.authorPhoto }}
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
{% endif %}
|
|
31
|
+
<strong class="site-quote__author-name">
|
|
32
|
+
{{ options.author }}
|
|
33
|
+
</strong>
|
|
34
|
+
{% if options.authorTitle %}
|
|
35
|
+
<span class="site-quote__author-title">
|
|
36
|
+
<span class="visually-hidden">, </span>
|
|
37
|
+
{{ options.authorTitle }}
|
|
38
|
+
</span>
|
|
39
|
+
{% endif %}
|
|
40
|
+
|
|
41
|
+
</figcaption>
|
|
42
|
+
{% endif %}
|
|
43
|
+
</figure>
|
|
44
|
+
{% endmacro %}
|
|
45
|
+
|
|
46
|
+
{% macro videoSection(options) %}
|
|
47
|
+
{% set defaults = {
|
|
48
|
+
title: null,
|
|
49
|
+
body: null,
|
|
50
|
+
url: null,
|
|
51
|
+
image: null
|
|
52
|
+
} %}
|
|
53
|
+
{% set options = defaults|merge(options) %}
|
|
54
|
+
<div class="video-section">
|
|
55
|
+
<div data-grid="columns: 12, gutters-row: true">
|
|
56
|
+
<div data-grid-item="width: 6">
|
|
57
|
+
{% if options.title %}
|
|
58
|
+
<h2 class="h2">{{ options.title }}</h2>
|
|
59
|
+
{% endif %}
|
|
60
|
+
{% if options.body %}
|
|
61
|
+
<div class="wysiwyg crop-margins margin-bottom">
|
|
62
|
+
{{ options.body }}
|
|
63
|
+
</div>
|
|
64
|
+
{% endif %}
|
|
65
|
+
<a class="button" href="{{ options.url }}">
|
|
66
|
+
Watch Video
|
|
67
|
+
<span class="fas fa-play-circle" aria-hidden="true"></span>
|
|
68
|
+
</a>
|
|
69
|
+
</div>
|
|
70
|
+
{% if options.image %}
|
|
71
|
+
<div data-grid-item="width: 5, offset: 1">
|
|
72
|
+
<a class="video-section__link-image" href="{{ options.url }}">
|
|
73
|
+
{{ options.image }}
|
|
74
|
+
</a>
|
|
75
|
+
</div>
|
|
76
|
+
{% endif %}
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
{% endmacro %}
|
|
80
|
+
|
|
81
|
+
{% macro card(ctx, options) %}
|
|
82
|
+
{% set defaults = {
|
|
83
|
+
class: null,
|
|
84
|
+
title: null,
|
|
85
|
+
titleElement: "h3",
|
|
86
|
+
titleHref: null,
|
|
87
|
+
titleLabel: null,
|
|
88
|
+
titleClass: null,
|
|
89
|
+
aboveTitle: null,
|
|
90
|
+
content: null,
|
|
91
|
+
footer: null,
|
|
92
|
+
image: null,
|
|
93
|
+
iconClass: null,
|
|
94
|
+
proxyClick: true
|
|
95
|
+
} %}
|
|
96
|
+
{% set options = defaults|merge(options) %}
|
|
97
|
+
{% set hasProxyClick = options.proxyClick and options.titleHref %}
|
|
98
|
+
{% set attributes = create_attribute({ class: [ "card", "site-card", options.class ] }) %}
|
|
99
|
+
{% if hasProxyClick %}
|
|
100
|
+
{% set attributes = attributes.setAttribute("data-proxy-click", "") %}
|
|
101
|
+
{% endif %}
|
|
102
|
+
|
|
103
|
+
{% set title %}
|
|
104
|
+
{% if options.titleLabel %}
|
|
105
|
+
<span class="site-card__label">{{ options.titleLabel }}</span>
|
|
106
|
+
{% endif %}
|
|
107
|
+
{{ options.aboveTitle }}
|
|
108
|
+
<span class="site-card__title">{{ options.title }}</span>
|
|
109
|
+
{% endset %}
|
|
110
|
+
|
|
111
|
+
<article {{ attributes }}>
|
|
112
|
+
<div class="card__body">
|
|
113
|
+
<{{ options.titleElement }} class="site-card__header">
|
|
114
|
+
{% if options.titleHref %}
|
|
115
|
+
|
|
116
|
+
{% set linkAttrs = create_attribute({ class: "site-card__link", href: options.titleHref }) %}
|
|
117
|
+
{% if options.proxyClick %}
|
|
118
|
+
{% set linkAttrs = linkAttrs.setAttribute("data-proxy-click-source", "") %}
|
|
119
|
+
{% endif %}
|
|
120
|
+
|
|
121
|
+
<a {{ linkAttrs }}>{{ title }}</a>
|
|
122
|
+
{% else %}
|
|
123
|
+
{{ title }}
|
|
124
|
+
{% endif %}
|
|
125
|
+
</{{ options.titleElement }}>
|
|
126
|
+
{% if options.content %}
|
|
127
|
+
<div class="site-card__body">
|
|
128
|
+
{{ options.content }}
|
|
129
|
+
</div>
|
|
130
|
+
{% endif %}
|
|
131
|
+
</div>
|
|
132
|
+
<div class="card__image site-card__image">
|
|
133
|
+
{% if options.image %}
|
|
134
|
+
{{ options.image }}
|
|
135
|
+
{% else %}
|
|
136
|
+
<img src="/{{ ctx.directory }}/dist/images/default-card.svg" alt="">
|
|
137
|
+
{% endif %}
|
|
138
|
+
{% if options.iconClass %}
|
|
139
|
+
<span class="site-card__image-icon {{ options.iconClass }}" aria-hidden="true"></span>
|
|
140
|
+
{% endif %}
|
|
141
|
+
</div>
|
|
142
|
+
{% if options.footer %}
|
|
143
|
+
<div class="card__footer">
|
|
144
|
+
{{ options.footer }}
|
|
145
|
+
</div>
|
|
146
|
+
{% endif %}
|
|
147
|
+
</article>
|
|
148
|
+
{% endmacro %}
|
|
149
|
+
|
|
150
|
+
{% macro sidebar(body, sidebar, options = {}) %}
|
|
151
|
+
{% set defaults = {
|
|
152
|
+
reversed: false,
|
|
153
|
+
reversedMobile: false,
|
|
154
|
+
bodyClasses: "",
|
|
155
|
+
sidebarClasses: "",
|
|
156
|
+
large: false
|
|
157
|
+
} %}
|
|
158
|
+
{% set options = defaults|merge(options) %}
|
|
159
|
+
|
|
160
|
+
{% set sidebarWidth = options.large ? "width: 5" : "width: 4" %}
|
|
161
|
+
{% set bodyWidth = options.large ? "width: 7" : "width: 8" %}
|
|
162
|
+
{% set classes = [
|
|
163
|
+
"layout-sidebar",
|
|
164
|
+
options.reversed ? "layout-sidebar--reversed",
|
|
165
|
+
options.reversedMobile ? "layout-sidebar--reversed-mobile",
|
|
166
|
+
]|join(" ") %}
|
|
167
|
+
{% set bodyClasses = ["layout-sidebar__body", "crop-margins", options.bodyClasses]|join(" ") %}
|
|
168
|
+
{% set sidebarClasses = ["layout-sidebar__sidebar", "crop-margins", options.sidebarClasses ]|join(" ") %}
|
|
169
|
+
<div
|
|
170
|
+
class="{{ classes }}"
|
|
171
|
+
data-grid="columns: 12; align: start, gutters-row: true, rules-column: right"
|
|
172
|
+
>
|
|
173
|
+
{% if options.reversed or options.reversedMobile %}
|
|
174
|
+
{# note: reversedMobile will set the order so that when the grid is active display: flex it
|
|
175
|
+
will appear on the side but on mobile non-grid sizes the order will not be used (on top) #}
|
|
176
|
+
<div
|
|
177
|
+
class="{{ sidebarClasses }}"
|
|
178
|
+
data-grid-item="{{ sidebarWidth }}"
|
|
179
|
+
style="{{ options.reversedMobile ? 'order: 2' }}"
|
|
180
|
+
>
|
|
181
|
+
{{ sidebar }}
|
|
182
|
+
</div>
|
|
183
|
+
<div class="{{ bodyClasses }}" data-grid-item="{{ bodyWidth }}">
|
|
184
|
+
{{ body }}
|
|
185
|
+
</div>
|
|
186
|
+
{% else %}
|
|
187
|
+
<div class="{{ bodyClasses }}" data-grid-item="{{ bodyWidth }}">
|
|
188
|
+
{{ body }}
|
|
189
|
+
</div>
|
|
190
|
+
{% if sidebar %}
|
|
191
|
+
<div class="{{ sidebarClasses }}" data-grid-item="{{ sidebarWidth }}">
|
|
192
|
+
{{ sidebar }}
|
|
193
|
+
</div>
|
|
194
|
+
{% endif %}
|
|
195
|
+
{% endif %}
|
|
196
|
+
</div>
|
|
197
|
+
{% endmacro %}
|
|
198
|
+
|
|
199
|
+
{% macro node(ctx, options = {}) %}
|
|
200
|
+
{% from _self import sidebar, responsiveImage %}
|
|
201
|
+
{% set defaults = {
|
|
202
|
+
label: ctx.label,
|
|
203
|
+
|
|
204
|
+
attributes: ctx.attributes ?
|
|
205
|
+
ctx.attributes|without("role") : create_attribute(),
|
|
206
|
+
content_attributes: ctx.content_attributes ?
|
|
207
|
+
ctx.content_attributes : create_attribute(),
|
|
208
|
+
title_attributes: ctx.title_attributes ?
|
|
209
|
+
ctx.title_attributes : create_attribute(),
|
|
210
|
+
parentTitle: not ctx.menu_parent_title is empty ?
|
|
211
|
+
ctx.menu_parent_title : null,
|
|
212
|
+
body: ctx.content.body|field_value is not empty ?
|
|
213
|
+
ctx.content.body|field_value : null,
|
|
214
|
+
sectioned_header: ctx.content.field_header is not empty ?
|
|
215
|
+
ctx.content.field_header : null,
|
|
216
|
+
sectioned_body: ctx.content.field_sectioned_content is not empty ?
|
|
217
|
+
ctx.content.field_sectioned_content : null,
|
|
218
|
+
sidebar: null,
|
|
219
|
+
sidebarOptions: {},
|
|
220
|
+
badgeImage: null,
|
|
221
|
+
bodyClass: null,
|
|
222
|
+
belowBody: null,
|
|
223
|
+
aboveBody: null,
|
|
224
|
+
beforeBody: null,
|
|
225
|
+
afterBody: null,
|
|
226
|
+
beforeHeader: null,
|
|
227
|
+
afterHeader: null,
|
|
228
|
+
bodyContained: true,
|
|
229
|
+
showBodyField: true,
|
|
230
|
+
showSectionedBodyField: true,
|
|
231
|
+
showHeaderField: true,
|
|
232
|
+
showParentTitle: true,
|
|
233
|
+
} %}
|
|
234
|
+
|
|
235
|
+
{% set options = defaults|merge(options) %}
|
|
236
|
+
{% set hasFieldBody = options.showBodyField and options.body %}
|
|
237
|
+
{% set hasFieldSectionedHeader = options.showHeaderField and options.sectioned_header %}
|
|
238
|
+
{% set hasFieldSectionedBody = options.showSectionedBodyField and options.sectioned_body %}
|
|
239
|
+
{% set hasBodyContent = hasFieldBody or hasFieldSectionedBody or options.aboveBody or options.belowBody %}
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
{% set body %}
|
|
243
|
+
{{ options.aboveBody }}
|
|
244
|
+
{% if hasFieldSectionedBody %}
|
|
245
|
+
{{ options.sectioned_body }}
|
|
246
|
+
{% endif %}
|
|
247
|
+
{% if hasFieldBody %}
|
|
248
|
+
<div class="wysiwyg crop-margins crop-margins--first">
|
|
249
|
+
{{ options.body }}
|
|
250
|
+
</div>
|
|
251
|
+
{% endif %}
|
|
252
|
+
{{ options.belowBody }}
|
|
253
|
+
{% endset %}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
{% set introClasses = [
|
|
257
|
+
"page__intro",
|
|
258
|
+
] %}
|
|
259
|
+
<div{{ options.attributes }}>
|
|
260
|
+
<div class="{{ introClasses|join(' ') }}">
|
|
261
|
+
{% if hasFieldSectionedHeader %}
|
|
262
|
+
{{ options.beforeHeader }}
|
|
263
|
+
{{ options.sectioned_header }}
|
|
264
|
+
{{ options.afterHeader }}
|
|
265
|
+
{% else %}
|
|
266
|
+
{{ options.beforeHeader }}
|
|
267
|
+
<div class="">
|
|
268
|
+
<div class="">
|
|
269
|
+
<h1 {{ options.title_attributes.addClass("h1 page-title") }}>
|
|
270
|
+
{% if options.showParentTitle and options.parentTitle %}
|
|
271
|
+
<span class="headline-label">
|
|
272
|
+
{{ options.parentTitle }}<span class="hidden-visually">:</span>
|
|
273
|
+
</span>
|
|
274
|
+
{% endif %}
|
|
275
|
+
{{ options.label }}
|
|
276
|
+
</h1>
|
|
277
|
+
</div>
|
|
278
|
+
</div>
|
|
279
|
+
{{ options.afterHeader }}
|
|
280
|
+
{% endif %}
|
|
281
|
+
</div>
|
|
282
|
+
|
|
283
|
+
<div class="page__content">
|
|
284
|
+
{{ options.beforeBody }}
|
|
285
|
+
{% if options.sidebar or hasBodyContent %}
|
|
286
|
+
<div class="page__content-body {{ options.bodyClass }}">
|
|
287
|
+
<div {{ options.content_attributes.addClass([
|
|
288
|
+
'page__content-body-inner',
|
|
289
|
+
options.bodyContained and not hasFieldSectionedBody ? 'container'
|
|
290
|
+
]) }}>
|
|
291
|
+
{% if options.sidebar %}
|
|
292
|
+
{{ sidebar(body, options.sidebar, options.sidebarOptions) }}
|
|
293
|
+
{% else %}
|
|
294
|
+
{{ body }}
|
|
295
|
+
{% endif %}
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
{% endif %}
|
|
299
|
+
{{ options.afterBody }}
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
302
|
+
{% endmacro %}
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
{% macro responsiveImage(options) %}
|
|
306
|
+
{% set defaults = {
|
|
307
|
+
alt: "",
|
|
308
|
+
class: null,
|
|
309
|
+
classImage: null,
|
|
310
|
+
src: null,
|
|
311
|
+
srcMedium: null,
|
|
312
|
+
srcLarge: null
|
|
313
|
+
} %}
|
|
314
|
+
{% set options = defaults|merge(options) %}
|
|
315
|
+
{% if options.src %}
|
|
316
|
+
<picture class="{{ options.class }}">
|
|
317
|
+
{# These line up to the breakpoints in Sass #}
|
|
318
|
+
{% if options.srcMedium %}
|
|
319
|
+
<source srcset="{{ options.srcMedium }}" media="(min-width: 53.5em)">
|
|
320
|
+
{% endif %}
|
|
321
|
+
{% if options.srcLarge %}
|
|
322
|
+
<source srcset="{{ options.srcLarge }}" media="(min-width: 76em)">
|
|
323
|
+
{% endif %}
|
|
324
|
+
<img
|
|
325
|
+
class="{{ options.classImage }}"
|
|
326
|
+
src="{{ options.src }}"
|
|
327
|
+
alt="{{ options.alt }}"
|
|
328
|
+
>
|
|
329
|
+
</picture>
|
|
330
|
+
{% elseif options.debug %}
|
|
331
|
+
{{ kint(options) }}
|
|
332
|
+
{% endif %}
|
|
333
|
+
{% endmacro %}
|
|
334
|
+
|
|
335
|
+
{#
|
|
336
|
+
Usage:
|
|
337
|
+
{% import directory ~ '/templates/_macros/element.twig' as elementMacros %}
|
|
338
|
+
#}
|