Skip to content

Commit e5defc0

Browse files
committed
Refactor CSS modules to use a consistent import name and provide a type definition file so dot syntax does not fail lint
1 parent 822ba99 commit e5defc0

12 files changed

Lines changed: 63 additions & 44 deletions

File tree

.github/instructions/general.instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ applyTo: "**"
1717
- Do not leave trailing spaces on lines.
1818
- Do not use run-astro-dev, always use "npm run dev".
1919
- Always create TypeScript files, not JavaScript files.
20+
- For every `*.module.css` file, also create the matching `*.module.css.d.ts` file, import it as `styles`, and access classnames via dot syntax (e.g., `styles.someClass`) instead of bracket syntax.
2021
- Prefer destructured imports over namespace imports when importing specific functions from modules (e.g., `import { resolve } from 'path'` instead of `import * as path from 'path'`).
2122
- Do not access nanostore observables (e.g., `$consent`) directly from components; expose helper/action methods in `@components/scripts/store` and import those instead.
2223
- Preact exists only for the Markdown E2E harness under `src/lib/markdown/__tests__/e2e`; all production UI components must use Lit web components instead of Preact.

_TODO.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -153,24 +153,6 @@ Google Calendar, Apple Calendar, Yahoo Calender, Microsoft 365, Outlook, and T
153153
`https://github.com/add2cal/add-to-calendar-button`
154154
`https://add-to-calendar-button.com/`
155155

156-
In a number of components where we've moved styles into a *.module.css file and imported it into the Astro layout, we've been inconsistent with naming the import and resolved lint errors concerning accessing object properties by using bracket access, such as:
157-
158-
import menuStyles from './menu.module.css'
159-
menuStyles['navItemActive']
160-
161-
In all of these cases, we need to refactor to use the pattern show in the Button and Footer components, where we create a *.module.css.d.ts to provide types, name the import consistently as "styles", and access those styles as follows:
162-
163-
styles.footerGrid
164-
165-
Components that need refactoring are as follows. Let's do this next.
166-
167-
src/components/Navigation/Menu.astro
168-
src/components/Navigation/NavToggle.astro
169-
src/components/Social/Shares/client/index.ts
170-
src/components/ThemePicker/index.astro
171-
src/components/Toasts/NetworkStatus/index.astro
172-
173-
174156
## Set up webmentions
175157

176158
Needs to add real API key and test

src/components/Navigation/Menu.astro

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
import { navigationItems } from '@components/Navigation/server'
3-
import menuStyles from './menu.module.css'
3+
import styles from './menu.module.css'
44
export interface Props {
55
path: string
66
}
@@ -12,15 +12,15 @@ const isActiveMenuItem = (url: string) => {
1212
}
1313
1414
const activeMenuItem = (url: string) => {
15-
return isActiveMenuItem(url) ? ['nav-item-active', menuStyles['navItemActive']] : []
15+
return isActiveMenuItem(url) ? ['nav-item-active', styles.navItemActive] : []
1616
}
1717
---
1818

