Skip to content

Commit 02a9199

Browse files
committed
💄 Use CSS modules to prevent style collisions
1 parent 72b191d commit 02a9199

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+741
-686
lines changed

scripts/createComponent.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const templates = {
2424
astro: `
2525
---
2626
import type { ${component}Props } from './${lowerCaseComponent}'
27-
import './${lowerCaseComponent}.scss'
27+
import styles from './${lowerCaseComponent}.module.scss'
2828
2929
interface Props extends ${component}Props {}
3030
@@ -33,20 +33,20 @@ const templates = {
3333
} = Astro.props
3434
3535
const classes = [
36-
'w-${lowerCaseComponent}',
36+
styles.${lowerCaseComponent},
3737
className
3838
]
3939
---
4040
`,
4141
svelte: `
4242
<script lang="ts">
4343
import type { ${component}Props } from './${lowerCaseComponent}'
44-
import './${lowerCaseComponent}.scss'
44+
import styles from './${lowerCaseComponent}.module.scss'
4545
4646
export let className: ${component}Props['className'] = ''
4747
4848
const classes = [
49-
'w-${lowerCaseComponent}',
49+
styles.${lowerCaseComponent},
5050
className
5151
].filter(Boolean).join(' ')
5252
</script>
@@ -55,13 +55,13 @@ const templates = {
5555
import React from 'react'
5656
import type { ${component}Props } from './${lowerCaseComponent}'
5757
58-
import './${lowerCaseComponent}.scss'
58+
import styles from './${lowerCaseComponent}.module.scss'
5959
6060
const ${component} = ({
6161
className
6262
}: ${component}Props) => {
6363
const classes = [
64-
'w-${lowerCaseComponent}',
64+
styles.${lowerCaseComponent},
6565
className
6666
].filter(Boolean).join(' ')
6767
@@ -78,7 +78,7 @@ const templates = {
7878
styles: `
7979
@import '../../scss/config.scss';
8080
81-
.w-${lowerCaseComponent} {
81+
.${lowerCaseComponent} {
8282
8383
}
8484
`,
@@ -133,7 +133,7 @@ fs.writeFileSync(`${rootPath}/${component}/${component}.astro`, format(templates
133133
fs.writeFileSync(`${rootPath}/${component}/${component}.svelte`, format(templates.svelte))
134134
fs.writeFileSync(`${rootPath}/${component}/${component}.tsx`, format(templates.react))
135135
fs.writeFileSync(`${rootPath}/${component}/${lowerCaseComponent}.ts`, format(templates.types))
136-
fs.writeFileSync(`${rootPath}/${component}/${lowerCaseComponent}.scss`, format(templates.styles))
136+
fs.writeFileSync(`${rootPath}/${component}/${lowerCaseComponent}.module.scss`, format(templates.styles))
137137
fs.writeFileSync(`src/pages/${lowerCaseComponent}.astro`, format(templates.page))
138138

139139
console.log(`✅ Component ${component} created at ${rootPath}/${component}.`)

src/components/Accordion/Accordion.astro

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
import type { AccordionProps } from './accordion'
33
import ArrowDown from '../../icons/arrow-down.svg?raw'
4-
import './accordion.scss'
4+
import styles from './accordion.module.scss'
55
66
interface Props extends AccordionProps {}
77
@@ -10,15 +10,15 @@ const {
1010
} = Astro.props
1111
---
1212

13-
<ul class="w-accordion" data-id="w-accordion">
13+
<ul class={styles.accordion} data-id="w-accordion">
1414
{items.map((item: AccordionProps['items'][0]) => (
1515
<li>
16-
<div class="accordion-title">
16+
<div class={styles.title} data-toggle="true">
1717
{item.title}
1818
<Fragment set:html={ArrowDown} />
1919
</div>
20-
<div class="accordion-wrapper">
21-
<div class="accordion-content">
20+
<div class={styles.wrapper}>
21+
<div class={styles.content}>
2222
<Fragment set:html={item.content} />
2323
</div>
2424
</div>
@@ -33,8 +33,10 @@ const {
3333
element.addEventListener('click', event => {
3434
const target = event.target as HTMLDivElement
3535

36-
if (target.classList.contains('accordion-title')) {
37-
target.classList.toggle('open')
36+
if (target.dataset.toggle) {
37+
target.dataset.open = target.dataset.open === 'true'
38+
? 'false'
39+
: 'true'
3840
}
3941
})
4042
})

src/components/Accordion/Accordion.svelte

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts">
22
import type { AccordionProps } from './accordion'
33
import ArrowDown from '../../icons/arrow-down.svg?raw'
4-
import './accordion.scss'
4+
import styles from './accordion.module.scss'
55
66
export let items: AccordionProps['items']
77
@@ -15,19 +15,19 @@
1515
}
1616
</script>
1717

18-
<ul class="w-accordion">
18+
<ul class={styles.accordion}>
1919
{#each items as item, index}
2020
<li>
2121
<div
22-
class="accordion-title"
23-
class:open={state[index]}
22+
class={styles.title}
23+
data-open={state[index]}
2424
on:click={() => toggle(index)}
2525
>
2626
{item.title}
2727
{@html ArrowDown}
2828
</div>
29-
<div class="accordion-wrapper">
30-
<div class="accordion-content">
29+
<div class={styles.wrapper}>
30+
<div class={styles.content}>
3131
{@html item.content}
3232
</div>
3333
</div>

src/components/Accordion/Accordion.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useState } from 'react'
22
import type { AccordionProps } from './accordion'
33
import ArrowDown from '../../icons/arrow-down.svg?raw'
4-
import './accordion.scss'
4+
import styles from './accordion.module.scss'
55

66
const Accordion = ({ items }: AccordionProps) => {
77
const [state, setState] = useState(Array(items.length).fill(false))
@@ -14,16 +14,17 @@ const Accordion = ({ items }: AccordionProps) => {
1414
}
1515

1616
return (
17-
<ul className="w-accordion">
17+
<ul className={styles.accordion}>
1818
{items.map((item, index) => (
1919
<li key={index}>
2020
<div
21-
className={state[index] ? 'accordion-title open' : 'accordion-title'}
21+
className={styles.title}
22+
data-open={state[index]}
2223
onClick={() => toggle(index)}
2324
dangerouslySetInnerHTML={{ __html: `${item.title} ${ArrowDown}` }}
2425
/>
25-
<div className="accordion-wrapper">
26-
<div className="accordion-content">
26+
<div className={styles.wrapper}>
27+
<div className={styles.content}>
2728
<div dangerouslySetInnerHTML={{ __html: item.content }} />
2829
</div>
2930
</div>

src/components/Accordion/accordion.scss renamed to src/components/Accordion/accordion.module.scss

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@import '../../scss/config.scss';
22

3-
.w-accordion {
3+
.accordion {
44
margin: 0;
55
padding: 0;
66
list-style-type: none;
@@ -19,7 +19,7 @@
1919
padding-bottom: 0;
2020
}
2121

22-
.accordion-title {
22+
.title {
2323
display: flex;
2424
justify-content: space-between;
2525
align-items: center;
@@ -33,28 +33,28 @@
3333
pointer-events: none;
3434
}
3535

36-
&.open {
36+
&[data-open="true"] {
3737
svg {
3838
transform: rotate(180deg);
3939
}
4040

41-
+ .accordion-wrapper {
41+
+ .wrapper {
4242
grid-template-rows: 1fr;
4343

44-
.accordion-content {
44+
.content {
4545
padding: 10px 0;
4646
}
4747
}
4848
}
4949
}
5050

51-
.accordion-wrapper {
51+
.wrapper {
5252
@include Transition(grid-template-rows);
5353
display: grid;
5454
grid-template-rows: 0fr;
5555
}
5656

57-
.accordion-content {
57+
.content {
5858
@include Transition();
5959
overflow: hidden;
6060
color: #BBB;

src/components/Alert/Alert.astro

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import success from '../../icons/circle-check.svg?raw'
77
import warning from '../../icons/warning.svg?raw'
88
import alert from '../../icons/alert.svg?raw'
99
10-
import './alert.scss'
10+
import styles from './alert.module.scss'
1111
1212
interface Props extends AlertProps {}
1313
@@ -22,6 +22,8 @@ const {
2222
element = 'section',
2323
title,
2424
titleTag = 'strong',
25+
titleProps,
26+
bodyProps,
2527
className,
2628
theme,
2729
...rest
@@ -32,9 +34,9 @@ const Title = titleTag
3234
const hasCustomIcon = Astro.slots.has('icon')
3335
3436
const classes = [
35-
'w-alert',
36-
(!hasCustomIcon && !theme) && 'col',
37-
theme,
37+
styles['w-alert'],
38+
(!hasCustomIcon && !theme) && styles.col,
39+
theme && styles[theme],
3840
className
3941
].filter(Boolean).join(' ')
4042
@@ -49,13 +51,15 @@ const props = {
4951
{!hasCustomIcon && theme && <Fragment set:html={iconMap[theme]} />}
5052

5153
<ConditionalWrapper condition={!!(hasCustomIcon || theme)}>
52-
<div class="alert-wrapper" slot="wrapper">
54+
<div class={styles.wrapper} slot="wrapper">
5355
children
5456
</div>
5557
{title && (
56-
<Title class:list="alert-title">{title}</Title>
58+
<Title class:list={styles.title} {...titleProps}>
59+
{title}
60+
</Title>
5761
)}
58-
<div class="alert-body">
62+
<div class={styles.body} {...bodyProps}>
5963
<slot />
6064
</div>
6165
</ConditionalWrapper>

src/components/Alert/Alert.svelte

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
import warning from '../../icons/warning.svg?raw'
88
import alert from '../../icons/alert.svg?raw'
99
10-
import './alert.scss'
10+
import styles from './alert.module.scss'
1111
1212
export let element: AlertProps['element'] = 'section'
1313
export let title: AlertProps['title'] = null
1414
export let titleTag: AlertProps['title'] = 'strong'
15+
export let titleProps: AlertProps['titleProps'] = null
16+
export let bodyProps: AlertProps['bodyProps'] = null
1517
export let className: AlertProps['className'] = null
1618
export let theme: AlertProps['theme'] = null
1719
@@ -25,9 +27,9 @@
2527
const hasCustomIcon = $$slots.icon
2628
2729
const classes = [
28-
'w-alert',
29-
(!hasCustomIcon && !theme) && 'col',
30-
theme,
30+
styles['w-alert'],
31+
(!hasCustomIcon && !theme) && styles.col,
32+
theme && styles[theme],
3133
className
3234
].filter(Boolean).join(' ')
3335
</script>
@@ -42,14 +44,14 @@
4244
<ConditionalWrapper
4345
condition={!!(hasCustomIcon || theme)}
4446
element="div"
45-
class="alert-wrapper"
47+
class={styles.wrapper}
4648
>
4749
{#if title}
48-
<svelte:element this={titleTag} class="alert-title">
50+
<svelte:element this={titleTag} class={styles.title} {...titleProps}>
4951
{title}
5052
</svelte:element>
5153
{/if}
52-
<div class="alert-body">
54+
<div class={styles.body} {...bodyProps}>
5355
<slot />
5456
</div>
5557
</ConditionalWrapper>

src/components/Alert/Alert.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import success from '../../icons/circle-check.svg?raw'
77
import warning from '../../icons/warning.svg?raw'
88
import alert from '../../icons/alert.svg?raw'
99

10-
import './alert.scss'
10+
import styles from './alert.module.scss'
1111

1212
const iconMap = {
1313
info,
@@ -20,16 +20,18 @@ const Alert = ({
2020
Element = 'section',
2121
title,
2222
TitleTag = 'strong',
23+
titleProps,
24+
bodyProps,
2325
className,
2426
theme,
2527
children,
2628
icon,
2729
...rest
2830
}: ReactAlertProps) => {
2931
const classes = [
30-
'w-alert',
31-
(!icon && !theme) && 'col',
32-
theme,
32+
styles['w-alert'],
33+
(!icon && !theme) && styles.col,
34+
theme && styles[theme],
3335
className
3436
].filter(Boolean).join(' ')
3537

@@ -39,14 +41,16 @@ const Alert = ({
3941
{!icon && theme && <div dangerouslySetInnerHTML={{ __html: iconMap[theme] }} />}
4042

4143
<ConditionalWrapper condition={!!(icon || theme)} wrapper={children => (
42-
<div className="alert-wrapper">
44+
<div className={styles.wrapper}>
4345
{children}
4446
</div>
4547
)}>
4648
{title && (
47-
<TitleTag className="alert-title">{title}</TitleTag>
49+
<TitleTag className={styles.title} {...titleProps}>
50+
{title}
51+
</TitleTag>
4852
)}
49-
<div className="alert-body">
53+
<div className={styles.body} {...bodyProps}>
5054
{children}
5155
</div>
5256
</ConditionalWrapper>

src/components/Alert/alert.scss renamed to src/components/Alert/alert.module.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@
4040
margin-top: 1px;
4141
}
4242

43-
.alert-title {
43+
.title {
4444
display: block;
4545
margin-bottom: 5px;
4646
}
4747

48-
.alert-body {
48+
.body {
4949
font-size: 16px;
5050
color: #BBB;
5151
line-height: 1.5;

src/components/Alert/alert.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ export type AlertProps = {
22
element?: string
33
title?: string | null
44
titleTag?: string
5+
titleProps?: any
6+
bodyProps?: any
57
icon?: string | null
68
className?: string | null
79
theme?: 'info'

0 commit comments

Comments
 (0)