@apolitical/component-library 10.4.5-pla-1077.0 → 10.4.6-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/index.js +44 -44
- package/index.mjs +3478 -3499
- package/layout/page-layout/components/header/header.d.ts +1 -3
- package/package.json +1 -1
- package/style.css +1 -1
- package/styles/README.md +46 -20
- package/styles/base/_fonts.scss +1 -1
package/styles/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# Styles
|
|
2
|
+
|
|
2
3
|
This directory contains the browser reset and base styling for the whole platform, Sass functions and mixins to handle repeated code, and reusable variables for colours and common spacing.
|
|
3
4
|
|
|
4
5
|
We use [Sass](https://sass-lang.com/) for our styling, which gives us the flexibility of using vanilla CSS's powerful features like [layers](#layer) and container queries, while also being able to write less code with variables, mixins, and functions.
|
|
@@ -27,10 +28,10 @@ We use [Sass](https://sass-lang.com/) for our styling, which gives us the flexib
|
|
|
27
28
|
- [Variables](#variables)
|
|
28
29
|
- [Colours](#colours)
|
|
29
30
|
|
|
30
|
-
|
|
31
31
|
---
|
|
32
32
|
|
|
33
33
|
## Set-up
|
|
34
|
+
|
|
34
35
|
For accessibility, we code all of our sizes in `rem`s. It's important that _every_ size is in `rem`s, otherwise some elements will resize when the user changes their browser's font size, but others won't, leading to a broken layout.
|
|
35
36
|
|
|
36
37
|
In Figma, all of the sizes are in pixels. To make it easier for us to work with (and reason about), we add them as variables in `px` and then convert them to `rem`s using a [custom mixin, `px-to-rem`](#px-to-rem).
|
|
@@ -85,9 +86,10 @@ It's the third layer in our CSS cascade (`@layer base`), so it's applied after t
|
|
|
85
86
|
|
|
86
87
|
Most of our base styling is for elements which we don't have components for - like `p` and `h1` - but we also keep all of the `button` and `form` styling here. While there is a `Button` component, the same styles are often used on elements which aren't interactive, like the connection statuses on profiles, and we have some form components, like `RichTextEditor` and `Search` which don't use the `Form` component; we've pulled the styling out to our base styling, as these are all important building blocks of our UI and aren't strictly linked to their functionality.
|
|
87
88
|
|
|
88
|
-
|
|
89
89
|
### Accessibility
|
|
90
|
+
|
|
90
91
|
#### Highlighting focus
|
|
92
|
+
|
|
91
93
|
Highlighting where the focus is, especially for interactive elements like links, buttons, and inputs, is an important part of the [WCAG AA guidelines](https://www.w3.org/WAI/WCAG21/Understanding/focus-visible.html).
|
|
92
94
|
|
|
93
95
|
In our base styling, we remove the browser's default `outline` on focused elements and add a `box-shadow`, which gives us a bit more control over the look.
|
|
@@ -95,6 +97,7 @@ In our base styling, we remove the browser's default `outline` on focused elemen
|
|
|
95
97
|
Please think twice before removing the `box-shadow` on a focused element as the page its on will immediately fail accessibility.
|
|
96
98
|
|
|
97
99
|
#### Hiding text visually
|
|
100
|
+
|
|
98
101
|
We sometimes want screen readers to receive text that we don't want on the page. While it sometimes makes sense to use an `aria-label` on an element, that will override the existing text. When we want to add text, rather than replacing it, we have the `.hidden` class. It uses the `hidden-element` mixin, which can be called directly if you need more control. It sets the width and height of an element to `0`, rendering it invisible visually but ensuring it's still read out to screen readers. (Using something like `display: none` would also hide the content from screen readers.)
|
|
99
102
|
|
|
100
103
|
It also has an optional class, `.show-on-focus`, which makes the element show visually if it is navigated to by keyboard. For example, we have a link above our iframes which allows people to skip past the iframe, in case the third party content is not accessible. We don't want to show this text all the time, but we do want to show it to people navigating by keyboard, so they don't click something they don't mean to.
|
|
@@ -103,8 +106,8 @@ The class uses the mixin `show-hidden-element`, which can also be used independe
|
|
|
103
106
|
|
|
104
107
|
The component `VisuallyHidden` uses this styling behind-the-scenes; it's best to use that directly if you're doing something simple, but the classes and mixins are available if you need them.
|
|
105
108
|
|
|
106
|
-
|
|
107
109
|
### Buttons
|
|
110
|
+
|
|
108
111
|
The `Button` component in the component library renders most of the buttons on the site. It can render `button` or `a` components, depending on if we need something to happen on click or if we just want a styled link. But we also sometimes want styling on elements which aren't interactive, like the connection statuses on profiles.
|
|
109
112
|
|
|
110
113
|
See the component library for in-depth documentation on `Button`.
|
|
@@ -136,6 +139,7 @@ You can change the icon on hover by adding a second file name, prepended with `h
|
|
|
136
139
|
See the `base/buttons/_icons.scss` file for the full list of available icons, and details on how to handle different sizes.
|
|
137
140
|
|
|
138
141
|
### Text
|
|
142
|
+
|
|
139
143
|
The text used across the site for paragraphs and lists, is styled in `base/_text.scss`.
|
|
140
144
|
|
|
141
145
|
We have three sizes of text used across the site: large (which is our default size, defined in `$default`), medium, and small.
|
|
@@ -153,11 +157,12 @@ In `base/_text.scss`, this is handled with the `$standard-text-elements` variabl
|
|
|
153
157
|
(We list the elements in variables as they're used in multiple media queries and we don't want to accidentally miss anything.)
|
|
154
158
|
|
|
155
159
|
### Titles
|
|
160
|
+
|
|
156
161
|
The titles used across the site for headings and subheadings are styled in `base/_titles.scss`.
|
|
157
162
|
|
|
158
|
-
Our Figma files have six heading styles, named h1-h6, as well as subheading and pre-title styles.
|
|
163
|
+
Our Figma files have six heading styles, named h1-h6, as well as subheading and pre-title styles.
|
|
159
164
|
|
|
160
|
-
By default, we code `h1`s to match the 'h1' styling in Figma, `h2`s to match the 'h2' styling, and so on. However, sometimes, for aesthetic reasons, we may want the styling of the 'h4' heading, but for accessibility and semantic mark-up, the heading would need to be an `h2` or a `p`.
|
|
165
|
+
By default, we code `h1`s to match the 'h1' styling in Figma, `h2`s to match the 'h2' styling, and so on. However, sometimes, for aesthetic reasons, we may want the styling of the 'h4' heading, but for accessibility and semantic mark-up, the heading would need to be an `h2` or a `p`.
|
|
161
166
|
|
|
162
167
|
All of the styling for each heading lives in a mixin, which can be included on any element, so we can use the styles where we need them.
|
|
163
168
|
|
|
@@ -168,11 +173,13 @@ All of the styling for each heading lives in a mixin, which can be included on a
|
|
|
168
173
|
<br />
|
|
169
174
|
|
|
170
175
|
## Functions and mixins
|
|
176
|
+
|
|
171
177
|
We have a lot of custom functions and mixins to make our code more maintainable and easier to write.
|
|
172
178
|
|
|
173
179
|
You won't likely need to change these functions but you should be using them in your code, to make it faster, more accessible, and more maintainable.
|
|
174
180
|
|
|
175
181
|
### `get-map`
|
|
182
|
+
|
|
176
183
|
Sass has a built-in function to get a value from a map (`map.get`), but it silently fails when the value can't be reached, which means a small typo in a key can mean styling you're expecting is never applied. It's easy to miss and can make us lose time.
|
|
177
184
|
|
|
178
185
|
Instead, we use a custom function, `get-map`, which throws an error if the key can't be found, so we're aware of any issues and can quickly fix them.
|
|
@@ -186,17 +193,18 @@ You shouldn't need to amend the function - just call it wherever you're retrievi
|
|
|
186
193
|
subkey: 2
|
|
187
194
|
)
|
|
188
195
|
);
|
|
189
|
-
|
|
196
|
+
|
|
190
197
|
get-map($map, 'value') // 1
|
|
191
198
|
get-map($map, 'key', 'subkey') // 2
|
|
192
199
|
```
|
|
193
200
|
|
|
194
201
|
### `px-to-rem`
|
|
202
|
+
|
|
195
203
|
It's important for accessibility that we use `rem`s, which can be scaled for the user's needs (e.g. someone with poor eyesight might need to have the screen zoomed in). Every unit of measurement should be a `rem`, as mixing different units can make the site look broken.
|
|
196
204
|
|
|
197
205
|
`1rem` will always be relative for the user, but `100px` will always be `100px`. If the user resizes their browser, `font-size: 1rem` text inside a `height: 100px` box will break out of the layout. A `6.25rem` box will resize with the text and always contain it.
|
|
198
206
|
|
|
199
|
-
However, `6.25rem` is a lot harder for us to reason about than `100px`; we know how big `100px` is and we know if it matches the Figma designs, which are always presented in `px`.
|
|
207
|
+
However, `6.25rem` is a lot harder for us to reason about than `100px`; we know how big `100px` is and we know if it matches the Figma designs, which are always presented in `px`.
|
|
200
208
|
|
|
201
209
|
To make it easier for us, we use the same units as Figma and use `px-to-rem` to convert them.
|
|
202
210
|
|
|
@@ -212,8 +220,8 @@ $wrapper: ('height': 100);
|
|
|
212
220
|
|
|
213
221
|
By default, `px-to-rem` uses `16px` as its baseline - `1rem` is `16px`. If you need to change this, you can pass a second argument, e.g. `px-to-rem(100, 10)` will convert `100px` to `10rem`, but this isn't likely to come up!
|
|
214
222
|
|
|
215
|
-
|
|
216
223
|
### `animate` and `transition`
|
|
224
|
+
|
|
217
225
|
Anywhere we use CSS animations or transitions on our platform, we need to use the `animate` and `transition` mixins.
|
|
218
226
|
|
|
219
227
|
Some users have conditions like epilepsy which can be triggered by animations; for accessibility, we need to avoid doing any kind of animation if the user has set their device to reduce motion. Devices won't just do this automatically - we are responsible for not triggering animations if the user has this setting.
|
|
@@ -221,21 +229,22 @@ Some users have conditions like epilepsy which can be triggered by animations; f
|
|
|
221
229
|
There is a special [media query, `prefers-reduced-motion`](https://www.smashingmagazine.com/2021/10/respecting-users-motion-preferences/) which we can use to target the users who have not opted out of animations; to avoid having to set this up everywhere you need it, and to avoid accidentally missing it and making your component inaccessible, the `animate` and `transition` mixins will do all the work for you.
|
|
222
230
|
|
|
223
231
|
#### `animate`
|
|
224
|
-
|
|
232
|
+
|
|
233
|
+
`animate` is a very simple mixin which just wraps the code inside a media query. It renders the new styling [`@at-root`](https://sass-lang.com/documentation/at-rules/at-root/), in the root of the document, so you don't have to set up the animation out of context.
|
|
225
234
|
|
|
226
235
|
To use CSS animations, wrap your code in the `animate` mixin, like:
|
|
227
236
|
|
|
228
237
|
```
|
|
229
238
|
.element {
|
|
230
|
-
transform: translateX(0%);
|
|
231
|
-
|
|
239
|
+
transform: translateX(0%);
|
|
240
|
+
|
|
232
241
|
@include animate {
|
|
233
242
|
@keyframes loading {
|
|
234
243
|
100% {
|
|
235
244
|
transform: translateX(100%);
|
|
236
245
|
}
|
|
237
246
|
}
|
|
238
|
-
|
|
247
|
+
|
|
239
248
|
// & is the selector to this point - `.element`
|
|
240
249
|
// We're just making sure we're only adding the animation when the user has not
|
|
241
250
|
// asked for reduced motion
|
|
@@ -249,6 +258,7 @@ To use CSS animations, wrap your code in the `animate` mixin, like:
|
|
|
249
258
|
You can see the `animate` mixin in action in the `LoadingPlaceholder` component.
|
|
250
259
|
|
|
251
260
|
#### `transition`
|
|
261
|
+
|
|
252
262
|
`transition` is a more complex mixin to read, though it's unlikely you will need to make changes to it.
|
|
253
263
|
|
|
254
264
|
It accepts a `$proprerties` argument - the CSS properties you want to transition, like `background` or `color` - and three optional arguments, the duration of the transition, what function to use for the animation, and the delay.
|
|
@@ -258,40 +268,47 @@ For performance reasons, it's important to only pass the properties you need to
|
|
|
258
268
|
You can listen for multiple properties on a single element, and each property can have its own duration, function, and delay. They can also use the same, if you'd prefer.
|
|
259
269
|
|
|
260
270
|
This will transition changes to the `color` and `text-decoration-color`, using the default duration, function, and delay:
|
|
271
|
+
|
|
261
272
|
```
|
|
262
273
|
a {
|
|
263
274
|
@include transition(color text-decoration-color);
|
|
264
|
-
}
|
|
275
|
+
}
|
|
265
276
|
```
|
|
266
277
|
|
|
267
278
|
This will transition the `color` over `0.2s` with no delay and the `text-decoration-color` over `0.5s` with a delay of `0.3s`. They will both use the `ease-in-out` function:
|
|
279
|
+
|
|
268
280
|
```
|
|
269
281
|
a {
|
|
270
282
|
@include transition(color text-decoration-color, 0.2s 0.5s, ease-in-out, 0s 0.3s);
|
|
271
|
-
}
|
|
283
|
+
}
|
|
272
284
|
```
|
|
273
285
|
|
|
274
286
|
The mixin takes all the arguments, breaks them by space, and turns it into the correct transition CSS, and ensures users who have asked for reduced motion don't see it.
|
|
275
287
|
|
|
276
288
|
### `image`
|
|
289
|
+
|
|
277
290
|
We use the `image` mixin to handle background images on the site--this lets us easily handle CSS masks without repeating a lot of code, and it lets us have a single reference to our assets bucket, so we can easily change things.
|
|
278
291
|
|
|
279
292
|
The mixin has one required prop, which is the image file (everything after the asset bucket address, which is defined in variables), and optional props for if it's a CSS mask, the size, repeat, and position properties.
|
|
280
293
|
|
|
281
294
|
Passing just the image, like:
|
|
295
|
+
|
|
282
296
|
```
|
|
283
297
|
@include image('icons/tick.svg');
|
|
284
298
|
```
|
|
299
|
+
|
|
285
300
|
would render the image as a background image. It couldn't be recoloured.
|
|
286
301
|
|
|
287
302
|
Passing `true` as the second argument, like:
|
|
303
|
+
|
|
288
304
|
```
|
|
289
305
|
@include image('icons/tick.svg', true);
|
|
290
306
|
```
|
|
291
|
-
would render a CSS mask, so the icon could be recoloured to anything using `background`. This is especially useful for hover and disabled states, where we want to change the color without downloading a new asset.
|
|
292
307
|
|
|
308
|
+
would render a CSS mask, so the icon could be recoloured to anything using `background`. This is especially useful for hover and disabled states, where we want to change the color without downloading a new asset.
|
|
293
309
|
|
|
294
310
|
### `breakpoint`
|
|
311
|
+
|
|
295
312
|
We have a custom mixin to handle media queries for us, which allows us to use easy shortcuts for the most common viewport sizes. When the design changes, we can remap these names to the new sizes, rather than having to update every media query in the code.
|
|
296
313
|
|
|
297
314
|
The common sizes are defined in `$breakpoint-sizes`. We only name the most common sizes, to keep the map manageable. It's possible to pass a number to the `breakpoint` query instead, to target a viewport we only care about in one-off cases. It's passed in as the second argument.
|
|
@@ -301,6 +318,7 @@ Using the mixin also lets us write less code for more complex media queries.
|
|
|
301
318
|
The mixin takes two arguments: the media feature you are targeting, like `max-height` or `min-width` and the viewport size, either as a named variable, like `md` or as a number, like `951`, which will be converted to `px`.
|
|
302
319
|
|
|
303
320
|
This will apply the styles when the viewport width is at least the `md` value, `769px`:
|
|
321
|
+
|
|
304
322
|
```
|
|
305
323
|
@include breakpoint(min-width, md) {
|
|
306
324
|
// styles
|
|
@@ -308,15 +326,17 @@ This will apply the styles when the viewport width is at least the `md` value, `
|
|
|
308
326
|
```
|
|
309
327
|
|
|
310
328
|
You can pass multiple media features and viewport sizes for media queries which have a minimum and maximum viewport size, like:
|
|
329
|
+
|
|
311
330
|
```
|
|
312
331
|
@include breakpoint(min-width max-width, md lg) {
|
|
313
332
|
// styles
|
|
314
333
|
}
|
|
315
334
|
```
|
|
316
|
-
The styles in this query will apply when the viewport width is at least `769px` and less than `1180px`.
|
|
317
335
|
|
|
336
|
+
The styles in this query will apply when the viewport width is at least `769px` and less than `1180px`.
|
|
318
337
|
|
|
319
338
|
### `container-query`
|
|
339
|
+
|
|
320
340
|
[Container queries](https://www.smashingmagazine.com/2021/05/complete-guide-css-container-queries/) are very similar to media queries but apply to an element's parent. We may sometimes want to change the style of an element when it's in a smaller area, like a sidebar, which won't always correlate to the viewport being small.
|
|
321
341
|
|
|
322
342
|
For example, on individual article pages, we show a `MarketingBanner` with smaller padding and no purple circle element in the sidebar and in its normal styling after the article--using its parent lets us change things in specific circumstances without needing to add a lot of extra classes.
|
|
@@ -325,8 +345,8 @@ The `container-query` mixin handles this for us. It uses the same named breakpoi
|
|
|
325
345
|
|
|
326
346
|
Instead of a media feature, its first argument is the `container-name` of the container parent, which is set as part of the parent's normal styling alongside the `container-type`. (NB: this is needed for container queries to behave as expected. Be aware container queries don't play nicely with flex styling.)
|
|
327
347
|
|
|
328
|
-
|
|
329
348
|
### `amend-selector-path`
|
|
349
|
+
|
|
330
350
|
Sass has a built-in function,`@at-root`, which allows you to write styling in context which is rendered in the root of the final CSS file, instead of in the current selector--like a Sass version of `React.Portal`.
|
|
331
351
|
|
|
332
352
|
We can also use it to overwrite the current selector path for a block of styling, which is useful if we have styling which should only be applied when there's a certain parent element in the path. `amend-selector-path` is a mixin which does this for us, to make it more obvious what the code is doing and to make it easier to read.
|
|
@@ -334,14 +354,15 @@ We can also use it to overwrite the current selector path for a block of styling
|
|
|
334
354
|
It takes two arguments, the old path and the new one.
|
|
335
355
|
|
|
336
356
|
All styles inside this would only apply to the link inside the sidebar:
|
|
357
|
+
|
|
337
358
|
```
|
|
338
359
|
@include amend-selector-path('a', '.sidebar a') {
|
|
339
360
|
// styles
|
|
340
361
|
}
|
|
341
362
|
```
|
|
342
363
|
|
|
343
|
-
|
|
344
364
|
### Repeated styles
|
|
365
|
+
|
|
345
366
|
We have a lot of repeated styles across the site, which are used across different elements. To avoid duplicating code, we have pulled the common ones out into mixins.
|
|
346
367
|
|
|
347
368
|
- `dashed-border` adds a dashed border with an inline SVG.
|
|
@@ -349,16 +370,19 @@ We have a lot of repeated styles across the site, which are used across differen
|
|
|
349
370
|
- `full-width-section` makes an element the full width of the user's viewport. This is used in the `FullWidthSection` component (which is the recommended component to use, over this mixin), but the styling is available as a mixin in cases where it might not make sense to render a component wrapper.
|
|
350
371
|
|
|
351
372
|
### Lesser needed mixins
|
|
373
|
+
|
|
352
374
|
There are some mixins that aren't used as often, which are worth knowing about.
|
|
353
375
|
|
|
354
376
|
#### `query-touchscreen` and `query-not-touchscreen`
|
|
377
|
+
|
|
355
378
|
If you want to apply styling to only touchscreen (or non-touchscreen) devices--for example, applying hover states, you can use these mizins to limit what receives the styling.
|
|
356
379
|
|
|
357
380
|
#### `target-safari`
|
|
358
|
-
Safari has some unique bugs which can make it difficult to work with. We have a mixin, `target-safari`, which can be used to target Safari specifically, to fix these bugs.
|
|
359
381
|
|
|
382
|
+
Safari has some unique bugs which can make it difficult to work with. We have a mixin, `target-safari`, which can be used to target Safari specifically, to fix these bugs.
|
|
360
383
|
|
|
361
384
|
#### `hidden-element` and `show-hidden-element`
|
|
385
|
+
|
|
362
386
|
We sometimes want to add text to the page which we don't want to be visible, but we do want to be read out by screen readers. This is often used for accessibility, to give more context to a user who can't see the screen.
|
|
363
387
|
|
|
364
388
|
We have classes and a component, `VisuallyHidden` (see the ['hiding text visually'](#hiding-text-visually)) section, which utilise these mixins. If you need to, you can call them directly.
|
|
@@ -370,9 +394,11 @@ We have classes and a component, `VisuallyHidden` (see the ['hiding text visuall
|
|
|
370
394
|
<br />
|
|
371
395
|
|
|
372
396
|
## Variables
|
|
397
|
+
|
|
373
398
|
The variables that are re-used across the site are defined in `./variables`, such as asset bucket URLs, common sizes, and colours.
|
|
374
399
|
|
|
375
400
|
### Sizes
|
|
401
|
+
|
|
376
402
|
We don't store variables for repeated margins/paddings, like `md-padding`, as sizes are unlikely to stay the same between redesigns. Instead, we put those in maps at the top of every component styling file.
|
|
377
403
|
|
|
378
404
|
However, there are a few widths we frequently use for the width of the content of a page which are likely to change together when the site is redesigned. We store these in variables in `./variables/sizes/_common`, so we can manage them from one place.
|
|
@@ -380,6 +406,7 @@ However, there are a few widths we frequently use for the width of the content o
|
|
|
380
406
|
There are also some variables whose sizes we need to be able to access across different components. For example, as our header can animate in and out of the layout, we need to know what height it is in many places, to ensure we're never covering content when it shows. We store the maps the header uses for its sizes in `./variables/sizes/_header`, so we can import them anywhere they're needed.
|
|
381
407
|
|
|
382
408
|
### Colours
|
|
409
|
+
|
|
383
410
|
Our colour variables are defined in `./variables/colors`.
|
|
384
411
|
|
|
385
412
|
We have two separate files:
|
|
@@ -395,4 +422,3 @@ We can't rely on these colours making sense in the future, so we don't use them
|
|
|
395
422
|
Using these names, rather than the direct colour values, future-proofs the code against redesigns and makes it easy to maintain; when we redesign the platform, we can update the colours in one place, rather than having to amend every component.
|
|
396
423
|
|
|
397
424
|
To avoid `theme` being a giant, difficult-to-navigate file, we split out all the values by the component directory they're in (e.g. `base`, `buttons`, `cards`, etc.) and then import them into `./theme/index.scss`. We use a Sass function to pull everything into the `$theme` variable, so we don't need to know exactly what's in each file.
|
|
398
|
-
|
package/styles/base/_fonts.scss
CHANGED