1919
<nav id="main-nav" class="main-nav" role="navigation" aria-label="Main">
2020
<ul
2121
class:list={[
2222
'main-nav-menu',
23-
menuStyles['mainNavMenu'],
23+
styles.mainNavMenu,
2424
'w-full font-heading text-[0.85rem] uppercase tracking-[0.22em] text-primary',
2525
'lg:relative lg:text-[0.8rem] lg:tracking-[0.12em]'
2626
]}
@@ -30,14 +30,14 @@ const activeMenuItem = (url: string) => {
3030
navigationItems.map((navItem) => {
3131
const isActive = isActiveMenuItem(navItem.url)
3232
return (
33-
<li class:list={['main-nav-item', menuStyles['mainNavItem'], 'lg:relative', ...activeMenuItem(navItem.url)]}>
33+
<li class:list={['main-nav-item', styles.mainNavItem, 'lg:relative', ...activeMenuItem(navItem.url)]}>
3434
<a
3535
href={navItem.url}
3636
aria-current={isActive ? 'page' : undefined}
3737
class:list={[
3838
'block text-primary text-xl font-bold tracking-[5px] uppercase no-underline text-center p-4 focus:outline-0',
3939
'lg:text-lg lg:lowercase lg:tracking-normal lg:px-5 lg:py-3 lg:flex lg:items-center lg:relative lg:whitespace-nowrap lg:z-10',
40-
menuStyles['mainNavLink'],
40+
styles.mainNavLink,
4141
]}
4242
>
4343
{navItem.title}
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
import navToggleStyles from './navToggle.module.css'
2+
import styles from './navToggle.module.css'
33
/**
44
* Menu Toggle Button
55
*/
@@ -9,26 +9,26 @@ import navToggleStyles from './navToggle.module.css'
99
class:list={[
1010
'nav-toggle-btn',
1111
'lg:hidden inline-flex items-center justify-center rounded-full border-0 bg-primary-offset text-bg transition-colors duration-150 ease-linear hover:bg-primary focus:bg-primary focus:outline-none',
12-
navToggleStyles['button'],
12+
styles.button,
1313
]}
1414
type="button"
1515
aria-expanded="false"
1616
aria-controls="main-nav"
1717
aria-label="Open main menu"
1818
>
1919
<svg
20-
class:list={['nav-toggle-svg', 'h-(--header-icon-size) w-(--header-icon-size)', navToggleStyles['icon']]}
20+
class:list={['nav-toggle-svg', 'h-(--header-icon-size) w-(--header-icon-size)', styles.icon]}
2121
xmlns="http://www.w3.org/2000/svg"
2222
viewBox="0 0 50 50"
2323
aria-hidden="true"
2424
focusable="false"
2525
>
2626
<g>
27-
<line class:list={['nav-toggle-bar', navToggleStyles['bar']]} x1="13" y1="16.5" x2="37" y2="16.5"></line>
28-
<line class:list={['nav-toggle-bar', navToggleStyles['bar']]} x1="13" y1="24.5" x2="37" y2="24.5"></line>
29-
<line class:list={['nav-toggle-bar', navToggleStyles['bar']]} x1="13" y1="24.5" x2="37" y2="24.5"></line>
30-
<line class:list={['nav-toggle-bar', navToggleStyles['bar']]} x1="13" y1="32.5" x2="37" y2="32.5"></line>
31-
<circle class:list={['nav-toggle-circle', navToggleStyles['circle']]} r="23" cx="25" cy="25"></circle>
27+
<line class:list={['nav-toggle-bar', styles.bar]} x1="13" y1="16.5" x2="37" y2="16.5"></line>
28+
<line class:list={['nav-toggle-bar', styles.bar]} x1="13" y1="24.5" x2="37" y2="24.5"></line>
29+
<line class:list={['nav-toggle-bar', styles.bar]} x1="13" y1="24.5" x2="37" y2="24.5"></line>
30+
<line class:list={['nav-toggle-bar', styles.bar]} x1="13" y1="32.5" x2="37" y2="32.5"></line>
31+
<circle class:list={['nav-toggle-circle', styles.circle]} r="23" cx="25" cy="25"></circle>
3232
</g>
3333
</svg>
3434
</button>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
declare const styles: {
2+
readonly mainNavMenu: string
3+
readonly mainNavItem: string
4+
readonly navItemActive: string
5+
readonly mainNavLink: string
6+
}
7+
8+
export default styles
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
declare const styles: {
2+
readonly button: string
3+
readonly icon: string
4+
readonly bar: string
5+
readonly circle: string
6+
}
7+
8+
export default styles

src/components/Social/Shares/client/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export class SocialShareElement extends LitElement {
7070
const shareData = this.getShareData()
7171
const shareText = `${shareData.text} ${shareData.url}`.trim()
7272
const containerClassList = [
73-
styles['container'],
73+
styles.container,
7474
'social-share',
7575
this.layout === 'vertical' ? 'flex flex-col gap-2' : 'flex flex-wrap gap-3',
7676
this.containerClass,
@@ -79,7 +79,7 @@ export class SocialShareElement extends LitElement {
7979
.join(' ')
8080

8181
const labelClassList = [
82-
styles['label'],
82+
styles.label,
8383
'social-share__label text-sm font-semibold text-text-offset mr-2 self-center',
8484
]
8585
.filter(Boolean)
@@ -125,7 +125,7 @@ export class SocialShareElement extends LitElement {
125125
private renderPlatform(platform: SharePlatform, shareData: ShareData, shareText: string) {
126126
const icon = PLATFORM_ICONS[platform.id]?.()
127127
const buttonClassList = [
128-
styles['button'],
128+
styles.button,
129129
'social-share__button inline-flex items-center gap-2 px-4 py-2 rounded-lg text-white font-medium transition-colors hover:shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500',
130130
platform.colorClasses,
131131
]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
declare const styles: {
2+
readonly button: string
3+
readonly container: string
4+
readonly label: string
5+
}
6+
7+
export default styles

src/components/ThemePicker/index.astro

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77
import { themes } from '@components/ThemePicker/server'
88
import Icon from '@components/Icon/index.astro'
9-
import themePickerStyles from './themePicker.module.css'
9+
import styles from './themePicker.module.css'
1010
1111
export interface Props {
1212
closeComponent?: string
@@ -18,7 +18,7 @@ const { closeComponent = 'close', label = 'Select theme' } = Astro.props
1818

1919
<theme-picker transition:name="theme-picker-island" transition:persist>
2020
<div
21-
class:list={[themePickerStyles['themePicker'], 'themepicker', 'bg-bg-offset block overflow-hidden relative w-full']}
21+
class:list={[styles.themePicker, 'themepicker', 'bg-bg-offset block overflow-hidden relative w-full']}
2222
data-theme-modal
2323
data-nosnippet
2424
id="theme-picker-panel"
@@ -35,7 +35,7 @@ const { closeComponent = 'close', label = 'Select theme' } = Astro.props
3535
<ul
3636
id="theme-menu"
3737
class:list={[
38-
themePickerStyles['list'],
38+
styles.list,
3939
'themepicker__list',
4040
'block mb-[0.25em] overflow-x-auto overflow-y-hidden py-4 px-6 pb-8 text-center whitespace-nowrap w-full',
4141
]}
@@ -44,7 +44,7 @@ const { closeComponent = 'close', label = 'Select theme' } = Astro.props
4444
themes.map(theme => (
4545
<li
4646
class:list={[
47-
themePickerStyles['item'],
47+
styles.item,
4848
'themepicker__item',
4949
'inline-block relative rounded-lg scale-100 ml-4 first:ml-0 hover:shadow-md hover:scale-105 hover:z-1',
5050
]}
@@ -58,35 +58,35 @@ const { closeComponent = 'close', label = 'Select theme' } = Astro.props
5858
<span class="block py-0.5">
5959
<span
6060
class:list={[
61-
themePickerStyles['hue'],
61+
styles.hue,
6262
'themepicker__hue',
6363
'rounded-full shadow-[0_0_0_2px_var(--color-text)] inline-block h-6 w-6 overflow-hidden text-left indent-full align-bottom whitespace-nowrap bg-primary',
6464
]}
6565
/>
6666
<span
6767
class:list={[
68-
themePickerStyles['hue'],
68+
styles.hue,
6969
'themepicker__hue',
7070
'rounded-full shadow-[0_0_0_2px_var(--color-text)] inline-block h-6 w-6 overflow-hidden text-left indent-full align-bottom whitespace-nowrap bg-secondary',
7171
]}
7272
/>
7373
<span
7474
class:list={[
75-
themePickerStyles['hue'],
75+
styles.hue,
7676
'themepicker__hue',
7777
'rounded-full shadow-[0_0_0_2px_var(--color-text)] inline-block h-6 w-6 overflow-hidden text-left indent-full align-bottom whitespace-nowrap bg-border',
7878
]}
7979
/>
8080
<span
8181
class:list={[
82-
themePickerStyles['hue'],
82+
styles.hue,
8383
'themepicker__hue',
8484
'rounded-full shadow-[0_0_0_2px_var(--color-text)] inline-block h-6 w-6 overflow-hidden text-left indent-full align-bottom whitespace-nowrap bg-text-offset',
8585
]}
8686
/>
8787
<span
8888
class:list={[
89-
themePickerStyles['hue'],
89+
styles.hue,
9090
'themepicker__hue',
9191
'rounded-full shadow-[0_0_0_2px_var(--color-text)] inline-block h-6 w-6 overflow-hidden text-left indent-full align-bottom whitespace-nowrap bg-text',
9292
]}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
declare const styles: {
2+
readonly themePicker: string
3+
readonly item: string
4+
readonly list: string
5+
readonly hue: string
6+
}
7+
8+
export default styles

0 commit comments

Comments
 (0)