This commit is contained in:
oneao committed 2025-09-14 21:38:52 +08:00
1 parent 5e3dccc88b
commit ae0ad2bd63
16 files changed
+199 -107

No files matched your search

@@ -1,2 +1 @@
@use './theme/index.scss' as *; @use './theme/index.scss' as *;
@@ -17,7 +17,6 @@ $btn-prefix: #{$prefix}-btn;
transition: all 0.2s ease; transition: all 0.2s ease;
font-weight: 500; font-weight: 500;
border: 1px solid transparent; border: 1px solid transparent;
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
&-small { &-small {
height: 24px; height: 24px;
@@ -27,7 +27,6 @@ $drawer-prefix: '#{$prefix}-drawer';
background: #fff; background: #fff;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
transition: transition:
transform 0.25s ease, transform 0.25s ease,
opacity 0.25s ease; opacity 0.25s ease;
@@ -1,4 +1,5 @@
@use './_styles/index.scss' as *; @use './_styles/index.scss' as *;
@use './_styles/variables' as variables;
@use './button/index.scss' as *; @use './button/index.scss' as *;
@use './input/index.scss' as *; @use './input/index.scss' as *;
@@ -16,3 +17,99 @@
@use './space/index.scss' as *; @use './space/index.scss' as *;
@use './separator/index.scss' as *; @use './separator/index.scss' as *;
@use './radio/index.scss' as *; @use './radio/index.scss' as *;
[class*='#{variables.$prefix}-'] {
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-family:
'Helvetica', 'Arial', 'PingFangSC-Regular', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', 'Microsoft JhengHei';
}
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
@@ -36,7 +36,6 @@ $input-prefix: #{$prefix}-input;
background-color cubic-bezier(0.38, 0, 0.24, 1) 0.2s; background-color cubic-bezier(0.38, 0, 0.24, 1) 0.2s;
.#{$input-prefix}-inner { .#{$input-prefix}-inner {
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
width: 100%; width: 100%;
border: none; border: none;
outline: none; outline: none;
@@ -23,7 +23,6 @@ $message-prefix: #{$prefix}-message;
color: $text-color-base; color: $text-color-base;
box-shadow: $shadow-overlay; box-shadow: $shadow-overlay;
box-sizing: border-box; box-sizing: border-box;
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
&-message { &-message {
font-size: 14px; font-size: 14px;
line-height: 1; line-height: 1;
@@ -19,7 +19,6 @@ $notification-prefix: #{$prefix}-notification;
color: $text-color-base; color: $text-color-base;
box-shadow: $shadow-overlay; box-shadow: $shadow-overlay;
box-sizing: border-box; box-sizing: border-box;
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
outline: 0; outline: 0;
border: 0; border: 0;
margin: 0; margin: 0;
@@ -23,7 +23,6 @@ $popconfirm-prefix: '#{$prefix}-popconfirm';
vertical-align: top; vertical-align: top;
max-width: 320px; max-width: 320px;
color: $text-color-base; color: $text-color-base;
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
word-break: break-all; word-break: break-all;
} }
@@ -0,0 +1,12 @@
import type { InjectionKey, Slots } from 'vue'
export interface RadioGroupContext {
name: 'ArcoRadioGroup'
value: string | number | boolean
disabled: boolean
slots: Slots
handleChange: (value: string | number | boolean, e: Event) => void
}
export const radioGroupKey: InjectionKey<RadioGroupContext>
= Symbol('RadioGroup')
@@ -3,80 +3,75 @@
$radio-prefix: '#{$prefix}-radio'; $radio-prefix: '#{$prefix}-radio';
.#{$radio-prefix} { .#{$radio-prefix} {
color: $text-color-base;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 8px; position: relative;
cursor: pointer; cursor: pointer;
font-size: 14px;
user-select: none; user-select: none;
&-wrapper { &:hover .#{$radio-prefix}-main .#{$radio-prefix}-inner {
position: relative; border-color: $primary-color;
width: 16px; }
height: 16px;
input[type='radio'] { &.#{$radio-prefix}-checked .#{$radio-prefix}-main .#{$radio-prefix}-inner {
position: absolute; border-color: $primary-color;
opacity: 0; &::after {
width: 100%; transform: translate(-50%, -50%) scale(1);
height: 100%; background-color: $primary-color;
margin: 0; }
}
.#{$radio-prefix}-main {
cursor: pointer; cursor: pointer;
z-index: 2; display: inline-flex;
white-space: nowrap;
outline: 0;
.#{$radio-prefix}-input {
opacity: 0;
outline: 0;
position: absolute;
z-index: -1;
margin: 0;
width: 0;
height: 0;
box-sizing: border-box;
} }
& .#{$radio-prefix}-circle { .#{$radio-prefix}-inner {
position: absolute; border: 1px solid $border-color;
top: 0; border-radius: 100%;
left: 0;
width: 16px; width: 16px;
height: 16px; height: 16px;
border: 1px solid #d9d9d9; background-color: $bg-color-container;
border-radius: 50%; position: relative;
background-color: #fff; display: inline-block;
transition: all 0.2s; cursor: pointer;
display: flex; box-sizing: border-box;
align-items: center; outline: 0;
justify-content: center; &::after {
z-index: 1; box-sizing: border-box;
}
// 勾选圆点
input[type='radio']:checked + .#{$radio-prefix}-circle::after {
content: '';
width: 8px; width: 8px;
height: 8px; height: 8px;
background-color: #1890ff; border-radius: 999px;
border-radius: 50%; background-color: transparent;
display: block; content: '';
animation: scaleIn 0.2s ease forwards; position: absolute;
box-shadow: 0 0 6px #1890ff33; // #33 = 20% 透明度 left: 50%;
} top: 50%;
} transform: translate(-50%, -50%) scale(0);
transition:
&-content { transform 0.15s ease-in,
display: flex; background-color 0.15s ease-in;
flex-direction: column;
}
&-disabled {
cursor: not-allowed;
opacity: 0.5;
}
&-clicked {
.#{$radio-prefix}-circle {
transform: scale(0.9);
transition: transform 0.15s ease;
} }
} }
} }
@keyframes scaleIn { .#{$radio-prefix}-content {
from { font-size: 12px;
transform: scale(0); margin-left: 8px;
} vertical-align: middle;
to { line-height: 1;
transform: scale(1);
} }
} }
@@ -1,70 +1,69 @@
import { computed, defineComponent, ref } from 'vue' import { defineComponent, inject } from 'vue'
import { getPrefixCls } from '../_utils/getPrefixCls' import { getPrefixCls } from '../_utils/getPrefixCls'
import { radioGroupKey } from './context'
export default defineComponent({ export default defineComponent({
name: 'AnimatedRadio', name: 'Radio',
props: { props: {
modelValue: { checked: {
type: [String, Number, Boolean], type: Boolean,
default: null, default: false,
}, },
value: { value: {
type: [String, Number, Boolean], type: [String, Number],
required: true, required: false,
}, },
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
class: { // private
type: [String, Array, Object], uninjectGroupContext: {
default: '', type: Boolean,
}, default: false,
style: {
type: Object,
default: () => ({}),
}, },
}, },
emits: ['update:modelValue'], emits: ['change', 'update:checked'],
setup(props, { slots, emit }) { setup(props, { slots, emit }) {
const prefixCls = getPrefixCls('radio') const prefixCls = getPrefixCls('radio')
const isClicked = ref(false)
const checked = computed(() => props.modelValue === props.value) const radioGroupCtx = !props.uninjectGroupContext
? inject(radioGroupKey, undefined)
: undefined
const handleChange = () => { const handleClick = () => {
if (!props.disabled) { if (props.disabled)
emit('update:modelValue', props.value) return
// 播放点击动画 const newChecked = !props.checked
isClicked.value = true emit('update:checked', newChecked)
setTimeout(() => (isClicked.value = false), 300) emit('change', {
} value: props.value,
checked: newChecked,
})
} }
return () => ( return () => (
<label <label
class={[ class={[
prefixCls, prefixCls,
props.class, props.checked ? `${prefixCls}-checked` : '',
checked.value ? `${prefixCls}-checked` : '',
props.disabled ? `${prefixCls}-disabled` : '', props.disabled ? `${prefixCls}-disabled` : '',
isClicked.value ? `${prefixCls}-clicked` : '',
]} ]}
style={{ ...props.style }} onClick={handleClick}
> >
<div class={`${prefixCls}-wrapper`}> <span class={`${prefixCls}-main`}>
<span class={`${prefixCls}-inner`} />
<input <input
class={`${prefixCls}-input`}
type="radio" type="radio"
value={props.value} checked={props.checked}
checked={checked.value}
disabled={props.disabled} disabled={props.disabled}
onChange={handleChange} onClick={e => e.stopPropagation()}
/> />
<span class={`${prefixCls}-circle`} /> </span>
</div> <span class={`${prefixCls}-content`}>
<div class={`${prefixCls}-content`}>
{slots.default ? slots.default() : null} {slots.default ? slots.default() : null}
</div> </span>
</label> </label>
) )
}, },
@@ -8,7 +8,6 @@ $separator-prefix: '#{$prefix}-separator';
padding: 0; padding: 0;
list-style: none; list-style: none;
font-size: 14px; font-size: 14px;
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
color: $text-color-base; color: $text-color-base;
box-sizing: border-box; box-sizing: border-box;
&.#{$separator-prefix}-layout-horizontal { &.#{$separator-prefix}-layout-horizontal {
@@ -14,7 +14,6 @@ $tag-prefix: '#{$prefix}-tag';
border: 1px solid transparent; border: 1px solid transparent;
white-space: nowrap; white-space: nowrap;
border-radius: $border-color; border-radius: $border-color;
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
&.#{$tag-prefix}-size-large { &.#{$tag-prefix}-size-large {
padding: 0 8px; padding: 0 8px;
@@ -6,7 +6,6 @@ import Icon from '../icon/index'
export default defineComponent({ export default defineComponent({
name: 'Tag', name: 'Tag',
props: { props: {
shape: { shape: {
type: String as PropType<'square' | 'round' | 'mark'>, type: String as PropType<'square' | 'round' | 'mark'>,
default: 'square', default: 'square',
@@ -12,7 +12,6 @@ $textarea-prefix: #{$prefix}-textarea;
width: 100%; width: 100%;
.#{$textarea-prefix}-inner { .#{$textarea-prefix}-inner {
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
height: 100%; height: 100%;
width: 100%; width: 100%;
display: flex; display: flex;
+2 -2
View File
@@ -3,8 +3,8 @@
<template> <template>
<div style="height: 800px;display: flex;align-items: center;justify-content: center;"> <div style="height: 800px;display: flex;align-items: center;justify-content: center;">
<ARadio> <ARadio :checked="true">
123 选项一
</ARadio> </ARadio>
</div> </div>
</template> </template>