mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-24 17:23:50 +02:00
replace el-button-group with ToggleGroup
This commit is contained in:
@@ -9,65 +9,85 @@
|
||||
<el-tab-pane name="Normal" :label="t('dialog.new_instance.normal')">
|
||||
<el-form :model="newInstanceDialog" label-width="150px">
|
||||
<el-form-item :label="t('dialog.new_instance.access_type')">
|
||||
<el-radio-group v-model="newInstanceDialog.accessType" size="small" @change="buildInstance">
|
||||
<el-radio-button value="public">{{
|
||||
<ToggleGroup
|
||||
type="single"
|
||||
required
|
||||
variant="outline"
|
||||
size="sm"
|
||||
:model-value="newInstanceDialog.accessType"
|
||||
@update:model-value="(value) => {
|
||||
newInstanceDialog.accessType = value;
|
||||
buildInstance();
|
||||
}">
|
||||
<ToggleGroupItem value="public">{{
|
||||
t('dialog.new_instance.access_type_public')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="group">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="group">{{
|
||||
t('dialog.new_instance.access_type_group')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="friends+">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="friends+">{{
|
||||
t('dialog.new_instance.access_type_friend_plus')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="friends">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="friends">{{
|
||||
t('dialog.new_instance.access_type_friend')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="invite+">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="invite+">{{
|
||||
t('dialog.new_instance.access_type_invite_plus')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="invite">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="invite">{{
|
||||
t('dialog.new_instance.access_type_invite')
|
||||
}}</el-radio-button>
|
||||
</el-radio-group>
|
||||
}}</ToggleGroupItem>
|
||||
</ToggleGroup>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
:label="t('dialog.new_instance.group_access_type')">
|
||||
<el-radio-group
|
||||
v-model="newInstanceDialog.groupAccessType"
|
||||
size="small"
|
||||
@change="buildInstance">
|
||||
<el-radio-button
|
||||
<ToggleGroup
|
||||
type="single"
|
||||
required
|
||||
variant="outline"
|
||||
size="sm"
|
||||
:model-value="newInstanceDialog.groupAccessType"
|
||||
@update:model-value="(value) => {
|
||||
newInstanceDialog.groupAccessType = value;
|
||||
buildInstance();
|
||||
}">
|
||||
<ToggleGroupItem
|
||||
value="members"
|
||||
:disabled="
|
||||
!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-open-create')
|
||||
"
|
||||
>{{ t('dialog.new_instance.group_access_type_members') }}</el-radio-button
|
||||
:disabled="!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-open-create')"
|
||||
>{{ t('dialog.new_instance.group_access_type_members') }}</ToggleGroupItem
|
||||
>
|
||||
<el-radio-button
|
||||
<ToggleGroupItem
|
||||
value="plus"
|
||||
:disabled="
|
||||
!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-plus-create')
|
||||
"
|
||||
>{{ t('dialog.new_instance.group_access_type_plus') }}</el-radio-button
|
||||
:disabled="!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-plus-create')"
|
||||
>{{ t('dialog.new_instance.group_access_type_plus') }}</ToggleGroupItem
|
||||
>
|
||||
<el-radio-button
|
||||
<ToggleGroupItem
|
||||
value="public"
|
||||
:disabled="
|
||||
!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-public-create') ||
|
||||
newInstanceDialog.groupRef.privacy === 'private'
|
||||
"
|
||||
>{{ t('dialog.new_instance.group_access_type_public') }}</el-radio-button
|
||||
>{{ t('dialog.new_instance.group_access_type_public') }}</ToggleGroupItem
|
||||
>
|
||||
</el-radio-group>
|
||||
</ToggleGroup>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('dialog.new_instance.region')">
|
||||
<el-radio-group v-model="newInstanceDialog.region" size="small" @change="buildInstance">
|
||||
<el-radio-button value="US West">{{ t('dialog.new_instance.region_usw') }}</el-radio-button>
|
||||
<el-radio-button value="US East">{{ t('dialog.new_instance.region_use') }}</el-radio-button>
|
||||
<el-radio-button value="Europe">{{ t('dialog.new_instance.region_eu') }}</el-radio-button>
|
||||
<el-radio-button value="Japan">{{ t('dialog.new_instance.region_jp') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
<ToggleGroup
|
||||
type="single"
|
||||
required
|
||||
variant="outline"
|
||||
size="sm"
|
||||
:model-value="newInstanceDialog.region"
|
||||
@update:model-value="(value) => {
|
||||
newInstanceDialog.region = value;
|
||||
buildInstance();
|
||||
}">
|
||||
<ToggleGroupItem value="US West">{{ t('dialog.new_instance.region_usw') }}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="US East">{{ t('dialog.new_instance.region_use') }}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="Europe">{{ t('dialog.new_instance.region_eu') }}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="Japan">{{ t('dialog.new_instance.region_jp') }}</ToggleGroupItem>
|
||||
</ToggleGroup>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
@@ -172,55 +192,76 @@
|
||||
<el-tab-pane name="Legacy" :label="t('dialog.new_instance.legacy')">
|
||||
<el-form :model="newInstanceDialog" label-width="150px">
|
||||
<el-form-item :label="t('dialog.new_instance.access_type')">
|
||||
<el-radio-group
|
||||
v-model="newInstanceDialog.accessType"
|
||||
size="small"
|
||||
@change="buildLegacyInstance">
|
||||
<el-radio-button value="public">{{
|
||||
<ToggleGroup
|
||||
type="single"
|
||||
required
|
||||
variant="outline"
|
||||
size="sm"
|
||||
:model-value="newInstanceDialog.accessType"
|
||||
@update:model-value="(value) => {
|
||||
newInstanceDialog.accessType = value;
|
||||
buildLegacyInstance();
|
||||
}">
|
||||
<ToggleGroupItem value="public">{{
|
||||
t('dialog.new_instance.access_type_public')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="group">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="group">{{
|
||||
t('dialog.new_instance.access_type_group')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="friends+">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="friends+">{{
|
||||
t('dialog.new_instance.access_type_friend_plus')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="friends">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="friends">{{
|
||||
t('dialog.new_instance.access_type_friend')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="invite+">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="invite+">{{
|
||||
t('dialog.new_instance.access_type_invite_plus')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="invite">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="invite">{{
|
||||
t('dialog.new_instance.access_type_invite')
|
||||
}}</el-radio-button>
|
||||
</el-radio-group>
|
||||
}}</ToggleGroupItem>
|
||||
</ToggleGroup>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
:label="t('dialog.new_instance.group_access_type')">
|
||||
<el-radio-group
|
||||
v-model="newInstanceDialog.groupAccessType"
|
||||
size="small"
|
||||
@change="buildLegacyInstance">
|
||||
<el-radio-button value="members">{{
|
||||
<ToggleGroup
|
||||
type="single"
|
||||
required
|
||||
variant="outline"
|
||||
size="sm"
|
||||
:model-value="newInstanceDialog.groupAccessType"
|
||||
@update:model-value="(value) => {
|
||||
newInstanceDialog.groupAccessType = value;
|
||||
buildLegacyInstance();
|
||||
}">
|
||||
<ToggleGroupItem value="members">{{
|
||||
t('dialog.new_instance.group_access_type_members')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="plus">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="plus">{{
|
||||
t('dialog.new_instance.group_access_type_plus')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button value="public">{{
|
||||
}}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="public">{{
|
||||
t('dialog.new_instance.group_access_type_public')
|
||||
}}</el-radio-button>
|
||||
</el-radio-group>
|
||||
}}</ToggleGroupItem>
|
||||
</ToggleGroup>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('dialog.new_instance.region')">
|
||||
<el-radio-group v-model="newInstanceDialog.region" size="small" @change="buildLegacyInstance">
|
||||
<el-radio-button value="US West">{{ t('dialog.new_instance.region_usw') }}</el-radio-button>
|
||||
<el-radio-button value="US East">{{ t('dialog.new_instance.region_use') }}</el-radio-button>
|
||||
<el-radio-button value="Europe">{{ t('dialog.new_instance.region_eu') }}</el-radio-button>
|
||||
<el-radio-button value="Japan">{{ t('dialog.new_instance.region_jp') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
<ToggleGroup
|
||||
type="single"
|
||||
required
|
||||
variant="outline"
|
||||
size="sm"
|
||||
:model-value="newInstanceDialog.region"
|
||||
@update:model-value="(value) => {
|
||||
newInstanceDialog.region = value;
|
||||
buildLegacyInstance();
|
||||
}">
|
||||
<ToggleGroupItem value="US West">{{ t('dialog.new_instance.region_usw') }}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="US East">{{ t('dialog.new_instance.region_use') }}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="Europe">{{ t('dialog.new_instance.region_eu') }}</ToggleGroupItem>
|
||||
<ToggleGroupItem value="Japan">{{ t('dialog.new_instance.region_jp') }}</ToggleGroupItem>
|
||||
</ToggleGroup>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
@@ -483,6 +524,8 @@
|
||||
import { toast } from 'vue-sonner';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { ToggleGroup, ToggleGroupItem } from '../ui/toggle-group';
|
||||
|
||||
import {
|
||||
copyToClipboard,
|
||||
getLaunchURL,
|
||||
|
||||
57
src/components/ui/toggle-group/ToggleGroup.vue
Normal file
57
src/components/ui/toggle-group/ToggleGroup.vue
Normal file
@@ -0,0 +1,57 @@
|
||||
<script setup>
|
||||
import { ToggleGroupRoot, useForwardPropsEmits } from 'reka-ui';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { provide } from 'vue';
|
||||
import { reactiveOmit } from '@vueuse/core';
|
||||
|
||||
const props = defineProps({
|
||||
rovingFocus: { type: Boolean, required: false },
|
||||
disabled: { type: Boolean, required: false },
|
||||
orientation: { type: String, required: false },
|
||||
dir: { type: String, required: false },
|
||||
loop: { type: Boolean, required: false },
|
||||
asChild: { type: Boolean, required: false },
|
||||
as: { type: null, required: false },
|
||||
name: { type: String, required: false },
|
||||
required: { type: Boolean, required: false },
|
||||
type: { type: String, required: false },
|
||||
modelValue: { type: null, required: false },
|
||||
defaultValue: { type: null, required: false },
|
||||
class: { type: null, required: false },
|
||||
variant: { type: null, required: false },
|
||||
size: { type: null, required: false },
|
||||
spacing: { type: Number, required: false, default: 0 }
|
||||
});
|
||||
|
||||
const emits = defineEmits(['update:modelValue']);
|
||||
|
||||
provide('toggleGroup', {
|
||||
variant: props.variant,
|
||||
size: props.size,
|
||||
spacing: props.spacing
|
||||
});
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class', 'size', 'variant');
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ToggleGroupRoot
|
||||
v-slot="slotProps"
|
||||
data-slot="toggle-group"
|
||||
:data-size="size"
|
||||
:data-variant="variant"
|
||||
:data-spacing="spacing"
|
||||
:style="{
|
||||
'--gap': spacing
|
||||
}"
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs',
|
||||
props.class
|
||||
)
|
||||
">
|
||||
<slot v-bind="slotProps" />
|
||||
</ToggleGroupRoot>
|
||||
</template>
|
||||
45
src/components/ui/toggle-group/ToggleGroupItem.vue
Normal file
45
src/components/ui/toggle-group/ToggleGroupItem.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<script setup>
|
||||
import { ToggleGroupItem, useForwardProps } from 'reka-ui';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { inject } from 'vue';
|
||||
import { reactiveOmit } from '@vueuse/core';
|
||||
import { toggleVariants } from '@/components/ui/toggle';
|
||||
|
||||
const props = defineProps({
|
||||
value: { type: null, required: true },
|
||||
disabled: { type: Boolean, required: false },
|
||||
asChild: { type: Boolean, required: false },
|
||||
as: { type: null, required: false },
|
||||
class: { type: null, required: false },
|
||||
variant: { type: null, required: false },
|
||||
size: { type: null, required: false }
|
||||
});
|
||||
|
||||
const context = inject('toggleGroup');
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class', 'size', 'variant');
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ToggleGroupItem
|
||||
v-slot="slotProps"
|
||||
data-slot="toggle-group-item"
|
||||
:data-variant="context?.variant || variant"
|
||||
:data-size="context?.size || size"
|
||||
:data-spacing="context?.spacing"
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
toggleVariants({
|
||||
variant: context?.variant || variant,
|
||||
size: context?.size || size
|
||||
}),
|
||||
'w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10',
|
||||
'data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l',
|
||||
props.class
|
||||
)
|
||||
">
|
||||
<slot v-bind="slotProps" />
|
||||
</ToggleGroupItem>
|
||||
</template>
|
||||
2
src/components/ui/toggle-group/index.js
Normal file
2
src/components/ui/toggle-group/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as ToggleGroup } from './ToggleGroup.vue';
|
||||
export { default as ToggleGroupItem } from './ToggleGroupItem.vue';
|
||||
35
src/components/ui/toggle/Toggle.vue
Normal file
35
src/components/ui/toggle/Toggle.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<script setup>
|
||||
import { Toggle, useForwardPropsEmits } from 'reka-ui';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { reactiveOmit } from '@vueuse/core';
|
||||
|
||||
import { toggleVariants } from '.';
|
||||
|
||||
const props = defineProps({
|
||||
defaultValue: { type: Boolean, required: false },
|
||||
modelValue: { type: [Boolean, null], required: false },
|
||||
disabled: { type: Boolean, required: false, default: false },
|
||||
asChild: { type: Boolean, required: false },
|
||||
as: { type: null, required: false },
|
||||
name: { type: String, required: false },
|
||||
required: { type: Boolean, required: false },
|
||||
class: { type: null, required: false },
|
||||
variant: { type: null, required: false, default: 'default' },
|
||||
size: { type: null, required: false, default: 'default' }
|
||||
});
|
||||
|
||||
const emits = defineEmits(['update:modelValue']);
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class', 'size', 'variant');
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Toggle
|
||||
v-slot="slotProps"
|
||||
data-slot="toggle"
|
||||
v-bind="forwarded"
|
||||
:class="cn(toggleVariants({ variant, size }), props.class)">
|
||||
<slot v-bind="slotProps" />
|
||||
</Toggle>
|
||||
</template>
|
||||
25
src/components/ui/toggle/index.js
Normal file
25
src/components/ui/toggle/index.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { cva } from 'class-variance-authority';
|
||||
|
||||
export { default as Toggle } from './Toggle.vue';
|
||||
|
||||
export const toggleVariants = cva(
|
||||
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'bg-transparent',
|
||||
outline:
|
||||
'border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground'
|
||||
},
|
||||
size: {
|
||||
default: 'h-9 px-2 min-w-9',
|
||||
sm: 'h-8 px-1.5 min-w-8',
|
||||
lg: 'h-10 px-2.5 min-w-10'
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default',
|
||||
size: 'default'
|
||||
}
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user