@financial-times/o-private-foundation 1.0.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/README.md +108 -0
- package/demos/src/demo.mustache +0 -0
- package/demos/src/demo.scss +1 -0
- package/main.js +60 -0
- package/main.scss +32 -0
- package/origami.json +26 -0
- package/package.json +33 -0
- package/src/scss/_brand.scss +68 -0
- package/src/scss/_tokens.scss +15 -0
- package/src/scss/_variables.scss +1 -0
- package/src/scss/o-buttons/custom-themes.scss +631 -0
- package/src/scss/o-buttons/main.scss +255 -0
- package/src/scss/o-colors/_functions.scss +354 -0
- package/src/scss/o-colors/_palette.scss +2 -0
- package/src/scss/o-colors/_variables.scss +50 -0
- package/src/scss/o-colors/main.scss +6 -0
- package/src/scss/o-grid/_functions.scss +90 -0
- package/src/scss/o-grid/_mixins.scss +384 -0
- package/src/scss/o-grid/_variables.scss +105 -0
- package/src/scss/o-grid/main.scss +5 -0
- package/src/scss/o-icons/_mixins.scss +71 -0
- package/src/scss/o-icons/main.scss +1 -0
- package/src/scss/o-normalise/_mixins.scss +126 -0
- package/src/scss/o-normalise/_variables.scss +10 -0
- package/src/scss/o-normalise/main.scss +4 -0
- package/src/scss/o-spacing/_variables.scss +29 -0
- package/src/scss/o-spacing/main.scss +28 -0
- package/src/scss/o-typography/main.scss +428 -0
- package/src/scss/o-visual-effects/main.scss +4 -0
- package/src/scss/o-visual-effects/scss/_shadows.scss +31 -0
- package/src/scss/o-visual-effects/scss/_variables.scss +13 -0
- package/src/scss/tokens/core.scss +563 -0
- package/src/scss/tokens/internal.scss +456 -0
- package/src/scss/tokens/professional.scss +537 -0
- package/src/scss/tokens/sustainable-views.scss +493 -0
- package/src/scss/tokens/whitelabel.scss +465 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/// Get the grid gutter at a given layout (breakpoint).
|
|
2
|
+
///
|
|
3
|
+
/// @param {String|null|Boolean} $layout-name [default] - One of $o-pf-grid-layouts breakpoints e.g. S, M, L...
|
|
4
|
+
@function oPrivateGridGutter($layout-name: default) {
|
|
5
|
+
// This layout was assigned a gutter directly
|
|
6
|
+
@if map-get($o-pf-grid-gutters, $layout-name) {
|
|
7
|
+
@return map-get($o-pf-grid-gutters, $layout-name);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Checking the position of the layout in the list of layouts
|
|
11
|
+
$layout-index: index($_o-pf-grid-layout-names, $layout-name);
|
|
12
|
+
|
|
13
|
+
// The first layout (S) should get the default gutter
|
|
14
|
+
@if $layout-index == 1 {
|
|
15
|
+
@return oPrivateGridGutter();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// No gutter found for this layout, let's try again with a smaller one
|
|
19
|
+
$layout: nth($_o-pf-grid-layout-names, $layout-index - 1);
|
|
20
|
+
@return oPrivateGridGutter($layout);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/// Get the max width of a layout (breakpoint).
|
|
24
|
+
///
|
|
25
|
+
/// @example
|
|
26
|
+
/// .my-large-container { width: oPrivateGridGetMaxWidthForLayout(L); }
|
|
27
|
+
///
|
|
28
|
+
/// @param {String} $layout-name - one of $o-pf-grid-layouts
|
|
29
|
+
/// @param {String} $grid-mode [$o-pf-grid-mode]
|
|
30
|
+
@function oPrivateGridGetMaxWidthForLayout($layout-name, $grid-mode: $o-pf-grid-mode) {
|
|
31
|
+
$grid-is-responsive: $grid-mode != 'fixed';
|
|
32
|
+
|
|
33
|
+
$index: index($_o-pf-grid-layout-names, $layout-name);
|
|
34
|
+
|
|
35
|
+
// Largest layout: return its width directly
|
|
36
|
+
@if $index == length($_o-pf-grid-layout-names) {
|
|
37
|
+
@return $_o-pf-grid-max-width;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Smaller layouts:
|
|
41
|
+
@if $grid-is-responsive {
|
|
42
|
+
// - The grid is responsive (fluid or snappy):
|
|
43
|
+
// return the next larger layout width
|
|
44
|
+
$next-layout: nth($_o-pf-grid-layout-names, $index + 1);
|
|
45
|
+
@return map-get($o-pf-grid-layouts, $next-layout);
|
|
46
|
+
} @else {
|
|
47
|
+
// - The grid is fixed, return the current layout width
|
|
48
|
+
@return map-get($o-pf-grid-layouts, $layout-name);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/// % width of an element in the grid
|
|
53
|
+
///
|
|
54
|
+
/// @example
|
|
55
|
+
/// .one-half { width: oPrivateGridColspan(1/2); } // 50%
|
|
56
|
+
/// .other-half { width: oPrivateGridColspan(one-half); } // 50%
|
|
57
|
+
/// .sidebar { width: oPrivateGridColspan(5); } // 41.66667%
|
|
58
|
+
/// .two-thirds { width: oPrivateGridColspan(2/3); } // 66.66667%
|
|
59
|
+
/// .4-out-of-6 { width: oPrivateGridColspan(4, 6); } // 66.66667%
|
|
60
|
+
///
|
|
61
|
+
/// @param {Number | String} $span - Number of columns the element spans over
|
|
62
|
+
/// @param {Number} $total-cols [$_o-pf-grid-columns] - Number of columns in the grid
|
|
63
|
+
///
|
|
64
|
+
/// @returns {Number} width of the element in the grid, in percents
|
|
65
|
+
@function oPrivateGridColspan($span, $total-cols: $_o-pf-grid-columns) {
|
|
66
|
+
// Match the HTML helper API with human-friendly numbers
|
|
67
|
+
@if $span == 'one-half' { $span: div(1, 2); }
|
|
68
|
+
@if $span == 'one-quarter' { $span: div(1, 4); }
|
|
69
|
+
@if $span == 'one-third' { $span: div(1, 3); }
|
|
70
|
+
@if $span == 'two-thirds' { $span: div(2, 3); }
|
|
71
|
+
@if $span == 'three-quarters' { $span: div(3, 4); }
|
|
72
|
+
|
|
73
|
+
@if $span == 'full-width' {
|
|
74
|
+
@return 100%;
|
|
75
|
+
} @else {
|
|
76
|
+
@if $span >= 1 {
|
|
77
|
+
// A number of columns is supplied: converting it into a fraction
|
|
78
|
+
// of the total number of columns
|
|
79
|
+
@return percentage(div($span, $total-cols));
|
|
80
|
+
} @else {
|
|
81
|
+
// A fraction (1/2) or a number (0.5) is supplied:
|
|
82
|
+
// converting it into a percentage
|
|
83
|
+
@return percentage($span);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@function _oPrivateGridQuoteString($value) {
|
|
89
|
+
@return '"#{$value}"';
|
|
90
|
+
}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/// Apply styles at a given layout size (breakpoint) as the grid. It should be
|
|
2
|
+
// passed one of $o-pf-grid-layouts e.g. `S`, `M`, etc... depending on which layout
|
|
3
|
+
// size the style should apply at.
|
|
4
|
+
///
|
|
5
|
+
/// @example
|
|
6
|
+
/// // Turn the color of an element red at medium layout size and up
|
|
7
|
+
/// @include oPrivateGridRespondTo(M) {
|
|
8
|
+
/// element {
|
|
9
|
+
/// color: red;
|
|
10
|
+
/// }
|
|
11
|
+
/// }
|
|
12
|
+
/// // Turn the color of an element blue until medium layout
|
|
13
|
+
/// element {
|
|
14
|
+
/// @include oPrivateGridRespondTo($until: M) {
|
|
15
|
+
/// color: blue;
|
|
16
|
+
/// }
|
|
17
|
+
/// }
|
|
18
|
+
/// // Turn the color of an element green from small layout until medium layout
|
|
19
|
+
/// element {
|
|
20
|
+
/// @include oPrivateGridRespondTo($from: S, $until: M) {
|
|
21
|
+
/// color: green;
|
|
22
|
+
/// }
|
|
23
|
+
/// }
|
|
24
|
+
///
|
|
25
|
+
/// @param {String} from - one of $o-pf-grid-layouts
|
|
26
|
+
/// @param {String} until - one of $o-pf-grid-layouts
|
|
27
|
+
@mixin oPrivateGridRespondTo($from: false, $until: false) {
|
|
28
|
+
$grid-is-responsive: $o-pf-grid-mode != 'fixed';
|
|
29
|
+
@include mq(
|
|
30
|
+
$from: $from,
|
|
31
|
+
$until: $until,
|
|
32
|
+
$responsive: $grid-is-responsive,
|
|
33
|
+
$breakpoints: $o-pf-grid-layouts,
|
|
34
|
+
$static-breakpoint: $o-pf-grid-fixed-layout
|
|
35
|
+
) {
|
|
36
|
+
@content;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// Base column styles and responsive layout width
|
|
41
|
+
///
|
|
42
|
+
/// @example scss Block has column styles
|
|
43
|
+
/// el { @include oPrivateGridColspan(); }
|
|
44
|
+
///
|
|
45
|
+
/// @example scss 4-column wide block
|
|
46
|
+
/// el { @include oPrivateGridColspan(4); }
|
|
47
|
+
///
|
|
48
|
+
/// @example scss Half-width block
|
|
49
|
+
/// el { @include oPrivateGridColspan(1/2); }
|
|
50
|
+
///
|
|
51
|
+
/// @example scss Block is full-width by default, 8-column wide on Medium layouts and hidden on Large layouts
|
|
52
|
+
/// el { @include oPrivateGridColspan((default: 12, M: 8, L: hide)); }
|
|
53
|
+
///
|
|
54
|
+
/// @param {Number | Map} $span [null]
|
|
55
|
+
@mixin oPrivateGridColspan($span: null, $width-only: false) {
|
|
56
|
+
@if not $width-only {
|
|
57
|
+
box-sizing: border-box;
|
|
58
|
+
float: left;
|
|
59
|
+
flex: 1 1 0%;
|
|
60
|
+
position: relative; // Required for push and pull
|
|
61
|
+
|
|
62
|
+
@if $o-pf-grid-mode == 'fixed' {
|
|
63
|
+
padding-left: oPrivateGridGutter($o-pf-grid-fixed-layout);
|
|
64
|
+
} @else {
|
|
65
|
+
@each $layout-name in map-keys($o-pf-grid-gutters) {
|
|
66
|
+
@if $layout-name == 'default' {
|
|
67
|
+
padding-left: oPrivateGridGutter();
|
|
68
|
+
} @else {
|
|
69
|
+
@include oPrivateGridRespondTo($layout-name) {
|
|
70
|
+
padding-left: oPrivateGridGutter($layout-name);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
@if $span {
|
|
77
|
+
@include _oPrivateGridColumnWidth($span);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// Grid container
|
|
82
|
+
///
|
|
83
|
+
/// @param {String} $grid-mode [$o-pf-grid-mode]
|
|
84
|
+
/// @param {Boolean} $bleed [false]
|
|
85
|
+
@mixin oPrivateGridContainer($grid-mode: $o-pf-grid-mode, $bleed: false) {
|
|
86
|
+
box-sizing: border-box;
|
|
87
|
+
margin-left: auto;
|
|
88
|
+
margin-right: auto;
|
|
89
|
+
min-width: $_o-pf-grid-min-width;
|
|
90
|
+
// Older browsers get a fixed-width layout
|
|
91
|
+
max-width: oPrivateGridGetMaxWidthForLayout($o-pf-grid-fixed-layout);
|
|
92
|
+
position: relative;
|
|
93
|
+
|
|
94
|
+
@if $bleed {
|
|
95
|
+
padding-left: 0;
|
|
96
|
+
padding-right: 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@if $grid-mode == 'fixed' {
|
|
100
|
+
// If the grid isn't fluid, we set it to a certain width
|
|
101
|
+
width: oPrivateGridGetMaxWidthForLayout(
|
|
102
|
+
$o-pf-grid-fixed-layout,
|
|
103
|
+
$grid-mode: 'fixed'
|
|
104
|
+
);
|
|
105
|
+
@if not $bleed {
|
|
106
|
+
padding-left: oPrivateGridGutter($o-pf-grid-fixed-layout);
|
|
107
|
+
padding-right: oPrivateGridGutter($o-pf-grid-fixed-layout);
|
|
108
|
+
}
|
|
109
|
+
} @else {
|
|
110
|
+
max-width: $_o-pf-grid-max-width;
|
|
111
|
+
|
|
112
|
+
@each $layout-name in map-keys($o-pf-grid-gutters) {
|
|
113
|
+
@if $layout-name == 'default' {
|
|
114
|
+
@if not $bleed {
|
|
115
|
+
padding-left: oPrivateGridGutter();
|
|
116
|
+
padding-right: oPrivateGridGutter();
|
|
117
|
+
}
|
|
118
|
+
} @else {
|
|
119
|
+
@include oPrivateGridRespondTo($layout-name) {
|
|
120
|
+
@if not $bleed {
|
|
121
|
+
padding-left: oPrivateGridGutter($layout-name);
|
|
122
|
+
padding-right: oPrivateGridGutter($layout-name);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@each $layout-name in $_o-pf-grid-layout-names {
|
|
129
|
+
@if index($_o-pf-grid-layout-names, $layout-name) >=
|
|
130
|
+
index($_o-pf-grid-layout-names, $_o-pf-grid-start-snappy-mode-at)
|
|
131
|
+
{
|
|
132
|
+
@include oPrivateGridRespondTo($layout-name) {
|
|
133
|
+
@if $grid-mode == 'snappy' {
|
|
134
|
+
max-width: map-get($o-pf-grid-layouts, $layout-name);
|
|
135
|
+
}
|
|
136
|
+
@if $grid-mode == 'fluid' {
|
|
137
|
+
// If the grid mode is fluid, then use a class to make a row or a set of rows snappy
|
|
138
|
+
.o-grid-snappy &,
|
|
139
|
+
&--snappy {
|
|
140
|
+
max-width: map-get($o-pf-grid-layouts, $layout-name);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/// Base row styles
|
|
150
|
+
@mixin oPrivateGridRow {
|
|
151
|
+
clear: both;
|
|
152
|
+
flex-wrap: wrap; // Note that this breaks in old Firefox
|
|
153
|
+
display: flex;
|
|
154
|
+
|
|
155
|
+
@media print {
|
|
156
|
+
display: inherit;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@if $o-pf-grid-mode == 'fixed' {
|
|
160
|
+
margin-left: -1 * oPrivateGridGutter($o-pf-grid-fixed-layout);
|
|
161
|
+
} @else {
|
|
162
|
+
@each $layout-name in map-keys($o-pf-grid-gutters) {
|
|
163
|
+
@if $layout-name == 'default' {
|
|
164
|
+
margin-left: -1 * oPrivateGridGutter();
|
|
165
|
+
} @else {
|
|
166
|
+
@include oPrivateGridRespondTo($layout-name) {
|
|
167
|
+
margin-left: -1 * oPrivateGridGutter($layout-name);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Clearfix for IE9 and below
|
|
174
|
+
zoom: 1;
|
|
175
|
+
|
|
176
|
+
&:before,
|
|
177
|
+
&:after {
|
|
178
|
+
content: '';
|
|
179
|
+
display: table;
|
|
180
|
+
display: flex; // stylelint-disable-line declaration-block-no-duplicate-properties
|
|
181
|
+
}
|
|
182
|
+
&:after {
|
|
183
|
+
clear: both;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/// Surface the layout currently displayed to make it readable in JS.
|
|
188
|
+
///
|
|
189
|
+
/// @example js
|
|
190
|
+
/// // your-app/main.js
|
|
191
|
+
/// // Return the current layout (e.g. default, S, M, L, XL)
|
|
192
|
+
/// import oPrivateGrid from 'o-private-foundation/o-grid';
|
|
193
|
+
/// let currentLayout = oPrivateGrid.getCurrentLayout();
|
|
194
|
+
/// console.log(currentLayout);
|
|
195
|
+
///
|
|
196
|
+
/// // Return the current gutter (e.g. 10px, 20px)
|
|
197
|
+
/// import oPrivateGrid from 'o-private-foundation/o-grid';
|
|
198
|
+
/// let currentGutter = oPrivateGrid.getCurrentGutter();
|
|
199
|
+
/// console.log(currentGutter);
|
|
200
|
+
@mixin oPrivateGridSurfaceCurrentLayout {
|
|
201
|
+
html:after {
|
|
202
|
+
content: '{ "layout": "default", "gutter": "' + oPrivateGridGutter() + '" }';
|
|
203
|
+
display: none;
|
|
204
|
+
|
|
205
|
+
@each $breakpoint in $_o-pf-grid-layout-names {
|
|
206
|
+
@include oPrivateGridRespondTo($breakpoint) {
|
|
207
|
+
content: '{ "layout": "' + $breakpoint + '", "gutter": "' +
|
|
208
|
+
oPrivateGridGutter($breakpoint) + '" }';
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/// Fix a bug in Safari where items wouldn't wrap properly
|
|
215
|
+
/// Remove when Safari 10 support is no longer required.
|
|
216
|
+
/// @link https://github.com/philipwalton/flexbugs#11-min-and-max-size-declarations-are-ignored-when-wrapping-flex-items
|
|
217
|
+
/// @access private
|
|
218
|
+
@mixin _oPrivateGridFixSafariWrap($args...) {
|
|
219
|
+
flex-basis: oPrivateGridColspan($args...);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/// Cross browser column widths across layouts
|
|
223
|
+
///
|
|
224
|
+
/// @access private
|
|
225
|
+
///
|
|
226
|
+
/// @example scss
|
|
227
|
+
/// el { @include _oPrivateGridColumnWidth(4); }
|
|
228
|
+
/// el { @include _oPrivateGridColumnWidth(1/2); }
|
|
229
|
+
/// el { @include _oPrivateGridColumnWidth(hide); }
|
|
230
|
+
/// el { @include _oPrivateGridColumnWidth((default: 12, M: 8, L: hide)); }
|
|
231
|
+
///
|
|
232
|
+
/// @param {Number | Map} $span
|
|
233
|
+
@mixin _oPrivateGridColumnWidth($span) {
|
|
234
|
+
// Special case: the column is hidden by default
|
|
235
|
+
@if $span == 'hide' {
|
|
236
|
+
display: none;
|
|
237
|
+
} @else {
|
|
238
|
+
// $span is a number or a keyword, so we're outputting the default width for that column
|
|
239
|
+
@if type-of($span) == number or type-of($span) == string {
|
|
240
|
+
// Restore visibility from `display: none`
|
|
241
|
+
// if `data-o-grid-colspan` was set to `0` or `hide`
|
|
242
|
+
display: block;
|
|
243
|
+
|
|
244
|
+
// Define width in %
|
|
245
|
+
@include _oPrivateGridFixSafariWrap(
|
|
246
|
+
$span
|
|
247
|
+
); //stylelint-disable-line order/order
|
|
248
|
+
min-width: oPrivateGridColspan($span);
|
|
249
|
+
max-width: oPrivateGridColspan($span);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// $span is a map, we're looping through all of the layouts
|
|
254
|
+
@if type-of($span) == map {
|
|
255
|
+
@each $layout-name, $layout-span in $span {
|
|
256
|
+
@if $layout-name == 'default' {
|
|
257
|
+
@include _oPrivateGridColumnWidth($layout-span);
|
|
258
|
+
} @else {
|
|
259
|
+
@if $layout-span == 'hide' {
|
|
260
|
+
@include oPrivateGridRespondTo($layout-name) {
|
|
261
|
+
display: none;
|
|
262
|
+
}
|
|
263
|
+
} @else {
|
|
264
|
+
@include oPrivateGridRespondTo($layout-name) {
|
|
265
|
+
// Restore visibility from `display: none`
|
|
266
|
+
// if `data-o-grid-colspan` was set to `0` or `hide`
|
|
267
|
+
display: block;
|
|
268
|
+
// Define width in %
|
|
269
|
+
@include _oPrivateGridFixSafariWrap(
|
|
270
|
+
$layout-span
|
|
271
|
+
); // stylelint-disable-line order/order
|
|
272
|
+
min-width: oPrivateGridColspan($layout-span);
|
|
273
|
+
max-width: oPrivateGridColspan($layout-span);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/// Remove gutters from columns in a row
|
|
282
|
+
///
|
|
283
|
+
/// @param {string} $column-selector ["[o-grid-colspan]"] - CSS selector for row element
|
|
284
|
+
@mixin oPrivateGridRowCompact($column-selector: '[o-grid-colspan]') {
|
|
285
|
+
margin-left: 0;
|
|
286
|
+
|
|
287
|
+
> #{unquote($column-selector)} {
|
|
288
|
+
padding-left: 0;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/// Add a layout (breakpoint). This can be used to add a new breakpoint to a
|
|
293
|
+
/// project, in addition to the default layouts (S, M, L, XL).
|
|
294
|
+
///
|
|
295
|
+
/// @example scss
|
|
296
|
+
/// @include oGridAddLayout($layout-name: P, $layout-width: 600px);
|
|
297
|
+
/// @include oGridAddLayout($layout-name: XXL, $layout-width: 1600px, $gutter-width: 30px);
|
|
298
|
+
///
|
|
299
|
+
/// @param {String} $layout-name - Name of the layout (e.g. S)
|
|
300
|
+
/// @param {Number} $layout-width - Layout width in px
|
|
301
|
+
/// @param {Number} $gutter-width [null] - Gutter width in px
|
|
302
|
+
@mixin oPrivateGridAddLayout($layout-name, $layout-width, $gutter-width: null) {
|
|
303
|
+
$temp-layouts: ();
|
|
304
|
+
$temp-gutters: (
|
|
305
|
+
default: oGridGutter(),
|
|
306
|
+
);
|
|
307
|
+
$current-max-width: map-get(
|
|
308
|
+
$o-pf-grid-layouts,
|
|
309
|
+
nth($_o-pf-grid-layout-names, -1)
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
// Add the new layout in the correct position:
|
|
313
|
+
// (we want $o-grid-layouts and $o-grid-gutters to be ordered from the smallest to the largest layout)
|
|
314
|
+
@if ($layout-width >= $current-max-width) {
|
|
315
|
+
$temp-layouts: map-merge(
|
|
316
|
+
$o-pf-grid-layouts,
|
|
317
|
+
(
|
|
318
|
+
$layout-name: $layout-width,
|
|
319
|
+
)
|
|
320
|
+
);
|
|
321
|
+
$temp-gutters: map-merge(
|
|
322
|
+
$o-pf-grid-gutters,
|
|
323
|
+
(
|
|
324
|
+
$layout-name: $gutter-width,
|
|
325
|
+
)
|
|
326
|
+
);
|
|
327
|
+
} @else {
|
|
328
|
+
@for $index from 1 through length($o-pf-grid-layouts) {
|
|
329
|
+
$previous-layout-width: if(
|
|
330
|
+
$index == 1,
|
|
331
|
+
0,
|
|
332
|
+
map-get($o-pf-grid-layouts, nth($_o-pf-grid-layout-names, $index - 1))
|
|
333
|
+
);
|
|
334
|
+
$current-layout-name: nth($_o-pf-grid-layout-names, $index);
|
|
335
|
+
$current-layout-width: map-get($o-pf-grid-layouts, $current-layout-name);
|
|
336
|
+
|
|
337
|
+
$current-gutter-width: map-get($o-pf-grid-gutters, $current-layout-name);
|
|
338
|
+
|
|
339
|
+
// Assumes all layouts use the same unit e.g. px or rem (as does the JavaScript)
|
|
340
|
+
@if not(
|
|
341
|
+
$previous-layout-width >
|
|
342
|
+
$layout-width or
|
|
343
|
+
$current-layout-width <
|
|
344
|
+
$layout-width
|
|
345
|
+
)
|
|
346
|
+
{
|
|
347
|
+
$temp-layouts: map-merge(
|
|
348
|
+
$temp-layouts,
|
|
349
|
+
(
|
|
350
|
+
$layout-name: $layout-width,
|
|
351
|
+
)
|
|
352
|
+
);
|
|
353
|
+
$temp-gutters: map-merge(
|
|
354
|
+
$temp-gutters,
|
|
355
|
+
(
|
|
356
|
+
$layout-name: $gutter-width,
|
|
357
|
+
)
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
$temp-layouts: map-merge(
|
|
362
|
+
$temp-layouts,
|
|
363
|
+
(
|
|
364
|
+
$current-layout-name: $current-layout-width,
|
|
365
|
+
)
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
@if $current-gutter-width {
|
|
369
|
+
$temp-gutters: map-merge(
|
|
370
|
+
$temp-gutters,
|
|
371
|
+
(
|
|
372
|
+
$current-layout-name: $current-gutter-width,
|
|
373
|
+
)
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
$o-pf-grid-layouts: $temp-layouts !global;
|
|
379
|
+
$_o-pf-grid-layout-names: map-keys($o-pf-grid-layouts) !global;
|
|
380
|
+
|
|
381
|
+
@if $gutter-width {
|
|
382
|
+
$o-pf-grid-gutters: $temp-gutters !global;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// ----------------------------------------------------------------------------
|
|
2
|
+
// Responsive behaviour configuration
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
/// Grid mode
|
|
6
|
+
/// - fluid: full width up to the largest layout's width
|
|
7
|
+
/// - snappy: fluid width until the layout defined in $_o-pf-grid-start-snappy-mode-at (default: M),
|
|
8
|
+
/// and then snaps into a larger fixed layout at each breakpoint
|
|
9
|
+
/// - fixed: always fixed-width with the layout defined by $o-pf-grid-fixed-layout (default: L)
|
|
10
|
+
///
|
|
11
|
+
/// @type String - one of fluid (default), snappy, fixed
|
|
12
|
+
$o-pf-grid-mode: if(
|
|
13
|
+
global-variable-exists(o-grid-mode),
|
|
14
|
+
$o-grid-mode,
|
|
15
|
+
'fluid'
|
|
16
|
+
) !default;
|
|
17
|
+
|
|
18
|
+
/// Layout to default to when the grid has a fixed width (not fluid)
|
|
19
|
+
///
|
|
20
|
+
/// @type String - One of $o-pf-grid-layouts
|
|
21
|
+
$o-pf-grid-fixed-layout: if(
|
|
22
|
+
global-variable-exists(o-grid-fixed-layout),
|
|
23
|
+
$o-grid-fixed-layout,
|
|
24
|
+
'L'
|
|
25
|
+
) !default;
|
|
26
|
+
|
|
27
|
+
/// When the grid start snapping between fixed-width layouts
|
|
28
|
+
/// in the case where a row has the `o-grid-row--snappy` class
|
|
29
|
+
///
|
|
30
|
+
/// @type String
|
|
31
|
+
$_o-pf-grid-start-snappy-mode-at: 'M' !default;
|
|
32
|
+
|
|
33
|
+
// ----------------------------------------------------------------------------
|
|
34
|
+
// Grid settings and dimensions
|
|
35
|
+
// ----------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
/// Number of columns
|
|
38
|
+
///
|
|
39
|
+
/// @type Number (unitless)
|
|
40
|
+
$_o-pf-grid-columns: 12 !default;
|
|
41
|
+
|
|
42
|
+
/// Minimum width, in pixels
|
|
43
|
+
///
|
|
44
|
+
/// @type Number
|
|
45
|
+
$_o-pf-grid-min-width: 240px !default;
|
|
46
|
+
|
|
47
|
+
/// Layouts
|
|
48
|
+
///
|
|
49
|
+
/// Each layout is calculated following a specific column width,
|
|
50
|
+
/// in order to base breakpoints on the structure of the grid itself
|
|
51
|
+
///
|
|
52
|
+
/// @type Map
|
|
53
|
+
$o-pf-grid-layouts: if(
|
|
54
|
+
global-variable-exists(o-grid-layouts),
|
|
55
|
+
$o-grid-layouts,
|
|
56
|
+
(
|
|
57
|
+
S: 490px,
|
|
58
|
+
// column-width: 30px, inner width: 470px
|
|
59
|
+
M: 740px,
|
|
60
|
+
// column-width: 40px, inner width: 700px
|
|
61
|
+
L: 980px,
|
|
62
|
+
// column-width: 60px, inner width: 940px
|
|
63
|
+
XL: 1220px,
|
|
64
|
+
// column-width: 80px, inner width: 1180px
|
|
65
|
+
)
|
|
66
|
+
) !default;
|
|
67
|
+
|
|
68
|
+
/// Layout names
|
|
69
|
+
///
|
|
70
|
+
/// @access private
|
|
71
|
+
/// @type List
|
|
72
|
+
$_o-pf-grid-layout-names: map-keys($o-pf-grid-layouts);
|
|
73
|
+
|
|
74
|
+
/// Gutter sizes
|
|
75
|
+
///
|
|
76
|
+
/// @type Map
|
|
77
|
+
|
|
78
|
+
$o-pf-grid-gutters: if(
|
|
79
|
+
global-variable-exists(o-grid-gutters),
|
|
80
|
+
$o-grid-gutters,
|
|
81
|
+
(
|
|
82
|
+
default: 10px,
|
|
83
|
+
M: 20px,
|
|
84
|
+
)
|
|
85
|
+
) !default;
|
|
86
|
+
|
|
87
|
+
// If layouts have changed but gutters haven't,
|
|
88
|
+
// prune non-existant layouts.
|
|
89
|
+
@each $layout-name, $gutter-size in $o-pf-grid-gutters {
|
|
90
|
+
@if ($layout-name != 'default') and
|
|
91
|
+
(not map-has-key($o-pf-grid-layouts, $layout-name))
|
|
92
|
+
{
|
|
93
|
+
$o-pf-grid-gutters: map-remove($o-pf-grid-gutters, $layout-name);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/// Maximum grid width
|
|
98
|
+
/// Defaults to the largest layout width
|
|
99
|
+
///
|
|
100
|
+
/// @access private
|
|
101
|
+
/// @type Number
|
|
102
|
+
$_o-pf-grid-max-width: map-get(
|
|
103
|
+
$o-pf-grid-layouts,
|
|
104
|
+
nth($_o-pf-grid-layout-names, -1)
|
|
105
|
+
);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/// Output styles for an SVG icon.
|
|
2
|
+
/// Styles the icon as a background image, setting a width and height on the element as requested.
|
|
3
|
+
/// A fallback background for Windows High Contrast mode is also output.
|
|
4
|
+
///
|
|
5
|
+
/// @access public
|
|
6
|
+
/// @param {String} $icon-name - This should be a reference to an icon included in o-icons eg arrow-down
|
|
7
|
+
/// @param {String} $color - This should be a hex colour value. Used to color the icon. We suggest using an o-colors function.
|
|
8
|
+
/// @param {Number|Null} $size [128] - The width and height of the icon (units optional, defaults to px). Set to `null` to set no width or height.
|
|
9
|
+
/// @param {Bool} $include-base-styles [true] - If true, will output style rules for the container. If false will only output the background-image property
|
|
10
|
+
/// @param {Bool} $high-contrast-fallback [true] - To output Microsoft High Contrast fallback for accessibility reasons or not.
|
|
11
|
+
/// @param {Number} $iconset-version [1] - At present only 1 version of the icon set is available.
|
|
12
|
+
@mixin oPrivateIconsContent($icon-name, $color: null, $size: 128, $include-base-styles: true, $high-contrast-fallback: true, $iconset-version: 1) {
|
|
13
|
+
// Error if the global $system-code variable is not set.
|
|
14
|
+
// This is required for image service requests.
|
|
15
|
+
@if(global-variable-exists('system-code') == false or type-of($system-code) != 'string') {
|
|
16
|
+
@error 'A global "$system-code" Sass variable must be set to a valid [Bizops system code](https://biz-ops.in.ft.com/list/Systems).';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// If the size of the icons has been given without a unit, default to px.
|
|
20
|
+
@if (type-of($size) == 'number' and unitless($size)) {
|
|
21
|
+
$size: $size + 0px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Define base image service path.
|
|
25
|
+
$scheme: "fticon-v#{$iconset-version}";
|
|
26
|
+
$service-url: "https://www.ft.com/__origami/service/image/v2/images/raw/#{$scheme}:#{$icon-name}";
|
|
27
|
+
|
|
28
|
+
// Include base styles shared by all icons.
|
|
29
|
+
@if ($include-base-styles == true) {
|
|
30
|
+
@include oPrivateIconsContentBaseStyles;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Set the icon dimentions.
|
|
34
|
+
width: $size;
|
|
35
|
+
height: $size;
|
|
36
|
+
|
|
37
|
+
// Include the icon via the image service.
|
|
38
|
+
// Build an image service url for the requested icon.
|
|
39
|
+
$query: "?source=#{$system-code}";
|
|
40
|
+
@if $color != null {
|
|
41
|
+
$color: str-slice(ie-hex-str($color), 4);
|
|
42
|
+
$query: $query + "&tint=%23#{$color},%23#{$color}";
|
|
43
|
+
}
|
|
44
|
+
background-image: url($service-url + $query + "&format=svg");
|
|
45
|
+
|
|
46
|
+
// Include a fallback for Window's high contrast mode.
|
|
47
|
+
// This mode removes background images unless specifcally included
|
|
48
|
+
// for high contrast mode.
|
|
49
|
+
// sass-lint:disable no-vendor-prefixes
|
|
50
|
+
@if $high-contrast-fallback {
|
|
51
|
+
@media screen and (-ms-high-contrast: active) {
|
|
52
|
+
background-image: url($service-url + "?source=#{$system-code}&tint=%23ffffff,%23ffffff&format=svg");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@media screen and (-ms-high-contrast: black-on-white) {
|
|
56
|
+
background-image: url($service-url + "?source=#{$system-code}&tint=%23000000,%23000000&format=svg");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// sass-lint:enable no-vendor-prefixes
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/// Base styles for all icons
|
|
63
|
+
/// @access public
|
|
64
|
+
@mixin oPrivateIconsContentBaseStyles() {
|
|
65
|
+
display: inline-block;
|
|
66
|
+
background-repeat: no-repeat;
|
|
67
|
+
background-size: contain;
|
|
68
|
+
background-position: 50%;
|
|
69
|
+
background-color: transparent;
|
|
70
|
+
vertical-align: baseline;
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "mixins";
|