@ulu/frontend 0.0.23 → 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/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 +57 -26
- 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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
{#
|
|
2
|
+
* ==============================================================================
|
|
3
|
+
* Slider
|
|
4
|
+
* ==============================================================================
|
|
5
|
+
*
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* {% import directory ~ '/templates/_macros/slider.twig' as sliderMacros %}
|
|
10
|
+
*
|
|
11
|
+
* @param {String} modifier Slider modifier class (BEM)
|
|
12
|
+
* @param {String} titleClass Class that goes on the slider's title (title is required)
|
|
13
|
+
* @param {String} titleElement Element for the title
|
|
14
|
+
* @param {Array<Markup>} slides Array of slides markup/HTML
|
|
15
|
+
#}
|
|
16
|
+
|
|
17
|
+
{% macro slider(options = {}) %}
|
|
18
|
+
{% set defaults = {
|
|
19
|
+
modifier: "default",
|
|
20
|
+
title: null,
|
|
21
|
+
titleClass: "hidden-visually",
|
|
22
|
+
titleElement: "h2",
|
|
23
|
+
slides: [],
|
|
24
|
+
slideClass: null,
|
|
25
|
+
pluginOptions: {}
|
|
26
|
+
} %}
|
|
27
|
+
{% set options = defaults|merge(options) %}
|
|
28
|
+
{% if options.slides|length %}
|
|
29
|
+
{% set markup %}
|
|
30
|
+
<div
|
|
31
|
+
class="site-slider site-slider--{{ options.modifier }}"
|
|
32
|
+
data-site-slider="{{ options.pluginOptions|json_encode }}"
|
|
33
|
+
>
|
|
34
|
+
<div class="site-slider__control-context" data-site-slider-control-context>
|
|
35
|
+
<div class="site-slider__track-crop" data-site-slider-track-container>
|
|
36
|
+
<ul class="site-slider__track" data-site-slider-track>
|
|
37
|
+
{% for slide in options.slides %}
|
|
38
|
+
<li class="site-slider__slide {{ options.slideClass }}" data-site-slider-slide>
|
|
39
|
+
{{ slide }}
|
|
40
|
+
</li>
|
|
41
|
+
{% endfor %}
|
|
42
|
+
</ul>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
{% endset %}
|
|
47
|
+
{#
|
|
48
|
+
We define the region if the user passes a title (which is hidden)
|
|
49
|
+
- else user needs to define the region and title so we just output the functional inner markup
|
|
50
|
+
#}
|
|
51
|
+
{% if options.title %}
|
|
52
|
+
{% set titleId = ctwig_uniqid("slider-title") %}
|
|
53
|
+
<section class="site-slider-region" aria-labelledby="{{ titleId }}">
|
|
54
|
+
<{{ options.titleElement }} class="{{ options.titleClass }}" id="{{ titleId }}">
|
|
55
|
+
{{ options.title }}
|
|
56
|
+
</{{ options.titleElement }}>
|
|
57
|
+
{{ markup }}
|
|
58
|
+
</section>
|
|
59
|
+
{% else %}
|
|
60
|
+
{{ markup }}
|
|
61
|
+
{% endif %}
|
|
62
|
+
{% endif %}
|
|
63
|
+
{% endmacro %}
|
|
64
|
+
|
|
65
|
+
{% macro sectionLayout(options) %}
|
|
66
|
+
{% from _self import slider %}
|
|
67
|
+
{% set defaults = {
|
|
68
|
+
title: null,
|
|
69
|
+
titleClass: "h2",
|
|
70
|
+
titleElement: "h2",
|
|
71
|
+
slides: [],
|
|
72
|
+
class: null,
|
|
73
|
+
modifier: "in-content"
|
|
74
|
+
} %}
|
|
75
|
+
{% set options = defaults|merge(options) %}
|
|
76
|
+
{% if options.slides|length %}
|
|
77
|
+
{% set titleId = ctwig_uniqid("slider-title") %}
|
|
78
|
+
<section class="slider-section-layout {{ options.class }}" aria-labelledby="{{ titleId }}">
|
|
79
|
+
<div class="slider-section-layout__title container-small no-padding-bottom">
|
|
80
|
+
<{{ options.titleElement }} class="{{ options.titleClass }}" id="{{ titleId }}">
|
|
81
|
+
{{ options.title }}
|
|
82
|
+
</{{ options.titleElement }}>
|
|
83
|
+
</div>
|
|
84
|
+
<div class="slider-section-layout__slides container no-padding-top">
|
|
85
|
+
{{ slider({
|
|
86
|
+
slides: options.slides,
|
|
87
|
+
modifier: options.modifier,
|
|
88
|
+
pluginOptions: {
|
|
89
|
+
transitionFade: false
|
|
90
|
+
}
|
|
91
|
+
})}}
|
|
92
|
+
</div>
|
|
93
|
+
</section>
|
|
94
|
+
{% endif %}
|
|
95
|
+
{% endmacro %}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
{% macro scrollSliderSection(options = {}) %}
|
|
99
|
+
{% from _self import scrollSlider %}
|
|
100
|
+
{% set defaults = {
|
|
101
|
+
title: null,
|
|
102
|
+
titleClass: "h2 h2--no-rule no-margin-bottom",
|
|
103
|
+
titleElement: "h2",
|
|
104
|
+
slides: [],
|
|
105
|
+
modifier: null,
|
|
106
|
+
titleContainerClasses: null
|
|
107
|
+
} %}
|
|
108
|
+
{% set options = defaults|merge(options) %}
|
|
109
|
+
{% if options.slides|length %}
|
|
110
|
+
{% set titleId = ctwig_uniqid("slider-title") %}
|
|
111
|
+
<section class="scroll-slider-section container-full" aria-labelledby="{{ titleId }}">
|
|
112
|
+
<div class="scroll-slider-section__title container-fit">
|
|
113
|
+
<{{ options.titleElement }} class="{{ options.titleClass }}" id="{{ titleId }}">
|
|
114
|
+
{{ options.title }}
|
|
115
|
+
</{{ options.titleElement }}>
|
|
116
|
+
</div>
|
|
117
|
+
<div class="scroll-slider-section__slides">
|
|
118
|
+
{{ scrollSlider({
|
|
119
|
+
slides: options.slides,
|
|
120
|
+
modifier: options.modifier,
|
|
121
|
+
addEmptyEnds: true
|
|
122
|
+
})}}
|
|
123
|
+
</div>
|
|
124
|
+
</section>
|
|
125
|
+
{% endif %}
|
|
126
|
+
{% endmacro %}
|
|
127
|
+
|
|
128
|
+
{% macro scrollSlider(options = {}) %}
|
|
129
|
+
{% set defaults = {
|
|
130
|
+
modifier: "default",
|
|
131
|
+
slides: [],
|
|
132
|
+
slideClass: null,
|
|
133
|
+
addEmptyEnds: false,
|
|
134
|
+
pluginOptions: {}
|
|
135
|
+
} %}
|
|
136
|
+
{% set options = defaults|merge(options) %}
|
|
137
|
+
{% set emptySlide %}
|
|
138
|
+
<li
|
|
139
|
+
class="scroll-slider__slide scroll-slider__slide--empty"
|
|
140
|
+
role="presentation"
|
|
141
|
+
data-scroll-slider-slide
|
|
142
|
+
>
|
|
143
|
+
|
|
144
|
+
</li>
|
|
145
|
+
{% endset %}
|
|
146
|
+
{% if options.slides|length %}
|
|
147
|
+
<div
|
|
148
|
+
class="scroll-slider scroll-slider--{{ options.modifier }}"
|
|
149
|
+
data-scroll-slider="{{ options.pluginOptions|json_encode }}"
|
|
150
|
+
>
|
|
151
|
+
<div class="scroll-slider__control-context" data-scroll-slider-control-context>
|
|
152
|
+
<div class="scroll-slider__track-crop" data-scroll-slider-track-container>
|
|
153
|
+
<ul class="scroll-slider__track" data-scroll-slider-track>
|
|
154
|
+
{% if options.addEmptyEnds %}
|
|
155
|
+
{{ emptySlide }}
|
|
156
|
+
{% endif %}
|
|
157
|
+
{% for slide in options.slides %}
|
|
158
|
+
<li class="scroll-slider__slide {{ options.slideClass }}" data-scroll-slider-slide>
|
|
159
|
+
{{ slide }}
|
|
160
|
+
</li>
|
|
161
|
+
{% endfor %}
|
|
162
|
+
{% if options.addEmptyEnds %}
|
|
163
|
+
{{ emptySlide }}
|
|
164
|
+
{% endif %}
|
|
165
|
+
</ul>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
{% endif %}
|
|
170
|
+
{% endmacro %}
|
|
171
|
+
|
|
172
|
+
{# Note: From success gaps, scrapped for now #}
|
|
173
|
+
{# {% macro imageLayout(options = {}) %}
|
|
174
|
+
{% set defaults = {
|
|
175
|
+
image: null,
|
|
176
|
+
title: null,
|
|
177
|
+
titleElement: "h3",
|
|
178
|
+
titleClass: "h3",
|
|
179
|
+
body: null,
|
|
180
|
+
bodyClass: "wysiwyg",
|
|
181
|
+
linkHref: null,
|
|
182
|
+
linkText: null,
|
|
183
|
+
linkClass: "button",
|
|
184
|
+
imageBefore: false
|
|
185
|
+
} %}
|
|
186
|
+
{% set options = defaults|merge(options) %}
|
|
187
|
+
<div class="site-slider__slide-inner">
|
|
188
|
+
|
|
189
|
+
<div class="site-slider__slide-content">
|
|
190
|
+
{% if options.title %}
|
|
191
|
+
<{{ options.titleElement }} class="site-slider__slide-title {{ options.titleClass }}">
|
|
192
|
+
{{ options.title }}
|
|
193
|
+
</{{ options.titleElement }}>
|
|
194
|
+
{% endif %}
|
|
195
|
+
{% if options.body %}
|
|
196
|
+
<div class="{{ options.bodyClass }}">
|
|
197
|
+
{{ options.body }}
|
|
198
|
+
</div>
|
|
199
|
+
{% endif %}
|
|
200
|
+
{% if options.linkText and options.linkHref %}
|
|
201
|
+
<p>
|
|
202
|
+
<a href="{{ options.linkHref }}" class="{{ options.linkClass }}">
|
|
203
|
+
{{ options.linkText }}
|
|
204
|
+
</a>
|
|
205
|
+
</p>
|
|
206
|
+
{% endif %}
|
|
207
|
+
</div>
|
|
208
|
+
{% if options.image %}
|
|
209
|
+
<div class="site-slider__slide-image {{ options.imageClass }}" style="{{ options.imageBefore ? 'order: -1;' }}">
|
|
210
|
+
{{ options.image }}
|
|
211
|
+
</div>
|
|
212
|
+
{% endif %}
|
|
213
|
+
</div>
|
|
214
|
+
{% endmacro %} #}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{#
|
|
2
|
+
* ==============================================================================
|
|
3
|
+
* Interactive tab Interface (Aria-tablist implementation)
|
|
4
|
+
* ==============================================================================
|
|
5
|
+
*
|
|
6
|
+
* @version 1.0.2
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
{% import directory ~ '/templates/_macros/tabs.twig' as tabMacros %}
|
|
10
|
+
{{ set tabs = [
|
|
11
|
+
{
|
|
12
|
+
tab: "About",
|
|
13
|
+
panel: aboutMarkup
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
tab: "Directions",
|
|
17
|
+
panel: directionsMarkup
|
|
18
|
+
}
|
|
19
|
+
] }}
|
|
20
|
+
{{ tabMacros.tabs(tabs, {} ) }}
|
|
21
|
+
* @version 1.0.0
|
|
22
|
+
* @param {Array[Tab]} tabs Array of config objects per tab/panel
|
|
23
|
+
* @property {Object} item Config object example
|
|
24
|
+
* @property {Markup} item.tab Markup to be included in tab button (no interactive)
|
|
25
|
+
* @property {Markup} item.panel Markup to be included in panel
|
|
26
|
+
* @property {Boolean} item.open This panel should be open by default
|
|
27
|
+
* @param {Object} options Configuration
|
|
28
|
+
* @param {Object} options.modifier Modifer class (needs to correspond with styling)
|
|
29
|
+
#}
|
|
30
|
+
|
|
31
|
+
{% macro tabs(tabs, options = {}) %}
|
|
32
|
+
{% set defaults = {
|
|
33
|
+
modifier: "default",
|
|
34
|
+
equalHeights: false,
|
|
35
|
+
openByUrlHash: false,
|
|
36
|
+
vertical: false,
|
|
37
|
+
fullpage: false,
|
|
38
|
+
panelContainer: false,
|
|
39
|
+
class: null,
|
|
40
|
+
} %}
|
|
41
|
+
{% set options = defaults|merge(options) %}
|
|
42
|
+
{% set idPrefix = ctwig_uniqid("site-tabs--") %}
|
|
43
|
+
{% set attributes = create_attribute({
|
|
44
|
+
class: [
|
|
45
|
+
"site-tabs",
|
|
46
|
+
options.vertical ? 'site-tabs--' ~ 'vertical',
|
|
47
|
+
options.fullpage ? 'site-tabs--' ~ 'fullpage',
|
|
48
|
+
options.modifier ? 'site-tabs--' ~ options.modifier,
|
|
49
|
+
options.class
|
|
50
|
+
]
|
|
51
|
+
}) %}
|
|
52
|
+
{# {% set mods = mods|map((m) => "site-tabs--#{ m }")|join(" ") %} #}
|
|
53
|
+
<div {{ attributes }}>
|
|
54
|
+
<div
|
|
55
|
+
class="site-tabs__tablist"
|
|
56
|
+
data-site-tablist="{{ options|json_encode }}"
|
|
57
|
+
{{ options.vertical ? 'aria-orientation="vertical"' }}
|
|
58
|
+
>
|
|
59
|
+
{% for item in tabs %}
|
|
60
|
+
<button
|
|
61
|
+
type="button"
|
|
62
|
+
id="{{ idPrefix }}-{{ loop.index }}"
|
|
63
|
+
{{ item.open ? 'aria-selected="true"' }}
|
|
64
|
+
>
|
|
65
|
+
{{ item.tab }}
|
|
66
|
+
</button>
|
|
67
|
+
{% endfor %}
|
|
68
|
+
</div>
|
|
69
|
+
{% for item in tabs %}
|
|
70
|
+
<div
|
|
71
|
+
class="site-tabs__tabpanel"
|
|
72
|
+
aria-labelledby="{{ idPrefix }}-{{ loop.index }}"
|
|
73
|
+
>
|
|
74
|
+
{% if options.fullpage or options.panelContainer %}
|
|
75
|
+
<div class="site-tabs__tabpanel-container">
|
|
76
|
+
{{ item.panel }}
|
|
77
|
+
</div>
|
|
78
|
+
{% else %}
|
|
79
|
+
{{ item.panel }}
|
|
80
|
+
{% endif %}
|
|
81
|
+
</div>
|
|
82
|
+
{% endfor %}
|
|
83
|
+
</div>
|
|
84
|
+
{% endmacro %}
|
package/scss/README.md
CHANGED
|
@@ -55,4 +55,16 @@
|
|
|
55
55
|
- Could use a global config/theme and allow that to be set with "with"
|
|
56
56
|
- Or allow the user to configure the modules and not try and group modules
|
|
57
57
|
- One flat list
|
|
58
|
-
- Needs more thought
|
|
58
|
+
- Needs more thought
|
|
59
|
+
|
|
60
|
+
### Naming Convention for Config Options
|
|
61
|
+
|
|
62
|
+
- When naming config options, the hierarchy is: Element, Styling, State of Element
|
|
63
|
+
- For Example: icon-color-hover = element-styling-state
|
|
64
|
+
|
|
65
|
+
### Organizing Config Options
|
|
66
|
+
|
|
67
|
+
- Config options are alphabetized with the following exceptions.
|
|
68
|
+
- If the options has 3 or more matching first word, they are grouped together at the bottom. (ie: icon-background-color, icon-margin, icon-size)
|
|
69
|
+
- Any maps go at the very bottom. This is to help with scanning the rest of the options
|
|
70
|
+
<!-- add a section about how to document the modules. Add the naming convention rules and the alphabetizing rules -->
|
package/scss/_breakpoint.scss
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
////
|
|
2
2
|
/// @group breakpoint
|
|
3
|
+
/// Utilities for working with breakpoints
|
|
3
4
|
////
|
|
4
5
|
|
|
5
6
|
@use "sass:map";
|
|
6
|
-
@use "calculate";
|
|
7
7
|
@use "utils";
|
|
8
8
|
|
|
9
9
|
/// Module Settings
|
|
10
10
|
/// @type Map
|
|
11
|
-
/// @prop {Number} base [16px] Assumed pixel base, can change based on users font settings so this is just
|
|
12
|
-
/// @prop {Number} gap [0.01em] The amount to offset min from max media queries incase you are using both (
|
|
13
|
-
/// @prop {String} null-name ["none"] The name of the space from 0 to the first breakpoint (doesn't really matter) used when passing breakpoints to JS via content property
|
|
14
|
-
/// @prop {String} default ["small"] The name of the
|
|
11
|
+
/// @prop {Number} base [16px] Assumed pixel base, can change based on users font settings so this is just to get us in the ballpark. Note this is not the base font size but the user agent's or user's browser preference. This number is just being used for calculating estimated em sizes from average base. Since pixels are easier to understand but since we allow the user to set their font size. All of our css is relative to that, including most of the layout (rems, other relative units)
|
|
12
|
+
/// @prop {Number} gap [0.01em] The amount to offset min from max media queries incase you are using both (prevent overlap)
|
|
13
|
+
/// @prop {String} null-name ["none"] The name of the space from 0 to the first breakpoint (doesn't really matter) used when passing breakpoints to JS via content property (see breakpoint.embed-for-scripts() or cssvar.declare-breakpoint-sizes()) to pass breakpoints to JS. The js ui/breakpoints.js module provides methods for interacting with breakpoints in JS.
|
|
14
|
+
/// @prop {String} default ["small"] The name of the breakpoint that is considered the major change (ie desktop to mobile) used by other modules/components
|
|
15
15
|
|
|
16
16
|
$config: (
|
|
17
17
|
"base": 16px,
|
|
18
|
+
"default" : "small",
|
|
18
19
|
"gap": 0.01em,
|
|
19
20
|
"null-name": "none",
|
|
20
|
-
"default" : "small"
|
|
21
21
|
) !default;
|
|
22
22
|
|
|
23
23
|
/// Change modules $config
|
|
24
24
|
/// @example scss Change default name
|
|
25
|
-
/// @include breakpoint
|
|
25
|
+
/// @include ulu.breakpoint-set(( "default" : "mini" ));
|
|
26
26
|
/// @param {Map} $changes Map of changes
|
|
27
27
|
|
|
28
28
|
@mixin set($changes) {
|
|
@@ -31,7 +31,7 @@ $config: (
|
|
|
31
31
|
|
|
32
32
|
/// Get a config option
|
|
33
33
|
/// @example scss Get default breakpoint name
|
|
34
|
-
/// $default: breakpoint
|
|
34
|
+
/// $default: ulu.breakpoint-get("default");
|
|
35
35
|
/// @param {Map} $name Name of property
|
|
36
36
|
/// @return {*} Property Value
|
|
37
37
|
|
|
@@ -39,38 +39,39 @@ $config: (
|
|
|
39
39
|
@return utils.require-map-get($config, $name, 'breakpoint [config]');
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
/// The default breakpoint sizes (targets are not precise, using em's)
|
|
42
|
+
/// The default breakpoint sizes
|
|
44
43
|
/// - Map of breakpoints
|
|
45
44
|
/// - Each property is the breakpoints name
|
|
46
|
-
/// - Each value is that breakpoints point (set in em)
|
|
45
|
+
/// - Each value is that breakpoints point (set in em by default)
|
|
47
46
|
/// @type Map
|
|
48
47
|
|
|
49
48
|
$sizes: (
|
|
50
|
-
"small" :
|
|
51
|
-
"medium" :
|
|
52
|
-
"large" :
|
|
49
|
+
"small" : utils.pixel-to-em(680px, get("base")),
|
|
50
|
+
"medium" : utils.pixel-to-em(1200px, get("base")),
|
|
51
|
+
"large" : utils.pixel-to-em(1500px, get("base"))
|
|
53
52
|
) !default;
|
|
54
53
|
|
|
55
54
|
/// Update the breakpoint sizes map
|
|
56
55
|
/// @example scss Changing the medium breakpoint and adding jumbo
|
|
57
|
-
/// @include breakpoints
|
|
56
|
+
/// @include ulu.breakpoints-set-sizes((
|
|
58
57
|
/// "medium" : 50em,
|
|
59
58
|
/// "jumbo" : 100em
|
|
60
59
|
/// ));
|
|
61
60
|
/// @param {Map} $changes A map to merge into the breakpoints map
|
|
62
|
-
/// @param {Map} $merge-mode [null] Merge
|
|
61
|
+
/// @param {Map} $merge-mode [null] Merge strategy see, utils.map-merge options
|
|
63
62
|
|
|
64
63
|
@mixin set-sizes($changes, $merge-mode: null) {
|
|
65
64
|
$sizes: utils.map-merge($sizes, $changes, $merge-mode) !global;
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
/// Get all breakpoint sizes
|
|
67
|
+
/// Get all breakpoint sizes
|
|
68
|
+
/// @return {Map} Map of breakpoints (equivalent to $sizes)
|
|
69
|
+
|
|
69
70
|
@function get-sizes() {
|
|
70
71
|
@return $sizes;
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
///
|
|
74
|
+
/// Get a specific breakpoint's raw value/size
|
|
74
75
|
/// @param {String} $size The name of the size to get
|
|
75
76
|
/// @return {Number} The sizes value
|
|
76
77
|
|
|
@@ -78,6 +79,18 @@ $sizes: (
|
|
|
78
79
|
@return utils.require-map-get($sizes, $size, "breakpoint size");
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
/// Get a specific breakpoint's size's value and optionally specify max to get the ending/max value for a breakpoint
|
|
83
|
+
/// @param {Boolean} $max [false] Get the max value
|
|
84
|
+
/// @return {Number} The value for the given size
|
|
85
|
+
|
|
86
|
+
@function get-size-value($size, $max: false) {
|
|
87
|
+
@if ($max) {
|
|
88
|
+
@return get-size($size) - get("gap");
|
|
89
|
+
} @else {
|
|
90
|
+
@return get-size($size);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
81
94
|
/// Check if a specific size exist
|
|
82
95
|
/// @param {String} $name The breakpoint size to check if exists
|
|
83
96
|
/// @return {Boolean}
|
|
@@ -89,7 +102,7 @@ $sizes: (
|
|
|
89
102
|
|
|
90
103
|
/// Create a media query that matches the min-width for a given size
|
|
91
104
|
/// @example scss
|
|
92
|
-
/// @include breakpoints
|
|
105
|
+
/// @include ulu.breakpoints-min("small") {
|
|
93
106
|
/// // Your styles
|
|
94
107
|
/// }
|
|
95
108
|
/// @example css
|
|
@@ -100,7 +113,7 @@ $sizes: (
|
|
|
100
113
|
|
|
101
114
|
@mixin min($size) {
|
|
102
115
|
// Adding the small fraction to prevent overlap
|
|
103
|
-
$min: get-size($size);
|
|
116
|
+
$min: get-size-value($size);
|
|
104
117
|
@media screen and (min-width: $min) {
|
|
105
118
|
@content;
|
|
106
119
|
}
|
|
@@ -119,7 +132,7 @@ $sizes: (
|
|
|
119
132
|
|
|
120
133
|
@mixin max($size) {
|
|
121
134
|
// Adding the small fraction to prevent overlap
|
|
122
|
-
$max: get-size($size
|
|
135
|
+
$max: get-size-value($size, true);
|
|
123
136
|
@media screen and (max-width: $max) {
|
|
124
137
|
@content;
|
|
125
138
|
}
|
|
@@ -147,7 +160,7 @@ $sizes: (
|
|
|
147
160
|
}
|
|
148
161
|
|
|
149
162
|
/// Create a media query from a specific size in either direction
|
|
150
|
-
/// - This is for mostly programmatic usage, so that a user could pass a breakpoint
|
|
163
|
+
/// - This is for mostly programmatic usage, so that a user could pass a breakpoint configuration that may contain values that go in either direction
|
|
151
164
|
/// - This way you don't need to repeat conditions (ie if min ... else ...)
|
|
152
165
|
/// @example scss
|
|
153
166
|
/// $size: map.get($user-breakpoint, "size");
|
|
@@ -172,9 +185,39 @@ $sizes: (
|
|
|
172
185
|
}
|
|
173
186
|
}
|
|
174
187
|
|
|
175
|
-
///
|
|
176
|
-
///
|
|
177
|
-
///
|
|
188
|
+
/// Utility Method for iterating over a map of breakpoints and apply styles
|
|
189
|
+
/// @example scss
|
|
190
|
+
/// @include breakpoints.fromEach($breakpoints) using ($props) {
|
|
191
|
+
/// width: map.get($props, "width");
|
|
192
|
+
/// }
|
|
193
|
+
/// @param {String} $breakpoints A map with breakpoints direction will be pulled from each items "direction" property, if direction is missing and no breakpoint will wrap the code
|
|
194
|
+
/// @param {String} $options A map with options to change the behavior
|
|
195
|
+
/// @param {Boolean} $options.directionRequired Require direction throw error if missing direction
|
|
196
|
+
|
|
197
|
+
@mixin from-each($breakpoints, $options: ()) {
|
|
198
|
+
$directionRequired: map.get($options, "directionRequired");
|
|
199
|
+
@each $name, $props in $breakpoints {
|
|
200
|
+
$direction: map.get($props, "direction");
|
|
201
|
+
// If direction print with breakpoint
|
|
202
|
+
@if ($direction) {
|
|
203
|
+
@include from($name, $direction) {
|
|
204
|
+
@content($props);
|
|
205
|
+
}
|
|
206
|
+
// If user requires direction throw error if missing
|
|
207
|
+
} @else if ($directionRequired) {
|
|
208
|
+
@debug $breakpoints;
|
|
209
|
+
@error 'ULU: Missing required "direction" in breakpoints map (above).';
|
|
210
|
+
// Else direction wasn't required print without media query (useful for default style)
|
|
211
|
+
} @else {
|
|
212
|
+
@content($props);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/// Attaches breakpoints to an element pseudo content for access via script
|
|
218
|
+
/// - Note you can also use cssvar.declare-breakpoints to get a similar implementation with css custom-properties
|
|
219
|
+
/// - Use with ulu/js/breakpoints (class has options for content property or css custom property)
|
|
220
|
+
/// - Breakpoints always min-width (upwards) for javascript setup
|
|
178
221
|
|
|
179
222
|
@mixin embed-for-scripts() {
|
|
180
223
|
&:before {
|
|
@@ -186,4 +229,4 @@ $sizes: (
|
|
|
186
229
|
}
|
|
187
230
|
}
|
|
188
231
|
}
|
|
189
|
-
}
|
|
232
|
+
}
|