Skip to content

Commit 697a4bb

Browse files
committed
refactor!: Implement global state and methods to replace Alpine.js store
BREAKING CHANGE: After a team discussion about Alpine.js implementation, I realized is possible to use global state and methods to achieve the same result as with Alpine.js store --without any warnings in local testing PS.: I'll preserve previus commit with store implementation: maybe it could be useful in the future
1 parent e1d7348 commit 697a4bb

File tree

2 files changed

+39
-56
lines changed

2 files changed

+39
-56
lines changed

src/components/Accordion.astro

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,17 @@ const { title, description, id, last } = Astro.props;
55
<!--
66
Child component: Alpine.js logic
77
8-
1. Each child observes the `activeId` state from the `faqs` store by using the reactive `visible` property.
9-
2. When clicking on a child component, the global `activeId` state in the store is updated:
10-
- If accordion is open (in child: `visible` === `true`), it sets `activeId` to `null` and closes.
11-
- If accordion is closed (in child: `visible` === `false`), it replaces the `activeId` value with its own `id` value and opens.
12-
3. When `activeId` changes, the child's classes related to its visibility are automatically updated.
8+
1. Each accordion receives a unique `id` that identifies it.
9+
2. When clicking on an accordion:
10+
2.1 The `toggle(id)` method defined in the parent component is called.
11+
2.2 The global state `activeId` is updated with the new ID.
12+
3. Each accordion checks if its ID matches `activeId` using the `isVisible` method:
13+
- If it matches, the accordion expands (`isVisible` is `true`).
14+
- If it doesn't match, it remains collapsed (`isVisible` is `false`).
1315
1416
This way, each child component can respond reactively to the `activeId` global state.
1517
-->
16-
<div
17-
x-data=`{
18-
get visible() {
19-
return Alpine.store && Alpine.store('faqs')?.isVisible(${id});
20-
},
21-
22-
toggle(id){
23-
if ($store.faqs.activeId === id) {
24-
$store.faqs.setActiveId(null);
25-
} else {
26-
$store.faqs.setActiveId(id);
27-
};
28-
29-
}
30-
}`
31-
18+
<div
3219
class:list={[
3320
"bg-white py-6 accordion-transition overflow-hidden",
3421
{"border-b-0": last === id},
@@ -38,15 +25,15 @@ This way, each child component can respond reactively to the `activeId` global s
3825
<div
3926
@click=`toggle(${id})`
4027
class="flex flex-row items-center text-lg font-semibold cursor-pointer"
41-
:class="visible && 'text-blue-500'"
28+
:class=`isVisible(${id}) && 'text-blue-500'`
4229
>
4330
<div class="w-[95%] px-4">
4431
{title}
4532
</div>
4633
<div
4734
x-transition
4835
class="w-fit"
49-
:class="visible ? 'transform rotate-180 accordion-transition' : 'transform rotate-0 accordion-transition'"
36+
:class=`isVisible(${id}) ? 'transform rotate-180 accordion-transition' : 'transform rotate-0 accordion-transition'`
5037
>
5138
<Fragment set:html={downIcon} />
5239
</div>
@@ -55,7 +42,7 @@ This way, each child component can respond reactively to the `activeId` global s
5542
<div
5643
x-transition
5744
class="accordion-transition overflow-hidden"
58-
:class="visible ? 'max-h-72 opacity-100' : 'max-h-0 opacity-0'"
45+
:class=`isVisible(${id}) ? 'max-h-72 opacity-100' : 'max-h-0 opacity-0'`
5946
>
6047
<p class="w-[90%] text-gray-600 text-base mt-2 px-4 overflow-hidden">
6148
{description}

src/components/Faq.astro

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,37 @@ import Accordion from "./Accordion.astro";
66
77
Father component: Alpine.js logic
88
9-
1. The global store `faqs` manages the `activeId` state, which represents the ID of the last accordion opened by the user.
10-
2. Each child component observes the `activeId` state using the store's `isVisible` function.
11-
3. When the user clicks a child component, the store's `activeId` is updated, and this change automatically propagates to all children.
12-
4. Every child checks if the new active ID matches its own, and opens or closes accordingly.
9+
1. `activeId` is a global state that stores the ID of the last accordion opened by the user.
10+
2. When clicking on a child component (an accordion), the `toggle` method updates the `activeId`:
11+
- If the clicked accordion's ID matches the current `activeId`, it collapses (resets to `null`).
12+
- If it's different, the new ID is set as `activeId`.
13+
3. Every accordion checks if its ID matches `activeId` by using the `isVisible` method. This way, accordion opens or closes.
1314
14-
This ensures that only one accordion is open at a time.
15+
This ensures only one accordion is open at a time.
1516
1617
-->
17-
<section class="py-16 bg-white">
18+
<section
19+
x-data="{
20+
activeId: null,
21+
22+
setActiveId(id) {
23+
this.activeId = id;
24+
},
25+
26+
isVisible(id) {
27+
return this.activeId === id;
28+
},
29+
30+
toggle(id){
31+
if (this.activeId === id) {
32+
this.setActiveId(null)
33+
} else {
34+
this.setActiveId(id)
35+
};
36+
}
37+
}"
38+
39+
class="py-16 bg-white">
1840
<div class="container mx-auto px-4">
1941
<h2 class="text-3xl font-bold text-center mb-12">Preguntas frecuentes</h2>
2042
<div
@@ -32,29 +54,3 @@ This ensures that only one accordion is open at a time.
3254
</div>
3355
</div>
3456
</section>
35-
36-
<!-- Client side rendering -->
37-
<script>
38-
import Alpine from "alpinejs";
39-
40-
interface FaqStore {
41-
activeId: number | null;
42-
setActiveId(id: number | null): void;
43-
isVisible(id:number | null): boolean
44-
}
45-
46-
Alpine.store('faqs', {
47-
activeId: null,
48-
49-
setActiveId(id:number | null) {
50-
this.activeId = id;
51-
},
52-
53-
isVisible(id:number) {
54-
return this.activeId === id;
55-
},
56-
57-
} as FaqStore)
58-
59-
Alpine.start()
60-
</script>

0 commit comments

Comments
 (0)