Skip to content

Commit 7232a89

Browse files
committed
feat: refactored vue sdk into same format as react
1 parent 2c0d54f commit 7232a89

14 files changed

Lines changed: 430 additions & 284 deletions

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
"[typescriptreact]": {
2121
"editor.defaultFormatter": "esbenp.prettier-vscode"
2222
},
23+
"[vue]": {
24+
"editor.defaultFormatter": "esbenp.prettier-vscode"
25+
},
2326
"[yaml]": {
2427
"editor.defaultFormatter": "esbenp.prettier-vscode"
2528
},

packages/vue-sdk/README.md

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ If using Nuxt, wrap `<ReflagProvider>` in `<ClientOnly>`. `<ReflagProvider>` onl
6666
<script setup lang="ts">
6767
import { useFlag } from "@reflag/vue-sdk";
6868
69-
const { isEnabled } = useFlag("huddle");
69+
const { isEnabled } = useFlag("huddles");
7070
</script>
7171
7272
<template>
7373
<div v-if="isEnabled">
74-
<button>Start huddle!</button>
74+
<button>Start huddles!</button>
7575
</div>
7676
</template>
7777
```
@@ -169,7 +169,7 @@ ReflagProvider lets you define a template to be shown while ReflagProvider is in
169169
:company="{ id: 'acme_inc', plan: 'pro' }"
170170
>
171171
<template #loading>Loading...</template>
172-
<StartHuddleButton />
172+
<StartHuddlesButton />
173173
</ReflagProvider>
174174
</template>
175175
```
@@ -193,7 +193,7 @@ const bootstrappedFlags = {
193193
company: { id: "company456", name: "Acme Inc", plan: "enterprise" },
194194
},
195195
flags: {
196-
huddle: {
196+
huddles: {
197197
isEnabled: true,
198198
config: {
199199
key: "enhanced",
@@ -209,7 +209,7 @@ const bootstrappedFlags = {
209209
:publishable-key="publishableKey"
210210
:flags="bootstrappedFlags"
211211
>
212-
<StartHuddleButton />
212+
<StartHuddlesButton />
213213
</ReflagBootstrappedProvider>
214214
</template>
215215
```
@@ -271,14 +271,14 @@ Example:
271271
<script setup lang="ts">
272272
import { useFlag } from "@reflag/vue-sdk";
273273
274-
const { isEnabled, track, requestFeedback, config } = useFlag("huddle");
274+
const { isEnabled, track, requestFeedback, config } = useFlag("huddles");
275275
</script>
276276
277277
<template>
278278
<div v-if="isLoading">Loading...</div>
279279
<div v-else-if="!isEnabled">Flag not available</div>
280280
<div v-else>
281-
<button @click="track()">Start huddle!</button>
281+
<button @click="track()">Start huddles!</button>
282282
<button
283283
@click="
284284
(e) =>
@@ -316,8 +316,8 @@ const track = useTrack();
316316
317317
<template>
318318
<div>
319-
<button @click="track('Huddle Started', { huddleType: 'voice' })">
320-
Start voice huddle!
319+
<button @click="track('Huddles Started', { huddlesType: 'voice' })">
320+
Start voice huddles!
321321
</button>
322322
</div>
323323
</template>
@@ -344,7 +344,7 @@ const requestFeedback = useRequestFeedback();
344344
@click="
345345
(e) =>
346346
requestFeedback({
347-
flagKey: 'huddle-flag',
347+
flagKey: 'huddles',
348348
title: 'How satisfied are you with file uploads?',
349349
position: {
350350
type: 'POPOVER',
@@ -452,10 +452,41 @@ import { onMounted } from "vue";
452452
453453
const client = useClient();
454454
455-
onMounted(() => {
456-
client.value.on("check", (evt) => {
457-
console.log(`The flag ${evt.key} is ${evt.value} for user.`);
458-
});
455+
console.log(client.getContext());
456+
</script>
457+
458+
<template>
459+
<!-- your component content -->
460+
</template>
461+
```
462+
463+
### `useClientEvent()`
464+
465+
Vue composable for listening to Reflag client events. This composable automatically handles mounting and unmounting of event listeners.
466+
467+
Available events include:
468+
469+
- `flagsUpdated`: Triggered when flags are updated
470+
- `track`: Triggered when tracking events are sent
471+
- `feedback`: Triggered when feedback is sent
472+
473+
```vue
474+
<script setup lang="ts">
475+
import { useClientEvent } from "@reflag/vue-sdk";
476+
477+
// Listen to flag updates
478+
useClientEvent("flagsUpdated", () => {
479+
console.log("Flags have been updated");
480+
});
481+
482+
// Listen to tracking events
483+
useClientEvent("track", (event) => {
484+
console.log("Tracking event:", event);
485+
});
486+
487+
// Listen to feedback events
488+
useClientEvent("feedback", (event) => {
489+
console.log("Feedback event:", event);
459490
});
460491
</script>
461492
@@ -464,6 +495,28 @@ onMounted(() => {
464495
</template>
465496
```
466497

498+
You can also provide a specific client instance if needed:
499+
500+
```vue
501+
<script setup lang="ts">
502+
import { ReflagClient } from "@reflag/browser-sdk";
503+
504+
const myReflagClient = new ReflagClient();
505+
506+
useClientEvent(
507+
"flagsUpdated",
508+
() => {
509+
console.log("flags updated");
510+
},
511+
myReflagClient,
512+
);
513+
</script>
514+
515+
<template>
516+
<!-- your component content -->
517+
</template>
518+
```
519+
467520
### `useIsLoading()`
468521

469522
Returns a `Ref<boolean>` to indicate if Reflag has finished loading.

packages/vue-sdk/dev/plain/App.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import FlagsList from "./components/FlagsList.vue";
88
import MissingKeyMessage from "./components/MissingKeyMessage.vue";
99
import RequestFeedback from "./components/RequestFeedback.vue";
1010
import Section from "./components/Section.vue";
11-
import StartHuddleButton from "./components/StartHuddleButton.vue";
11+
import StartHuddlesButton from "./components/StartHuddlesButton.vue";
1212
import Track from "./components/Track.vue";
1313
1414
// Initial context
@@ -53,7 +53,7 @@ const isBootstrapped = computed(() => {
5353
>
5454
<template #loading>......loading......</template>
5555
<h1>Vue SDK (Bootstrapped)</h1>
56-
<StartHuddleButton />
56+
<StartHuddlesButton />
5757
<Track />
5858
<RequestFeedback />
5959

@@ -75,7 +75,7 @@ const isBootstrapped = computed(() => {
7575
>
7676
<template #loading>......loading......</template>
7777
<h1>Vue SDK</h1>
78-
<StartHuddleButton />
78+
<StartHuddlesButton />
7979
<Track />
8080
<RequestFeedback />
8181

packages/vue-sdk/dev/plain/components/Events.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ function trackEvent(evt: TrackEvent) {
2525
}
2626
2727
onMounted(() => {
28-
client.value.on("check", checkEvent);
29-
client.value.on("flagsUpdated", featuresUpdatedEvent);
30-
client.value.on("track", trackEvent);
28+
client.on("check", checkEvent);
29+
client.on("flagsUpdated", featuresUpdatedEvent);
30+
client.on("track", trackEvent);
3131
});
3232
onUnmounted(() => {
33-
client.value.off("check", checkEvent);
34-
client.value.off("flagsUpdated", featuresUpdatedEvent);
35-
client.value.off("track", trackEvent);
33+
client.off("check", checkEvent);
34+
client.off("flagsUpdated", featuresUpdatedEvent);
35+
client.off("track", trackEvent);
3636
});
3737
</script>
3838

packages/vue-sdk/dev/plain/components/FlagsList.vue

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
style="list-style-type: none; padding: 0"
1111
>
1212
<li
13-
v-for="[flagKey, feature] in flagEntries"
13+
v-for="[flagKey, flag] in flagEntries"
1414
:key="flagKey"
1515
style="
1616
margin-bottom: 10px;
@@ -24,21 +24,19 @@
2424
<span
2525
:style="{
2626
color:
27-
(feature.isEnabledOverride ?? feature.isEnabled)
28-
? 'green'
29-
: 'red',
27+
(flag.isEnabledOverride ?? flag.isEnabled) ? 'green' : 'red',
3028
}"
3129
>
3230
{{
33-
(feature.isEnabledOverride ?? feature.isEnabled)
31+
(flag.isEnabledOverride ?? flag.isEnabled)
3432
? "Enabled"
3533
: "Disabled"
3634
}}
3735
</span>
3836

3937
<!-- Reset button if override is active -->
4038
<button
41-
v-if="feature.isEnabledOverride !== null"
39+
v-if="flag.isEnabledOverride !== null"
4240
style="margin-left: 10px; padding: 2px 8px; font-size: 12px"
4341
@click="() => resetOverride(flagKey)"
4442
>
@@ -48,15 +46,21 @@
4846
<!-- Toggle checkbox -->
4947
<input
5048
type="checkbox"
51-
:checked="feature.isEnabledOverride ?? feature.isEnabled"
49+
:checked="flag.isEnabledOverride ?? flag.isEnabled"
5250
style="margin-left: auto"
53-
@change="(e) => toggleFlag(flagKey, e.target.checked)"
51+
@change="
52+
(e) => {
53+
const isChecked = e.target.checked;
54+
const isEnabledOverride = flag.isEnabledOverride !== null;
55+
toggleFlag(flagKey, !isEnabledOverride ? isChecked : null);
56+
}
57+
"
5458
/>
5559
</div>
5660

5761
<!-- Show config if available -->
5862
<div
59-
v-if="feature.config && feature.config.key"
63+
v-if="flag.config && flag.config.key"
6064
style="margin-top: 5px; font-size: 12px; color: #666"
6165
>
6266
<strong>Config:</strong>
@@ -68,7 +72,7 @@
6872
border-radius: 2px;
6973
overflow: auto;
7074
"
71-
>{{ JSON.stringify(feature.config.payload, null, 2) }}</pre
75+
>{{ JSON.stringify(flag.config.payload, null, 2) }}</pre
7276
>
7377
</div>
7478
</li>
@@ -79,9 +83,9 @@
7983
</template>
8084

8185
<script setup lang="ts">
82-
import { computed, onBeforeUnmount, ref } from "vue";
86+
import { computed, onMounted, ref } from "vue";
8387
84-
import { useClient } from "../../../src";
88+
import { useClient, useClientEvent } from "../../../src";
8589
8690
import Section from "./Section.vue";
8791
@@ -90,38 +94,29 @@ const flagsData = ref({});
9094
9195
// Update flags data when flags are updated
9296
function updateFlags() {
93-
if (client.value) {
94-
flagsData.value = client.value.getFlags();
95-
}
97+
flagsData.value = client.getFlags();
9698
}
9799
98100
// Initial load
99-
updateFlags();
101+
onMounted(() => {
102+
updateFlags();
103+
});
100104
101-
// Listen for flag updates
102-
if (client.value) {
103-
client.value.on("flagsUpdated", updateFlags);
104-
onBeforeUnmount(() => {
105-
client.value?.off("flagsUpdated", updateFlags);
106-
});
107-
}
105+
// Update flags data when flags are updated
106+
useClientEvent("flagsUpdated", updateFlags);
108107
109108
const flagEntries = computed(() => {
110109
return Object.entries(flagsData.value);
111110
});
112111
113112
function resetOverride(flagKey: string) {
114-
if (client.value) {
115-
client.value.getFlag(flagKey).setIsEnabledOverride(null);
116-
updateFlags();
117-
}
113+
client.getFlag(flagKey).setIsEnabledOverride(null);
114+
updateFlags();
118115
}
119116
120117
function toggleFlag(flagKey: string, checked: boolean) {
121-
if (client.value) {
122-
// Use simplified logic similar to React implementation
123-
client.value.getFlag(flagKey).setIsEnabledOverride(checked);
124-
updateFlags();
125-
}
118+
// Use simplified logic similar to React implementation
119+
client.getFlag(flagKey).setIsEnabledOverride(checked);
120+
updateFlags();
126121
}
127122
</script>

packages/vue-sdk/dev/plain/components/StartHuddleButton.vue renamed to packages/vue-sdk/dev/plain/components/StartHuddlesButton.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ import { useFlag } from "../../../src";
44
import Section from "./Section.vue";
55
66
const { isLoading, isEnabled, config, requestFeedback, track } =
7-
useFlag("huddle");
7+
useFlag("huddles");
88
</script>
99
<template>
10-
<Section title="Huddle">
10+
<Section title="Huddles">
1111
<div style="display: flex; gap: 10px; flex-wrap: wrap">
12-
<div>Huddle enabled: {{ isEnabled }}</div>
12+
<div>huddles enabled: {{ isEnabled }}</div>
1313
<div v-if="isLoading">Loading...</div>
1414
<div v-else style="display: flex; gap: 10px; flex-wrap: wrap">
1515
<div>
1616
<button @click="track()">
17-
{{ config?.payload?.buttonTitle ?? "Start Huddle (track event)" }}
17+
{{ config?.payload?.buttonTitle ?? "Start Huddles (track event)" }}
1818
</button>
1919
</div>
2020
<div>

packages/vue-sdk/dev/plain/components/Track.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const track = useTrack();
88

99
<template>
1010
<Section title="Custom track event">
11-
<button @click="track('Huddle Started', { huddleType: 'voice' })">
11+
<button @click="track('Huddles Started', { huddlesType: 'voice' })">
1212
Send custom track event
1313
</button>
1414
</Section>

0 commit comments

Comments
 (0)