yuyeon 0.0.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/package.json +38 -0
- package/src/components/button/index.ts +3 -0
- package/src/components/button/y-btn.scss +79 -0
- package/src/components/button/y-btn.ts +104 -0
- package/src/components/card/index.ts +6 -0
- package/src/components/card/y-card-body.ts +8 -0
- package/src/components/card/y-card-footer.ts +8 -0
- package/src/components/card/y-card-header.ts +8 -0
- package/src/components/card/y-card.scss +30 -0
- package/src/components/card/y-card.ts +16 -0
- package/src/components/checkbox/IconCheckbox.vue +24 -0
- package/src/components/checkbox/YCheckbox.vue +113 -0
- package/src/components/checkbox/YInputCheckbox.vue +108 -0
- package/src/components/checkbox/index.ts +8 -0
- package/src/components/checkbox/y-checkbox.scss +48 -0
- package/src/components/checkbox/y-input-checkbox.scss +86 -0
- package/src/components/chip/index.ts +3 -0
- package/src/components/chip/y-chip.scss +28 -0
- package/src/components/chip/y-chip.vue +69 -0
- package/src/components/dialog/index.ts +3 -0
- package/src/components/dialog/y-dialog.scss +5 -0
- package/src/components/dialog/y-dialog.vue +46 -0
- package/src/components/field-input/index.scss +5 -0
- package/src/components/field-input/index.ts +11 -0
- package/src/components/field-input/y-field-input.scss +65 -0
- package/src/components/field-input/y-field-input.ts +214 -0
- package/src/components/form/index.ts +9 -0
- package/src/components/form/y-form.ts +93 -0
- package/src/components/icons/icon-clearable.ts +6 -0
- package/src/components/index.ts +17 -0
- package/src/components/input/index.scss +5 -0
- package/src/components/input/index.ts +9 -0
- package/src/components/input/y-input.scss +209 -0
- package/src/components/input/y-input.ts +368 -0
- package/src/components/layer/index.ts +3 -0
- package/src/components/layer/y-layer.scss +32 -0
- package/src/components/layer/y-layer.vue +146 -0
- package/src/components/lottie-player.ts +41 -0
- package/src/components/progress-bar/index.ts +3 -0
- package/src/components/progress-bar/y-progress-bar.vue +144 -0
- package/src/components/ring-spinner/y-ring-spinner.scss +25 -0
- package/src/components/ring-spinner/y-ring-spinner.vue +31 -0
- package/src/components/switch/YSwitch.vue +217 -0
- package/src/components/switch/index.scss +5 -0
- package/src/components/switch/index.ts +11 -0
- package/src/components/switch/y-switch.scss +206 -0
- package/src/components/text-highlighter/index.scss +5 -0
- package/src/components/text-highlighter/index.ts +3 -0
- package/src/components/text-highlighter/y-text-highlighter.scss +7 -0
- package/src/components/text-highlighter/y-text-highlighter.ts +89 -0
- package/src/composables/layer-group.ts +31 -0
- package/src/composables/lazy.ts +30 -0
- package/src/composables/progress.ts +19 -0
- package/src/composables/theme.ts +25 -0
- package/src/directives/complement-click/index.ts +123 -0
- package/src/directives/plate-wave/index.ts +114 -0
- package/src/directives/plate-wave/plate-wave.scss +33 -0
- package/src/directives/theme-class.ts +14 -0
- package/src/file-extension.d.ts +14 -0
- package/src/index.ts +21 -0
- package/src/mixins/di.ts +23 -0
- package/src/mixins/rebind-attrs.ts +36 -0
- package/src/styles/base.scss +28 -0
- package/src/styles/palette.scss +94 -0
- package/src/styles/theme/dark.scss +35 -0
- package/src/styles/theme/index.scss +8 -0
- package/src/styles/theme/light.scss +32 -0
- package/src/styles/util/helper.scss +6 -0
- package/src/styles/util/theme.scss +16 -0
- package/src/styles/variables.scss +1 -0
- package/src/util/common.ts +59 -0
- package/src/util/date-time.ts +41 -0
- package/src/util/dom.ts +6 -0
- package/src/util/string.ts +9 -0
- package/src/util/ui.ts +39 -0
- package/src/util/validation.ts +9 -0
- package/src/util/vue-component.ts +18 -0
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "yuyeon",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Vue UI Library ",
|
|
5
|
+
"repository": "git@github.com:yuyeonUI/yuyeon.git",
|
|
6
|
+
"author": "yeonyu <yeonyu@yeonyu.dev>",
|
|
7
|
+
"license": "Apache-2.0",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"components",
|
|
10
|
+
"component library",
|
|
11
|
+
"UI library",
|
|
12
|
+
"vue components"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=14.13"
|
|
16
|
+
},
|
|
17
|
+
"main": "src/index.ts",
|
|
18
|
+
"module": "src/index.mjs",
|
|
19
|
+
"files": ["src/"],
|
|
20
|
+
"exports": {
|
|
21
|
+
"./*": "./src/*"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@vitejs/plugin-vue": "^4.0.0",
|
|
25
|
+
"prettier": "^2.8.3",
|
|
26
|
+
"vite": "^4.0.4",
|
|
27
|
+
"vue-tsc": "^1.0.24"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"vue": "^3.2.0",
|
|
31
|
+
"vue-i18n": "^9.0.0"
|
|
32
|
+
},
|
|
33
|
+
"peerDependenciesMeta": {
|
|
34
|
+
"vue-i18n": {
|
|
35
|
+
"optional": true
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
@use '../../styles/variables';
|
|
2
|
+
@use '../../styles/palette';
|
|
3
|
+
|
|
4
|
+
$button-border-radius: variables.$border-radius-root !default;
|
|
5
|
+
$button-before-opacity: 0.06 !default;
|
|
6
|
+
$button-disabled-background: #b3b3b3;
|
|
7
|
+
|
|
8
|
+
.y-btn {
|
|
9
|
+
--y-btn__color: var(--y-palette--primary);
|
|
10
|
+
|
|
11
|
+
cursor: pointer;
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
position: relative;
|
|
16
|
+
border-radius: $button-border-radius;
|
|
17
|
+
font-weight: 500;
|
|
18
|
+
transition: all 240ms cubic-bezier(0.42, 0.5, 0.51, 1.02);
|
|
19
|
+
|
|
20
|
+
&__content {
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
padding: 4px 8px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&:not(&--disabled):not(&--outlined):not(&--loading):not(&--filled):not(
|
|
27
|
+
&--text
|
|
28
|
+
) {
|
|
29
|
+
box-shadow: 1px 1px 4px 1px rgba(0, 0, 0, 0.14);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&--filled {
|
|
33
|
+
background-color: var(--y-btn__color);
|
|
34
|
+
color: #ffffff;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&:not(&--outlined):disabled,
|
|
38
|
+
&--disabled:not(&--outlined) {
|
|
39
|
+
background-color: $button-disabled-background;
|
|
40
|
+
opacity: 0.4;
|
|
41
|
+
cursor: default;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
&:before {
|
|
45
|
+
background-color: currentColor;
|
|
46
|
+
border-radius: inherit;
|
|
47
|
+
bottom: 0;
|
|
48
|
+
color: inherit;
|
|
49
|
+
content: '';
|
|
50
|
+
left: 0;
|
|
51
|
+
opacity: 0;
|
|
52
|
+
pointer-events: none;
|
|
53
|
+
position: absolute;
|
|
54
|
+
right: 0;
|
|
55
|
+
top: 0;
|
|
56
|
+
transition: opacity 0.2s cubic-bezier(0.4, 0, 0.6, 1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&:hover:before {
|
|
60
|
+
opacity: 0.06;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&--rounded {
|
|
64
|
+
border-radius: 10vh;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&--outlined {
|
|
68
|
+
color: var(--y-btn__color);
|
|
69
|
+
border: 1px solid var(--y-btn__color);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
&--loading {
|
|
73
|
+
cursor: wait;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&:active:not(&--loading) {
|
|
77
|
+
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.14);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { defineComponent, h, VNodeArrayChildren, withDirectives } from 'vue';
|
|
2
|
+
import { getSlot } from "../../util/vue-component";
|
|
3
|
+
import { PlateWave } from "../../directives/plate-wave";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Style
|
|
7
|
+
*/
|
|
8
|
+
import './y-btn.scss';
|
|
9
|
+
import YRingSpinner from '../ring-spinner/y-ring-spinner.vue';
|
|
10
|
+
import { isColorValue } from '../../util/ui';
|
|
11
|
+
|
|
12
|
+
const NAME = 'y-btn';
|
|
13
|
+
|
|
14
|
+
export default defineComponent({
|
|
15
|
+
name: NAME,
|
|
16
|
+
directives: {
|
|
17
|
+
PlateWave,
|
|
18
|
+
},
|
|
19
|
+
props: {
|
|
20
|
+
loading: Boolean,
|
|
21
|
+
outlined: {
|
|
22
|
+
type: Boolean,
|
|
23
|
+
default: false,
|
|
24
|
+
},
|
|
25
|
+
rounded: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: false,
|
|
28
|
+
},
|
|
29
|
+
filled: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
default: false,
|
|
32
|
+
},
|
|
33
|
+
disabled: {
|
|
34
|
+
type: Boolean,
|
|
35
|
+
},
|
|
36
|
+
text: {
|
|
37
|
+
type: Boolean,
|
|
38
|
+
},
|
|
39
|
+
color: {
|
|
40
|
+
type: String,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
computed: {
|
|
44
|
+
classes() {
|
|
45
|
+
return {
|
|
46
|
+
[`${NAME}--outlined`]: this.outlined,
|
|
47
|
+
[`${NAME}--loading`]: this.loading,
|
|
48
|
+
[`${NAME}--rounded`]: this.rounded,
|
|
49
|
+
[`${NAME}--filled`]: this.filled,
|
|
50
|
+
[`${NAME}--disabled`]: this.disabled,
|
|
51
|
+
[`${NAME}--text`]: this.text,
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
styles(): Record<string, any> {
|
|
55
|
+
let { color } = this;
|
|
56
|
+
if (color && !isColorValue(color)) {
|
|
57
|
+
color = `var(--y-palette--${color})`;
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
[`--y-btn__color`]: color,
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
methods: {
|
|
65
|
+
createContent() {
|
|
66
|
+
const defaultSlot = getSlot(this, 'default');
|
|
67
|
+
const children: VNodeArrayChildren = [];
|
|
68
|
+
if (this.loading) {
|
|
69
|
+
children.push(h(YRingSpinner));
|
|
70
|
+
}
|
|
71
|
+
children.push(defaultSlot);
|
|
72
|
+
return h('span', { class: 'y-btn__content' }, children);
|
|
73
|
+
},
|
|
74
|
+
getClasses() {
|
|
75
|
+
return this.classes;
|
|
76
|
+
},
|
|
77
|
+
/// Events
|
|
78
|
+
onClick(e: MouseEvent) {
|
|
79
|
+
e.preventDefault();
|
|
80
|
+
if (this.loading) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
render() {
|
|
86
|
+
const { onClick, styles } = this;
|
|
87
|
+
return withDirectives(
|
|
88
|
+
h(
|
|
89
|
+
'button',
|
|
90
|
+
{
|
|
91
|
+
class: {
|
|
92
|
+
...this.getClasses(),
|
|
93
|
+
[`${NAME}`]: true,
|
|
94
|
+
},
|
|
95
|
+
style: styles,
|
|
96
|
+
onClick,
|
|
97
|
+
'^disabled': this.disabled ? true : undefined,
|
|
98
|
+
},
|
|
99
|
+
this.createContent(),
|
|
100
|
+
),
|
|
101
|
+
[[PlateWave, true]],
|
|
102
|
+
);
|
|
103
|
+
},
|
|
104
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
@use '../../styles/palette';
|
|
2
|
+
@use '../../styles/variables';
|
|
3
|
+
|
|
4
|
+
$card__border-radius: variables.$border-radius-root !default;
|
|
5
|
+
$card__padding: 24px;
|
|
6
|
+
|
|
7
|
+
.y-card {
|
|
8
|
+
--y-card__border-radius: #{$card__border-radius};
|
|
9
|
+
--y-card__background: #fff;
|
|
10
|
+
|
|
11
|
+
background-color: var(--y-card__background);
|
|
12
|
+
border-radius: var(--y-card__border-radius, $card__border-radius);
|
|
13
|
+
|
|
14
|
+
&__header {
|
|
15
|
+
padding: $card__padding $card__padding 0;
|
|
16
|
+
display: flex;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&__body {
|
|
20
|
+
padding: 0 $card__padding;
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
&__footer {
|
|
26
|
+
padding: 12px 24px;
|
|
27
|
+
display: flex;
|
|
28
|
+
justify-content: space-between;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineComponent, h, VNode } from 'vue';
|
|
2
|
+
|
|
3
|
+
import './y-card.scss';
|
|
4
|
+
|
|
5
|
+
export default defineComponent({
|
|
6
|
+
name: 'y-card',
|
|
7
|
+
render(): VNode {
|
|
8
|
+
return h(
|
|
9
|
+
'div',
|
|
10
|
+
{
|
|
11
|
+
class: ['y-card'],
|
|
12
|
+
},
|
|
13
|
+
this.$slots.default?.call(this),
|
|
14
|
+
);
|
|
15
|
+
},
|
|
16
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg
|
|
3
|
+
class="icon-checkbox"
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
>
|
|
8
|
+
<path
|
|
9
|
+
class="icon-checkbox__border-path"
|
|
10
|
+
d="M 15.525 21.825 H 8.325 C 4.851 21.825 2.025 18.999 2.025 15.525 V 8.325 C 2.025 4.851 4.851 2.025 8.325 2.025 H 15.525 C 18.999 2.025 21.825 4.851 21.825 8.325 V 15.525 C 21.825 18.999 18.999 21.825 15.525 21.825 Z"
|
|
11
|
+
/>
|
|
12
|
+
<path
|
|
13
|
+
class="icon-checkbox__checkmark-path"
|
|
14
|
+
fill="none"
|
|
15
|
+
d="M5.73,11.91 11.1,16.28 17.79,7.59"
|
|
16
|
+
></path>
|
|
17
|
+
</svg>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script>
|
|
21
|
+
export default {
|
|
22
|
+
name: 'IconCheckbox',
|
|
23
|
+
};
|
|
24
|
+
</script>
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
- Created by yeonyu at 2021-09-23
|
|
3
|
+
-->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div class="y-checkbox" :class="classes">
|
|
7
|
+
<slot name="prepend"></slot>
|
|
8
|
+
<div class="y-checkbox__slot">
|
|
9
|
+
<y-input-checkbox
|
|
10
|
+
@click.stop="onClick"
|
|
11
|
+
:id="counterId"
|
|
12
|
+
:value="innerValue"
|
|
13
|
+
:icon="computedIcon"
|
|
14
|
+
@focus="onFocus"
|
|
15
|
+
@blur="onBlur"
|
|
16
|
+
:color="color"
|
|
17
|
+
:disabled="disabled"
|
|
18
|
+
:readonly="readonly"
|
|
19
|
+
>
|
|
20
|
+
<template v-if="$slots.icon" #icon="{ checked }">
|
|
21
|
+
<slot name="icon" :checked="checked"></slot>
|
|
22
|
+
</template>
|
|
23
|
+
</y-input-checkbox>
|
|
24
|
+
<label @click.stop="" class="y-checkbox__label" :for="inputId">
|
|
25
|
+
<slot name="label">{{ label }}</slot>
|
|
26
|
+
</label>
|
|
27
|
+
</div>
|
|
28
|
+
<slot name="append"></slot>
|
|
29
|
+
</div>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script lang="ts">
|
|
33
|
+
import { defineComponent, PropType } from 'vue';
|
|
34
|
+
import YInputCheckbox from './YInputCheckbox.vue';
|
|
35
|
+
|
|
36
|
+
import './y-checkbox.scss';
|
|
37
|
+
|
|
38
|
+
export default defineComponent({
|
|
39
|
+
name: 'y-checkbox',
|
|
40
|
+
components: { YInputCheckbox },
|
|
41
|
+
created() {
|
|
42
|
+
this.counterId = this.$yeonyui.getComponentCounter().toString();
|
|
43
|
+
this.innerValue = this.inputValue;
|
|
44
|
+
},
|
|
45
|
+
model: {
|
|
46
|
+
prop: 'inputValue',
|
|
47
|
+
event: 'change',
|
|
48
|
+
},
|
|
49
|
+
props: {
|
|
50
|
+
label: String as PropType<string>,
|
|
51
|
+
reverse: Boolean as PropType<boolean>,
|
|
52
|
+
icon: {
|
|
53
|
+
type: [Object, String] as PropType<
|
|
54
|
+
{ checked?: string; unchecked?: string } | string
|
|
55
|
+
>,
|
|
56
|
+
},
|
|
57
|
+
color: {
|
|
58
|
+
type: String as PropType<string>,
|
|
59
|
+
default: () => 'primary',
|
|
60
|
+
},
|
|
61
|
+
disabled: Boolean as PropType<boolean>,
|
|
62
|
+
readonly: Boolean as PropType<boolean>,
|
|
63
|
+
},
|
|
64
|
+
data() {
|
|
65
|
+
return {
|
|
66
|
+
innerValue: false,
|
|
67
|
+
focused: false,
|
|
68
|
+
counterId: '',
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
computed: {
|
|
72
|
+
classes(): Record<string, boolean> {
|
|
73
|
+
const { reverse, focused, disabled, readonly } = this;
|
|
74
|
+
return {
|
|
75
|
+
'y-checkbox--reverse': reverse,
|
|
76
|
+
'y-checkbox--focused': focused,
|
|
77
|
+
'y-checkbox--disabled': disabled,
|
|
78
|
+
'y-checkbox--readonly': readonly,
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
computedIcon(): string | undefined {
|
|
82
|
+
if (typeof this.icon === 'string') {
|
|
83
|
+
return this.icon;
|
|
84
|
+
}
|
|
85
|
+
return undefined;
|
|
86
|
+
},
|
|
87
|
+
inputId() {
|
|
88
|
+
const id = this.counterId;
|
|
89
|
+
return `input-${id}`;
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
methods: {
|
|
93
|
+
onFocus(e: FocusEvent) {
|
|
94
|
+
this.focused = true;
|
|
95
|
+
this.$emit('focus', e);
|
|
96
|
+
},
|
|
97
|
+
onBlur(e: FocusEvent) {
|
|
98
|
+
this.focused = false;
|
|
99
|
+
this.$emit('blur', e);
|
|
100
|
+
},
|
|
101
|
+
onClick(e: MouseEvent) {
|
|
102
|
+
if (this.disabled || this.readonly) return;
|
|
103
|
+
this.innerValue = !this.innerValue;
|
|
104
|
+
this.$emit('change', this.innerValue, e);
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
watch: {
|
|
108
|
+
inputValue(neo: boolean) {
|
|
109
|
+
this.innerValue = neo;
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
</script>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
- Created by yeonyu at 2021-09-23
|
|
3
|
+
-->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div @click="onClick" class="y-input y-input--checkbox" :class="classes">
|
|
7
|
+
<input
|
|
8
|
+
:id="inputId"
|
|
9
|
+
:aria-checked="checked"
|
|
10
|
+
role="checkbox"
|
|
11
|
+
type="checkbox"
|
|
12
|
+
:checked="checked"
|
|
13
|
+
@focus="onFocus"
|
|
14
|
+
@blur="onBlur"
|
|
15
|
+
:disabled="disabled"
|
|
16
|
+
:readonly="readonly"
|
|
17
|
+
/>
|
|
18
|
+
<slot name="icon" :checked="checked">
|
|
19
|
+
<component :is="iconComponent" v-if="iconComponent"></component>
|
|
20
|
+
<icon-checkbox v-else></icon-checkbox>
|
|
21
|
+
</slot>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script lang="ts">
|
|
26
|
+
import { defineComponent, PropType } from 'vue';
|
|
27
|
+
import IconCheckbox from './IconCheckbox.vue';
|
|
28
|
+
|
|
29
|
+
import './y-input-checkbox.scss';
|
|
30
|
+
|
|
31
|
+
export default defineComponent({
|
|
32
|
+
name: 'y-input-checkbox',
|
|
33
|
+
components: { IconCheckbox },
|
|
34
|
+
props: {
|
|
35
|
+
id: String as PropType<string>,
|
|
36
|
+
value: Boolean as PropType<boolean>,
|
|
37
|
+
icon: String as PropType<string>,
|
|
38
|
+
color: {
|
|
39
|
+
type: String as PropType<string>,
|
|
40
|
+
default: () => 'primary',
|
|
41
|
+
},
|
|
42
|
+
disabled: Boolean as PropType<boolean>,
|
|
43
|
+
readonly: Boolean as PropType<boolean>,
|
|
44
|
+
},
|
|
45
|
+
data() {
|
|
46
|
+
return {
|
|
47
|
+
counterId: '',
|
|
48
|
+
checked: false,
|
|
49
|
+
focused: false,
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
computed: {
|
|
53
|
+
coloredClass() {
|
|
54
|
+
if (this.color.startsWith('#')) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
return `color--${this.color}`;
|
|
58
|
+
},
|
|
59
|
+
classes() {
|
|
60
|
+
const ret: Record<string, boolean> = {
|
|
61
|
+
'y-input--active': this.checked,
|
|
62
|
+
'y-input--focused': this.focused,
|
|
63
|
+
};
|
|
64
|
+
if (this.coloredClass) {
|
|
65
|
+
ret[this.coloredClass] = true;
|
|
66
|
+
}
|
|
67
|
+
return ret;
|
|
68
|
+
},
|
|
69
|
+
inputId() {
|
|
70
|
+
let id = this.counterId;
|
|
71
|
+
if (this.id) {
|
|
72
|
+
id = this.id;
|
|
73
|
+
}
|
|
74
|
+
return `input-${id}`;
|
|
75
|
+
},
|
|
76
|
+
iconComponent() {
|
|
77
|
+
if (this.icon) {
|
|
78
|
+
if (this.$yeonyui.icons[this.icon]) {
|
|
79
|
+
return this.$yeonyui.icons[this.icon];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
methods: {
|
|
86
|
+
onFocus(e: FocusEvent) {
|
|
87
|
+
this.focused = true;
|
|
88
|
+
this.$emit('focus', e);
|
|
89
|
+
},
|
|
90
|
+
onBlur(e: FocusEvent) {
|
|
91
|
+
this.focused = false;
|
|
92
|
+
this.$emit('blur', e);
|
|
93
|
+
},
|
|
94
|
+
onClick(event: MouseEvent) {
|
|
95
|
+
this.$emit('click', event);
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
watch: {
|
|
99
|
+
value(neo: boolean) {
|
|
100
|
+
this.checked = neo;
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
created() {
|
|
104
|
+
this.checked = this.value;
|
|
105
|
+
this.counterId = this.$yeonyui.getComponentCounter().toString();
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
</script>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
@use '../../styles/palette';
|
|
2
|
+
|
|
3
|
+
$checkbox__label-color: #585858 !default;
|
|
4
|
+
|
|
5
|
+
.y-checkbox {
|
|
6
|
+
display: flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
|
|
9
|
+
&__slot {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: row;
|
|
12
|
+
align-items: center;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.y-checkbox__label {
|
|
16
|
+
cursor: pointer;
|
|
17
|
+
font-weight: 400;
|
|
18
|
+
color: $checkbox__label-color;
|
|
19
|
+
font-size: 14px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&--reverse .y-checkbox__slot {
|
|
23
|
+
flex-direction: row-reverse;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&:not(&--reverse) .y-input--checkbox {
|
|
27
|
+
margin-right: 8px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&--reverse .y-input--checkbox {
|
|
31
|
+
margin-left: 8px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&--readonly,
|
|
35
|
+
&--disabled {
|
|
36
|
+
.y-checkbox__label,
|
|
37
|
+
.y-input--checkbox {
|
|
38
|
+
cursor: default;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&--disabled {
|
|
43
|
+
.y-checkbox__slot {
|
|
44
|
+
filter: grayscale(1);
|
|
45
|
+
opacity: 0.4;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
@use '../../styles/palette';
|
|
2
|
+
|
|
3
|
+
$checkbox__color: palette.$primary;
|
|
4
|
+
$checkbox__border-color: #a4a4a4;
|
|
5
|
+
|
|
6
|
+
.y-input--checkbox {
|
|
7
|
+
--y-checkbox__color: var(--y-palette--primary);
|
|
8
|
+
|
|
9
|
+
position: relative;
|
|
10
|
+
width: 24px;
|
|
11
|
+
height: 24px;
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
flex: 0 0 auto;
|
|
14
|
+
box-sizing: border-box;
|
|
15
|
+
|
|
16
|
+
input[role='checkbox'] {
|
|
17
|
+
position: absolute;
|
|
18
|
+
opacity: 0;
|
|
19
|
+
width: 100%;
|
|
20
|
+
height: 100%;
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
user-select: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.icon-checkbox__checkmark-path {
|
|
26
|
+
fill: none;
|
|
27
|
+
stroke: #ffffff;
|
|
28
|
+
stroke-width: 2px;
|
|
29
|
+
stroke-dashoffset: 29.7833385;
|
|
30
|
+
stroke-dasharray: 29.7833385;
|
|
31
|
+
transition: stroke-dashoffset 120ms cubic-bezier(0.4, 0, 0.6, 1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.icon-checkbox__border-path {
|
|
35
|
+
fill: rgba($checkbox__color, 0);
|
|
36
|
+
stroke: rgba($checkbox__border-color, 0.8);
|
|
37
|
+
stroke-width: 2;
|
|
38
|
+
transition: fill 200ms 180ms ease-in;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
input:checked ~ .icon-checkbox,
|
|
42
|
+
&.y-input--active .icon-checkbox {
|
|
43
|
+
.icon-checkbox__checkmark-path {
|
|
44
|
+
stroke-dashoffset: 0;
|
|
45
|
+
transition: stroke-dashoffset 120ms 140ms cubic-bezier(0.4, 0, 0.6, 1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.icon-checkbox__border-path {
|
|
49
|
+
fill: $checkbox__color;
|
|
50
|
+
stroke: rgba($checkbox__color, 0.8);
|
|
51
|
+
transition: fill 200ms ease-in;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
input:focus ~ .icon-checkbox {
|
|
56
|
+
.icon-checkbox__border-path {
|
|
57
|
+
outline: rgba($checkbox__color, 0.5) solid 4px;
|
|
58
|
+
outline-offset: -6px;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&:hover {
|
|
63
|
+
.icon-checkbox__border-path {
|
|
64
|
+
stroke: rgba($checkbox__color, 0.5);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&.y-input--active:hover {
|
|
69
|
+
.icon-checkbox__border-path {
|
|
70
|
+
fill: lighten($checkbox__color, 10);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&.y-input--indeterminate .icon-checkbox {
|
|
75
|
+
.icon-checkbox__checkmark-path {
|
|
76
|
+
stroke-dashoffset: 0;
|
|
77
|
+
d: path('M5.73,11.91 11.1,11.91 17.79,11.91');
|
|
78
|
+
transition: stroke-dashoffset 400ms ease;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.icon-checkbox__border-path {
|
|
82
|
+
fill: rgba($checkbox__border-color, 0.8);
|
|
83
|
+
stroke: rgba($checkbox__border-color, 0.8);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|