@soubiran/ui 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,843 +1,4 @@
1
- import { Fragment, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, markRaw, mergeModels, normalizeClass, onMounted, openBlock, readonly, ref, renderList, renderSlot, toDisplayString, unref, useModel, withCtx } from "vue";
2
- import { tv } from "tailwind-variants";
3
- import UButton from "@nuxt/ui/components/Button.vue";
4
- import UPopover from "@nuxt/ui/components/Popover.vue";
5
- import { useRoute } from "vue-router";
6
- import UCard from "@nuxt/ui/components/Card.vue";
7
- import UFormField from "@nuxt/ui/components/FormField.vue";
8
- import UIcon from "@nuxt/ui/components/Icon.vue";
9
- import UTextarea from "@nuxt/ui/components/Textarea.vue";
10
- import UTooltip from "@nuxt/ui/components/Tooltip.vue";
11
- import { useMutation } from "@pinia/colada";
12
- import { motion } from "motion-v";
13
- import { ofetch } from "ofetch";
14
- import { RadioGroupIndicator, RadioGroupItem, RadioGroupRoot } from "reka-ui";
15
- import USeparator from "@nuxt/ui/components/Separator.vue";
16
- import { createSharedComposable } from "@vueuse/core";
17
- import PartySocket from "partysocket";
18
- //#region src/components/Container.vue
19
- const container = tv({ slots: {
20
- base: "px-4 sm:px-6 lg:px-8",
21
- inner: "w-full max-w-7xl mx-auto"
22
- } });
23
- const _sfc_main = /* @__PURE__ */ defineComponent({
24
- __name: "Container",
25
- props: {
26
- class: {},
27
- ui: {}
28
- },
29
- setup(__props) {
30
- const props = __props;
31
- const ui = computed(() => container());
32
- return (_ctx, _cache) => {
33
- return openBlock(), createElementBlock("div", { class: normalizeClass(ui.value.base({ class: [props.ui?.base, props.class] })) }, [createElementVNode("div", { class: normalizeClass(ui.value.inner({ class: props.ui?.inner })) }, [renderSlot(_ctx.$slots, "default")], 2)], 2);
34
- };
35
- }
36
- });
37
- //#endregion
38
- //#region ~icons/ph/thumbs-up
39
- const _hoisted_1$11 = {
40
- viewBox: "0 0 256 256",
41
- width: "1.2em",
42
- height: "1.2em"
43
- };
44
- function render$7(_ctx, _cache) {
45
- return openBlock(), createElementBlock("svg", _hoisted_1$11, [..._cache[0] || (_cache[0] = [createElementVNode("path", {
46
- fill: "currentColor",
47
- d: "M234 80.12A24 24 0 0 0 216 72h-56V56a40 40 0 0 0-40-40a8 8 0 0 0-7.16 4.42L75.06 96H32a16 16 0 0 0-16 16v88a16 16 0 0 0 16 16h172a24 24 0 0 0 23.82-21l12-96A24 24 0 0 0 234 80.12M32 112h40v88H32Zm191.94-15l-12 96a8 8 0 0 1-7.94 7H88v-94.11l36.71-73.43A24 24 0 0 1 144 56v24a8 8 0 0 0 8 8h64a8 8 0 0 1 7.94 9"
48
- }, null, -1)])]);
49
- }
50
- var thumbs_up_default = markRaw({
51
- name: "ph-thumbs-up",
52
- render: render$7
53
- });
54
- //#endregion
55
- //#region src/composables/useUmami.ts
56
- function useUmami() {
57
- const route = useRoute();
58
- function track(event, data) {
59
- window.umami?.track(event, {
60
- ...data,
61
- page_path: route.path
62
- });
63
- }
64
- return { track };
65
- }
66
- //#endregion
67
- //#region ~icons/ph/check-circle
68
- const _hoisted_1$10 = {
69
- viewBox: "0 0 256 256",
70
- width: "1.2em",
71
- height: "1.2em"
72
- };
73
- function render$6(_ctx, _cache) {
74
- return openBlock(), createElementBlock("svg", _hoisted_1$10, [..._cache[0] || (_cache[0] = [createElementVNode("path", {
75
- fill: "currentColor",
76
- d: "M173.66 98.34a8 8 0 0 1 0 11.32l-56 56a8 8 0 0 1-11.32 0l-24-24a8 8 0 0 1 11.32-11.32L112 148.69l50.34-50.35a8 8 0 0 1 11.32 0M232 128A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88"
77
- }, null, -1)])]);
78
- }
79
- var check_circle_default = markRaw({
80
- name: "ph-check-circle",
81
- render: render$6
82
- });
83
- //#endregion
84
- //#region src/components/FeedbackCard.vue
85
- const _hoisted_1$9 = ["for"];
86
- const feedbackCard = tv({ slots: {
87
- base: "relative w-64",
88
- successfullySentOverlay: "absolute z-10 inset-0 bg-default",
89
- successfullySentContent: "absolute z-20 inset-0 flex flex-col justify-center items-center text-muted text-xs",
90
- successfullySentIcon: "size-5",
91
- input: "w-full",
92
- radioGroup: "flex flex-row gap-2 text-lg",
93
- radioGroupItem: "peer",
94
- radioGroupLabel: "grayscale-100 hover:grayscale-0 peer-data-[state=checked]:grayscale-0"
95
- } });
96
- const _sfc_main$2 = /* @__PURE__ */ defineComponent({
97
- __name: "FeedbackCard",
98
- props: /* @__PURE__ */ mergeModels({
99
- id: {},
100
- class: {},
101
- ui: {}
102
- }, {
103
- "content": { required: true },
104
- "contentModifiers": {},
105
- "rating": { required: true },
106
- "ratingModifiers": {}
107
- }),
108
- emits: /* @__PURE__ */ mergeModels(["success"], ["update:content", "update:rating"]),
109
- setup(__props, { emit: __emit }) {
110
- const props = __props;
111
- const emits = __emit;
112
- const content = useModel(__props, "content");
113
- const rating = useModel(__props, "rating");
114
- const ratings = [
115
- {
116
- label: "😭",
117
- value: "Hate it"
118
- },
119
- {
120
- label: "🙁",
121
- value: "Not great"
122
- },
123
- {
124
- label: "🙂",
125
- value: "It's ok"
126
- },
127
- {
128
- label: "🤩",
129
- value: "Love it"
130
- }
131
- ];
132
- const successfullySent = ref(false);
133
- const { track } = useUmami();
134
- const { mutate, isLoading, error } = useMutation({
135
- mutation: ({ rating, content }) => ofetch(`/api/posts/${props.id}/feedback`, {
136
- method: "POST",
137
- body: {
138
- rating,
139
- content
140
- },
141
- baseURL: import.meta.env.VITE_API_BASE_URL
142
- }),
143
- onSuccess: () => {
144
- successfullySent.value = true;
145
- track("feedback_submit");
146
- setTimeout(() => emits("success"), 200);
147
- }
148
- });
149
- function sendFeedback() {
150
- mutate({
151
- rating: rating.value,
152
- content: content.value
153
- });
154
- }
155
- const formattedError = computed(() => {
156
- if (!error.value) return void 0;
157
- if (error.value.data?.errors) return error.value.data.errors.content?.[0] || error.value.data.errors.rating?.[0];
158
- if (error.value.status === 404) return "Page not found. Cannot send feedback. It's us, not you!";
159
- if (error.value.status === 503) return "Service is currently unavailable. Please try again later.";
160
- return "An unexpected error occurred.";
161
- });
162
- const ui = computed(() => feedbackCard());
163
- return (_ctx, _cache) => {
164
- return openBlock(), createBlock(UCard, {
165
- class: normalizeClass(ui.value.base({ class: [props.ui?.base, props.class] })),
166
- ui: {
167
- body: "p-2 sm:p-2",
168
- footer: "p-2 sm:p-2 flex items-center justify-between"
169
- }
170
- }, {
171
- footer: withCtx(() => [createVNode(unref(RadioGroupRoot), {
172
- modelValue: rating.value,
173
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => rating.value = $event),
174
- class: normalizeClass(ui.value.radioGroup({ class: props.ui?.radioGroup }))
175
- }, {
176
- default: withCtx(() => [(openBlock(), createElementBlock(Fragment, null, renderList(ratings, (item) => {
177
- return createElementVNode("div", { key: item.value }, [createVNode(unref(RadioGroupItem), {
178
- id: item.value,
179
- value: item.value,
180
- class: normalizeClass(ui.value.radioGroupItem({ class: props.ui?.radioGroupItem }))
181
- }, {
182
- default: withCtx(() => [createVNode(unref(RadioGroupIndicator))]),
183
- _: 1
184
- }, 8, [
185
- "id",
186
- "value",
187
- "class"
188
- ]), createVNode(UTooltip, { text: item.value }, {
189
- default: withCtx(() => [createElementVNode("label", {
190
- for: item.value,
191
- class: normalizeClass(ui.value.radioGroupLabel({ class: props.ui?.radioGroupLabel }))
192
- }, toDisplayString(item.label), 11, _hoisted_1$9)]),
193
- _: 2
194
- }, 1032, ["text"])]);
195
- }), 64))]),
196
- _: 1
197
- }, 8, ["modelValue", "class"]), createVNode(UButton, {
198
- size: "sm",
199
- label: "Send",
200
- loading: unref(isLoading),
201
- onClick: sendFeedback
202
- }, null, 8, ["loading"])]),
203
- default: withCtx(() => [successfullySent.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createVNode(unref(motion).div, {
204
- initial: { opacity: 0 },
205
- animate: {
206
- opacity: 1,
207
- transition: { duration: .2 }
208
- },
209
- class: normalizeClass(ui.value.successfullySentOverlay({ class: props.ui?.successfullySentOverlay }))
210
- }, null, 8, ["class"]), createElementVNode("div", { class: normalizeClass(ui.value.successfullySentContent({ class: props.ui?.successfullySentContent })) }, [
211
- createVNode(unref(motion).div, {
212
- initial: {
213
- opacity: 0,
214
- transform: "translateY(4px)"
215
- },
216
- animate: {
217
- opacity: 1,
218
- transform: "translateY(0)",
219
- transition: {
220
- delay: .1,
221
- duration: .3
222
- }
223
- }
224
- }, {
225
- default: withCtx(() => [createVNode(UIcon, {
226
- name: unref(check_circle_default),
227
- class: normalizeClass(ui.value.successfullySentIcon({ class: props.ui?.successfullySentIcon }))
228
- }, null, 8, ["name", "class"])]),
229
- _: 1
230
- }),
231
- createVNode(unref(motion).p, {
232
- initial: {
233
- opacity: 0,
234
- transform: "translateY(4px)"
235
- },
236
- animate: {
237
- opacity: 1,
238
- transform: "translateY(0)",
239
- transition: {
240
- delay: .2,
241
- duration: .3
242
- }
243
- },
244
- class: "mt-3"
245
- }, {
246
- default: withCtx(() => [..._cache[2] || (_cache[2] = [createTextVNode(" Your feedback has been received. ", -1)])]),
247
- _: 1
248
- }),
249
- createVNode(unref(motion).p, {
250
- initial: {
251
- opacity: 0,
252
- transform: "translateY(4px)"
253
- },
254
- animate: {
255
- opacity: 1,
256
- transform: "translateY(0)",
257
- transition: {
258
- delay: .3,
259
- duration: .3
260
- }
261
- },
262
- class: "mt-1"
263
- }, {
264
- default: withCtx(() => [..._cache[3] || (_cache[3] = [createTextVNode(" Thanks for your help! ", -1)])]),
265
- _: 1
266
- })
267
- ], 2)], 64)) : createCommentVNode("v-if", true), createVNode(UFormField, { error: formattedError.value }, {
268
- error: withCtx(({ error: formFieldError }) => [formFieldError ? (openBlock(), createBlock(unref(motion).div, {
269
- key: 0,
270
- initial: { height: 0 },
271
- animate: { height: "auto" },
272
- class: "text-sm"
273
- }, {
274
- default: withCtx(() => [createTextVNode(toDisplayString(formFieldError), 1)]),
275
- _: 2
276
- }, 1024)) : createCommentVNode("v-if", true)]),
277
- default: withCtx(() => [createVNode(UTextarea, {
278
- modelValue: content.value,
279
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => content.value = $event),
280
- placeholder: "Your feedback...",
281
- variant: "soft",
282
- class: normalizeClass(ui.value.input({ class: props.ui?.input }))
283
- }, null, 8, ["modelValue", "class"])]),
284
- _: 1
285
- }, 8, ["error"])]),
286
- _: 1
287
- }, 8, ["class"]);
288
- };
289
- }
290
- });
291
- //#endregion
292
- //#region src/components/Feedback.vue
293
- const feedback = tv({ slots: { base: "px-0 py-1 text-dimmed text-sm" } });
294
- const _sfc_main$1 = /* @__PURE__ */ defineComponent({
295
- __name: "Feedback",
296
- props: {
297
- id: {},
298
- class: {},
299
- ui: {}
300
- },
301
- setup(__props) {
302
- const props = __props;
303
- const { track } = useUmami();
304
- function onClick() {
305
- track("feedback_click");
306
- }
307
- const content = ref("");
308
- const rating = ref("");
309
- function onSuccess() {
310
- content.value = "";
311
- rating.value = "";
312
- }
313
- const ui = computed(() => feedback());
314
- return (_ctx, _cache) => {
315
- return openBlock(), createBlock(UPopover, { ui: { content: "ring-0 data-[state=open]:animate-[scale-up_100ms_ease-out]" } }, {
316
- content: withCtx(() => [createVNode(_sfc_main$2, {
317
- id: props.id,
318
- rating: rating.value,
319
- "onUpdate:rating": _cache[0] || (_cache[0] = ($event) => rating.value = $event),
320
- content: content.value,
321
- "onUpdate:content": _cache[1] || (_cache[1] = ($event) => content.value = $event),
322
- onSuccess
323
- }, null, 8, [
324
- "id",
325
- "rating",
326
- "content"
327
- ])]),
328
- default: withCtx(() => [createVNode(UButton, {
329
- variant: "link",
330
- color: "neutral",
331
- label: "Give feedback",
332
- size: "sm",
333
- icon: unref(thumbs_up_default),
334
- class: normalizeClass(ui.value.base({ class: [props.ui?.base, props.class] })),
335
- onClick
336
- }, null, 8, ["icon", "class"])]),
337
- _: 1
338
- });
339
- };
340
- }
341
- });
342
- //#endregion
343
- //#region ~icons/simple-icons/discord
344
- const _hoisted_1$8 = {
345
- viewBox: "0 0 24 24",
346
- width: "1.2em",
347
- height: "1.2em"
348
- };
349
- function render$5(_ctx, _cache) {
350
- return openBlock(), createElementBlock("svg", _hoisted_1$8, [..._cache[0] || (_cache[0] = [createElementVNode("path", {
351
- fill: "currentColor",
352
- d: "M20.317 4.37a19.8 19.8 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.3 18.3 0 0 0-5.487 0a13 13 0 0 0-.617-1.25a.08.08 0 0 0-.079-.037A19.7 19.7 0 0 0 3.677 4.37a.1.1 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.08.08 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.08.08 0 0 0 .084-.028a14 14 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13 13 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10 10 0 0 0 .372-.292a.07.07 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.07.07 0 0 1 .078.01q.181.149.373.292a.077.077 0 0 1-.006.127a12.3 12.3 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.08.08 0 0 0 .084.028a19.8 19.8 0 0 0 6.002-3.03a.08.08 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.06.06 0 0 0-.031-.03M8.02 15.33c-1.182 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418m7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418"
353
- }, null, -1)])]);
354
- }
355
- var discord_default = markRaw({
356
- name: "simple-icons-discord",
357
- render: render$5
358
- });
359
- //#endregion
360
- //#region ~icons/simple-icons/github
361
- const _hoisted_1$7 = {
362
- viewBox: "0 0 24 24",
363
- width: "1.2em",
364
- height: "1.2em"
365
- };
366
- function render$4(_ctx, _cache) {
367
- return openBlock(), createElementBlock("svg", _hoisted_1$7, [..._cache[0] || (_cache[0] = [createElementVNode("path", {
368
- fill: "currentColor",
369
- d: "M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
370
- }, null, -1)])]);
371
- }
372
- var github_default = markRaw({
373
- name: "simple-icons-github",
374
- render: render$4
375
- });
376
- //#endregion
377
- //#region ~icons/simple-icons/linkedin
378
- const _hoisted_1$6 = {
379
- viewBox: "0 0 24 24",
380
- width: "1.2em",
381
- height: "1.2em"
382
- };
383
- function render$3(_ctx, _cache) {
384
- return openBlock(), createElementBlock("svg", _hoisted_1$6, [..._cache[0] || (_cache[0] = [createElementVNode("path", {
385
- fill: "currentColor",
386
- d: "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z"
387
- }, null, -1)])]);
388
- }
389
- var linkedin_default = markRaw({
390
- name: "simple-icons-linkedin",
391
- render: render$3
392
- });
393
- //#endregion
394
- //#region ~icons/simple-icons/twitch
395
- const _hoisted_1$5 = {
396
- viewBox: "0 0 24 24",
397
- width: "1.2em",
398
- height: "1.2em"
399
- };
400
- function render$2(_ctx, _cache) {
401
- return openBlock(), createElementBlock("svg", _hoisted_1$5, [..._cache[0] || (_cache[0] = [createElementVNode("path", {
402
- fill: "currentColor",
403
- d: "M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"
404
- }, null, -1)])]);
405
- }
406
- var twitch_default = markRaw({
407
- name: "simple-icons-twitch",
408
- render: render$2
409
- });
410
- //#endregion
411
- //#region ~icons/simple-icons/x
412
- const _hoisted_1$4 = {
413
- viewBox: "0 0 24 24",
414
- width: "1.2em",
415
- height: "1.2em"
416
- };
417
- function render$1(_ctx, _cache) {
418
- return openBlock(), createElementBlock("svg", _hoisted_1$4, [..._cache[0] || (_cache[0] = [createElementVNode("path", {
419
- fill: "currentColor",
420
- d: "M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z"
421
- }, null, -1)])]);
422
- }
423
- var x_default = markRaw({
424
- name: "simple-icons-x",
425
- render: render$1
426
- });
427
- //#endregion
428
- //#region src/components/Header.vue
429
- const header = tv({ slots: {
430
- base: "h-(--ui-header-height) flex flex-row gap-4 items-center justify-end",
431
- link: "p-0 text-dimmed"
432
- } });
433
- const _sfc_main$3 = /* @__PURE__ */ defineComponent({
434
- __name: "Header",
435
- props: {
436
- links: {},
437
- class: {},
438
- ui: {}
439
- },
440
- setup(__props) {
441
- const props = __props;
442
- const { track } = useUmami();
443
- function trackClick(label) {
444
- track("header_click", { label });
445
- }
446
- const ui = computed(() => header());
447
- return (_ctx, _cache) => {
448
- return openBlock(), createBlock(_sfc_main, { ui: { inner: "max-w-5xl" } }, {
449
- default: withCtx(() => [createElementVNode("header", { class: normalizeClass(ui.value.base({ class: [props.ui?.base, props.class] })) }, [
450
- (openBlock(true), createElementBlock(Fragment, null, renderList(props.links, (link) => {
451
- return openBlock(), createBlock(UTooltip, {
452
- key: link.label,
453
- text: link.label
454
- }, {
455
- default: withCtx(() => [createVNode(UButton, {
456
- variant: "link",
457
- color: "neutral",
458
- to: link.to,
459
- "aria-label": link.label,
460
- icon: link.icon,
461
- class: normalizeClass(ui.value.link({ class: props.ui?.link })),
462
- onClick: ($event) => trackClick(link.label)
463
- }, null, 8, [
464
- "to",
465
- "aria-label",
466
- "icon",
467
- "class",
468
- "onClick"
469
- ])]),
470
- _: 2
471
- }, 1032, ["text"]);
472
- }), 128)),
473
- createVNode(USeparator, {
474
- orientation: "vertical",
475
- class: "h-5"
476
- }),
477
- createVNode(UTooltip, { text: "LinkedIn" }, {
478
- default: withCtx(() => [createVNode(UButton, {
479
- href: "https://www.linkedin.com/in/esteban25/",
480
- target: "_blank",
481
- variant: "link",
482
- color: "neutral",
483
- "aria-label": "LinkedIn",
484
- icon: unref(linkedin_default),
485
- class: normalizeClass(ui.value.link({ class: props.ui?.link })),
486
- ui: { leadingIcon: "size-4" },
487
- onClick: _cache[0] || (_cache[0] = ($event) => trackClick("LinkedIn"))
488
- }, null, 8, ["icon", "class"])]),
489
- _: 1
490
- }),
491
- createVNode(UTooltip, { text: "X" }, {
492
- default: withCtx(() => [createVNode(UButton, {
493
- href: "https://x.com/soubiran_",
494
- target: "_blank",
495
- variant: "link",
496
- color: "neutral",
497
- "aria-label": "X",
498
- icon: unref(x_default),
499
- class: normalizeClass(ui.value.link({ class: props.ui?.link })),
500
- ui: { leadingIcon: "size-4" },
501
- onClick: _cache[1] || (_cache[1] = ($event) => trackClick("X"))
502
- }, null, 8, ["icon", "class"])]),
503
- _: 1
504
- }),
505
- createVNode(UTooltip, { text: "Twitch" }, {
506
- default: withCtx(() => [createVNode(UButton, {
507
- href: "https://www.twitch.tv/barbapapazes",
508
- target: "_blank",
509
- variant: "link",
510
- color: "neutral",
511
- "aria-label": "Twitch",
512
- icon: unref(twitch_default),
513
- class: normalizeClass(ui.value.link({ class: props.ui?.link })),
514
- ui: { leadingIcon: "size-4" },
515
- onClick: _cache[2] || (_cache[2] = ($event) => trackClick("Twitch"))
516
- }, null, 8, ["icon", "class"])]),
517
- _: 1
518
- }),
519
- createVNode(UTooltip, { text: "GitHub" }, {
520
- default: withCtx(() => [createVNode(UButton, {
521
- href: "https://github.com/barbapapazes",
522
- target: "_blank",
523
- variant: "link",
524
- color: "neutral",
525
- "aria-label": "GitHub",
526
- icon: unref(github_default),
527
- class: normalizeClass(ui.value.link({ class: props.ui?.link })),
528
- ui: { leadingIcon: "size-4" },
529
- onClick: _cache[3] || (_cache[3] = ($event) => trackClick("GitHub"))
530
- }, null, 8, ["icon", "class"])]),
531
- _: 1
532
- }),
533
- createVNode(UTooltip, { text: "Discord" }, {
534
- default: withCtx(() => [createVNode(UButton, {
535
- href: "https://discord.gg/q2ghCGUuFR",
536
- target: "_blank",
537
- variant: "link",
538
- color: "neutral",
539
- "aria-label": "Discord",
540
- icon: unref(discord_default),
541
- class: normalizeClass(ui.value.link({ class: props.ui?.link })),
542
- ui: { leadingIcon: "size-4" },
543
- onClick: _cache[4] || (_cache[4] = ($event) => trackClick("Discord"))
544
- }, null, 8, ["icon", "class"])]),
545
- _: 1
546
- })
547
- ], 2)]),
548
- _: 1
549
- });
550
- };
551
- }
552
- });
553
- //#endregion
554
- //#region src/components/Page.vue
555
- const page = tv({ slots: {
556
- base: "py-12",
557
- header: "max-w-3xl mx-auto xl:max-w-none xl:grid xl:grid-cols-[256px_768px_256px]",
558
- headerInner: "xl:col-start-2",
559
- content: "mt-6 max-w-3xl mx-auto xl:max-w-none xl:grid xl:grid-cols-[256px_768px_256px] xl:mx-auto",
560
- contentInner: "xl:col-start-2",
561
- right: "hidden xl:block xl:col-start-3 xl:pl-8 xl:h-full",
562
- rightInner: "sticky top-4"
563
- } });
564
- const _sfc_main$4 = /* @__PURE__ */ defineComponent({
565
- __name: "Page",
566
- props: {
567
- class: {},
568
- ui: {}
569
- },
570
- setup(__props) {
571
- const props = __props;
572
- const ui = computed(() => page());
573
- return (_ctx, _cache) => {
574
- return openBlock(), createElementBlock("div", { class: normalizeClass(ui.value.base({ class: [props.ui?.base, props.class] })) }, [createVNode(_sfc_main, null, {
575
- default: withCtx(() => [createElementVNode("div", { class: normalizeClass(ui.value.header({ class: props.ui?.header })) }, [createElementVNode("div", { class: normalizeClass(ui.value.headerInner({ class: props.ui?.headerInner })) }, [renderSlot(_ctx.$slots, "header")], 2)], 2), createElementVNode("div", { class: normalizeClass(ui.value.content({ class: props.ui?.content })) }, [createElementVNode("div", { class: normalizeClass(ui.value.contentInner({ class: props.ui?.contentInner })) }, [renderSlot(_ctx.$slots, "default")], 2), createElementVNode("div", { class: normalizeClass(ui.value.right({ class: props.ui?.right })) }, [createElementVNode("div", { class: normalizeClass(ui.value.rightInner({ class: props.ui?.rightInner })) }, [renderSlot(_ctx.$slots, "right")], 2)], 2)], 2)]),
576
- _: 3
577
- }), renderSlot(_ctx.$slots, "bottom")], 2);
578
- };
579
- }
580
- });
581
- //#endregion
582
- //#region src/components/PageTitle.vue
583
- const pageTitle = tv({ slots: { base: "text-xl font-bold text-highlighted" } });
584
- const _sfc_main$6 = /* @__PURE__ */ defineComponent({
585
- __name: "PageTitle",
586
- props: {
587
- title: {},
588
- class: {},
589
- ui: {}
590
- },
591
- setup(__props) {
592
- const props = __props;
593
- const ui = computed(() => pageTitle());
594
- return (_ctx, _cache) => {
595
- return openBlock(), createElementBlock("h1", { class: normalizeClass(ui.value.base({ class: [props.ui?.base, props.class] })) }, toDisplayString(__props.title), 3);
596
- };
597
- }
598
- });
599
- //#endregion
600
- //#region src/components/PageHeader.vue
601
- const pageHeader = tv({ slots: { base: "" } });
602
- const _sfc_main$5 = /* @__PURE__ */ defineComponent({
603
- __name: "PageHeader",
604
- props: {
605
- title: {},
606
- class: {},
607
- ui: {}
608
- },
609
- setup(__props) {
610
- const props = __props;
611
- const ui = computed(() => pageHeader());
612
- return (_ctx, _cache) => {
613
- return openBlock(), createElementBlock("div", { class: normalizeClass(ui.value.base({ class: [props.ui?.base, props.class] })) }, [createVNode(_sfc_main$6, { title: props.title }, null, 8, ["title"]), renderSlot(_ctx.$slots, "after")], 2);
614
- };
615
- }
616
- });
617
- //#endregion
618
- //#region ~icons/simple-icons/youtube
619
- const _hoisted_1$3 = {
620
- viewBox: "0 0 24 24",
621
- width: "1.2em",
622
- height: "1.2em"
623
- };
624
- function render(_ctx, _cache) {
625
- return openBlock(), createElementBlock("svg", _hoisted_1$3, [..._cache[0] || (_cache[0] = [createElementVNode("path", {
626
- fill: "currentColor",
627
- d: "M23.498 6.186a3.02 3.02 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.02 3.02 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.02 3.02 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.02 3.02 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814M9.545 15.568V8.432L15.818 12z"
628
- }, null, -1)])]);
629
- }
630
- var youtube_default = markRaw({
631
- name: "simple-icons-youtube",
632
- render
633
- });
634
- //#endregion
635
- //#region src/components/Socials.vue
636
- const socials = tv({ slots: {
637
- base: "flex flex-wrap gap-2",
638
- link: "flex items-center gap-1",
639
- icon: "size-4"
640
- } });
641
- const _sfc_main$7 = /* @__PURE__ */ defineComponent({
642
- __name: "Socials",
643
- props: {
644
- class: {},
645
- ui: {}
646
- },
647
- setup(__props) {
648
- const props = __props;
649
- const ui = computed(() => socials());
650
- return (_ctx, _cache) => {
651
- return openBlock(), createElementBlock("p", { class: normalizeClass(ui.value.base({ class: [props.ui?.base, props.class] })) }, [
652
- createElementVNode("a", {
653
- href: "https://www.linkedin.com/in/esteban25/",
654
- rel: "noopener noreferrer",
655
- target: "_blank",
656
- class: normalizeClass(ui.value.link({ class: props.ui?.link }))
657
- }, [createVNode(UIcon, {
658
- name: unref(linkedin_default),
659
- class: normalizeClass(ui.value.icon({ class: props.ui?.icon }))
660
- }, null, 8, ["name", "class"]), _cache[0] || (_cache[0] = createElementVNode("span", null, "LinkedIn", -1))], 2),
661
- createElementVNode("a", {
662
- href: "https://x.com/soubiran_",
663
- rel: "noopener noreferrer",
664
- target: "_blank",
665
- class: normalizeClass(ui.value.link({ class: props.ui?.link }))
666
- }, [createVNode(UIcon, {
667
- name: unref(x_default),
668
- class: normalizeClass(ui.value.icon({ class: props.ui?.icon }))
669
- }, null, 8, ["name", "class"]), _cache[1] || (_cache[1] = createElementVNode("span", null, "X (Twitter)", -1))], 2),
670
- createElementVNode("a", {
671
- href: "https://github.com/barbapapazes",
672
- rel: "noopener noreferrer",
673
- target: "_blank",
674
- class: normalizeClass(ui.value.link({ class: props.ui?.link }))
675
- }, [createVNode(UIcon, {
676
- name: unref(github_default),
677
- class: normalizeClass(ui.value.icon({ class: props.ui?.icon }))
678
- }, null, 8, ["name", "class"]), _cache[2] || (_cache[2] = createElementVNode("span", null, "GitHub", -1))], 2),
679
- createElementVNode("a", {
680
- href: "https://www.twitch.tv/barbapapazes",
681
- rel: "noopener noreferrer",
682
- target: "_blank",
683
- class: normalizeClass(ui.value.link({ class: props.ui?.link }))
684
- }, [createVNode(UIcon, {
685
- name: unref(twitch_default),
686
- class: normalizeClass(ui.value.icon({ class: props.ui?.icon }))
687
- }, null, 8, ["name", "class"]), _cache[3] || (_cache[3] = createElementVNode("span", null, "Twitch", -1))], 2),
688
- createElementVNode("a", {
689
- href: "https://www.youtube.com/@barbapapazes",
690
- target: "_blank",
691
- rel: "noopener noreferrer",
692
- class: normalizeClass(ui.value.link({ class: props.ui?.link }))
693
- }, [createVNode(UIcon, {
694
- name: unref(youtube_default),
695
- class: normalizeClass(ui.value.icon({ class: props.ui?.icon }))
696
- }, null, 8, ["name", "class"]), _cache[4] || (_cache[4] = createElementVNode("span", null, "YouTube", -1))], 2)
697
- ], 2);
698
- };
699
- }
700
- });
701
- //#endregion
702
- //#region src/components/Sponsors.vue
703
- const _hoisted_1$2 = {
704
- href: "https://soubiran.dev/sponsorship?utm_source=infra.soubiran.dev&utm_medium=link",
705
- target: "_blank"
706
- };
707
- const sponsors = tv({ slots: {
708
- base: "not-prose",
709
- img: "border-0"
710
- } });
711
- const _sfc_main$8 = /* @__PURE__ */ defineComponent({
712
- __name: "Sponsors",
713
- props: {
714
- class: {},
715
- ui: {}
716
- },
717
- setup(__props) {
718
- const props = __props;
719
- const ui = computed(() => sponsors());
720
- return (_ctx, _cache) => {
721
- return openBlock(), createElementBlock("p", { class: normalizeClass(ui.value.base({ class: [props.ui?.base, props.class] })) }, [createElementVNode("a", _hoisted_1$2, [createElementVNode("img", {
722
- src: "https://raw.githubusercontent.com/Barbapapazes/static/refs/heads/main/sponsors.svg",
723
- alt: "Sponsors",
724
- class: normalizeClass(ui.value.img({ class: props.ui?.img }))
725
- }, null, 2)])], 2);
726
- };
727
- }
728
- });
729
- //#endregion
730
- //#region src/composables/useTableOfContents.ts
731
- function _useTableOfContents() {
732
- const activeHeadings = ref([]);
733
- function setActive(id) {
734
- activeHeadings.value.push(id);
735
- }
736
- function unsetActive(id) {
737
- activeHeadings.value = activeHeadings.value.filter((h) => h !== id);
738
- }
739
- return {
740
- setActive,
741
- unsetActive,
742
- activeHeadings: readonly(activeHeadings)
743
- };
744
- }
745
- var useTableOfContents_default = createSharedComposable(_useTableOfContents);
746
- //#endregion
747
- //#region src/components/TableOfContents.vue
748
- const _hoisted_1$1 = [
749
- "href",
750
- "data-active",
751
- "onClick"
752
- ];
753
- const tableOfContents = tv({ slots: {
754
- base: "space-y-1 text-sm text-dimmed font-medium",
755
- title: "",
756
- list: "font-sofia",
757
- link: "flex gap-1 px-0 py-1 text-dimmed hover:text-default active:text-default transition-colors focus:outline-none focus-visible:ring-inset focus-visible:ring-2 focus-visible:ring-inverted data-active:text-default rounded-md"
758
- } });
759
- const _sfc_main$9 = /* @__PURE__ */ defineComponent({
760
- __name: "TableOfContents",
761
- props: {
762
- toc: {},
763
- class: {},
764
- ui: {}
765
- },
766
- setup(__props) {
767
- const props = __props;
768
- const { track } = useUmami();
769
- function trackClick(text, hash) {
770
- track("table_of_contents_click", {
771
- toc_text: text,
772
- toc_hash: hash
773
- });
774
- }
775
- const { activeHeadings } = useTableOfContents_default();
776
- const ui = computed(() => tableOfContents());
777
- return (_ctx, _cache) => {
778
- return openBlock(), createElementBlock("div", { class: normalizeClass(ui.value.base({ class: [props.ui?.base, props.class] })) }, [createElementVNode("div", { class: normalizeClass(ui.value.title({ class: props.ui?.title })) }, " Table of Contents ", 2), createElementVNode("ul", { class: normalizeClass(ui.value.list({ class: props.ui?.list })) }, [(openBlock(true), createElementBlock(Fragment, null, renderList(props.toc, (item, index) => {
779
- return openBlock(), createElementBlock("li", { key: item.anchor || index }, [createCommentVNode(" Cannot use RouterLink as the anchor will be prefixed with the route path. "), item.anchor ? (openBlock(), createElementBlock("a", {
780
- key: 0,
781
- custom: "",
782
- variant: "link",
783
- color: "neutral",
784
- href: `#${item.anchor}`,
785
- "data-active": unref(activeHeadings).includes(item.anchor || "") ? true : void 0,
786
- class: normalizeClass(ui.value.link({ class: props.ui?.link })),
787
- onClick: ($event) => trackClick(item.text, item.anchor)
788
- }, [createElementVNode("span", null, toDisplayString(index + 1) + ".", 1), createTextVNode(" " + toDisplayString(item.text), 1)], 10, _hoisted_1$1)) : createCommentVNode("v-if", true)]);
789
- }), 128))], 2)], 2);
790
- };
791
- }
792
- });
793
- //#endregion
794
- //#region src/components/ViewersCounter.vue
795
- const _hoisted_1 = ["title"];
796
- const viewersCounter = tv({ slots: {
797
- base: "flex items-center justify-center gap-[0.375rem] border border-green-400 rounded-full px-[0.375rem] py-[0.125rem] text-xs text-muted font-light leading-3 dark:border-green-700",
798
- dot: "inline-block h-[0.375rem] w-[0.375rem] animate-[pulse_4s_cubic-bezier(0.4,_0,_0.6,_1)_infinite] rounded-full bg-green-400 ring ring-2 ring-green-200 dark:bg-green-700 dark:ring-green-500"
799
- } });
800
- const _sfc_main$10 = /* @__PURE__ */ defineComponent({
801
- __name: "ViewersCounter",
802
- props: {
803
- class: {},
804
- ui: {}
805
- },
806
- setup(__props) {
807
- const props = __props;
808
- const count = ref(0);
809
- const connections = ref({});
810
- function connect() {
811
- return new PartySocket({
812
- host: import.meta.env.VITE_PARTYKIT_URL,
813
- room: "soubiran-dev"
814
- });
815
- }
816
- onMounted(() => {
817
- connect().addEventListener("message", (event) => {
818
- const data = JSON.parse(event.data);
819
- count.value = data.count;
820
- connections.value = data.connections;
821
- });
822
- });
823
- const title = computed(() => {
824
- return `${count.value} viewer${count.value > 1 ? "s" : ""} currently online (${Object.keys(connections.value).map((host) => `${connections.value[host]} from ${host}`).join(", ")})`;
825
- });
826
- const ui = computed(() => viewersCounter());
827
- return (_ctx, _cache) => {
828
- return openBlock(), createBlock(Transition, { name: "fade" }, {
829
- default: withCtx(() => [count.value ? (openBlock(), createElementBlock("div", {
830
- key: 0,
831
- title: title.value,
832
- class: normalizeClass(ui.value.base({ class: [props.class, props.ui?.base] }))
833
- }, [createElementVNode("span", null, toDisplayString(count.value), 1), createElementVNode("span", {
834
- class: normalizeClass(ui.value.dot({ class: props.ui?.dot })),
835
- "aria-hidden": "true"
836
- }, null, 2)], 10, _hoisted_1)) : createCommentVNode("v-if", true)]),
837
- _: 1
838
- });
839
- };
840
- }
841
- });
842
- //#endregion
843
- export { _sfc_main as Container, _sfc_main$1 as Feedback, _sfc_main$2 as FeedbackCard, _sfc_main$3 as Header, _sfc_main$4 as Page, _sfc_main$5 as PageHeader, _sfc_main$6 as PageTitle, _sfc_main$7 as Socials, _sfc_main$8 as Sponsors, _sfc_main$9 as TableOfContents, _sfc_main$10 as ViewersCounter, useTableOfContents_default as useTableOfContents, useUmami };
1
+ /* empty css */
2
+ import useTableOfContents_default from "./composables/useTableOfContents.js";
3
+ import useUmami from "./composables/useUmami.js";
4
+ export { useTableOfContents_default as useTableOfContents, useUmami };