diff --git a/.eslintrc b/.eslintrc
index 2738ee4..b6fa3ce 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -37,5 +37,7 @@
"import/extensions": "off",
"react/jsx-filename-extension": "off",
"implicit-arrow-linebreak": "off",
+ "no-colsole": "off",
+ "@typescript-eslint/no-unused-expressions": "off"
}
}
diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz
index c7e88da..b63da15 100644
Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ
diff --git a/blog/2024-11-17-event-propagation-of-react.mdx b/blog/2024-11-17-event-propagation-of-react.mdx
new file mode 100644
index 0000000..36490b1
--- /dev/null
+++ b/blog/2024-11-17-event-propagation-of-react.mdx
@@ -0,0 +1,271 @@
+---
+slug: event-propagation-of-react
+title: React의 이벤트 전파
+description: React의 이벤트 전파는 Javascript와 다르다
+keywords:
+ - react
+ - event
+ - event-propagation
+ - web
+authors: HyunmoAhn
+tags: [react, event, event-propagation, web, issue, trouble-shooting]
+---
+
+
+
+## Introduction
+React 이벤트 핸들러 방식과 vanilla Javascript의 이벤트 핸들러 방식을 혼용해서 사용할 때 이벤트 전파가 의도한대로 동작하지 않을 수 있다.
+예를 들면 아래와 같이 `button1`, `button2` 구조에서 `button2`를 클릭했을 때 `button1의` 이벤트 핸들러도 실행되는 문제가 발생한다.
+
+```tsx
+const buttonEl = document.getElementById('button1');
+buttonEl.addEventListener('click', () => {
+ console.log('button1 clicked');
+});
+
+const handleClick = (e) => {
+ e.stopPropagation();
+ console.log('button2 clicked');
+};
+
+return (
+
+ Click me
+
+);
+```
+
+```
+// When button2 is clicked
+button2 clicked
+button1 clicked
+```
+
+## Solution
+
+React에서 이벤트 전파는 vanilla Javascript에서 사용하는 이벤트 전파와 다르다.
+React에서 이벤트 전파를 delegation 방식으로 처리하기 때문이다. ([comment](https://github.com/facebook/react/issues/13635#issuecomment-421085767))
+
+React에서는 ([React 17 이후로](https://legacy.reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation)) 이벤트 리스너를 rootDOM에 등록해서 사용한다.
+따라서 React끼리의 event listener는 생각한 대로 DOM 구조에 따라 이벤트가 전파가 전달되지만 vanilla Javascript의 이벤트 전파는 생각대로 동작하지 않는다.
+
+가능하다면 두가지 이벤트를 섞어서 쓰지 않는 방향이 좋겠지만, 3rd party library를 사용하거나 제어하지 못하는 부분의 이벤트는 제어하기 힘들기 때문에 동작 방식에 맞춰 이벤트 전파를 막아야한다.
+
+```tsx
+// Unify event listener to vanilla Javascript
+const buttonEl = document.getElementById('button1');
+buttonEl.addEventListener('click', () => {
+ console.log('button1 clicked');
+});
+
+const button2El = document.getElementById('button2');
+button2El.addEventListener('click', (e) => {
+ e.stopPropagation();
+ console.log('button2 clicked');
+});
+
+return (
+
+ Click me
+
+);
+
+// Or
+// Unify event listener to React
+const handleClick1 = (e) => {
+ console.log('button1 clicked');
+};
+
+const handleClick = (e) => {
+ e.stopPropagation();
+ console.log('button2 clicked');
+};
+
+return (
+
+ Click me
+
+);
+```
+
+import { BasicEventPlayground, BothEventPlayground, BothStopEventPlayground, BothStopCapturingEventPlayground } from '@site/src/code-snippet/reactEventPropagation/index.tsx'
+import { Figure } from '@site/src/components/common/Figure/index.tsx'
+
+## Step by Step
+
+:::note
+이 내용은 Javascript의 Event Bubbling & Capturing을 이해하고 있다는 가정하에 설명한다.
+만약 이해가 안된다면 [MDN](https://developer.mozilla.org/ko/docs/Learn/JavaScript/Building_blocks/Event_bubbling)을 참고하자.
+:::
+
+React의 이벤트 전파를 이해하기 위해 아래와 같은 예제를 살펴보자.
+`Figure 1,2`는 각각의 방식으로 이벤트 전파를 설정하였을 때 UI를 보여준다. `#1,2,3` 아무 곳이나 클릭해보자.
+
+
+
+
+`Figure 1`에서는 Vanilla Javascript의 이벤트만 설정하였기 때문에 붉은 색으로 이벤트 전파가 일어난다.
+마찬가지로 `Figure 2`에서는 React의 이벤트만 설정하였기 때문에 파란 색으로 이벤트 전파가 일어난다.
+
+그렇다면 두 종류의 이벤트를 모두 설정한다면 어떻게 될까? `Figure 3`을 눌러보자.
+
+
+
+`Figure 3`에서는 두 종류의 이벤트를 모두 설정해두어서 이벤트가 모두 발생하고, 색은 보라색으로 표시된다.
+
+이벤트의 발생 순서는 다음과 같다.
+
+| Order | Target | Vanilla | React | Type |
+| --- | --- | --- | --- | --- |
+| 1 | `#1` | ✅ | ✅ | Capture |
+| 2 | `#2` | ✅ | ✅ | Capture |
+| 3 | `#3` | ✅ | ✅ | Capture |
+| 4 | `#3` | ✅ | ✅ | Bubble |
+| 5 | `#2` | ✅ | ✅ | Bubble |
+| 6 | `#1` | ✅ | ✅ | Bubble |
+
+이벤트 전파를 막지 않았기 때문에 이벤트가 모두 발생하고, 이벤트 전파가 일어난다.
+
+#1 -> #2 -> #3 순으로 capturing이 발생하고 #3 -> #2 -> #1 순으로 bubbling이 발생한다.
+
+그렇다면, 이벤트 전파를 막으면 어떻게 될까? `Figure 4,5`를 눌러보자.
+
+:::note
+전파를 막은 방식은 모두 동일하게 `e.stopPropagation()`으로 사용하였다.
+
+```tsx
+// React
+ e.stopPropagation()}>
+
+// Vanilla
+button.addEventListener('click', (e) => {
+ e.stopPropagation();
+});
+```
+
+:::
+
+
+`Figure 4`는 `#2` 의 React Event bubbling을 막은 경우이고, `Figure 5`는 `#2`의 Vanilla Event bubbling을 막은 경우이다.
+
+
+
+두 예제의 동작은 다르게 나타난다. 결과를 정리해보자.
+
+
+
+
Figure 4. #2 Stop Bubbling by React
+ | Order | Target | Vanilla | React | Type |
+ | --- | --- | --- | --- | --- |
+ | 1 | `#1` | ✅ | ✅ | Capture |
+ | 2 | `#2` | ✅ | ✅ | Capture |
+ | 3 | `#3` | ✅ | ✅ | Capture |
+ | 4 | `#3` | ✅ | ✅ | Bubble |
+ | 5 | `#2` | ✅ | ✅ | Bubble |
+ | 6 | `#1` | ✅ | ❌ | Bubble |
+
+
+
+
Figure 5. #2 Stop Bubbling by Vanilla
+
+ | Order | Target | Vanilla | React | Type |
+ | --- | --- | --- | --- | --- |
+ | 1 | `#1` | ✅ | ✅ | Capture |
+ | 2 | `#2` | ✅ | ✅ | Capture |
+ | 3 | `#3` | ✅ | ✅ | Capture |
+ | 4 | `#3` | ✅ | ❌ | Bubble |
+ | 5 | `#2` | ✅ | ❌ | Bubble |
+ | 6 | `#1` | ❌ | ❌ | Bubble |
+
+
+
+
+결과가 복잡 할 수 있는데, 이벤트 전파를 막은 방식과 동일한 이벤트의 결과를 살펴보자.
+
+`Figure 4`은 React 방식으로 전파를 막았으므로 `Figure 4`의 React 방식은 `#1`의 이벤트만 발생하지 않았고,
+`Figure 5`는 Vanilla Javascript 방식으로 막았으므로 `Figure 5`의 Vanilla Javascript 방식도 `#1`의 이벤트만 발생하지 않았다.
+
+여기까지는 우리가 익히 아는 이벤트 전파 방식이다. 그러면 다른 방식의 이벤트 전파 결과를 살펴보자.
+
+`Figure 4`의 Vanilla 이벤트는 `#2`의 React bubble 전파를 막았음에도 이벤트가 발생하였다.
+이와 다르게 `Figure 5`의 React 이벤트는 `#2`의 Vanilla bubble 전파를 막았는데, #1, #2, #3 모두 이벤트가 발생하지 않았다.
+
+여기서 중요한 사실은 React의 이벤트 핸들러 방식은 node에 직접 이벤트를 등록하지 않고, `rootDOM`에 등록하여 사용한다는 것이다. ([docs](https://legacy.reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation))
+
+
+
+
+
+이 사실을 기반하여 `Figure 4`와 `Figure 5`의 동작이 다른지 이해 할 수 있다.
+
+`Figure 4`는 React 이벤트의 전파를 막았기 때문에 실제 이벤트는 `rootDOM`에서 `stopPropagation`이 동작한다. 이는 실제로는 React 내부에서 이벤트 전파를 구현했다고 표현하는 게 맞을 것 같다.
+따라서 실제 이벤트는 다음과 같은 순서로 발생한다.
+
+1. `rootDOM`의 react event capturing
+2. `#1, #2, #3`에서의 vanilla javascript event capturing
+3. `#1, #2, #3`에서의 vanilla javascript event bubbling
+4. `rootDOM`의 react event bubbling
+
+따라서 `Figure 4`에서의 이벤트는 3번, `#1, #2, #3`에서의 event bubbling을 막지 못하여서 vanilla javascript의 이벤트가 모두 발생하였다.
+
+그렇다면 `Figure 5`는 어떻게 될까? `#2`에서 vanilla javascript의 이벤트를 막았기 때문에, 3번의 이벤트 중 `#2`에서 이벤트 전파가 중단 되었고 `#3`과 4번, rootDOM으로의 이벤트가 발생하지 않았다.
+따라서 `Figure 5`의 이벤트에서 React의 모든 bubbling 이벤트가 중단 된 것이다.
+
+그럼 다른 예제로 Capturing을 막는 건 어떨까? 아래 `Figure 7,8`을 살펴보자. 실행 전 동작을 예상해 보는 것도 재미있을 것 같다.
+두 예제 모두 `#2`에서의 event capturing을 막았다.
+
+
+
+결과는 다음과 같다.
+
+
+
+
Figure 7. #2 Stop Capturing by React
+ | Order | Target | Vanilla | React | Type |
+ | --- | --- | --- | --- | --- |
+ | 1 | `#1` | ❌ | ✅ | Capture |
+ | 2 | `#2` | ❌ | ✅ | Capture |
+ | 3 | `#3` | ❌ | ❌ | Capture |
+ | 4 | `#3` | ❌ | ❌ | Bubble |
+ | 5 | `#2` | ❌ | ❌ | Bubble |
+ | 6 | `#1` | ❌ | ❌ | Bubble |
+
+
+
+
Figure 8. #2 Stop Capturing by Vanilla
+
+ | Order | Target | Vanilla | React | Type |
+ | --- | --- | --- | --- | --- |
+ | 1 | `#1` | ✅ | ✅ | Capture |
+ | 2 | `#2` | ✅ | ✅ | Capture |
+ | 3 | `#3` | ❌ | ✅ | Capture |
+ | 4 | `#3` | ❌ | ❌ | Bubble |
+ | 5 | `#2` | ❌ | ❌ | Bubble |
+ | 6 | `#1` | ❌ | ❌ | Bubble |
+
+
+
+
+혹시 정답을 맞췄을까?
+
+`Figure 7`은 React의 capturing을 막았고, 이는 rootDOM에서 일어난다. 따라서 `#1, #2`의 react capturing은 발생했다.
+하지만, vanilla javascript의 capturing은 rootDOM에서 중단되었기 때문에 이벤트가 모두 발생하지 않는다.
+
+`Figure 8`은 vanilla javascript의 capturing을 막았고, 이는 `#2`에서 일어난다. 따라서 `#1, #2`의 valina javascript의 capturing은 발생했다.
+하지만, React의 capturing은 rootDOM에서 일어나기 때문에 `#2`에서 이벤트를 막았음에도 불구하고 capturing 이벤트가 모두 발생한다.
+
+
+## Conclusion
+React는 React에서 등록하는 이벤트를 모두 rootDOM에 등록하여 내부적으로 이벤트 전파를 처리하므로, vanilla javascript와의 이벤트 전파와는 다르게 동작한다.
+일반적으로 이 내용을 자세히 알 필요는 없겠지만, React와 vanilla javascript의 이벤트를 혼용해서 처리 할 때 이벤트 전파에서 문제가 발생할 수 있다.
+
+이는 프로젝트 내부에서 관리하는 코드 뿐 아니라 3rd party library를 사용 할 때도 동일하게 적용되므로 예상치 못한 부분에서 이슈가 발생 할 수 있다.
+필자도 React 환경에서 `swiper` 라이브러리를 사용할 때 이 이슈로 인해 문제가 발생한 적이 있어서 원인 분석을 하는 과정에서 이런 현상을 알게 되었다.
+
+따라서 React에서의 이벤트 등록 방식을 한번 더 인지하고 사용하는 것을 추천한다.
+
+
+## Reference
+- https://github.com/facebook/react/issues/13635#issuecomment-421085767
+- https://legacy.reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation
+
diff --git a/docusaurus.config.js b/docusaurus.config.js
index 4af533a..ec53aa8 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -135,7 +135,7 @@ module.exports = {
theme: {
customCss: [
require.resolve('@radix-ui/themes/styles.css'),
- require.resolve('./src/css/custom.css'),
+ require.resolve('./src/css/custom.scss'),
],
},
googleAnalytics: {
diff --git a/i18n/en/docusaurus-plugin-content-blog/2024-11-17-event-propagation-of-react.mdx b/i18n/en/docusaurus-plugin-content-blog/2024-11-17-event-propagation-of-react.mdx
new file mode 100644
index 0000000..c36a61b
--- /dev/null
+++ b/i18n/en/docusaurus-plugin-content-blog/2024-11-17-event-propagation-of-react.mdx
@@ -0,0 +1,291 @@
+---
+slug: event-propagation-of-react
+title: Event Propagation in React
+description: Event propagation in React differs from Javascript
+keywords:
+ - react
+ - event
+ - event-propagation
+ - web
+authors: HyunmoAhn
+tags: [react, event, event-propagation, web, issue, trouble-shooting]
+---
+
+
+
+## Introduction
+When mixing React's event handler method with vanilla Javascript's event handler method, event propagation may not work as intended.
+For example, in a structure like `button1`, `button2`, clicking `button2` can trigger the event handler of `button1` as well.
+
+```tsx
+const buttonEl = document.getElementById('button1');
+buttonEl.addEventListener('click', () => {
+ console.log('button1 clicked');
+});
+
+const handleClick = (e) => {
+ e.stopPropagation();
+ console.log('button2 clicked');
+};
+
+return (
+
+ Click me
+
+);
+```
+
+```
+// When button2 is clicked
+button2 clicked
+button1 clicked
+```
+
+## Solution
+
+Event propagation in React differs from that in vanilla Javascript
+because React handles event propagation using a delegation method. ([comment](https://github.com/facebook/react/issues/13635#issuecomment-421085767))
+
+In React ([post React 17](https://legacy.reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation)),
+event listeners are registered on the rootDOM.
+Therefore, event listeners within React propagate as expected according to the DOM structure,
+but vanilla Javascript event propagation may not behave as anticipated.
+
+While it's best to avoid mixing the two types of events,
+sometimes it's unavoidable when using third-party libraries or handling parts of the code you can't control.
+In such cases, you must block event propagation according to the behavior of each method.
+
+```tsx
+// Unify event listener to vanilla Javascript
+const buttonEl = document.getElementById('button1');
+buttonEl.addEventListener('click', () => {
+ console.log('button1 clicked');
+});
+
+const button2El = document.getElementById('button2');
+button2El.addEventListener('click', (e) => {
+ e.stopPropagation();
+ console.log('button2 clicked');
+});
+
+return (
+
+ Click me
+
+);
+
+// Or
+// Unify event listener to React
+const handleClick1 = (e) => {
+ console.log('button1 clicked');
+};
+
+const handleClick = (e) => {
+ e.stopPropagation();
+ console.log('button2 clicked');
+};
+
+return (
+
+ Click me
+
+);
+```
+
+import { BasicEventPlayground, BothEventPlayground, BothStopEventPlayground, BothStopCapturingEventPlayground } from '@site/src/code-snippet/reactEventPropagation/index.tsx'
+import { Figure } from '@site/src/components/common/Figure/index.tsx'
+
+## Step by Step
+
+:::note
+This explanation assumes you have an understanding of Javascript's Event Bubbling & Capturing.
+If you're not familiar with it, refer to MDN.
+:::
+
+To understand event propagation in React, let's look at the following example.
+`Figure 1,2` show the UI when event propagation is set in each method. Try clicking anywhere on `#1,2,3`.
+
+
+
+
+In `Figure 1`, only vanilla Javascript events are set, so the event propagates in red.
+Similarly, in `Figure 2`, only React events are set, so the event propagates in blue.
+
+What happens if both types of events are set? Click `Figure 3`.
+
+
+
+In `Figure 3`, both types of events are set, so both events occur, and the color is indicated in purple.
+
+The order of event occurrence is as follows:
+
+| Order | Target | Vanilla | React | Type |
+| --- | --- | --- | --- | --- |
+| 1 | `#1` | ✅ | ✅ | Capture |
+| 2 | `#2` | ✅ | ✅ | Capture |
+| 3 | `#3` | ✅ | ✅ | Capture |
+| 4 | `#3` | ✅ | ✅ | Bubble |
+| 5 | `#2` | ✅ | ✅ | Bubble |
+| 6 | `#1` | ✅ | ✅ | Bubble |
+
+Since event propagation wasn't blocked, all events occurred, and propagation took place.
+
+Capturing occurs in the order of #1 -> #2 -> #3, and bubbling occurs in the order of #3 -> #2 -> #1.
+
+What happens if we block event propagation? Click `Figure 4,5`.
+
+:::note
+The method used to block propagation is the same, using e.stopPropagation().
+
+```tsx
+// React
+ e.stopPropagation()}>
+
+// Vanilla
+button.addEventListener('click', (e) => {
+ e.stopPropagation();
+});
+```
+
+:::
+
+`Figure 4` blocks React Event bubbling on `#2`, and `Figure 5` blocks Vanilla Event bubbling on `#2`.
+
+
+
+The behavior of the two examples is different. Let's summarize the results.
+
+
+
+
Figure 4. #2 Stop Bubbling by React
+ | Order | Target | Vanilla | React | Type |
+ | --- | --- | --- | --- | --- |
+ | 1 | `#1` | ✅ | ✅ | Capture |
+ | 2 | `#2` | ✅ | ✅ | Capture |
+ | 3 | `#3` | ✅ | ✅ | Capture |
+ | 4 | `#3` | ✅ | ✅ | Bubble |
+ | 5 | `#2` | ✅ | ✅ | Bubble |
+ | 6 | `#1` | ✅ | ❌ | Bubble |
+
+
+
+
Figure 5. #2 Stop Bubbling by Vanilla
+
+ | Order | Target | Vanilla | React | Type |
+ | --- | --- | --- | --- | --- |
+ | 1 | `#1` | ✅ | ✅ | Capture |
+ | 2 | `#2` | ✅ | ✅ | Capture |
+ | 3 | `#3` | ✅ | ✅ | Capture |
+ | 4 | `#3` | ✅ | ❌ | Bubble |
+ | 5 | `#2` | ✅ | ❌ | Bubble |
+ | 6 | `#1` | ❌ | ❌ | Bubble |
+
+
+
+
+The results might seem complex, but let's focus on the event propagation method that was blocked.
+
+In `Figure 4`, the React method was used to block propagation,
+so only the React method in `Figure 4` did not trigger the event on `#1`.
+In `Figure 5`, the Vanilla Javascript method was used to block propagation,
+so only the Vanilla Javascript method in `Figure 5` did not trigger the event on `#1`.
+
+Up to this point, this is the event propagation method we are familiar with.
+Now, let's look at the results of the other method's event propagation.
+
+In `Figure 4`, the Vanilla event occurred even though the React bubble propagation on `#2` was blocked.
+Conversely, in `Figure 5`, the React event did not occur on #1, #2, or #3,
+even though the Vanilla bubble propagation on `#2` was blocked.
+
+The key point here is that React's event handler method doesn't directly register events on nodes
+but uses event delegation by registering them on the `rootDOM` ([docs](https://legacy.reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation))
+
+
+
+
+
+Based on this fact, we can understand why the behavior of `Figure 4` and `Figure 5` differs.
+
+In `Figure 4`, React event propagation was blocked, so the actual event propagation occurs at the `rootDOM`.
+This means the event propagation is actually implemented within React.
+Therefore, the actual event occurs in the following order:
+
+1. React event capturing at `rootDOM`
+2. Vanilla javascript event capturing at `#1, #2, #3`
+3. Vanilla javascript event bubbling at `#1, #2, #3`
+4. React event bubbling at `rootDOM`
+
+Therefore, in `Figure 4`, the event propagation wasn't blocked during the 3rd step, the bubbling at `#1, #2, #3`,
+so all vanilla javascript events occurred.
+
+So what about `Figure 5`?
+Since vanilla javascript's event was blocked at `#2`,
+the event propagation was interrupted on `#2` during the 3rd step,
+and no events occurred at `#3` or during the 4th step, at the rootDOM.
+Therefore, all React bubbling events in `Figure 5` were interrupted.
+
+What about blocking Capturing in another example?
+Let's look at `Figure 7,8`. It might be interesting to predict the behavior before running it.
+Both examples blocked event capturing at `#2`.
+
+
+
+
+The results are as follows.
+
+
+
+
Figure 7. #2 Stop Capturing by React
+ | Order | Target | Vanilla | React | Type |
+ | --- | --- | --- | --- | --- |
+ | 1 | `#1` | ❌ | ✅ | Capture |
+ | 2 | `#2` | ❌ | ✅ | Capture |
+ | 3 | `#3` | ❌ | ❌ | Capture |
+ | 4 | `#3` | ❌ | ❌ | Bubble |
+ | 5 | `#2` | ❌ | ❌ | Bubble |
+ | 6 | `#1` | ❌ | ❌ | Bubble |
+
+
+
+
Figure 8. #2 Stop Capturing by Vanilla
+
+ | Order | Target | Vanilla | React | Type |
+ | --- | --- | --- | --- | --- |
+ | 1 | `#1` | ✅ | ✅ | Capture |
+ | 2 | `#2` | ✅ | ✅ | Capture |
+ | 3 | `#3` | ❌ | ✅ | Capture |
+ | 4 | `#3` | ❌ | ❌ | Bubble |
+ | 5 | `#2` | ❌ | ❌ | Bubble |
+ | 6 | `#1` | ❌ | ❌ | Bubble |
+
+
+
+
+Did you get the answer right?
+
+In `Figure 7`, React capturing was blocked, which occurs at the rootDOM.
+Therefore, React capturing occurred at `#1, #2`.
+However, vanilla javascript capturing was interrupted at the rootDOM, so no events occurred.
+
+In `Figure 8`, vanilla javascript capturing was blocked, which occurs at `#2`.
+Therefore, vanilla javascript capturing occurred at `#1, #2`.
+However, React capturing occurs at the rootDOM, so even though the event was blocked at `#2`,
+all capturing events occurred.
+
+## Conclusion
+React registers events on the rootDOM and handles event propagation internally,
+so it behaves differently from vanilla javascript event propagation.
+Generally, there's no need to know this in detail,
+but when mixing React and vanilla javascript events, issues can arise in event propagation.
+
+This applies not only to code managed within the project
+but also when using third-party libraries, so unexpected issues can occur.
+The author encountered this issue when using the swiper library in a React environment,
+leading to this discovery during root cause analysis.
+
+Therefore, it's recommended to be aware of React's event registration method when using it.
+
+## Reference
+- https://github.com/facebook/react/issues/13635#issuecomment-421085767
+- https://legacy.reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation
+
diff --git a/package.json b/package.json
index cc526fe..823af37 100644
--- a/package.json
+++ b/package.json
@@ -70,6 +70,10 @@
"husky": "^8.0.3",
"lint-staged": "^13.2.3",
"prettier": "^3.0.1",
+ "stylelint": "^16.10.0",
+ "stylelint-config-prettier-scss": "^1.0.0",
+ "stylelint-config-standard-scss": "^13.1.0",
+ "stylelint-prettier": "^5.0.2",
"typescript": "^5.6.3"
},
"browserslist": {
diff --git a/src/code-snippet/reactEventPropagation/EventPlayground/EventPlayground.module.scss b/src/code-snippet/reactEventPropagation/EventPlayground/EventPlayground.module.scss
new file mode 100644
index 0000000..c7ffde1
--- /dev/null
+++ b/src/code-snippet/reactEventPropagation/EventPlayground/EventPlayground.module.scss
@@ -0,0 +1,44 @@
+.container {
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ padding: 30px;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ cursor: pointer;
+ overflow: hidden;
+ background-color: var(--docusaurus-highlighted-code-line-bg);
+ width: 100%;
+}
+
+.highlightContainer {
+ display: flex;
+ justify-content: flex-start;
+ align-items: flex-start;
+ gap: 5px;
+ margin: 5px;
+ margin-bottom: 20px;
+ min-height: 25px;
+}
+
+.highlight {
+ display: flex;
+ pointer-events: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+
+ &.react {
+ background-color: color-mix(in srgb, var(--color-blue) 70%, transparent);
+ }
+
+ &.vanilla {
+ background-color: color-mix(in srgb, var(--color-red) 50%, transparent);
+ }
+}
+
+.text {
+ z-index: 1;
+}
diff --git a/src/code-snippet/reactEventPropagation/EventPlayground/index.tsx b/src/code-snippet/reactEventPropagation/EventPlayground/index.tsx
new file mode 100644
index 0000000..71d70ad
--- /dev/null
+++ b/src/code-snippet/reactEventPropagation/EventPlayground/index.tsx
@@ -0,0 +1,148 @@
+import {
+ useId,
+ useEffect,
+ useState,
+ ReactNode,
+ MouseEvent,
+ createContext,
+ useContext,
+} from 'react';
+import cx from 'classnames';
+import style from './EventPlayground.module.scss';
+import { timeout, DELAY, createController } from './utils';
+
+export const ReactEventPlaygroundContext = createContext(createController());
+export const VanillaEventPlaygroundContext = createContext(createController());
+export const EventPlaygroundProvider = ({ children }: { children: ReactNode }) => (
+
+
+ {children}
+
+
+);
+
+interface EventPlaygroundProps {
+ label?: string;
+ children?: ReactNode;
+ reset?: boolean;
+ skipReact?: boolean;
+ skipVanilla?: boolean;
+ reactStopBubble?: boolean;
+ reactStopCapture?: boolean;
+ vanillaStopBubble?: boolean;
+ vanillaStopCapture?: boolean;
+}
+
+export const EventPlayground = ({
+ label,
+ children,
+ reset,
+ skipReact,
+ skipVanilla,
+ reactStopBubble,
+ reactStopCapture,
+ vanillaStopBubble,
+ vanillaStopCapture,
+}: EventPlaygroundProps) => {
+ const id = useId();
+ const reactEventController = useContext(ReactEventPlaygroundContext);
+ const vanillaEventController = useContext(VanillaEventPlaygroundContext);
+ const [reactEvent, setReactEvent] = useState(false);
+ const [vanillaEvent, setVanillaEvent] = useState(false);
+
+ const handleReactClick = () => {
+ if (!skipReact) {
+ reactEventController.register(() => {
+ setReactEvent(true);
+ });
+ reactEventController.register(async () => {
+ await timeout(DELAY);
+ });
+ reactEventController.register(() => {
+ setReactEvent(false);
+ });
+ }
+ };
+
+ const handleReactClickCapture = (e: MouseEvent) => {
+ if (reset) {
+ reactEventController.clear();
+ }
+ reactStopCapture && e.stopPropagation();
+ handleReactClick();
+ };
+
+ const handleReactClickBubble = (e: MouseEvent) => {
+ reactStopBubble && e.stopPropagation();
+ handleReactClick();
+ };
+
+ useEffect(() => {
+ const handleVanillaClick = (e: Event) => {
+ if (!skipVanilla) {
+ vanillaEventController.register(() => {
+ setVanillaEvent(true);
+ });
+ vanillaEventController.register(async () => {
+ await timeout(DELAY);
+ });
+ vanillaEventController.register(() => {
+ setVanillaEvent(false);
+ });
+ }
+ };
+ const handleVanillaClickBubble = (e: Event) => {
+ vanillaStopBubble && e.stopPropagation();
+ handleVanillaClick(e);
+ };
+
+ const handleVanillaClickCapture = (e: Event) => {
+ if (reset) {
+ vanillaEventController.clear();
+ }
+ vanillaStopCapture && e.stopPropagation();
+ handleVanillaClick(e);
+ };
+
+ const button = document.getElementById(id);
+
+ button.addEventListener('click', handleVanillaClickCapture, { capture: true });
+ button.addEventListener('click', handleVanillaClickBubble, { capture: false });
+ return () => {
+ button.removeEventListener('click', handleVanillaClickCapture, {
+ capture: true,
+ });
+ button.removeEventListener('click', handleVanillaClickBubble, {
+ capture: false,
+ });
+ };
+ }, [id, reset, skipVanilla, vanillaStopBubble, vanillaStopCapture]);
+
+ return (
+ // eslint-disable-next-line max-len
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
+
+
{label}
+
+ {reactEvent && (
+ <>
+
+
React Event
+ >
+ )}
+ {vanillaEvent && (
+ <>
+
+
Vanilla Event
+ >
+ )}
+
+ {children}
+
+ );
+};
diff --git a/src/code-snippet/reactEventPropagation/EventPlayground/utils.ts b/src/code-snippet/reactEventPropagation/EventPlayground/utils.ts
new file mode 100644
index 0000000..b3daee2
--- /dev/null
+++ b/src/code-snippet/reactEventPropagation/EventPlayground/utils.ts
@@ -0,0 +1,34 @@
+export const DELAY = 600;
+
+export function timeout(ns: number) {
+ return new Promise((resolve) => {
+ setTimeout(resolve, ns);
+ });
+}
+
+export const createController = () => {
+ let events: (() => void)[] = [];
+ const processor = eventProcessor();
+
+ const register = async (cb: () => void) => {
+ events.push(cb);
+ await processor.next();
+ };
+
+ async function* eventProcessor() {
+ while (true) {
+ const event = events.shift();
+ yield event?.();
+ }
+ }
+
+ const clear = () => {
+ events.forEach((event) => event());
+ events = [];
+ };
+
+ return {
+ register,
+ clear,
+ };
+};
diff --git a/src/code-snippet/reactEventPropagation/index.module.scss b/src/code-snippet/reactEventPropagation/index.module.scss
new file mode 100644
index 0000000..222721a
--- /dev/null
+++ b/src/code-snippet/reactEventPropagation/index.module.scss
@@ -0,0 +1,7 @@
+.basicEventPlayground {
+ display: flex;
+ width: 100%;
+ justify-content: space-around;
+ column-gap: 30px;
+ flex-wrap: wrap;
+}
diff --git a/src/code-snippet/reactEventPropagation/index.tsx b/src/code-snippet/reactEventPropagation/index.tsx
new file mode 100644
index 0000000..9917618
--- /dev/null
+++ b/src/code-snippet/reactEventPropagation/index.tsx
@@ -0,0 +1,97 @@
+import { Figure } from '../../components/common/Figure';
+import { EventPlayground, EventPlaygroundProvider } from './EventPlayground';
+import style from './index.module.scss';
+
+export { EventPlayground } from './EventPlayground';
+
+export const BasicEventPlayground = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export const BothEventPlayground = () => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export const BothStopEventPlayground = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export const BothStopCapturingEventPlayground = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/components/common/Figure/Figure.module.scss b/src/components/common/Figure/Figure.module.scss
new file mode 100644
index 0000000..357ced2
--- /dev/null
+++ b/src/components/common/Figure/Figure.module.scss
@@ -0,0 +1,28 @@
+.figureContainer {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+ column-gap: 5px;
+ padding: 10px;
+ flex: 1;
+
+ .titleContainer {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ column-gap: 10px;
+ cursor: default;
+ margin: 10px 0 15px;
+
+ .indexing {
+ font-weight: 700;
+ color: var(--color-gray-darker);
+ }
+
+ .title {
+ font-style: italic;
+ color: var(--ifm-color-primary-light);
+ }
+ }
+}
diff --git a/src/components/common/Figure/index.tsx b/src/components/common/Figure/index.tsx
new file mode 100644
index 0000000..8b77721
--- /dev/null
+++ b/src/components/common/Figure/index.tsx
@@ -0,0 +1,20 @@
+import { ReactNode } from 'react';
+import style from './Figure.module.scss';
+
+export interface FigureProps {
+ index: number;
+ title: string;
+ children: ReactNode;
+}
+
+export const Figure = ({ index, title, children }: FigureProps) => {
+ return (
+
+ {children}
+
+ Figure {index}
+ {title}
+
+
+ );
+};
diff --git a/src/css/color.scss b/src/css/color.scss
new file mode 100644
index 0000000..873e0de
--- /dev/null
+++ b/src/css/color.scss
@@ -0,0 +1,115 @@
+:root {
+ /* White and Black */
+ --color-white: #fff;
+ --color-black: #000;
+
+ /* Gray Palette */
+ --color-gray-lightest: #f5f5f5;
+ --color-gray-lighter: #eee;
+ --color-gray-light: #e0e0e0;
+ --color-gray: #9e9e9e;
+ --color-gray-dark: #757575;
+ --color-gray-darker: #616161;
+ --color-gray-darkest: #424242;
+
+ /* Red Palette */
+ --color-red-lightest: #ffebee;
+ --color-red-lighter: #ffcdd2;
+ --color-red-light: #ef9a9a;
+ --color-red: #f44336;
+ --color-red-dark: #e53935;
+ --color-red-darker: #d32f2f;
+ --color-red-darkest: #b71c1c;
+
+ /* Green Palette */
+ --color-green-lightest: #e8f5e9;
+ --color-green-lighter: #c8e6c9;
+ --color-green-light: #a5d6a7;
+ --color-green: #4caf50;
+ --color-green-dark: #43a047;
+ --color-green-darker: #388e3c;
+ --color-green-darkest: #1b5e20;
+
+ /* Yellow Palette */
+ --color-yellow-lightest: #fffde7;
+ --color-yellow-lighter: #fff9c4;
+ --color-yellow-light: #fff59d;
+ --color-yellow: #ffeb3b;
+ --color-yellow-dark: #fdd835;
+ --color-yellow-darker: #fbc02d;
+ --color-yellow-darkest: #f57f17;
+
+ /* Blue Palette */
+ --color-blue-lightest: #e3f2fd;
+ --color-blue-lighter: #bbdefb;
+ --color-blue-light: #90caf9;
+ --color-blue: #2196f3;
+ --color-blue-dark: #1e88e5;
+ --color-blue-darker: #1976d2;
+ --color-blue-darkest: #0d47a1;
+
+ /* Primary Color */
+ --ifm-color-primary: #286242;
+ --ifm-color-primary-dark: #24583b;
+ --ifm-color-primary-darker: #225338;
+ --ifm-color-primary-darkest: #1c452e;
+ --ifm-color-primary-light: #2c6c49;
+ --ifm-color-primary-lighter: #2e714c;
+ --ifm-color-primary-lightest: #347f56;
+}
+
+[data-theme='dark'] {
+ /* Primary Color */
+ --ifm-color-primary: #23fbcc;
+ --ifm-color-primary-dark: #07fac5;
+ --ifm-color-primary-darker: #04efbc;
+ --ifm-color-primary-darkest: #04c59b;
+ --ifm-color-primary-light: #3ffcd3;
+ --ifm-color-primary-lighter: #4dfcd6;
+ --ifm-color-primary-lightest: #77fde0;
+
+ /* Gray Palette */
+ --color-gray-lightest: #424242;
+ --color-gray-lighter: #616161;
+ --color-gray-light: #757575;
+ --color-gray: #9e9e9e;
+ --color-gray-dark: #e0e0e0;
+ --color-gray-darker: #eee;
+ --color-gray-darkest: #f5f5f5;
+
+ /* Red Palette */
+ --color-red-lightest: #b71c1c;
+ --color-red-lighter: #d32f2f;
+ --color-red-light: #e53935;
+ --color-red: #f44336;
+ --color-red-dark: #ef9a9a;
+ --color-red-darker: #ffcdd2;
+ --color-red-darkest: #ffebee;
+
+ /* Green Palette */
+ --color-green-lightest: #1b5e20;
+ --color-green-lighter: #388e3c;
+ --color-green-light: #43a047;
+ --color-green: #4caf50;
+ --color-green-dark: #a5d6a7;
+ --color-green-darker: #c8e6c9;
+ --color-green-darkest: #e8f5e9;
+
+ /* Yellow Palette */
+ --color-yellow-lightest: #f57f17;
+ --color-yellow-lighter: #fbc02d;
+ --color-yellow-light: #fdd835;
+ --color-yellow: #ffeb3b;
+ --color-yellow-dark: #fff59d;
+ --color-yellow-darker: #fff9c4;
+ --color-yellow-darkest: #fffde7;
+
+ /* Blue Palette */
+ --color-blue-lightest: #0d47a1;
+ --color-blue-lighter: #1976d2;
+ --color-blue-light: #1e88e5;
+ --color-blue: #2196f3;
+ --color-blue-dark: #90caf9;
+ --color-blue-darker: #bbdefb;
+ --color-blue-darkest: #e3f2fd;
+}
diff --git a/src/css/custom.css b/src/css/custom.scss
similarity index 69%
rename from src/css/custom.css
rename to src/css/custom.scss
index 0be5ffa..a1a276f 100644
--- a/src/css/custom.css
+++ b/src/css/custom.scss
@@ -1,3 +1,5 @@
+@use './color';
+
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
@@ -6,26 +8,17 @@
/* You can override the default Infima variables here. */
:root {
- --ifm-color-primary: #25c2a0;
- --ifm-color-primary-dark: rgb(33, 175, 144);
- --ifm-color-primary-darker: rgb(31, 165, 136);
- --ifm-color-primary-darkest: rgb(26, 136, 112);
- --ifm-color-primary-light: rgb(70, 203, 174);
- --ifm-color-primary-lighter: rgb(102, 212, 189);
- --ifm-color-primary-lightest: rgb(146, 224, 208);
--ifm-code-font-size: 95%;
-
- --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
+ --docusaurus-highlighted-code-line-bg: rgb(var(--color-black, 0.1));
--docusaurus-error-code-line-bg: #ffccc080;
--docusaurus-good-code-line-bg: #25a38940;
-
--ifm-container-width-xl: 1520px;
}
/* If you have a different syntax highlighting theme for dark mode. */
[data-theme='dark'] {
/* Color which works with dark mode syntax highlighting theme */
- --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
+ --docusaurus-highlighted-code-line-bg: rgb(0 0 0 / 0.3);
--docusaurus-error-code-line-bg: #cc333340;
--docusaurus-good-code-line-bg: #20d8a840;
}
@@ -33,7 +26,7 @@
.theme-code-block-highlighted-line {
background-color: var(--docusaurus-highlighted-code-line-bg);
display: block;
- margin: 0 calc(var(--ifm-pre-padding)*-1);
+ margin: 0 calc(var(--ifm-pre-padding) * -1);
padding: 0 var(--ifm-pre-padding);
}
@@ -51,10 +44,10 @@
display: block;
margin: 0 calc(-1 * var(--ifm-pre-padding));
padding: 0 var(--ifm-pre-padding);
- border-left: 3px solid rgb(37, 194, 160);
+ border-left: 3px solid rgb(37 194 160);
font-weight: 600;
}
.radix-themes {
- color: var(--ifm-font-color-base);
+ color: var(--ifm-font-color-base);
}
diff --git a/static/assets/event-propagation-of-react/react-event-handle.png b/static/assets/event-propagation-of-react/react-event-handle.png
new file mode 100644
index 0000000..a32da42
Binary files /dev/null and b/static/assets/event-propagation-of-react/react-event-handle.png differ
diff --git a/stylelint.config.js b/stylelint.config.js
new file mode 100644
index 0000000..5fd729e
--- /dev/null
+++ b/stylelint.config.js
@@ -0,0 +1,45 @@
+/** @type {import('stylelint').Config} */
+module.exports = {
+ extends: [
+ 'stylelint-config-standard-scss',
+ 'stylelint-config-prettier-scss',
+ 'stylelint-prettier/recommended',
+ ],
+ rules: {
+ 'selector-class-pattern': null,
+ 'declaration-block-no-redundant-longhand-properties': null,
+ 'value-keyword-case': null,
+ 'alpha-value-notation': 'number',
+ 'no-descending-specificity': null,
+ 'custom-property-pattern': null,
+ 'function-name-case': null,
+ 'font-family-no-missing-generic-family-keyword': [
+ true,
+ {
+ ignoreFontFamilies: ['apple-system-wrapper'],
+ },
+ ],
+ 'property-no-vendor-prefix': null,
+ 'value-no-vendor-prefix': null,
+ 'scss/no-global-function-names': null,
+ 'scss/at-mixin-pattern': null,
+ 'scss/dollar-variable-pattern': null,
+ 'selector-id-pattern': null,
+ 'scss/at-function-pattern': null,
+ 'scss/percent-placeholder-pattern': null,
+ 'no-duplicate-selectors': null,
+ 'selector-pseudo-class-no-unknown': [
+ true,
+ {
+ ignorePseudoClasses: ['global', 'local'],
+ },
+ ],
+ 'media-feature-name-no-unknown': [
+ true,
+ {
+ ignoreMediaFeatureNames: ['variables'],
+ },
+ ],
+ 'media-feature-range-notation': null,
+ },
+};
diff --git a/yarn.lock b/yarn.lock
index 22a4477..d390062 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3403,6 +3403,41 @@ __metadata:
languageName: node
linkType: hard
+"@csstools/css-parser-algorithms@npm:^3.0.1":
+ version: 3.0.4
+ resolution: "@csstools/css-parser-algorithms@npm:3.0.4"
+ peerDependencies:
+ "@csstools/css-tokenizer": ^3.0.3
+ checksum: 10c0/d411f07765e14eede17bccc6bd4f90ff303694df09aabfede3fd104b2dfacfd4fe3697cd25ddad14684c850328f3f9420ebfa9f78380892492974db24ae47dbd
+ languageName: node
+ linkType: hard
+
+"@csstools/css-tokenizer@npm:^3.0.1":
+ version: 3.0.3
+ resolution: "@csstools/css-tokenizer@npm:3.0.3"
+ checksum: 10c0/c31bf410e1244b942e71798e37c54639d040cb59e0121b21712b40015fced2b0fb1ffe588434c5f8923c9cd0017cfc1c1c8f3921abc94c96edf471aac2eba5e5
+ languageName: node
+ linkType: hard
+
+"@csstools/media-query-list-parser@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "@csstools/media-query-list-parser@npm:3.0.1"
+ peerDependencies:
+ "@csstools/css-parser-algorithms": ^3.0.1
+ "@csstools/css-tokenizer": ^3.0.1
+ checksum: 10c0/fca1935cabf9fb94128da87f72c34aa2cfce8eb0beba4c78d685c7b42aaba3521067710afc6905b7347fc41fe53947536ce15a7ef3387b48763d8f7d71778d5e
+ languageName: node
+ linkType: hard
+
+"@csstools/selector-specificity@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "@csstools/selector-specificity@npm:4.0.0"
+ peerDependencies:
+ postcss-selector-parser: ^6.1.0
+ checksum: 10c0/6f4d4ecfdcd37f950100de8ffe0b4c1b1cc8c004aab2c2ebaa5c3e2bca2412d15b17d4628435f47a62d2c56db41bcbf985cb9c69e74b89964d48e421e93e75ba
+ languageName: node
+ linkType: hard
+
"@discoveryjs/json-ext@npm:0.5.7":
version: 0.5.7
resolution: "@discoveryjs/json-ext@npm:0.5.7"
@@ -4013,6 +4048,13 @@ __metadata:
languageName: node
linkType: hard
+"@dual-bundle/import-meta-resolve@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "@dual-bundle/import-meta-resolve@npm:4.1.0"
+ checksum: 10c0/55069e550ee2710e738dd8bbd34aba796cede456287454b50c3be46fbef8695d00625677f3f41f5ffbec1174c0f57f314da9a908388bc9f8ad41a8438db884d9
+ languageName: node
+ linkType: hard
+
"@emnapi/runtime@npm:^1.2.0":
version: 1.3.1
resolution: "@emnapi/runtime@npm:1.3.1"
@@ -7687,6 +7729,18 @@ __metadata:
languageName: node
linkType: hard
+"ajv@npm:^8.0.1":
+ version: 8.17.1
+ resolution: "ajv@npm:8.17.1"
+ dependencies:
+ fast-deep-equal: "npm:^3.1.3"
+ fast-uri: "npm:^3.0.1"
+ json-schema-traverse: "npm:^1.0.0"
+ require-from-string: "npm:^2.0.2"
+ checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35
+ languageName: node
+ linkType: hard
+
"algoliasearch-helper@npm:^3.13.3":
version: 3.22.5
resolution: "algoliasearch-helper@npm:3.22.5"
@@ -8167,6 +8221,13 @@ __metadata:
languageName: node
linkType: hard
+"balanced-match@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "balanced-match@npm:2.0.0"
+ checksum: 10c0/60a54e0b75a61674e16a7a336b805f06c72d6f8fc457639c24efc512ba2bf9cb5744b9f6f5225afcefb99da39714440c83c737208cc65c5d9ecd1f3093331ca3
+ languageName: node
+ linkType: hard
+
"base64-js@npm:^1.3.1":
version: 1.5.1
resolution: "base64-js@npm:1.5.1"
@@ -9231,6 +9292,23 @@ __metadata:
languageName: node
linkType: hard
+"cosmiconfig@npm:^9.0.0":
+ version: 9.0.0
+ resolution: "cosmiconfig@npm:9.0.0"
+ dependencies:
+ env-paths: "npm:^2.2.1"
+ import-fresh: "npm:^3.3.0"
+ js-yaml: "npm:^4.1.0"
+ parse-json: "npm:^5.2.0"
+ peerDependencies:
+ typescript: ">=4.9.5"
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ checksum: 10c0/1c1703be4f02a250b1d6ca3267e408ce16abfe8364193891afc94c2d5c060b69611fdc8d97af74b7e6d5d1aac0ab2fb94d6b079573146bc2d756c2484ce5f0ee
+ languageName: node
+ linkType: hard
+
"crelt@npm:^1.0.5":
version: 1.0.6
resolution: "crelt@npm:1.0.6"
@@ -9281,6 +9359,13 @@ __metadata:
languageName: node
linkType: hard
+"css-functions-list@npm:^3.2.3":
+ version: 3.2.3
+ resolution: "css-functions-list@npm:3.2.3"
+ checksum: 10c0/03f9ed34eeed310d2b1cf0e524eea02bc5f87854a4de85f8957ea432ab1036841a3fb00879590519f7bb8fda40d992ce7a72fa9b61696ca1dc53b90064858f96
+ languageName: node
+ linkType: hard
+
"css-loader@npm:^6.8.1":
version: 6.11.0
resolution: "css-loader@npm:6.11.0"
@@ -9381,6 +9466,16 @@ __metadata:
languageName: node
linkType: hard
+"css-tree@npm:^3.0.0, css-tree@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "css-tree@npm:3.0.1"
+ dependencies:
+ mdn-data: "npm:2.12.1"
+ source-map-js: "npm:^1.0.1"
+ checksum: 10c0/9f117f3067e68e9edb0b3db0134f420db1a62bede3e84d8835767ecfaa6f8ced5e87989cf39b65ffe65d788c134c8ea9abd7393d7c35838a9da84326adf57a9b
+ languageName: node
+ linkType: hard
+
"css-tree@npm:~2.2.0":
version: 2.2.1
resolution: "css-tree@npm:2.2.1"
@@ -10479,7 +10574,7 @@ __metadata:
languageName: node
linkType: hard
-"env-paths@npm:^2.2.0":
+"env-paths@npm:^2.2.0, env-paths@npm:^2.2.1":
version: 2.2.1
resolution: "env-paths@npm:2.2.1"
checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4
@@ -11231,6 +11326,13 @@ __metadata:
languageName: node
linkType: hard
+"fast-diff@npm:^1.1.2":
+ version: 1.3.0
+ resolution: "fast-diff@npm:1.3.0"
+ checksum: 10c0/5c19af237edb5d5effda008c891a18a585f74bf12953be57923f17a3a4d0979565fc64dbc73b9e20926b9d895f5b690c618cbb969af0cf022e3222471220ad29
+ languageName: node
+ linkType: hard
+
"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0":
version: 3.3.1
resolution: "fast-glob@npm:3.3.1"
@@ -11271,6 +11373,20 @@ __metadata:
languageName: node
linkType: hard
+"fast-uri@npm:^3.0.1":
+ version: 3.0.3
+ resolution: "fast-uri@npm:3.0.3"
+ checksum: 10c0/4b2c5ce681a062425eae4f15cdc8fc151fd310b2f69b1f96680677820a8b49c3cd6e80661a406e19d50f0c40a3f8bffdd458791baf66f4a879d80be28e10a320
+ languageName: node
+ linkType: hard
+
+"fastest-levenshtein@npm:^1.0.16":
+ version: 1.0.16
+ resolution: "fastest-levenshtein@npm:1.0.16"
+ checksum: 10c0/7e3d8ae812a7f4fdf8cad18e9cde436a39addf266a5986f653ea0d81e0de0900f50c0f27c6d5aff3f686bcb48acbd45be115ae2216f36a6a13a7dbbf5cad878b
+ languageName: node
+ linkType: hard
+
"fastq@npm:^1.6.0":
version: 1.15.0
resolution: "fastq@npm:1.15.0"
@@ -11316,6 +11432,15 @@ __metadata:
languageName: node
linkType: hard
+"file-entry-cache@npm:^9.1.0":
+ version: 9.1.0
+ resolution: "file-entry-cache@npm:9.1.0"
+ dependencies:
+ flat-cache: "npm:^5.0.0"
+ checksum: 10c0/4b4dbc1e972f50202b1a4430d30fd99378ef6e2a64857176abdc65c5e4730a948fb37e274478520a7bacbc70f3abba455a4b9d2c1915c53f30d11dc85d3fef5e
+ languageName: node
+ linkType: hard
+
"file-loader@npm:^6.2.0":
version: 6.2.0
resolution: "file-loader@npm:6.2.0"
@@ -11426,6 +11551,16 @@ __metadata:
languageName: node
linkType: hard
+"flat-cache@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "flat-cache@npm:5.0.0"
+ dependencies:
+ flatted: "npm:^3.3.1"
+ keyv: "npm:^4.5.4"
+ checksum: 10c0/847f25eefec5d6614fdce76dc6097ee98f63fd4dfbcb908718905ac56610f939f4c28b1f908d6e8857d49286fe73235095d2e7ac9df096c35a3e8a15204c361b
+ languageName: node
+ linkType: hard
+
"flat@npm:^5.0.2":
version: 5.0.2
resolution: "flat@npm:5.0.2"
@@ -11442,6 +11577,13 @@ __metadata:
languageName: node
linkType: hard
+"flatted@npm:^3.3.1":
+ version: 3.3.1
+ resolution: "flatted@npm:3.3.1"
+ checksum: 10c0/324166b125ee07d4ca9bcf3a5f98d915d5db4f39d711fba640a3178b959919aae1f7cfd8aabcfef5826ed8aa8a2aa14cc85b2d7d18ff638ddf4ae3df39573eaf
+ languageName: node
+ linkType: hard
+
"follow-redirects@npm:^1.0.0":
version: 1.15.2
resolution: "follow-redirects@npm:1.15.2"
@@ -11874,6 +12016,13 @@ __metadata:
languageName: node
linkType: hard
+"globjoin@npm:^0.1.4":
+ version: 0.1.4
+ resolution: "globjoin@npm:0.1.4"
+ checksum: 10c0/236e991b48f1a9869fe2aa7bb5141fb1f32973940567a3c012f8ccb58c3c85ab78ce594d374fa819410fff3b48cfd24584d7ef726939f8a3c3772890e62ea16b
+ languageName: node
+ linkType: hard
+
"gopd@npm:^1.0.1":
version: 1.0.1
resolution: "gopd@npm:1.0.1"
@@ -12486,6 +12635,10 @@ __metadata:
react-dom: "npm:^18.2.0"
sass: "npm:^1.80.5"
styled-components: "npm:^6.0.7"
+ stylelint: "npm:^16.10.0"
+ stylelint-config-prettier-scss: "npm:^1.0.0"
+ stylelint-config-standard-scss: "npm:^13.1.0"
+ stylelint-prettier: "npm:^5.0.2"
typescript: "npm:^5.6.3"
url-loader: "npm:^4.1.1"
languageName: unknown
@@ -12539,6 +12692,13 @@ __metadata:
languageName: node
linkType: hard
+"ignore@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "ignore@npm:6.0.2"
+ checksum: 10c0/9a38feac1861906a78ba0f03e8ef3cd6b0526dce2a1a84e1009324b557763afeb9c3ebcc04666b21f7bbf71adda45e76781bb9e2eaa0903d45dcaded634454f5
+ languageName: node
+ linkType: hard
+
"image-size@npm:^1.0.2":
version: 1.1.1
resolution: "image-size@npm:1.1.1"
@@ -13037,6 +13197,13 @@ __metadata:
languageName: node
linkType: hard
+"is-plain-object@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "is-plain-object@npm:5.0.0"
+ checksum: 10c0/893e42bad832aae3511c71fd61c0bf61aa3a6d853061c62a307261842727d0d25f761ce9379f7ba7226d6179db2a3157efa918e7fe26360f3bf0842d9f28942c
+ languageName: node
+ linkType: hard
+
"is-regex@npm:^1.1.4":
version: 1.1.4
resolution: "is-regex@npm:1.1.4"
@@ -13454,7 +13621,7 @@ __metadata:
languageName: node
linkType: hard
-"keyv@npm:^4.5.3":
+"keyv@npm:^4.5.3, keyv@npm:^4.5.4":
version: 4.5.4
resolution: "keyv@npm:4.5.4"
dependencies:
@@ -13498,6 +13665,20 @@ __metadata:
languageName: node
linkType: hard
+"known-css-properties@npm:^0.34.0":
+ version: 0.34.0
+ resolution: "known-css-properties@npm:0.34.0"
+ checksum: 10c0/8549969f02b1858554e89faf4548ece37625d0d21b42e8d54fa53184e68e1512ef2531bb15941575ad816361ab7447b598c1b18c1b96ce0a868333d1a68f2e2c
+ languageName: node
+ linkType: hard
+
+"known-css-properties@npm:^0.35.0":
+ version: 0.35.0
+ resolution: "known-css-properties@npm:0.35.0"
+ checksum: 10c0/04a4a2859d62670bb25b5b28091a1f03f6f0d3298a5ed3e7476397c5287b98c434f6dd9c004a0c67a53b7f21acc93f83c972e98c122f568d4d0bd21fd2b90fb6
+ languageName: node
+ linkType: hard
+
"ky@npm:^1.2.0":
version: 1.7.2
resolution: "ky@npm:1.7.2"
@@ -13733,6 +13914,13 @@ __metadata:
languageName: node
linkType: hard
+"lodash.truncate@npm:^4.4.2":
+ version: 4.4.2
+ resolution: "lodash.truncate@npm:4.4.2"
+ checksum: 10c0/4e870d54e8a6c86c8687e057cec4069d2e941446ccab7f40b4d9555fa5872d917d0b6aa73bece7765500a3123f1723bcdba9ae881b679ef120bba9e1a0b0ed70
+ languageName: node
+ linkType: hard
+
"lodash.uniq@npm:^4.5.0":
version: 4.5.0
resolution: "lodash.uniq@npm:4.5.0"
@@ -13899,6 +14087,13 @@ __metadata:
languageName: node
linkType: hard
+"mathml-tag-names@npm:^2.1.3":
+ version: 2.1.3
+ resolution: "mathml-tag-names@npm:2.1.3"
+ checksum: 10c0/e2b094658a2618433efd2678a5a3e551645e09ba17c7c777783cd8dfa0178b0195fda0a5c46a6be5e778923662cf8dde891c894c869ff14fbb4ea3208c31bc4d
+ languageName: node
+ linkType: hard
+
"mdast-util-directive@npm:^3.0.0":
version: 3.0.0
resolution: "mdast-util-directive@npm:3.0.0"
@@ -14194,6 +14389,20 @@ __metadata:
languageName: node
linkType: hard
+"mdn-data@npm:2.12.1":
+ version: 2.12.1
+ resolution: "mdn-data@npm:2.12.1"
+ checksum: 10c0/1a09f441bdd423f2b0ab712665a1a3329fe7b15e9a2dad8c1c10c521ddb204ed186e7ac91052fd53a5ae0a07ac6eae53b5bcbb59ba8a1fb654268611297eea4a
+ languageName: node
+ linkType: hard
+
+"mdn-data@npm:^2.12.2":
+ version: 2.12.2
+ resolution: "mdn-data@npm:2.12.2"
+ checksum: 10c0/b22443b71d70f72ccc3c6ba1608035431a8fc18c3c8fc53523f06d20e05c2ac10f9b53092759a2ca85cf02f0d37036f310b581ce03e7b99ac74d388ef8152ade
+ languageName: node
+ linkType: hard
+
"media-typer@npm:0.3.0":
version: 0.3.0
resolution: "media-typer@npm:0.3.0"
@@ -14210,6 +14419,13 @@ __metadata:
languageName: node
linkType: hard
+"meow@npm:^13.2.0":
+ version: 13.2.0
+ resolution: "meow@npm:13.2.0"
+ checksum: 10c0/d5b339ae314715bcd0b619dd2f8a266891928e21526b4800d49b4fba1cc3fff7e2c1ff5edd3344149fac841bc2306157f858e8c4d5eaee4d52ce52ad925664ce
+ languageName: node
+ linkType: hard
+
"merge-descriptors@npm:1.0.1":
version: 1.0.1
resolution: "merge-descriptors@npm:1.0.1"
@@ -14968,7 +15184,7 @@ __metadata:
languageName: node
linkType: hard
-"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5":
+"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5, micromatch@npm:^4.0.8":
version: 4.0.8
resolution: "micromatch@npm:4.0.8"
dependencies:
@@ -16002,7 +16218,7 @@ __metadata:
languageName: node
linkType: hard
-"picocolors@npm:^1.0.1, picocolors@npm:^1.1.0":
+"picocolors@npm:^1.0.1, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1":
version: 1.1.1
resolution: "picocolors@npm:1.1.1"
checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
@@ -16180,6 +16396,13 @@ __metadata:
languageName: node
linkType: hard
+"postcss-media-query-parser@npm:^0.2.3":
+ version: 0.2.3
+ resolution: "postcss-media-query-parser@npm:0.2.3"
+ checksum: 10c0/252c8cf24f0e9018516b0d70b7b3d6f5b52e81c4bab2164b49a4e4c1b87bb11f5dbe708c0076990665cb24c70d5fd2f3aee9c922b0f67c7c619e051801484688
+ languageName: node
+ linkType: hard
+
"postcss-merge-idents@npm:^6.0.3":
version: 6.0.3
resolution: "postcss-merge-idents@npm:6.0.3"
@@ -16454,7 +16677,32 @@ __metadata:
languageName: node
linkType: hard
-"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.16":
+"postcss-resolve-nested-selector@npm:^0.1.6":
+ version: 0.1.6
+ resolution: "postcss-resolve-nested-selector@npm:0.1.6"
+ checksum: 10c0/84213a2bccce481b1569c595a3c547b25c6ef1cca839fbd6c82c12ab407559966e968613c7454b573aa54f38cfd7e900c1fd603f0efc9f51939ab9f93f115455
+ languageName: node
+ linkType: hard
+
+"postcss-safe-parser@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "postcss-safe-parser@npm:7.0.1"
+ peerDependencies:
+ postcss: ^8.4.31
+ checksum: 10c0/6957b10b818bd8d4664ec0e548af967f7549abedfb37f844d389571d36af681340f41f9477b9ccf34bcc7599bdef222d1d72e79c64373001fae77089fba6d965
+ languageName: node
+ linkType: hard
+
+"postcss-scss@npm:^4.0.9":
+ version: 4.0.9
+ resolution: "postcss-scss@npm:4.0.9"
+ peerDependencies:
+ postcss: ^8.4.29
+ checksum: 10c0/f917ecfd4b9113a6648e966a41f027ff7e14238393914978d44596e227a50f084667dc8818742348dc7d8b20130b30d4259aca1d4db86754a9c141202ae03714
+ languageName: node
+ linkType: hard
+
+"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.16, postcss-selector-parser@npm:^6.1.2":
version: 6.1.2
resolution: "postcss-selector-parser@npm:6.1.2"
dependencies:
@@ -16557,6 +16805,17 @@ __metadata:
languageName: node
linkType: hard
+"postcss@npm:^8.4.47":
+ version: 8.4.49
+ resolution: "postcss@npm:8.4.49"
+ dependencies:
+ nanoid: "npm:^3.3.7"
+ picocolors: "npm:^1.1.1"
+ source-map-js: "npm:^1.2.1"
+ checksum: 10c0/f1b3f17aaf36d136f59ec373459f18129908235e65dbdc3aee5eef8eba0756106f52de5ec4682e29a2eab53eb25170e7e871b3e4b52a8f1de3d344a514306be3
+ languageName: node
+ linkType: hard
+
"prelude-ls@npm:^1.2.1":
version: 1.2.1
resolution: "prelude-ls@npm:1.2.1"
@@ -16564,6 +16823,15 @@ __metadata:
languageName: node
linkType: hard
+"prettier-linter-helpers@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "prettier-linter-helpers@npm:1.0.0"
+ dependencies:
+ fast-diff: "npm:^1.1.2"
+ checksum: 10c0/81e0027d731b7b3697ccd2129470ed9913ecb111e4ec175a12f0fcfab0096516373bf0af2fef132af50cafb0a905b74ff57996d615f59512bb9ac7378fcc64ab
+ languageName: node
+ linkType: hard
+
"prettier@npm:^3.0.1":
version: 3.0.1
resolution: "prettier@npm:3.0.1"
@@ -17490,6 +17758,13 @@ __metadata:
languageName: node
linkType: hard
+"resolve-from@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "resolve-from@npm:5.0.0"
+ checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2
+ languageName: node
+ linkType: hard
+
"resolve-pathname@npm:^3.0.0":
version: 3.0.0
resolution: "resolve-pathname@npm:3.0.0"
@@ -18495,7 +18770,7 @@ __metadata:
languageName: node
linkType: hard
-"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0":
+"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3":
version: 4.2.3
resolution: "string-width@npm:4.2.3"
dependencies:
@@ -18761,6 +19036,149 @@ __metadata:
languageName: node
linkType: hard
+"stylelint-config-prettier-scss@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "stylelint-config-prettier-scss@npm:1.0.0"
+ peerDependencies:
+ stylelint: ">=15.0.0"
+ bin:
+ stylelint-config-prettier-scss: bin/check.js
+ stylelint-config-prettier-scss-check: bin/check.js
+ checksum: 10c0/4d5e1d1c200d4611b5b7bd2d2528cc9e301f26645802a2774aec192c4c2949cbf5a0147eba8b2e6e4ff14a071b03024f3034bb1b4fda37a8ed5a0081a9597d4d
+ languageName: node
+ linkType: hard
+
+"stylelint-config-recommended-scss@npm:^14.0.0":
+ version: 14.1.0
+ resolution: "stylelint-config-recommended-scss@npm:14.1.0"
+ dependencies:
+ postcss-scss: "npm:^4.0.9"
+ stylelint-config-recommended: "npm:^14.0.1"
+ stylelint-scss: "npm:^6.4.0"
+ peerDependencies:
+ postcss: ^8.3.3
+ stylelint: ^16.6.1
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ checksum: 10c0/0a1c1bb6d9f7a21acea82e12fee1b36a195181ae1dd0d8b59145a56f76232a80d5b706269bc4ca4929680d36f10371bd8a7d0aeeee468fa9119a3b56410b052f
+ languageName: node
+ linkType: hard
+
+"stylelint-config-recommended@npm:^14.0.1":
+ version: 14.0.1
+ resolution: "stylelint-config-recommended@npm:14.0.1"
+ peerDependencies:
+ stylelint: ^16.1.0
+ checksum: 10c0/a0a0ecd91f4d193bbe2cc3408228f8a2d8fcb2b2578d77233f86780c9247c796a04e16aad7a91d97cb918e2de34b6a8062bab66ee017c3835d855081d94f4828
+ languageName: node
+ linkType: hard
+
+"stylelint-config-standard-scss@npm:^13.1.0":
+ version: 13.1.0
+ resolution: "stylelint-config-standard-scss@npm:13.1.0"
+ dependencies:
+ stylelint-config-recommended-scss: "npm:^14.0.0"
+ stylelint-config-standard: "npm:^36.0.0"
+ peerDependencies:
+ postcss: ^8.3.3
+ stylelint: ^16.3.1
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ checksum: 10c0/d07cae806ee8b3e77684f019a8b22cc32642373da8053e6ae7ed716f8ddbe6ea1f7323633a6a1bbc9aa08c6a3dceb1dcf053d83fdd10d076b5a01da6e86801ae
+ languageName: node
+ linkType: hard
+
+"stylelint-config-standard@npm:^36.0.0":
+ version: 36.0.1
+ resolution: "stylelint-config-standard@npm:36.0.1"
+ dependencies:
+ stylelint-config-recommended: "npm:^14.0.1"
+ peerDependencies:
+ stylelint: ^16.1.0
+ checksum: 10c0/7f9b954694358e77be5110418f31335be579ce59dd952bc3c6a9449265297db3170ec520e0905769253b48b99c3109a95c71f5b985bf402e48fd6c89b5364cb2
+ languageName: node
+ linkType: hard
+
+"stylelint-prettier@npm:^5.0.2":
+ version: 5.0.2
+ resolution: "stylelint-prettier@npm:5.0.2"
+ dependencies:
+ prettier-linter-helpers: "npm:^1.0.0"
+ peerDependencies:
+ prettier: ">=3.0.0"
+ stylelint: ">=16.0.0"
+ checksum: 10c0/4755471cd8c8f3d308b25c3ad5db9eb1546dea6f6ba048ca0b83e9ca58169d29456deb50cfa13198a7f7178f9b7e64fddcbb7d0dd0c59669680f5bc6432c438b
+ languageName: node
+ linkType: hard
+
+"stylelint-scss@npm:^6.4.0":
+ version: 6.9.0
+ resolution: "stylelint-scss@npm:6.9.0"
+ dependencies:
+ css-tree: "npm:^3.0.1"
+ is-plain-object: "npm:^5.0.0"
+ known-css-properties: "npm:^0.35.0"
+ mdn-data: "npm:^2.12.2"
+ postcss-media-query-parser: "npm:^0.2.3"
+ postcss-resolve-nested-selector: "npm:^0.1.6"
+ postcss-selector-parser: "npm:^6.1.2"
+ postcss-value-parser: "npm:^4.2.0"
+ peerDependencies:
+ stylelint: ^16.0.2
+ checksum: 10c0/2b0a882589b2be252e730b933e0b9839a7734cd0c5fae8255511835d3d0c5eede171e750dc8ec35229f22a0a3f6e46279adb9dd655544e2fbed1f9fc25bf470a
+ languageName: node
+ linkType: hard
+
+"stylelint@npm:^16.10.0":
+ version: 16.10.0
+ resolution: "stylelint@npm:16.10.0"
+ dependencies:
+ "@csstools/css-parser-algorithms": "npm:^3.0.1"
+ "@csstools/css-tokenizer": "npm:^3.0.1"
+ "@csstools/media-query-list-parser": "npm:^3.0.1"
+ "@csstools/selector-specificity": "npm:^4.0.0"
+ "@dual-bundle/import-meta-resolve": "npm:^4.1.0"
+ balanced-match: "npm:^2.0.0"
+ colord: "npm:^2.9.3"
+ cosmiconfig: "npm:^9.0.0"
+ css-functions-list: "npm:^3.2.3"
+ css-tree: "npm:^3.0.0"
+ debug: "npm:^4.3.7"
+ fast-glob: "npm:^3.3.2"
+ fastest-levenshtein: "npm:^1.0.16"
+ file-entry-cache: "npm:^9.1.0"
+ global-modules: "npm:^2.0.0"
+ globby: "npm:^11.1.0"
+ globjoin: "npm:^0.1.4"
+ html-tags: "npm:^3.3.1"
+ ignore: "npm:^6.0.2"
+ imurmurhash: "npm:^0.1.4"
+ is-plain-object: "npm:^5.0.0"
+ known-css-properties: "npm:^0.34.0"
+ mathml-tag-names: "npm:^2.1.3"
+ meow: "npm:^13.2.0"
+ micromatch: "npm:^4.0.8"
+ normalize-path: "npm:^3.0.0"
+ picocolors: "npm:^1.0.1"
+ postcss: "npm:^8.4.47"
+ postcss-resolve-nested-selector: "npm:^0.1.6"
+ postcss-safe-parser: "npm:^7.0.1"
+ postcss-selector-parser: "npm:^6.1.2"
+ postcss-value-parser: "npm:^4.2.0"
+ resolve-from: "npm:^5.0.0"
+ string-width: "npm:^4.2.3"
+ supports-hyperlinks: "npm:^3.1.0"
+ svg-tags: "npm:^1.0.0"
+ table: "npm:^6.8.2"
+ write-file-atomic: "npm:^5.0.1"
+ bin:
+ stylelint: bin/stylelint.mjs
+ checksum: 10c0/d07dd156c225d16c740995daacd78090f7fc317602e87bda2fca323a4ae427a8526d724f3089df3b2185df4520f987547668ceea9b30985988ccbc514034aa21
+ languageName: node
+ linkType: hard
+
"stylis@npm:^4.1.3":
version: 4.3.4
resolution: "stylis@npm:4.3.4"
@@ -18784,7 +19202,7 @@ __metadata:
languageName: node
linkType: hard
-"supports-color@npm:^7.1.0":
+"supports-color@npm:^7.0.0, supports-color@npm:^7.1.0":
version: 7.2.0
resolution: "supports-color@npm:7.2.0"
dependencies:
@@ -18802,6 +19220,16 @@ __metadata:
languageName: node
linkType: hard
+"supports-hyperlinks@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "supports-hyperlinks@npm:3.1.0"
+ dependencies:
+ has-flag: "npm:^4.0.0"
+ supports-color: "npm:^7.0.0"
+ checksum: 10c0/78cc3e17eb27e6846fa355a8ebf343befe36272899cd409e45317a06c1997e95c23ff99d91080a517bd8c96508d4fa456e6ceb338c02ba5d7544277dbec0f10f
+ languageName: node
+ linkType: hard
+
"supports-preserve-symlinks-flag@npm:^1.0.0":
version: 1.0.0
resolution: "supports-preserve-symlinks-flag@npm:1.0.0"
@@ -18816,6 +19244,13 @@ __metadata:
languageName: node
linkType: hard
+"svg-tags@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "svg-tags@npm:1.0.0"
+ checksum: 10c0/5867e29e8f431bf7aecf5a244d1af5725f80a1086187dbc78f26d8433b5e96b8fe9361aeb10d1699ff483b9afec785a10916b9312fe9d734d1a7afd48226c954
+ languageName: node
+ linkType: hard
+
"svgo@npm:^3.0.2":
version: 3.0.2
resolution: "svgo@npm:3.0.2"
@@ -18849,6 +19284,19 @@ __metadata:
languageName: node
linkType: hard
+"table@npm:^6.8.2":
+ version: 6.8.2
+ resolution: "table@npm:6.8.2"
+ dependencies:
+ ajv: "npm:^8.0.1"
+ lodash.truncate: "npm:^4.4.2"
+ slice-ansi: "npm:^4.0.0"
+ string-width: "npm:^4.2.3"
+ strip-ansi: "npm:^6.0.1"
+ checksum: 10c0/f8b348af38ee34e419d8ce7306ba00671ce6f20e861ccff22555f491ba264e8416086063ce278a8d81abfa8d23b736ec2cca7ac4029b5472f63daa4b4688b803
+ languageName: node
+ linkType: hard
+
"tapable@npm:^1.0.0":
version: 1.1.3
resolution: "tapable@npm:1.1.3"
@@ -20253,6 +20701,16 @@ __metadata:
languageName: node
linkType: hard
+"write-file-atomic@npm:^5.0.1":
+ version: 5.0.1
+ resolution: "write-file-atomic@npm:5.0.1"
+ dependencies:
+ imurmurhash: "npm:^0.1.4"
+ signal-exit: "npm:^4.0.1"
+ checksum: 10c0/e8c850a8e3e74eeadadb8ad23c9d9d63e4e792bd10f4836ed74189ef6e996763959f1249c5650e232f3c77c11169d239cbfc8342fc70f3fe401407d23810505d
+ languageName: node
+ linkType: hard
+
"ws@npm:^7.3.1":
version: 7.5.10
resolution: "ws@npm:7.5.10"