какие-то приколы, не помню
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(python -c \"import sys,json; p=json.load\\(sys.stdin\\); deps={**p.get\\('dependencies',{}\\), **p.get\\('devDependencies',{}\\)}; [print\\(k,v\\) for k in sorted\\(deps\\) if any\\(x in k for x in ['mediasoup','socket','vueuse','vue']\\)]\")"
|
||||
"Bash(python -c \"import sys,json; p=json.load\\(sys.stdin\\); deps={**p.get\\('dependencies',{}\\), **p.get\\('devDependencies',{}\\)}; [print\\(k,v\\) for k in sorted\\(deps\\) if any\\(x in k for x in ['mediasoup','socket','vueuse','vue']\\)]\")",
|
||||
"Bash(yarn vue-tsc *)",
|
||||
"Bash(yarn eslint *)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
"@zag-js/file-upload": "^1.41.0",
|
||||
"@zag-js/file-utils": "^1.40.0",
|
||||
"@zag-js/password-input": "^1.40.0",
|
||||
"@zag-js/slider": "^1.41.2",
|
||||
"@zag-js/switch": "^1.41.1",
|
||||
"@zag-js/toggle": "^1.40.0",
|
||||
"@zag-js/vue": "^1.40.0",
|
||||
"date-fns": "^4.1.0",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ChatMessage } from '@shared/api/generated-chad-api.ts'
|
||||
import type { Channel, ChatMessage } from '@shared/api/generated-chad-api.ts'
|
||||
import { useAuth } from '@shared/composables/use-auth.ts'
|
||||
import { useClients } from '@shared/composables/use-clients'
|
||||
import { useEventBus } from '@shared/composables/use-event-bus.ts'
|
||||
@@ -12,12 +12,10 @@ export default function () {
|
||||
const { addClient, updateClient, removeClient, clear: clearClients } = useClients()
|
||||
const eventBus = useEventBus()
|
||||
|
||||
watch(signaling.connected, (connected) => {
|
||||
if (!connected)
|
||||
watch(signaling.socket, (socket) => {
|
||||
if (!socket)
|
||||
return
|
||||
|
||||
const socket = signaling.socket.value!
|
||||
|
||||
socket.on('initialized', async ({ clients }) => {
|
||||
addClient(...clients)
|
||||
})
|
||||
@@ -42,6 +40,22 @@ export default function () {
|
||||
socket.on('chat:new-message', (message: ChatMessage) => {
|
||||
eventBus.emit('chat:new-message', message)
|
||||
})
|
||||
|
||||
socket.on('channel-created', async (channel: Channel) => {
|
||||
eventBus.emit('channel:created', channel)
|
||||
|
||||
await queryClient.setQueryData(['channel-list'], (channels: Channel[]) => {
|
||||
return [...channels, channel]
|
||||
})
|
||||
})
|
||||
|
||||
socket.on('channel-removed', async (channelId: Channel['id']) => {
|
||||
eventBus.emit('channel:removed', channelId)
|
||||
|
||||
await queryClient.setQueryData(['channel-list'], (channels: Channel[]) => {
|
||||
return channels.filter(channel => channel.id !== channelId)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<template>
|
||||
<ChadDialog :id="DIALOG_ID" title="Create channel">
|
||||
<ChadInput v-model="name" label="Name" />
|
||||
<ChadInput v-model="name" label="Name" placeholder="Enter channel name..." />
|
||||
<ChadSwitch v-model="persistent" label="Persistent" style="margin-top: var(--space-4);" />
|
||||
|
||||
<template #actions>
|
||||
<ChadButton style="grid-column: 2" :disabled="!valid" :loading="submitting" @click="submit()">
|
||||
<ChadButton style="grid-column: 2" :disabled="!valid" :loading="submitting" size="lg" @click="submit()">
|
||||
Create
|
||||
</ChadButton>
|
||||
</template>
|
||||
@@ -14,6 +15,7 @@
|
||||
import ChadButton from '@shared/components/ui/Button.vue'
|
||||
import ChadDialog from '@shared/components/ui/Dialog.vue'
|
||||
import ChadInput from '@shared/components/ui/Input.vue'
|
||||
import ChadSwitch from '@shared/components/ui/Switch.vue'
|
||||
import { useDialogManager } from '@shared/composables/use-dialog.ts'
|
||||
import { computed, ref } from 'vue'
|
||||
import { mCreateChannel } from '@/entities/channel/api/mCreateChannel.ts'
|
||||
@@ -25,6 +27,7 @@ const dialogManager = useDialogManager()
|
||||
const { mutateAsync: createChannel, isPending: submitting } = mCreateChannel()
|
||||
|
||||
const name = ref('')
|
||||
const persistent = ref(false)
|
||||
|
||||
const valid = computed(() => {
|
||||
return name.value.trim().length > 0
|
||||
@@ -36,7 +39,7 @@ async function submit() {
|
||||
|
||||
await createChannel({
|
||||
name: name.value,
|
||||
persistent: false,
|
||||
persistent: persistent.value,
|
||||
})
|
||||
|
||||
dialogManager.close(DIALOG_ID)
|
||||
|
||||
93
new-client/src/entities/client/ui/ClientRow.vue
Normal file
93
new-client/src/entities/client/ui/ClientRow.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div class="client-row" v-bind="api.getRootProps()">
|
||||
<div class="client-row__header" v-bind="api.getTriggerProps()">
|
||||
<ChadAvatar class="client-row__avatar" src="" :fallback="initials" size="sm" :highlighted="isMe" />
|
||||
|
||||
<span class="client-row__name">{{ client.username }}</span>
|
||||
|
||||
<div class="client-row__badges" />
|
||||
</div>
|
||||
|
||||
<div class="client-row__settings" v-bind="api.getContentProps()">
|
||||
<ChadSlider label="Volume" />
|
||||
|
||||
<div class="client-row__actions">
|
||||
<ChadButton :icon="VolumeOffIcon" type="secondary" size="sm">
|
||||
Mute
|
||||
</ChadButton>
|
||||
|
||||
<ChadButton :icon="HandFistIcon" type="secondary" size="sm">
|
||||
Poke
|
||||
</ChadButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ChadClient } from '@shared/types.ts'
|
||||
import type { Props as CollapsibleProps } from '@zag-js/collapsible'
|
||||
import { HandFistIcon, VolumeOffIcon } from '@lucide/vue'
|
||||
import ChadAvatar from '@shared/components/ui/Avatar.vue'
|
||||
import ChadButton from '@shared/components/ui/Button.vue'
|
||||
import ChadSlider from '@shared/components/ui/Slider.vue'
|
||||
import { useClients } from '@shared/composables/use-clients.ts'
|
||||
import { connect as collapsibleConnect, machine as collapsibleMachine } from '@zag-js/collapsible'
|
||||
import { normalizeProps, useMachine } from '@zag-js/vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
client: ChadClient
|
||||
}>()
|
||||
|
||||
const { self } = useClients()
|
||||
|
||||
const initials = computed(() => props.client.username.slice(props.client.username.length - 2))
|
||||
|
||||
const isMe = computed(() => self.value?.socketId === props.client.socketId)
|
||||
|
||||
const service = useMachine(collapsibleMachine, computed(() => {
|
||||
return {
|
||||
id: `client-${props.client.socketId}`,
|
||||
} as CollapsibleProps
|
||||
}))
|
||||
|
||||
const api = computed(() => collapsibleConnect(service, normalizeProps))
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.client-row {
|
||||
padding-inline: var(--space-4);
|
||||
|
||||
&:hover,
|
||||
&[data-state='open'] {
|
||||
background-color: var(--grey-1);
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
overflow: hidden;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
&__name {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__settings {
|
||||
padding-block: var(--space-2);
|
||||
}
|
||||
|
||||
&__actions {
|
||||
margin-top: var(--space-3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -6,7 +6,7 @@
|
||||
</div>
|
||||
|
||||
<template #actions>
|
||||
<ChadButton full native-type="submit" :disabled="!valid" :loading="submitting">
|
||||
<ChadButton full native-type="submit" :disabled="!valid" :loading="submitting" size="lg">
|
||||
Let's go
|
||||
</ChadButton>
|
||||
</template>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</div>
|
||||
|
||||
<template #actions>
|
||||
<ChadButton full native-type="submit" :disabled="!valid" :loading="submitting">
|
||||
<ChadButton full native-type="submit" :disabled="!valid" :loading="submitting" size="lg">
|
||||
Create an account
|
||||
</ChadButton>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
<template>
|
||||
<div class="chad-avatar" :class="{ highlighted }" v-bind="api.getRootProps()">
|
||||
<span class="chad-avatar__fallback" v-bind="api.getFallbackProps()">{{ fallback }}</span>
|
||||
<img class="chad-avatar__image" :alt="fallback" :src="src" v-bind="api.getImageProps()">
|
||||
<div
|
||||
:class="[
|
||||
bem.b(),
|
||||
bem.is('highlighted', highlighted),
|
||||
bem.exp(!!size, bem.m(`size_${size!}`)),
|
||||
]"
|
||||
v-bind="api.getRootProps()"
|
||||
>
|
||||
<span :class="bem.e('fallback')" v-bind="api.getFallbackProps()">{{ fallback }}</span>
|
||||
<img :class="bem.e('image')" :alt="fallback" :src="src" v-bind="api.getImageProps()">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
import * as avatar from '@zag-js/avatar'
|
||||
import { normalizeProps, useMachine } from '@zag-js/vue'
|
||||
import { computed, useId } from 'vue'
|
||||
@@ -21,6 +29,8 @@ defineProps<{
|
||||
highlighted?: boolean
|
||||
}>()
|
||||
|
||||
const bem = useBem('chad-avatar')
|
||||
|
||||
const service = useMachine(avatar.machine, { id: useId() })
|
||||
|
||||
const api = computed(() => avatar.connect(service, normalizeProps))
|
||||
@@ -35,6 +45,12 @@ const api = computed(() => avatar.connect(service, normalizeProps))
|
||||
width: 32px;
|
||||
aspect-ratio: 1;
|
||||
|
||||
&--size_sm {
|
||||
width: 24px;
|
||||
outline-width: 1px;
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
&__fallback {
|
||||
@include font-label;
|
||||
|
||||
@@ -43,7 +59,13 @@ const api = computed(() => avatar.connect(service, normalizeProps))
|
||||
line-height: 32px;
|
||||
background-color: var(--grey-2);
|
||||
|
||||
#{$self}.highlighted & {
|
||||
#{$self}--size_sm & {
|
||||
@include font-micro;
|
||||
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
#{$self}.is-highlighted & {
|
||||
background-color: var(--yellow);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
<button
|
||||
:class="[
|
||||
bem.b(),
|
||||
bem.exp(!!type, bem.m(type!)),
|
||||
bem.exp(!!type, bem.m(`type_${type!}`)),
|
||||
bem.exp(!!size, bem.m(`size_${size!}`)),
|
||||
bem.is('icon-only', iconOnly),
|
||||
bem.is('loading', loading),
|
||||
bem.is('disabled', disabled),
|
||||
@@ -11,21 +12,20 @@
|
||||
:disabled="disabled"
|
||||
:type="nativeType"
|
||||
>
|
||||
<ChadSpinner v-if="loading" class="chad-button__spinner" />
|
||||
<!-- <ChadSpinner v-if="loading" class="chad-button__spinner" /> -->
|
||||
|
||||
<template v-else>
|
||||
<Component :is="icon" v-if="icon" class="chad-button__icon" />
|
||||
<!-- <template v-else> -->
|
||||
<Component :is="icon" v-if="icon" :class="bem.e('icon')" />
|
||||
|
||||
<span v-if="$slots.default">
|
||||
<slot />
|
||||
</span>
|
||||
</template>
|
||||
<span v-if="$slots.default">
|
||||
<slot />
|
||||
</span>
|
||||
<!-- </template> -->
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Component } from 'vue'
|
||||
import ChadSpinner from '@shared/components/ui/Spinner.vue'
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
import { computed, useSlots } from 'vue'
|
||||
|
||||
@@ -43,10 +43,11 @@ const props = withDefaults(
|
||||
export interface ChadButtonProps {
|
||||
loading?: boolean
|
||||
disabled?: boolean
|
||||
type?: 'secondary'
|
||||
type?: 'secondary' | 'danger'
|
||||
nativeType?: 'button' | 'submit'
|
||||
icon?: Component
|
||||
full?: boolean
|
||||
size?: 'sm' | 'lg'
|
||||
}
|
||||
|
||||
const slots = useSlots()
|
||||
@@ -59,13 +60,15 @@ const iconOnly = computed(() => {
|
||||
|
||||
<style lang="scss">
|
||||
.chad-button {
|
||||
$self: &;
|
||||
|
||||
@include font-display-14;
|
||||
|
||||
flex-shrink: 0;
|
||||
border: none;
|
||||
color: var(--ink);
|
||||
padding: 0 var(--space-3);
|
||||
height: 44px;
|
||||
height: 36px;
|
||||
background-color: var(--yellow);
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
@@ -82,45 +85,82 @@ const iconOnly = computed(() => {
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--yellow-deep);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--ink);
|
||||
color: var(--yellow);
|
||||
}
|
||||
|
||||
&--secondary {
|
||||
background-color: var(--grey-1);
|
||||
|
||||
&:not(:disabled) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--grey-2);
|
||||
background-color: var(--yellow-deep);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--grey-3);
|
||||
color: var(--ink);
|
||||
background-color: var(--ink);
|
||||
color: var(--yellow);
|
||||
}
|
||||
}
|
||||
|
||||
&--size_sm {
|
||||
@include font-body-bold;
|
||||
|
||||
height: 28px;
|
||||
outline-width: 1px;
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
&--size_lg {
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
&--type_secondary {
|
||||
background-color: var(--paper);
|
||||
|
||||
&:not(:disabled) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--grey-2);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--yellow);
|
||||
color: var(--ink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--type_danger {
|
||||
outline-color: var(--red);
|
||||
background-color: var(--paper);
|
||||
color: var(--red);
|
||||
|
||||
&:not(:disabled) {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: var(--red);
|
||||
color: var(--white);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
background-color: var(--grey-1);
|
||||
color: var(--grey-3);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&.is-loading {
|
||||
background-color: var(--grey-1);
|
||||
cursor: wait;
|
||||
--stripe-width: 44px;
|
||||
|
||||
@include diagonal-stripes;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
&:not(:last-child) {
|
||||
margin-right: var(--space-1);
|
||||
}
|
||||
|
||||
#{$self}--size_sm & {
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
<template>
|
||||
<Component :is="as" class="chad-card">
|
||||
<div v-if="title || description" class="chad-card__header">
|
||||
<p v-if="title" class="chad-card__title">
|
||||
<Component :is="as" :class="bem.b()">
|
||||
<div v-if="title || description" :class="bem.e('header')">
|
||||
<p v-if="title" :class="bem.e('title')">
|
||||
{{ title }}
|
||||
</p>
|
||||
|
||||
<p v-if="description" class="chad-card__description">
|
||||
<p v-if="description" :class="bem.e('description')">
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="chad-card__content">
|
||||
<div :class="bem.e('content')">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<div v-if="!!slots.actions" class="chad-card__actions">
|
||||
<div v-if="!!slots.actions" :class="bem.e('actions')">
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
|
||||
<div v-if="!!slots.bottom" class="chad-card__bottom">
|
||||
<div v-if="!!slots.bottom" :class="bem.e('bottom')">
|
||||
<slot name="bottom" />
|
||||
</div>
|
||||
</Component>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
|
||||
defineOptions({
|
||||
name: 'ChadCard',
|
||||
})
|
||||
@@ -42,6 +44,8 @@ const slots = defineSlots<{
|
||||
bottom: []
|
||||
}>()
|
||||
|
||||
const bem = useBem('chad-card')
|
||||
|
||||
interface Props {
|
||||
as?: string
|
||||
title?: string
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
<template>
|
||||
<div
|
||||
class="chad-input"
|
||||
:class="{
|
||||
'is-invalid': !!error,
|
||||
}"
|
||||
>
|
||||
<label v-if="label" :for="inputId" class="chad-input__label">
|
||||
<div :class="[bem.b(), bem.is('invalid', !!error)]">
|
||||
<label v-if="label" :for="inputId" :class="bem.e('label')">
|
||||
{{ label }}
|
||||
</label>
|
||||
|
||||
<input :id="inputId" v-model="modelValue" class="chad-input__input" :placeholder="placeholder" type="text" autocomplete="off">
|
||||
<input :id="inputId" v-model="modelValue" :class="bem.e('input')" :placeholder="placeholder" type="text" autocomplete="off">
|
||||
|
||||
<p v-if="helper" class="chad-input__helper">
|
||||
<p v-if="helper" :class="bem.e('helper')">
|
||||
{{ helper }}
|
||||
</p>
|
||||
<p v-if="error" class="chad-input__error">
|
||||
<p v-if="error" :class="bem.e('error')">
|
||||
{{ error }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
import { computed, useId } from 'vue'
|
||||
|
||||
interface Props {
|
||||
@@ -37,6 +33,8 @@ defineOptions({
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const bem = useBem('chad-input')
|
||||
|
||||
const modelValue = defineModel<string>('modelValue')
|
||||
|
||||
const inputId = computed(() => {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<div class="chad-notification-badge">
|
||||
<div :class="bem.b()">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
|
||||
const bem = useBem('chad-notification-badge')
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div class="chad-password-input" v-bind="api.getRootProps()">
|
||||
<label v-if="label" class="chad-password-input__label" v-bind="api.getLabelProps()">
|
||||
<div :class="bem.b()" v-bind="api.getRootProps()">
|
||||
<label v-if="label" :class="bem.e('label')" v-bind="api.getLabelProps()">
|
||||
{{ label }}
|
||||
</label>
|
||||
|
||||
<div class="chad-password-input__control" v-bind="api.getControlProps()">
|
||||
<input v-bind="api.getInputProps()" v-model="modelValue" class="chad-password-input__input">
|
||||
<div :class="bem.e('control')" v-bind="api.getControlProps()">
|
||||
<input v-bind="api.getInputProps()" v-model="modelValue" :class="bem.e('input')">
|
||||
|
||||
<button class="chad-password-input__visibility-trigger" v-bind="api.getVisibilityTriggerProps()">
|
||||
<button :class="bem.e('visibility-trigger')" v-bind="api.getVisibilityTriggerProps()">
|
||||
<Component :is="api.visible ? EyeIcon : EyeOffIcon " v-bind="api.getIndicatorProps()" />
|
||||
</button>
|
||||
</div>
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { EyeIcon, EyeOffIcon } from '@lucide/vue'
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
import * as passwordInput from '@zag-js/password-input'
|
||||
import { normalizeProps, useMachine } from '@zag-js/vue'
|
||||
import { computed, useId } from 'vue'
|
||||
@@ -34,6 +35,8 @@ defineOptions({
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const bem = useBem('chad-password-input')
|
||||
|
||||
const modelValue = defineModel<string>('modelValue')
|
||||
|
||||
const inputId = computed(() => {
|
||||
|
||||
86
new-client/src/shared/components/ui/Slider.vue
Normal file
86
new-client/src/shared/components/ui/Slider.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div v-bind="api.getRootProps()" :class="[bem.b()]">
|
||||
<div style="margin-bottom: var(--space-2);">
|
||||
<label v-if="label" :class="bem.e('label')" v-bind="api.getLabelProps()">{{ label }}</label>
|
||||
<output v-bind="api.getValueTextProps()">{{ api.value.at(0) }}</output>
|
||||
</div>
|
||||
|
||||
<div :class="bem.e('control')" v-bind="api.getControlProps()">
|
||||
<div :class="bem.e('track')" v-bind="api.getTrackProps()">
|
||||
<div :class="bem.e('range')" v-bind="api.getRangeProps()" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="(_, index) in api.value"
|
||||
:key="index"
|
||||
v-bind="api.getThumbProps({ index })"
|
||||
:class="bem.e('thumb')"
|
||||
>
|
||||
<input v-bind="api.getHiddenInputProps({ index })">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Props as SliderProps } from '@zag-js/slider'
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
import { connect, machine } from '@zag-js/slider'
|
||||
import { normalizeProps, useMachine } from '@zag-js/vue'
|
||||
import { computed, useId } from 'vue'
|
||||
|
||||
defineOptions({
|
||||
name: 'ChadSlider',
|
||||
})
|
||||
|
||||
const props = defineProps<ChadSliderProps>()
|
||||
|
||||
export interface ChadSliderProps {
|
||||
label?: string
|
||||
}
|
||||
|
||||
const id = useId()
|
||||
const bem = useBem('chad-slider')
|
||||
|
||||
const service = useMachine(machine, computed(() => {
|
||||
return {
|
||||
id,
|
||||
origin: 'center',
|
||||
thumbAlignment: 'center',
|
||||
} as SliderProps
|
||||
}))
|
||||
const api = computed(() => connect(service, normalizeProps))
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.chad-slider {
|
||||
&__label {
|
||||
@include font-micro;
|
||||
|
||||
color: var(--grey-3);
|
||||
}
|
||||
|
||||
&__control {
|
||||
background-color: var(--paper);
|
||||
border: var(--border-w) solid var(--ink);
|
||||
//outline-offset: calc(var(--border-w) * -1);
|
||||
}
|
||||
|
||||
&__track {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
&__range {
|
||||
background-color: var(--yellow);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&__thumb {
|
||||
width: 10px;
|
||||
height: 28px;
|
||||
background-color: var(--ink);
|
||||
top: -4px;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +1,15 @@
|
||||
<template>
|
||||
<div class="chad-spinner" />
|
||||
<div :class="bem.b()" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
|
||||
defineOptions({
|
||||
name: 'ChadSpinner',
|
||||
})
|
||||
|
||||
const bem = useBem('chad-spinner')
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
90
new-client/src/shared/components/ui/Switch.vue
Normal file
90
new-client/src/shared/components/ui/Switch.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div :class="[bem.b()]">
|
||||
<label :class="bem.e('root')" v-bind="api.getRootProps()">
|
||||
<input v-bind="api.getHiddenInputProps()">
|
||||
<span :class="bem.e('control')" v-bind="api.getControlProps()">
|
||||
<span :class="bem.e('thumb')" v-bind="api.getThumbProps()" />
|
||||
</span>
|
||||
<span v-if="label" :class="bem.e('label')" v-bind="api.getLabelProps()">
|
||||
<span>{{ label }}</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Props as SwitchProps } from '@zag-js/switch'
|
||||
import useBem from '@shared/composables/use-bem'
|
||||
import { connect, machine } from '@zag-js/switch'
|
||||
import { normalizeProps, useMachine } from '@zag-js/vue'
|
||||
import { computed, useId } from 'vue'
|
||||
|
||||
export interface ChadSwitchProps {
|
||||
label?: string
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: 'ChadSwitch',
|
||||
})
|
||||
|
||||
const props = defineProps<ChadSwitchProps>()
|
||||
|
||||
const modelValue = defineModel('modelValue')
|
||||
|
||||
const id = useId()
|
||||
const bem = useBem('chad-switch')
|
||||
|
||||
const service = useMachine(machine, computed(() => {
|
||||
return {
|
||||
id,
|
||||
checked: modelValue.value,
|
||||
onCheckedChange: (details) => {
|
||||
modelValue.value = details.checked
|
||||
},
|
||||
} as SwitchProps
|
||||
}))
|
||||
|
||||
const api = computed(() => connect(service, normalizeProps))
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.chad-switch {
|
||||
&__root {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
cursor: pointer;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__control {
|
||||
border: var(--border-w) solid var(--ink);
|
||||
height: var(--space-6);
|
||||
aspect-ratio: 2;
|
||||
position: relative;
|
||||
display: flex;
|
||||
padding: var(--border-w);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__thumb {
|
||||
background-color: var(--ink);
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
|
||||
&[data-state='checked'] {
|
||||
background-color: var(--yellow);
|
||||
translate: 100% 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__label {
|
||||
@include font-label;
|
||||
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,10 +1,12 @@
|
||||
<template>
|
||||
<div class="chad-tag" :data-type="type">
|
||||
<div :class="[bem.b(), bem.m(`type_${type}`)]">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
|
||||
interface Props {
|
||||
type: 'success' | 'error'
|
||||
}
|
||||
@@ -14,6 +16,8 @@ defineOptions({
|
||||
})
|
||||
|
||||
defineProps<Props>()
|
||||
|
||||
const bem = useBem('chad-tag')
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -32,13 +36,13 @@ defineProps<Props>()
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
&[data-type='success'] {
|
||||
&--type_success {
|
||||
&::before {
|
||||
background-color: var(--green);
|
||||
}
|
||||
}
|
||||
|
||||
&[data-type='error'] {
|
||||
&--type_error {
|
||||
&::before {
|
||||
background-color: var(--red);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<template>
|
||||
<button class="chad-to-bottom">
|
||||
<button :class="bem.b()">
|
||||
<ArrowDown />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ArrowDown } from '@lucide/vue'
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
|
||||
defineOptions({
|
||||
name: 'ChadToBottom',
|
||||
})
|
||||
|
||||
const bem = useBem('chad-to-bottom')
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<button class="chad-toggle" v-bind="api.getRootProps()">
|
||||
<span class="chad-toggle__indicator" v-bind="api.getIndicatorProps()" />
|
||||
<button :class="bem.b()" v-bind="api.getRootProps()">
|
||||
<span :class="bem.e('indicator')" v-bind="api.getIndicatorProps()" />
|
||||
<slot />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Component } from 'vue'
|
||||
import useBem from '@shared/composables/use-bem.ts'
|
||||
import * as toggle from '@zag-js/toggle'
|
||||
import { normalizeProps, useMachine } from '@zag-js/vue'
|
||||
import { computed } from 'vue'
|
||||
@@ -20,6 +21,8 @@ const props = defineProps<{
|
||||
icon?: Component
|
||||
}>()
|
||||
|
||||
const bem = useBem('chad-toggle')
|
||||
|
||||
const modelValue = defineModel<boolean>('modelValue')
|
||||
|
||||
const service = useMachine(toggle.machine, computed(() => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ChatMessage } from '@shared/api/generated-chad-api.ts'
|
||||
import type { Channel, ChatMessage } from '@shared/api/generated-chad-api.ts'
|
||||
import type { EventType } from 'mitt'
|
||||
import mitt from 'mitt'
|
||||
|
||||
@@ -21,6 +21,10 @@ export interface AppEvents extends Record<EventType, unknown> {
|
||||
// 'producer:paused': Producer
|
||||
// 'producer:resumed': Producer
|
||||
|
||||
'channel:created': Channel
|
||||
'channel:removed': Channel['id']
|
||||
'channel:updated': Channel
|
||||
|
||||
'audio:muted': void
|
||||
'audio:unmuted': void
|
||||
'output:muted': void
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
</header>
|
||||
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar__top">
|
||||
<ChadButton type="secondary" full :icon="PlusIcon" @click="createChannelDialog.open()">
|
||||
Create channel
|
||||
</ChadButton>
|
||||
</div>
|
||||
|
||||
<ChannelList class="sidebar__channel-list" />
|
||||
|
||||
<!-- <dl> -->
|
||||
@@ -37,9 +43,6 @@
|
||||
<!-- Logout -->
|
||||
<!-- </ChadButton> -->
|
||||
|
||||
<ChadButton style="margin: var(--space-2)" type="secondary" @click="createChannelDialog.open()">
|
||||
Create channel
|
||||
</ChadButton>
|
||||
<ControlPanel />
|
||||
</aside>
|
||||
|
||||
@@ -50,6 +53,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PlusIcon } from '@lucide/vue'
|
||||
import ChadButton from '@shared/components/ui/Button.vue'
|
||||
import { useApp } from '@shared/composables/use-app.js'
|
||||
import { useDialog } from '@shared/composables/use-dialog.ts'
|
||||
@@ -140,6 +144,10 @@ watchEffect(() => {
|
||||
border-right: var(--border-w) solid var(--ink);
|
||||
overflow-y: auto;
|
||||
|
||||
&__top {
|
||||
padding: var(--space-3);
|
||||
}
|
||||
|
||||
&__channel-list {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
8
new-client/src/shared/styles/animations.scss
Normal file
8
new-client/src/shared/styles/animations.scss
Normal file
@@ -0,0 +1,8 @@
|
||||
@keyframes diagonal-stripes {
|
||||
from {
|
||||
background-position-x: 0;
|
||||
}
|
||||
to {
|
||||
background-position-x: var(--stripe-width);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
@use 'tokens.scss';
|
||||
@use 'animations.scss';
|
||||
|
||||
html,
|
||||
body,
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
@forward 'mixins/typography';
|
||||
11
new-client/src/shared/styles/mixins/animations.scss
Normal file
11
new-client/src/shared/styles/mixins/animations.scss
Normal file
@@ -0,0 +1,11 @@
|
||||
@mixin diagonal-stripes {
|
||||
background-image: repeating-linear-gradient(
|
||||
-45deg,
|
||||
var(--grey-1) 25%,
|
||||
var(--grey-1) 50%,
|
||||
var(--grey-2) 50%,
|
||||
var(--grey-2) 75%
|
||||
);
|
||||
background-size: var(--stripe-width) var(--stripe-width);
|
||||
animation: diagonal-stripes 800ms infinite linear;
|
||||
}
|
||||
2
new-client/src/shared/styles/mixins/index.scss
Normal file
2
new-client/src/shared/styles/mixins/index.scss
Normal file
@@ -0,0 +1,2 @@
|
||||
@forward 'typography';
|
||||
@forward 'animations';
|
||||
@@ -1,53 +1,119 @@
|
||||
<template>
|
||||
<li v-bind="api.getRootProps()" class="channel">
|
||||
<div class="channel__header" v-bind="api.getTriggerProps()">
|
||||
{{ channel.name }}
|
||||
<div
|
||||
class="channel"
|
||||
:class="{
|
||||
'is-active': isActive,
|
||||
}"
|
||||
>
|
||||
<div class="channel__header" @click="joinChannel">
|
||||
<span class="channel__name">{{ channel.name }}</span>
|
||||
|
||||
<div v-if="false" class="channel__actions">
|
||||
<ChadButton size="sm" type="danger" :icon="TrashIcon" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-bind="api.getContentProps()" class="channel__content">
|
||||
<p v-for="client in clients" :key="client.socketId">
|
||||
{{ client.username }}
|
||||
</p>
|
||||
<div v-if="clients.length > 0" class="channel__content">
|
||||
<ClientRow v-for="client in clients" :key="client.socketId" class="channel__client" :client="client" />
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Channel } from '@shared/api/generated-chad-api.ts'
|
||||
import { TrashIcon } from '@lucide/vue'
|
||||
import ChadButton from '@shared/components/ui/Button.vue'
|
||||
import { useClients } from '@shared/composables/use-clients.ts'
|
||||
import * as collapsible from '@zag-js/collapsible'
|
||||
import { normalizeProps, useMachine } from '@zag-js/vue'
|
||||
import { useSignaling } from '@shared/composables/use-signaling.ts'
|
||||
import { computed } from 'vue'
|
||||
import ClientRow from '@/entities/client/ui/ClientRow.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
channel: Channel
|
||||
}>()
|
||||
|
||||
const { findByChannel } = useClients()
|
||||
|
||||
const service = useMachine(collapsible.machine, computed(() => {
|
||||
return {
|
||||
id: props.channel.id,
|
||||
defaultOpen: true,
|
||||
}
|
||||
}))
|
||||
|
||||
const api = computed(() => collapsible.connect(service, normalizeProps))
|
||||
const { findByChannel, self } = useClients()
|
||||
const { socket } = useSignaling()
|
||||
|
||||
const clients = computed(() => {
|
||||
return findByChannel(props.channel.id)
|
||||
})
|
||||
|
||||
const isActive = computed(() => {
|
||||
return self.value?.channelId === props.channel.id
|
||||
})
|
||||
|
||||
function joinChannel() {
|
||||
if (isActive.value || !socket.value)
|
||||
return
|
||||
|
||||
socket.value.emit('join-channel', { channelId: props.channel.id })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.channel {
|
||||
padding-inline: var(--space-3);
|
||||
$self: &;
|
||||
|
||||
&__header {
|
||||
@include font-micro;
|
||||
|
||||
padding-block: var(--space-2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding-inline: var(--space-4);
|
||||
color: var(--grey-3);
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: var(--space-1);
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--grey-1);
|
||||
|
||||
&::after {
|
||||
background-color: var(--grey-2);
|
||||
}
|
||||
|
||||
#{$self}__actions {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
#{$self}.is-active &:after {
|
||||
background-color: var(--yellow);
|
||||
}
|
||||
}
|
||||
|
||||
&__name {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
flex-shrink: 0;
|
||||
justify-self: flex-end;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-1);
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&__content {
|
||||
padding-block: var(--space-2);
|
||||
}
|
||||
|
||||
&__client {
|
||||
&:not(:last-child) {
|
||||
margin-bottom: var(--space-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -24,8 +24,6 @@ const bem = useBem('chat-attachment')
|
||||
|
||||
<style lang="scss">
|
||||
.chat-attachment {
|
||||
--stripe-width: 20px;
|
||||
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -39,24 +37,9 @@ const bem = useBem('chat-attachment')
|
||||
color: var(--grey-3);
|
||||
|
||||
&.is-loading {
|
||||
background-image: repeating-linear-gradient(
|
||||
-45deg,
|
||||
transparent 25%,
|
||||
transparent 50%,
|
||||
var(--grey-2) 50%,
|
||||
var(--grey-2) 75%
|
||||
);
|
||||
background-size: var(--stripe-width) var(--stripe-width);
|
||||
animation: loading 500ms infinite linear;
|
||||
}
|
||||
}
|
||||
--stripe-width: 20px;
|
||||
|
||||
@keyframes loading {
|
||||
from {
|
||||
background-position-x: 0;
|
||||
}
|
||||
to {
|
||||
background-position-x: var(--stripe-width);
|
||||
@include diagonal-stripes;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
class="chat-input__add-attachment"
|
||||
type="secondary"
|
||||
:icon="Plus"
|
||||
size="lg"
|
||||
@click="fileUploadApi.openFilePicker()"
|
||||
/>
|
||||
|
||||
@@ -18,6 +19,7 @@
|
||||
<ChadButton
|
||||
class="chat-input__send"
|
||||
:loading="isUploading"
|
||||
size="lg"
|
||||
@click="sendMessage()"
|
||||
>
|
||||
Send
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ChatMessage } from '@shared/api/generated-chad-api.ts'
|
||||
import ChadSpinner from '@shared/components/ui/Spinner.vue'
|
||||
import ChadToBottom from '@shared/components/ui/ToBottom.vue'
|
||||
import { useClients } from '@shared/composables/use-clients.ts'
|
||||
import { useEventBus } from '@shared/composables/use-event-bus.ts'
|
||||
import { useChatScroll } from '@widgets/chat/composables/use-chat-scroll.ts'
|
||||
import ChatMessageGroup from '@widgets/chat/ui/ChatMessageGroup.vue'
|
||||
@@ -33,6 +35,7 @@ import { onUnmounted, ref, useTemplateRef, watch } from 'vue'
|
||||
import { useChatHistory } from '../composables/use-chat-history'
|
||||
|
||||
const eventBus = useEventBus()
|
||||
const { self } = useClients()
|
||||
|
||||
const scrollRef = useTemplateRef('scroll')
|
||||
|
||||
@@ -64,8 +67,8 @@ onUnmounted(() => {
|
||||
eventBus.off('chat:new-message', onNewChatMessage)
|
||||
})
|
||||
|
||||
function onNewChatMessage() {
|
||||
if (!arrivedState.start) {
|
||||
function onNewChatMessage(message: ChatMessage) {
|
||||
if (!arrivedState.start && message.senderUsername !== self.value?.username) {
|
||||
hasUnreadMessages.value = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export default defineConfig({
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: `
|
||||
@use "@shared/styles/mixins.scss" as *;
|
||||
@use "@shared/styles/mixins" as *;
|
||||
`,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1210,6 +1210,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/anatomy/-/anatomy-1.41.1.tgz#9cb2a4c6506fd14bbd3387e523885257ed1e37d9"
|
||||
integrity sha512-wBQVpl8TC9O5AjeJrnmNdJWEUYorTi7iklOcySeXIeaz6D7Y0YY0YbEOSFNsRTpn/NQHwkPejf3i5qkKavNHXw==
|
||||
|
||||
"@zag-js/anatomy@1.41.2":
|
||||
version "1.41.2"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/anatomy/-/anatomy-1.41.2.tgz#16569b7eb743cb4459fbaf218bdcd5fd72cea32d"
|
||||
integrity sha512-Fm9hqdrvaCzCsdcf19G8WZxYtHElKltkGHdhqMEt4XU+ULTr1DK7KbOtDDv9J27CuzqSLALUz5QfRjPftoKHwg==
|
||||
|
||||
"@zag-js/aria-hidden@1.41.1":
|
||||
version "1.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/aria-hidden/-/aria-hidden-1.41.1.tgz#69c7c695c718baaaad4db9ae8ddae1c17d5bbfcb"
|
||||
@@ -1255,6 +1260,14 @@
|
||||
"@zag-js/dom-query" "1.41.1"
|
||||
"@zag-js/utils" "1.41.1"
|
||||
|
||||
"@zag-js/core@1.41.2":
|
||||
version "1.41.2"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/core/-/core-1.41.2.tgz#d315e84ac55ec4038e5f40d870b3987613882fb3"
|
||||
integrity sha512-xXTN3zKwOtMI4+5dG2cG+T1B4WR3X9alXiYaPJKaGd4N2eYRj9JEPte3Hv9gtFm+RM0b9VIwksHEg25rqE4apw==
|
||||
dependencies:
|
||||
"@zag-js/dom-query" "1.41.2"
|
||||
"@zag-js/utils" "1.41.2"
|
||||
|
||||
"@zag-js/dialog@^1.41.1":
|
||||
version "1.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/dialog/-/dialog-1.41.1.tgz#12d3e5e341064103184dbfeeb1e77c0f7f0036a6"
|
||||
@@ -1293,6 +1306,13 @@
|
||||
dependencies:
|
||||
"@zag-js/types" "1.41.1"
|
||||
|
||||
"@zag-js/dom-query@1.41.2":
|
||||
version "1.41.2"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/dom-query/-/dom-query-1.41.2.tgz#fad51d82f548a55c9116c76370224f0f3fc5f656"
|
||||
integrity sha512-+eBk1nlJA312mNmY/GSThLRwcCRqMIL+A1pLsWvTlQLQjmH1/UxoAuv6l2yvRCT33XmC8FBlBIKnXhOCpDvIZA==
|
||||
dependencies:
|
||||
"@zag-js/types" "1.41.2"
|
||||
|
||||
"@zag-js/file-upload@^1.41.0":
|
||||
version "1.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/file-upload/-/file-upload-1.41.0.tgz#6ad2deb4d5edc9db1c46fda6823be3a9d404b625"
|
||||
@@ -1320,6 +1340,13 @@
|
||||
dependencies:
|
||||
"@zag-js/dom-query" "1.41.1"
|
||||
|
||||
"@zag-js/focus-visible@1.41.1":
|
||||
version "1.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/focus-visible/-/focus-visible-1.41.1.tgz#5f27ded76a0ab81bd063e01165ecde68168a2ebf"
|
||||
integrity sha512-uIPkVk7gTVFCEGuDTI/2f3tWEcbsX88SrjgIA31F/m3e5/ieDaeiTfq7pxn+naHwZKEhRNScAgwOpu2AQgc6ag==
|
||||
dependencies:
|
||||
"@zag-js/dom-query" "1.41.1"
|
||||
|
||||
"@zag-js/i18n-utils@1.41.0":
|
||||
version "1.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/i18n-utils/-/i18n-utils-1.41.0.tgz#da493ffac2482df38668a99d542d85a568516cc4"
|
||||
@@ -1353,6 +1380,17 @@
|
||||
dependencies:
|
||||
"@zag-js/dom-query" "1.41.1"
|
||||
|
||||
"@zag-js/slider@^1.41.2":
|
||||
version "1.41.2"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/slider/-/slider-1.41.2.tgz#d5f5f5f39a925cdde39b301eaccbacced64fa78b"
|
||||
integrity sha512-mKK2BwoDbIGxAdkdKkPZJA1SHtEQt3lS9hJ6WghefYU2vyd0BXoIKvcDV3xJOzly5LXYhH5cJITn6JtGK8353A==
|
||||
dependencies:
|
||||
"@zag-js/anatomy" "1.41.2"
|
||||
"@zag-js/core" "1.41.2"
|
||||
"@zag-js/dom-query" "1.41.2"
|
||||
"@zag-js/types" "1.41.2"
|
||||
"@zag-js/utils" "1.41.2"
|
||||
|
||||
"@zag-js/store@1.41.0":
|
||||
version "1.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/store/-/store-1.41.0.tgz#97a3ecc1bbb5fe8de51083e4dafaa0d0d3c2d741"
|
||||
@@ -1360,6 +1398,18 @@
|
||||
dependencies:
|
||||
proxy-compare "3.0.1"
|
||||
|
||||
"@zag-js/switch@^1.41.1":
|
||||
version "1.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/switch/-/switch-1.41.1.tgz#81141dfbba50c151800cf4548782d458091b632a"
|
||||
integrity sha512-69F4F/rGD8swQSPJY01J8To6qDVIWp87nfgNpsrUZ2CRcWxRCAjHqC3LwmVARg3pn8sa82jJPhw6VLJ81biXWQ==
|
||||
dependencies:
|
||||
"@zag-js/anatomy" "1.41.1"
|
||||
"@zag-js/core" "1.41.1"
|
||||
"@zag-js/dom-query" "1.41.1"
|
||||
"@zag-js/focus-visible" "1.41.1"
|
||||
"@zag-js/types" "1.41.1"
|
||||
"@zag-js/utils" "1.41.1"
|
||||
|
||||
"@zag-js/toggle@^1.40.0":
|
||||
version "1.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/toggle/-/toggle-1.41.0.tgz#3245e651fc6f7ae2a2c4f86ae244ae90f3d3b517"
|
||||
@@ -1385,6 +1435,13 @@
|
||||
dependencies:
|
||||
csstype "3.2.3"
|
||||
|
||||
"@zag-js/types@1.41.2":
|
||||
version "1.41.2"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/types/-/types-1.41.2.tgz#99e8eec960b6c6b5157e281be40cf380d0b7c8ed"
|
||||
integrity sha512-L6CNvK06lIVpy0X8eG3kbDIx8Uuv+3KHElxXYSzRXSJ7/OLCv1sTRgEvnxNtdIWOrksGgxF4JtT7PXtoClGqNQ==
|
||||
dependencies:
|
||||
csstype "3.2.3"
|
||||
|
||||
"@zag-js/utils@1.41.0":
|
||||
version "1.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/utils/-/utils-1.41.0.tgz#61639369aeadf26f91fe009b4ddce926c5ba607c"
|
||||
@@ -1395,6 +1452,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/utils/-/utils-1.41.1.tgz#248fc28510d625034553fd9a4213147204fca323"
|
||||
integrity sha512-IZGqDpQYvgCQlGcLTVCzWG5DEz318ZLVJhp8TtT9HPDNd+RJTcVHRja7z+vqQ0Su+wKZkuLlIh5gtraxQ+YX9Q==
|
||||
|
||||
"@zag-js/utils@1.41.2":
|
||||
version "1.41.2"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/utils/-/utils-1.41.2.tgz#1668137bc7b7bf5138203bac1feeeed0059c8e29"
|
||||
integrity sha512-Yj8FSrR7vGA6ahUhjrThfHAF+PM2Y1Yv2lkXkqZZd60mPBhixcot1+SHOfEMV63JimQcWrmQ8QbeYYMmF+ZpLQ==
|
||||
|
||||
"@zag-js/vue@^1.40.0":
|
||||
version "1.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/vue/-/vue-1.41.0.tgz#7e5649c1d5e7979493987de66d25d3deda90976e"
|
||||
|
||||
Reference in New Issue
Block a user