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.
Files changed (77) hide show
  1. package/package.json +38 -0
  2. package/src/components/button/index.ts +3 -0
  3. package/src/components/button/y-btn.scss +79 -0
  4. package/src/components/button/y-btn.ts +104 -0
  5. package/src/components/card/index.ts +6 -0
  6. package/src/components/card/y-card-body.ts +8 -0
  7. package/src/components/card/y-card-footer.ts +8 -0
  8. package/src/components/card/y-card-header.ts +8 -0
  9. package/src/components/card/y-card.scss +30 -0
  10. package/src/components/card/y-card.ts +16 -0
  11. package/src/components/checkbox/IconCheckbox.vue +24 -0
  12. package/src/components/checkbox/YCheckbox.vue +113 -0
  13. package/src/components/checkbox/YInputCheckbox.vue +108 -0
  14. package/src/components/checkbox/index.ts +8 -0
  15. package/src/components/checkbox/y-checkbox.scss +48 -0
  16. package/src/components/checkbox/y-input-checkbox.scss +86 -0
  17. package/src/components/chip/index.ts +3 -0
  18. package/src/components/chip/y-chip.scss +28 -0
  19. package/src/components/chip/y-chip.vue +69 -0
  20. package/src/components/dialog/index.ts +3 -0
  21. package/src/components/dialog/y-dialog.scss +5 -0
  22. package/src/components/dialog/y-dialog.vue +46 -0
  23. package/src/components/field-input/index.scss +5 -0
  24. package/src/components/field-input/index.ts +11 -0
  25. package/src/components/field-input/y-field-input.scss +65 -0
  26. package/src/components/field-input/y-field-input.ts +214 -0
  27. package/src/components/form/index.ts +9 -0
  28. package/src/components/form/y-form.ts +93 -0
  29. package/src/components/icons/icon-clearable.ts +6 -0
  30. package/src/components/index.ts +17 -0
  31. package/src/components/input/index.scss +5 -0
  32. package/src/components/input/index.ts +9 -0
  33. package/src/components/input/y-input.scss +209 -0
  34. package/src/components/input/y-input.ts +368 -0
  35. package/src/components/layer/index.ts +3 -0
  36. package/src/components/layer/y-layer.scss +32 -0
  37. package/src/components/layer/y-layer.vue +146 -0
  38. package/src/components/lottie-player.ts +41 -0
  39. package/src/components/progress-bar/index.ts +3 -0
  40. package/src/components/progress-bar/y-progress-bar.vue +144 -0
  41. package/src/components/ring-spinner/y-ring-spinner.scss +25 -0
  42. package/src/components/ring-spinner/y-ring-spinner.vue +31 -0
  43. package/src/components/switch/YSwitch.vue +217 -0
  44. package/src/components/switch/index.scss +5 -0
  45. package/src/components/switch/index.ts +11 -0
  46. package/src/components/switch/y-switch.scss +206 -0
  47. package/src/components/text-highlighter/index.scss +5 -0
  48. package/src/components/text-highlighter/index.ts +3 -0
  49. package/src/components/text-highlighter/y-text-highlighter.scss +7 -0
  50. package/src/components/text-highlighter/y-text-highlighter.ts +89 -0
  51. package/src/composables/layer-group.ts +31 -0
  52. package/src/composables/lazy.ts +30 -0
  53. package/src/composables/progress.ts +19 -0
  54. package/src/composables/theme.ts +25 -0
  55. package/src/directives/complement-click/index.ts +123 -0
  56. package/src/directives/plate-wave/index.ts +114 -0
  57. package/src/directives/plate-wave/plate-wave.scss +33 -0
  58. package/src/directives/theme-class.ts +14 -0
  59. package/src/file-extension.d.ts +14 -0
  60. package/src/index.ts +21 -0
  61. package/src/mixins/di.ts +23 -0
  62. package/src/mixins/rebind-attrs.ts +36 -0
  63. package/src/styles/base.scss +28 -0
  64. package/src/styles/palette.scss +94 -0
  65. package/src/styles/theme/dark.scss +35 -0
  66. package/src/styles/theme/index.scss +8 -0
  67. package/src/styles/theme/light.scss +32 -0
  68. package/src/styles/util/helper.scss +6 -0
  69. package/src/styles/util/theme.scss +16 -0
  70. package/src/styles/variables.scss +1 -0
  71. package/src/util/common.ts +59 -0
  72. package/src/util/date-time.ts +41 -0
  73. package/src/util/dom.ts +6 -0
  74. package/src/util/string.ts +9 -0
  75. package/src/util/ui.ts +39 -0
  76. package/src/util/validation.ts +9 -0
  77. package/src/util/vue-component.ts +18 -0
