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,209 @@
1
+ /*!
2
+ * Created by yeonyu 2022.
3
+ */
4
+
5
+ @use '../../styles/palette';
6
+ @use '../../styles/variables';
7
+
8
+ $input-border-radius: variables.$border-radius-root !default;
9
+
10
+ .y-input {
11
+ font-size: 14px;
12
+ flex: 1 1 auto;
13
+ display: flex;
14
+ align-items: flex-start;
15
+ letter-spacing: normal;
16
+ text-align: left;
17
+
18
+ &__prepend-outer,
19
+ &__append-outer {
20
+ height: 100%;
21
+ }
22
+
23
+ &__stack {
24
+ display: flex;
25
+ flex-direction: column;
26
+ height: 100%; // auto
27
+ flex: 1;
28
+ flex-wrap: wrap;
29
+ min-width: 0;
30
+ width: 100%;
31
+ }
32
+
33
+ &__display {
34
+ display: flex;
35
+ position: relative;
36
+ cursor: text;
37
+ flex: 1 1 auto;
38
+ border-radius: $input-border-radius;
39
+ }
40
+
41
+ &__plate {
42
+ position: absolute;
43
+ inset: 0;
44
+ border-top: 1px solid transparent;
45
+ contain: paint;
46
+ border-radius: $input-border-radius;
47
+ outline: 0 solid rgba(0, 0, 0, 0);
48
+ }
49
+
50
+ &__value {
51
+ position: relative;
52
+ flex: 1 0 auto;
53
+ padding: 0.5rem 0.875rem;
54
+ display: flex;
55
+ align-items: center;
56
+ line-height: 1em;
57
+ }
58
+
59
+ &__helper-text {
60
+ font-size: 14px;
61
+ font-weight: 320;
62
+ color: #444;
63
+ }
64
+
65
+ @keyframes label-float {
66
+ 0% {
67
+ opacity: 0;
68
+ }
69
+ 100% {
70
+ opacity: 1;
71
+ transform: translateY(-26px) scale(0.74);
72
+ }
73
+ }
74
+
75
+ @keyframes label-sink {
76
+ 0% {
77
+ opacity: 1;
78
+ transform: translateY(-26px) scale(0.74);
79
+ }
80
+ 30% {
81
+ opacity: 0;
82
+ }
83
+ 80% {
84
+ opacity: 0;
85
+ transform: translateY(-8px) scale(1);
86
+ }
87
+ 100% {
88
+ opacity: 1;
89
+ transform: translateY(0) scale(1);
90
+ }
91
+ }
92
+
93
+ &__label {
94
+ position: absolute;
95
+ color: #5e5e5e;
96
+ max-width: 90%;
97
+ overflow: hidden;
98
+ text-overflow: ellipsis;
99
+ white-space: nowrap;
100
+ pointer-events: none;
101
+ left: 0;
102
+ top: 6px;
103
+ transform-origin: left center;
104
+
105
+ &--floated {
106
+ animation: label-float 200ms ease-in-out forwards;
107
+ }
108
+
109
+ &:not(&--floated) {
110
+ animation: label-sink 200ms linear;
111
+ }
112
+ }
113
+
114
+ &__prepend {
115
+ position: relative;
116
+ display: inline-flex;
117
+ margin-top: 10px;
118
+ padding-right: 8px;
119
+ align-self: flex-start;
120
+
121
+ > * {
122
+ width: 24px;
123
+ height: 24px;
124
+ user-select: none;
125
+ }
126
+ }
127
+
128
+ &__append {
129
+ position: relative;
130
+ display: inline-flex;
131
+ justify-content: center;
132
+ align-items: center;
133
+ }
134
+
135
+ &--labeled {
136
+ padding-top: 12px;
137
+ margin-top: 4px;
138
+ }
139
+
140
+ &--filled {
141
+ .y-input__plate {
142
+ background: #f2f2f2;
143
+ }
144
+
145
+ .y-input__prepend {
146
+ padding-left: 12px;
147
+ }
148
+ }
149
+
150
+ &--outlined {
151
+ .y-input__plate {
152
+ border: 1px solid #a4a4a4;
153
+ box-sizing: border-box;
154
+ inset: 0;
155
+ }
156
+ .y-input__plate:before {
157
+ top: 0;
158
+ height: 100%;
159
+ background: transparent;
160
+ border-radius: inherit;
161
+ }
162
+ }
163
+
164
+ &--ceramic {
165
+ .y-input__plate {
166
+ border: 1px solid #e4e4e4;
167
+ box-sizing: border-box;
168
+ inset: 0;
169
+ border-top-color: transparent;
170
+ border-left-width: 0;
171
+ border-right-width: 0;
172
+ box-shadow: 1px 2px 8px -1px rgb(0 0 0 / 11%),
173
+ inset 1px 1px 8px -4px rgb(0 0 0 / 11%);
174
+ outline: 0 solid rgba(0, 0, 0, 0);
175
+ }
176
+
177
+ .y-input__plate:before {
178
+ inset: -1px;
179
+ height: 100%;
180
+ background: transparent;
181
+ border-radius: inherit;
182
+ }
183
+ }
184
+
185
+ &--focused {
186
+ .y-input__value {
187
+ outline: none;
188
+ }
189
+
190
+ .y-input__plate {
191
+ outline: 1px solid rgba(var(--y-palette--primary, #4f97dc), 0.1);
192
+ }
193
+
194
+ .y-input__prepend {
195
+ color: currentColor;
196
+ }
197
+ }
198
+
199
+ &--error {
200
+ &.y-input--outlined {
201
+ .y-input__plate {
202
+ border-color: palette.$alert-negative !important;
203
+ }
204
+ }
205
+ .y-input__helper-text {
206
+ color: palette.$alert-negative;
207
+ }
208
+ }
209
+ }
@@ -0,0 +1,368 @@
1
+ /*
2
+ * Created by yeonyu 2022.
3
+ */
4
+ import { getSlot } from '../../util/vue-component';
5
+
6
+ import './index.scss';
7
+ import {
8
+ defineComponent,
9
+ Directive,
10
+ h,
11
+ PropType,
12
+ resolveDirective,
13
+ VNode,
14
+ withDirectives,
15
+ } from 'vue';
16
+ import RebindAttrs from '../../mixins/rebind-attrs';
17
+ import DiMixin from '../../mixins/di';
18
+
19
+ const NAME = 'y-input';
20
+ let uidCounter = 0;
21
+
22
+ export default defineComponent({
23
+ name: NAME,
24
+ inheritAttrs: false,
25
+ mixins: [RebindAttrs, DiMixin],
26
+ props: {
27
+ name: String,
28
+ width: {
29
+ type: [String, Number] as PropType<string | number>,
30
+ },
31
+ height: [Number, String],
32
+ displayTag: {
33
+ type: String as PropType<string>,
34
+ default: 'div',
35
+ },
36
+ outlined: Boolean as PropType<boolean>,
37
+ filled: {
38
+ type: Boolean as PropType<boolean>,
39
+ },
40
+ ceramic: Boolean as PropType<boolean>,
41
+ label: String as PropType<string>,
42
+ modelValue: { type: [String, Number] as PropType<string | number> },
43
+ autoSelect: {
44
+ type: Boolean as PropType<boolean>,
45
+ default: true,
46
+ },
47
+ floated: { type: Boolean as PropType<boolean>, default: () => false },
48
+ placeholder: String as PropType<string>,
49
+ loading: Boolean as PropType<boolean>,
50
+ // validate
51
+ readonly: Boolean as PropType<boolean>,
52
+ disabled: Boolean as PropType<boolean>,
53
+ error: Boolean as PropType<boolean>,
54
+ validators: Array as PropType<((v: any) => boolean | string)[] | string[]>,
55
+ },
56
+ data() {
57
+ const iid = uidCounter.toString();
58
+ uidCounter += 1;
59
+ return {
60
+ isFocused: false,
61
+ iid,
62
+ lazyValue: undefined as string | undefined,
63
+ inValue: '' as string | number | undefined,
64
+ hasMouseDown: false,
65
+ errorResult: undefined as string | undefined,
66
+ inError: false,
67
+ };
68
+ },
69
+ computed: {
70
+ classes(): Record<string, boolean> {
71
+ return {
72
+ 'y-input--outlined': !this.ceramic && !!this.outlined,
73
+ 'y-input--filled': !!this.filled,
74
+ 'y-input--focused': this.isFocused,
75
+ 'y-input--ceramic': !!this.ceramic,
76
+ 'y-input--readonly': !!this.readonly,
77
+ 'y-input--has-value': !!this.inValue,
78
+ 'y-input--disabled': !!this.disabled,
79
+ 'y-input--error': this.isError,
80
+ };
81
+ },
82
+ displayStyles(): Record<string, any> {
83
+ let { width } = this;
84
+ if (!Number.isNaN(Number(width))) {
85
+ width = `${width}px`;
86
+ }
87
+ return {
88
+ width,
89
+ height: this.getDisplayHeight(),
90
+ };
91
+ },
92
+ attrId(): string {
93
+ return (this.$attrs.id as string) ?? `y-input--${this.iid}`;
94
+ },
95
+ isFloatedLabel(): boolean {
96
+ return (
97
+ this.floated ||
98
+ !!this.placeholder ||
99
+ (!this.placeholder && this.isFocused) ||
100
+ !!this.inValue
101
+ );
102
+ },
103
+ formLoading(): boolean {
104
+ const form$ = (this as any).form$ as any;
105
+ if (form$) {
106
+ return form$.loading;
107
+ }
108
+ return false;
109
+ },
110
+ isError(): boolean {
111
+ return !!this.error || this.inError;
112
+ },
113
+ },
114
+ methods: {
115
+ createPrependOuter(): VNode | undefined {
116
+ const slot = getSlot(this, 'prepend-outer');
117
+ return slot
118
+ ? h('div', { class: `${NAME}__prepend-outer` }, slot)
119
+ : undefined;
120
+ },
121
+ createAppendOuter(): VNode | undefined {
122
+ const slot = getSlot(this, 'append-outer');
123
+ return slot
124
+ ? h('div', { class: `${NAME}__append-outer` }, slot)
125
+ : undefined;
126
+ },
127
+ createLabelSlot(): (VNode | string | VNode[])[] {
128
+ const slot: VNode[] | undefined = getSlot(this, 'label');
129
+ if (!slot) {
130
+ if (this.label) {
131
+ return [this.label];
132
+ }
133
+ if (this.placeholder && !this.inValue) {
134
+ return [this.placeholder];
135
+ }
136
+ }
137
+
138
+ return slot ? [slot] : [];
139
+ },
140
+ createLabel(): VNode | undefined {
141
+ const show = !!this.label || !!getSlot(this, 'label');
142
+ if (!show) {
143
+ return undefined;
144
+ }
145
+ return h(
146
+ 'label',
147
+ {
148
+ class: {
149
+ [`${NAME}__label`]: true,
150
+ 'y-input__label--floated': this.isFloatedLabel,
151
+ },
152
+ '.for': this.attrId,
153
+ },
154
+ this.createLabelSlot(),
155
+ );
156
+ },
157
+ createDefaultSlot(): VNode[] | string | undefined {
158
+ const { modelValue } = this;
159
+ const slotContent = getSlot(this, 'default', { modelValue });
160
+ return slotContent ?? modelValue?.toString();
161
+ },
162
+ createDefaultChildren(): (VNode | undefined | VNode[] | string)[] {
163
+ return [this.createLabel(), this.createDefaultSlot()];
164
+ },
165
+ createDefault(): VNode {
166
+ return h(
167
+ 'div',
168
+ {
169
+ [`.${NAME}__value`]: true,
170
+ '.data-id': this.attrId,
171
+ '.tabindex': 0,
172
+ onFocus: this.onFocus,
173
+ onBlur: this.onBlur,
174
+ },
175
+ this.createDefaultChildren(),
176
+ );
177
+ },
178
+ createPrepend(): VNode | undefined {
179
+ const slot = getSlot(this, 'prepend', { error: this.isError });
180
+ return slot
181
+ ? h(
182
+ 'div',
183
+ {
184
+ class: 'y-input__prepend',
185
+ onClick: this.onClickPrepend,
186
+ },
187
+ slot,
188
+ )
189
+ : undefined;
190
+ },
191
+ createAppend(): VNode | undefined {
192
+ const slot = getSlot(this, 'append');
193
+ return slot ? h('div', { class: 'y-input__append' }, slot) : undefined;
194
+ },
195
+ getDisplayHeight() {
196
+ const { height } = this;
197
+ if (!isNaN(Number(height))) {
198
+ return `${height}px`;
199
+ }
200
+ return height;
201
+ },
202
+ createDisplay(): VNode {
203
+ return h(
204
+ 'div',
205
+ {
206
+ class: {
207
+ [`${NAME}__display`]: true,
208
+ },
209
+ onClick: this.onClick,
210
+ onMousedown: this.onMousedown,
211
+ onMouseup: this.onMouseup,
212
+ ref: 'display',
213
+ style: {
214
+ ...this.displayStyles,
215
+ },
216
+ },
217
+ [
218
+ h('div', { class: `${NAME}__plate` }),
219
+ this.createPrepend(),
220
+ this.createDefault(),
221
+ this.createAppend(),
222
+ ],
223
+ );
224
+ },
225
+ createHelperText(): VNode {
226
+ const helperTextSlot = getSlot(this, 'helper-text', {
227
+ error: !!this.error || this.inError,
228
+ errorResult: this.errorResult,
229
+ });
230
+ const children = [];
231
+ if (helperTextSlot) {
232
+ children.push(helperTextSlot);
233
+ } else {
234
+ children.push(this.errorResult);
235
+ }
236
+ return h('div', { class: `${NAME}__helper-text` }, children);
237
+ },
238
+ createStackChildren(): VNode[] {
239
+ return [this.createDisplay(), this.createHelperText()];
240
+ },
241
+ createStack(): VNode {
242
+ return h(
243
+ 'div',
244
+ {
245
+ class: `${NAME}__stack`,
246
+ ref: 'stack',
247
+ },
248
+ this.createStackChildren(),
249
+ );
250
+ },
251
+ createContent(): (VNode | undefined)[] {
252
+ return [
253
+ this.createPrependOuter(),
254
+ this.createStack(),
255
+ this.createAppendOuter(),
256
+ ];
257
+ },
258
+ //
259
+ onClick(event: MouseEvent) {
260
+ if (this.autoSelect) {
261
+ if (event.target) {
262
+ window.getSelection()?.selectAllChildren(event.target as HTMLElement);
263
+ }
264
+ }
265
+ this.$emit('click', event);
266
+ },
267
+ onMousedown(e: Event) {
268
+ this.hasMouseDown = true;
269
+ this.$emit('mousedown', e);
270
+ },
271
+ onMouseup(e: Event) {
272
+ this.hasMouseDown = false;
273
+ this.$emit('mouseup', e);
274
+ },
275
+ onFocus(event: FocusEvent) {
276
+ this.isFocused = true;
277
+ this.$emit('focus', event);
278
+ },
279
+ onBlur(event: FocusEvent) {
280
+ this.isFocused = false;
281
+ this.invokeValidators();
282
+ this.$emit('blur', event);
283
+ },
284
+ onClickPrepend(event: MouseEvent) {
285
+ this.$emit('click:prepend', event);
286
+ },
287
+ onChange(event?: Event) {
288
+ this.invokeValidators();
289
+ },
290
+ //
291
+ invokeValidators(): boolean {
292
+ const { validators, inValue, $attrs } = this;
293
+ const { required } = $attrs;
294
+ this.resetError();
295
+ let flag = true;
296
+ if (Array.isArray(validators)) {
297
+ validators.some((validator: any) => {
298
+ const result = validator(inValue);
299
+ if (typeof result === 'string') {
300
+ this.inError = true;
301
+ this.errorResult = result;
302
+ flag = false;
303
+ return true;
304
+ }
305
+ if (result === false) {
306
+ this.inError = true;
307
+ this.errorResult = '';
308
+ flag = false;
309
+ return true;
310
+ }
311
+ return false;
312
+ });
313
+ }
314
+ if (flag && required && !inValue) {
315
+ this.inError = true;
316
+ return false;
317
+ }
318
+ return flag;
319
+ },
320
+ resetError() {
321
+ this.inError = false;
322
+ this.errorResult = undefined;
323
+ },
324
+ getClasses() {
325
+ return this.classes;
326
+ },
327
+ },
328
+ watch: {
329
+ modelValue(neo: string) {
330
+ if (!this.readonly) {
331
+ this.inValue = neo;
332
+ }
333
+ },
334
+ readonly(neo: boolean) {
335
+ if (!neo) {
336
+ this.inValue = this.modelValue;
337
+ }
338
+ },
339
+ inValue(neo: string) {
340
+ if (!this.readonly) {
341
+ this.$emit('update:modelValue', neo);
342
+ }
343
+ },
344
+ isError(neo: boolean) {
345
+ this.$emit('error', neo);
346
+ },
347
+ },
348
+ created() {
349
+ this.inValue = this.modelValue;
350
+ },
351
+ render(): VNode {
352
+ return withDirectives(
353
+ h(
354
+ 'div',
355
+ {
356
+ class: { ...this.getClasses(), [`${NAME}`]: true },
357
+ },
358
+ this.createContent(),
359
+ ),
360
+ [
361
+ // [
362
+ // resolveDirective('theme') as Directive,
363
+ // (this as any).theme.dark ? 'dark' : 'light',
364
+ // ],
365
+ ],
366
+ );
367
+ },
368
+ });
@@ -0,0 +1,3 @@
1
+ import YLayer from './y-layer.vue';
2
+
3
+ export { YLayer };
@@ -0,0 +1,32 @@
1
+ .y-layer-group {
2
+ contain: layout;
3
+ left: 0;
4
+ top: 0;
5
+ pointer-events: none;
6
+ position: absolute;
7
+ display: contents;
8
+ }
9
+
10
+ .y-layer {
11
+ border-radius: inherit;
12
+ display: flex;
13
+ inset: 0;
14
+ position: fixed;
15
+
16
+ &__scrim {
17
+ pointer-events: auto;
18
+ background: rgb(var(--y-layer-scrim, 0, 0, 0));
19
+ border-radius: inherit;
20
+ inset: 0;
21
+ opacity: 0.4;
22
+ position: fixed;
23
+ }
24
+
25
+ &__content {
26
+ outline: none;
27
+ position: absolute;
28
+ pointer-events: auto;
29
+ contain: layout;
30
+ transform-style: preserve-3d;
31
+ }
32
+ }