@apolitical/component-library 10.4.5 → 10.4.6-beta.1

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/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
- `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.
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
-
@@ -1,4 +1,4 @@
1
- $font-path: 'https://apolitical.co/fonts/Web/';
1
+ $font-path: 'https://assets.apolitical.co/fonts/';
2
2
  $font-name: 'Moderat';
3
3
 
4
4
  @mixin font-styling($weight: 400, $style: normal) {