@@ -0,0 +1,3 @@
1
+ import YChip from './y-chip.vue';
2
+
3
+ export { YChip };
@@ -0,0 +1,28 @@
1
+ /*!
2
+ * Created by yeonyu 2022.
3
+ */
4
+
5
+ @use '../../styles/variables';
6
+
7
+ $chip-border-radius: variables.$border-radius-root;
8
+
9
+ .y-chip {
10
+ display: inline-flex;
11
+ position: relative;
12
+ padding: 4px 16px;
13
+ background: rgba(0, 0, 0, 0.14);
14
+ border-radius: $chip-border-radius;
15
+ align-items: center;
16
+
17
+ &--clickable {
18
+ cursor: pointer;
19
+ }
20
+
21
+ &__content {
22
+ color: inherit;
23
+ }
24
+
25
+ &--clickable &__content {
26
+ user-select: none;
27
+ }
28
+ }
@@ -0,0 +1,69 @@
1
+ <!--
2
+ - Created by yeonyu 2022.
3
+ -->
4
+
5
+ <template>
6
+ <span class="y-chip" :class="classes" :style="styles">
7
+ <span class="y-chip__content">
8
+ <slot></slot>
9
+ </span>
10
+ </span>
11
+ </template>
12
+
13
+ <script lang="ts">
14
+ import { defineComponent } from 'vue';
15
+ import { hasOwnProperty } from '../../util/common';
16
+ import { colorHexToRgb } from '../../util/ui';
17
+
18
+ import './y-chip.scss';
19
+
20
+ export default defineComponent({
21
+ name: 'y-chip',
22
+ props: {
23
+ color: String,
24
+ background: String,
25
+ small: Boolean,
26
+ bgOpacity: {
27
+ type: Number,
28
+ default: 0.14,
29
+ },
30
+ },
31
+ computed: {
32
+ clickable() {
33
+ return hasOwnProperty(this.$attrs, 'onClick');
34
+ },
35
+ classes() {
36
+ return {
37
+ 'y-chip--clickable': this.clickable,
38
+ };
39
+ },
40
+ backgroundColor() {
41
+ const color = (this.background as string) ?? this.color;
42
+ return this.colorRgb(color);
43
+ },
44
+ styles() {
45
+ return {
46
+ color: this.color,
47
+ background: `rgba(${this.backgroundColor}, ${this.bgOpacity})`,
48
+ };
49
+ },
50
+ },
51
+ methods: {
52
+ colorRgb(color: string): string {
53
+ if (color?.startsWith('#')) {
54
+ return colorHexToRgb(color)?.join(',') || '';
55
+ }
56
+ const RGBA_REGEX = /rgb(a?)\((?<v>.*)\)/;
57
+ if (RGBA_REGEX.test(color)) {
58
+ const value = RGBA_REGEX.exec(color)?.[2] || '';
59
+ if (value) {
60
+ const valueArray = value.trim().split(',');
61
+ valueArray.splice(3, 1);
62
+ return valueArray.join(',');
63
+ }
64
+ }
65
+ return '';
66
+ },
67
+ },
68
+ });
69
+ </script>
@@ -0,0 +1,3 @@
1
+ import YDialog from './y-dialog.vue';
2
+
3
+ export { YDialog };
@@ -0,0 +1,5 @@
1
+ .y-dialog {
2
+ justify-content: center;
3
+ align-items: center;
4
+ backdrop-filter: blur(0.8px) saturate(0.4);
5
+ }
@@ -0,0 +1,46 @@
1
+ <template>
2
+ <y-layer v-model="active" content-tag-dialog scrim>
3
+ <slot name="activator"></slot>
4
+ <slot></slot>
5
+ </y-layer>
6
+ </template>
7
+
8
+ <script lang="ts">
9
+ import { computed, defineComponent, PropType, provide } from 'vue';
10
+ import { YLayer } from '../layer';
11
+ import { YCard } from '../card';
12
+
13
+ import './y-dialog.scss';
14
+
15
+ export default defineComponent({
16
+ name: 'YDialog',
17
+ components: {
18
+ YLayer,
19
+ YCard,
20
+ },
21
+ props: {
22
+ modelValue: {
23
+ type: Boolean as PropType<boolean>,
24
+ },
25
+ },
26
+ emits: {
27
+ 'update:modelValue': (value: boolean) => true,
28
+ },
29
+ setup(props: any, { emit }) {
30
+ const active = computed({
31
+ get: () => {
32
+ return props.modelValue;
33
+ },
34
+ set: (v: boolean) => {
35
+ emit('update:modelValue', v);
36
+ },
37
+ });
38
+
39
+ provide('poly', 'y-dialog');
40
+
41
+ return {
42
+ active,
43
+ };
44
+ },
45
+ });
46
+ </script>
@@ -0,0 +1,5 @@
1
+ /*!
2
+ * Created by yeonyu 2022.
3
+ */
4
+
5
+ @import 'y-field-input';
@@ -0,0 +1,11 @@
1
+ /*
2
+ * Created by yeonyu 2022.
3
+ */
4
+
5
+ import YFieldInput from './y-field-input';
6
+
7
+ export { YFieldInput };
8
+
9
+ export default {
10
+ YFieldInput,
11
+ };
@@ -0,0 +1,65 @@
1
+ /*!
2
+ * Created by yeonyu 2022.
3
+ */
4
+ @use '../../styles/util/theme';
5
+ @use '../../styles/util/helper';
6
+ @use '../../styles/variables';
7
+
8
+ .y-field-input {
9
+ .y-input {
10
+ &__display {
11
+ padding: 0 2px;
12
+ }
13
+
14
+ &__plate {
15
+ pointer-events: none;
16
+ }
17
+ }
18
+
19
+ &__field {
20
+ position: relative;
21
+ flex: 1 1 auto;
22
+ min-height: 36px;
23
+ padding: 1px 0;
24
+ border-radius: inherit;
25
+
26
+ > input {
27
+ position: relative;
28
+ outline: none;
29
+ padding: 8px 10px;
30
+ width: 100%;
31
+ height: 100%;
32
+ line-height: 1.2;
33
+ font-size: 0.875rem;
34
+ color: inherit;
35
+ border-radius: inherit;
36
+ }
37
+ }
38
+
39
+ .y-input__prepend + &__field {
40
+ > input {
41
+ padding-left: 0;
42
+ }
43
+ }
44
+
45
+ .y-input__append:last-child {
46
+ &.y-input__append--clear {
47
+ margin-right: 8px;
48
+ }
49
+ }
50
+
51
+ &__clear {
52
+ width: 16px;
53
+ height: 16px;
54
+ padding: 0;
55
+ cursor: pointer;
56
+ }
57
+ }
58
+
59
+ @include theme.basicTheme('y-field-input') using ($themeMap, $class) {
60
+ .y-field-input {
61
+ &__clear {
62
+ color: helper.deepGet($themeMap, 'fieldInput', 'clear');
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,214 @@
1
+ /*
2
+ * Created by yeonyu 2022.
3
+ */
4
+
5
+ import { YInput } from '../input';
6
+ import { VNode, defineComponent, h } from 'vue';
7
+
8
+ import './index.scss';
9
+ import { getSlot } from '../../util/vue-component';
10
+ import IconClearable from '../icons/icon-clearable';
11
+
12
+ const NAME = 'y-field-input';
13
+
14
+ export default defineComponent({
15
+ extends: YInput,
16
+ name: NAME,
17
+ inheritAttrs: false,
18
+ props: {
19
+ clearable: Boolean,
20
+ inputAlign: String,
21
+ displayText: [String, Function],
22
+ whenInputValid: [Boolean, Number],
23
+ tabindex: {
24
+ type: String,
25
+ default: '0',
26
+ },
27
+ },
28
+ mounted() {
29
+ this.displayValue = this.inValue as string;
30
+ },
31
+ data() {
32
+ return {
33
+ displayValue: '' as string,
34
+ };
35
+ },
36
+ computed: {
37
+ fieldInputClasses(): Record<string, any> {
38
+ return {
39
+ ...this.classes,
40
+ [NAME]: true,
41
+ };
42
+ },
43
+ inputType(): string {
44
+ const attr = (this.$attrs.type as string) || 'text';
45
+ return attr;
46
+ },
47
+ },
48
+ methods: {
49
+ getClasses() {
50
+ return {
51
+ ...YInput.methods?.getClasses(),
52
+ ...this.fieldInputClasses,
53
+ };
54
+ },
55
+ createInput(): VNode {
56
+ const { readonly, placeholder, disabled } = this;
57
+ return h('input', {
58
+ '.value': this.displayValue,
59
+ '.id': this.attrId,
60
+ '.type': this.inputType,
61
+ readonly: readonly || this.loading || this.formLoading,
62
+ '.placeholder': placeholder,
63
+ '.disabled': disabled,
64
+ '^tabindex': this.tabindex || '0',
65
+ autocomplete: this.$attrs.autocomplete,
66
+ maxlength: this.$attrs.maxlength,
67
+ onInput: this.onInput,
68
+ onFocus: this.onFocus,
69
+ onBlur: this.onBlur,
70
+ onChange: this.onChange,
71
+ onKeydown: this.onKeydown,
72
+ onKeyup: this.onKeyup,
73
+ style: {
74
+ textAlign: this.inputAlign,
75
+ },
76
+ ref: 'input',
77
+ });
78
+ },
79
+ createDefaultChildren(): (VNode | undefined)[] {
80
+ return [
81
+ YInput.methods!.createLabel.call(this),
82
+ this.createInput.call(this),
83
+ ];
84
+ },
85
+ createDefault(): VNode {
86
+ return h(
87
+ 'div',
88
+ {
89
+ class: `${NAME}__field`,
90
+ 'data-id': this.attrId,
91
+ ref: 'field',
92
+ },
93
+ this.createDefaultChildren(),
94
+ );
95
+ },
96
+ createClearAppend(): VNode {
97
+ return h('div', { class: 'y-input__append y-input__append--clear' }, [
98
+ h(
99
+ 'button',
100
+ {
101
+ class: `${NAME}__clear`,
102
+ onClick: this.onClickClear,
103
+ onKeydown: this.onKeydownClear,
104
+ '^tabindex': '2',
105
+ },
106
+ [h(IconClearable)],
107
+ ),
108
+ ]);
109
+ },
110
+ createAppend(): VNode[] {
111
+ const appends = [];
112
+ if (this.clearable && this.inValue) {
113
+ appends.push(this.createClearAppend());
114
+ }
115
+ const slot = getSlot(this, 'append');
116
+ if (slot) {
117
+ appends.push(h('div', { class: 'y-input__append' }, slot));
118
+ }
119
+ return appends;
120
+ },
121
+ //
122
+ onClick(event: MouseEvent) {
123
+ (this.$refs.input as HTMLElement).focus();
124
+ this.$emit('click', event);
125
+ },
126
+ onFocus(event: FocusEvent) {
127
+ if (this) {
128
+ this.isFocused = true;
129
+ this.displayValue = this.inValue as string;
130
+ this.$emit('focus', event);
131
+ }
132
+ },
133
+ onBlur(event: FocusEvent) {
134
+ this.isFocused = false;
135
+ this.invokeValidators();
136
+ this.$emit('blur', event);
137
+ this.changeDisplay();
138
+ },
139
+ onInput(event: InputEvent) {
140
+ const target = event.target as HTMLInputElement | null;
141
+ this.inValue = target?.value;
142
+ this.displayValue = target?.value as string;
143
+ if (this.whenInputValid) {
144
+ this.invokeValidators();
145
+ }
146
+ this.$emit('update:modelValue', this.inValue);
147
+ },
148
+ onChange(event: Event) {
149
+ YInput.methods?.onChange.call(this, event);
150
+ this.$emit('change', this.inValue);
151
+ },
152
+ onKeydown(event: KeyboardEvent) {
153
+ this.$emit('keydown', event);
154
+ },
155
+ onKeyup(event: KeyboardEvent) {
156
+ this.$emit('keyup', event);
157
+ },
158
+ //
159
+ clear() {
160
+ this.inValue = '';
161
+ this.$emit('update:modelValue', this.inValue);
162
+ },
163
+ onClickClear(event: MouseEvent) {
164
+ this.clear();
165
+ },
166
+ onKeydownClear(event: KeyboardEvent) {
167
+ if (event.code === 'Space' || event.code === 'Enter') {
168
+ this.clear();
169
+ }
170
+ },
171
+ //
172
+ /**
173
+ * @public
174
+ */
175
+ focus() {
176
+ (this.$refs.input as HTMLInputElement).focus();
177
+ },
178
+ /**
179
+ * @public
180
+ */
181
+ select() {
182
+ (this.$refs.input as HTMLInputElement).select();
183
+ },
184
+ //
185
+ changeDisplay() {
186
+ const { displayText } = this;
187
+ if (displayText !== undefined) {
188
+ let text = this.inValue;
189
+ if (typeof displayText === 'string') {
190
+ text = displayText;
191
+ }
192
+ if (displayText && typeof displayText === 'function') {
193
+ text = (displayText as any).call(this, text);
194
+ }
195
+ this.$nextTick(() => {
196
+ this.displayValue = text as string;
197
+ });
198
+ }
199
+ },
200
+ },
201
+ watch: {
202
+ modelValue(neo: any) {
203
+ this.inValue = neo;
204
+ this.displayValue = neo;
205
+ },
206
+ inValue(neo: string) {
207
+ if (!this.isFocused) {
208
+ this.changeDisplay();
209
+ } else {
210
+ this.displayValue = neo;
211
+ }
212
+ },
213
+ },
214
+ });
@@ -0,0 +1,9 @@
1
+ /*
2
+ * Created by yeonyu 2022.
3
+ */
4
+
5
+ import YForm from './y-form';
6
+
7
+ export { YForm };
8
+
9
+ export default YForm;
@@ -0,0 +1,93 @@
1
+ /*
2
+ * Created by yeonyu 2022.
3
+ */
4
+
5
+ import {
6
+ defineComponent,
7
+ PropType,
8
+ VNode,
9
+ h,
10
+ ComponentPublicInstance,
11
+ withKeys,
12
+ } from 'vue';
13
+ //
14
+ import RebindAttrs from '../../mixins/rebind-attrs';
15
+
16
+ const NAME = 'y-form';
17
+ const rootTags = ['form', 'div', 'section', 'article'];
18
+
19
+ export default defineComponent({
20
+ name: NAME,
21
+ inheritAttrs: false,
22
+ mixins: [RebindAttrs],
23
+ provide() {
24
+ return {
25
+ form$: this,
26
+ };
27
+ },
28
+ props: {
29
+ tag: {
30
+ type: String as PropType<string>,
31
+ default: 'form',
32
+ validator(value: string) {
33
+ return rootTags.includes(value);
34
+ },
35
+ },
36
+ loading: Boolean,
37
+ },
38
+ data() {
39
+ return {
40
+ inputs: {} as Record<string, ComponentPublicInstance>,
41
+ formData: {} as any,
42
+ };
43
+ },
44
+ methods: {
45
+ register(component: any) {
46
+ const { iid, name } = component;
47
+ // TODO: vue3 에서 $on 제거됨에 따라 트리거 따로 만들어야 함
48
+ this.inputs[iid] = component;
49
+ },
50
+ unregister(component: any) {
51
+ delete this.inputs[component.iid];
52
+ },
53
+ validate(): boolean {
54
+ let flag = true;
55
+ Object.values(this.inputs).forEach((input: any) => {
56
+ const valid = input?.invokeValidators.call(input);
57
+ flag = flag && valid;
58
+ });
59
+ return flag;
60
+ },
61
+ },
62
+ computed: {
63
+ attrs() {
64
+ return {
65
+ ...this.attrs_$,
66
+ };
67
+ },
68
+ },
69
+ render(): VNode {
70
+ const { tag }: any = this;
71
+ // this.attrs_$
72
+ return h(
73
+ tag,
74
+ {
75
+ class: NAME,
76
+ '.novalidate': true,
77
+ onSubmit: (e: Event) => {
78
+ e.preventDefault();
79
+ this.$emit('submit', e, this.formData);
80
+ },
81
+ onKeydown: withKeys(
82
+ (e: Event) => {
83
+ e.preventDefault();
84
+ e.stopImmediatePropagation();
85
+ this.$emit('keydown.enter', e);
86
+ },
87
+ ['enter'],
88
+ ),
89
+ },
90
+ this.$slots.default?.(),
91
+ );
92
+ },
93
+ });
@@ -0,0 +1,6 @@
1
+ import { defineComponent, h, VNode } from 'vue';
2
+
3
+ export default defineComponent({
4
+ name: 'icon-clearable',
5
+ template: `<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1.5c-3.5839 0-6.5 2.9161-6.5 6.5 0 3.5839 2.9161 6.5 6.5 6.5 3.5839 0 6.5-2.9161 6.5-6.5 0-3.5839-2.9161-6.5-6.5-6.5zm-2 4a.5.5 0 01.35352.14648l1.6465 1.6465 1.6465-1.6465a.5.5 0 01.35352-.14648.5.5 0 01.35352.14648.5.5 0 010 .70703l-1.6465 1.6465 1.6465 1.6465a.5.5 0 010 .70703.5.5 0 01-.70703 0l-1.6465-1.6465-1.6465 1.6465a.5.5 0 01-.70703 0 .5.5 0 010-.70703l1.6465-1.6465-1.6465-1.6465a.5.5 0 010-.70703.5.5 0 01.35352-.14648z" fill="currentColor" stroke-miterlimit="10" /></svg>`,
6
+ });
@@ -0,0 +1,17 @@
1
+ export * from './button';
2
+ export * from './input';
3
+ export * from './field-input';
4
+ export * from './form';
5
+ export * from './progress-bar';
6
+ export * from './card';
7
+ export * from './chip';
8
+ export * from './layer';
9
+ export * from './dialog';
10
+
11
+ import YLottiePlayer from './lottie-player';
12
+ import YRingSpinner from './ring-spinner/y-ring-spinner.vue';
13
+
14
+ export {
15
+ YRingSpinner,
16
+ YLottiePlayer,
17
+ };
@@ -0,0 +1,5 @@
1
+ /*!
2
+ * Created by yeonyu 2022.
3
+ */
4
+
5
+ @import 'y-input';
@@ -0,0 +1,9 @@
1
+ /*
2
+ * Created by yeonyu 2022.
3
+ */
4
+
5
+ import YInput from './y-input';
6
+
7
+ export { YInput };
8
+
9
+ export default YInput;