@dcrackel/hematournamentui 1.0.708 → 1.0.709

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.
@@ -927,6 +927,9 @@
927
927
  .scrollbar-thin {
928
928
  scrollbar-width: thin;
929
929
  }
930
+ .list-disc {
931
+ list-style-type: disc;
932
+ }
930
933
  .appearance-none {
931
934
  appearance: none;
932
935
  }
@@ -1125,6 +1128,10 @@
1125
1128
  border-style: var(--tw-border-style);
1126
1129
  border-width: 1px;
1127
1130
  }
1131
+ .border-0 {
1132
+ border-style: var(--tw-border-style);
1133
+ border-width: 0px;
1134
+ }
1128
1135
  .border-2 {
1129
1136
  border-style: var(--tw-border-style);
1130
1137
  border-width: 2px;
@@ -1366,6 +1373,9 @@
1366
1373
  .object-cover {
1367
1374
  object-fit: cover;
1368
1375
  }
1376
+ .p-0 {
1377
+ padding: calc(var(--spacing) * 0);
1378
+ }
1369
1379
  .p-0\! {
1370
1380
  padding: calc(var(--spacing) * 0) !important;
1371
1381
  }
@@ -1510,6 +1520,9 @@
1510
1520
  .pl-4 {
1511
1521
  padding-left: calc(var(--spacing) * 4);
1512
1522
  }
1523
+ .pl-5 {
1524
+ padding-left: calc(var(--spacing) * 5);
1525
+ }
1513
1526
  .text-center {
1514
1527
  text-align: center;
1515
1528
  }
@@ -1851,12 +1864,6 @@
1851
1864
  -webkit-user-select: none;
1852
1865
  user-select: none;
1853
1866
  }
1854
- .placeholder\:text-xs {
1855
- &::placeholder {
1856
- font-size: var(--text-xs);
1857
- line-height: var(--tw-leading, var(--text-xs--line-height));
1858
- }
1859
- }
1860
1867
  .last\:border-b-0 {
1861
1868
  &:last-child {
1862
1869
  border-bottom-style: var(--tw-border-style);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dcrackel/hematournamentui",
3
3
  "private": false,
4
- "version": "1.0.708",
4
+ "version": "1.0.709",
5
5
  "type": "module",
6
6
  "main": "dist/HemaTournamentUI-lib.umd.js",
7
7
  "module": "dist/HemaTournamentUI-lib.es.js",
@@ -1,85 +1,97 @@
1
- import BaseInput from './BaseInput.vue';
2
- import { mount } from '@vue/test-utils';
3
- import { describe, expect, test, it } from 'vitest';
4
-
5
- describe('BaseInput.vue', () => {
6
- it('renders with default props', () => {
7
- const wrapper = mount(BaseInput);
8
- const inputElement = wrapper.find('input');
9
-
10
- expect(inputElement.attributes('placeholder')).toBe('');
11
- expect(wrapper.vm.internalValue).toBe('');
12
- });
13
-
14
- it('initializes with the correct value prop', () => {
15
- const initialValue = 'Hello, World!';
16
- const wrapper = mount(BaseInput, {
17
- props: {
18
- value: initialValue
19
- }
20
- });
21
-
22
- expect(wrapper.vm.internalValue).toBe(initialValue);
23
- });
24
-
25
- it('updates internalValue when value prop changes', async () => {
26
- const wrapper = mount(BaseInput);
27
- await wrapper.setProps({ value: 'New Value' });
28
-
29
- expect(wrapper.vm.internalValue).toBe('New Value');
30
- });
31
-
32
- it('emits update:value with a delay upon input', async () => {
33
- const wrapper = mount(BaseInput);
34
- const inputElement = wrapper.find('input');
35
-
36
- await inputElement.setValue('Test Input');
37
-
38
- // TODO: Handle timer-related functionality with vitest
39
- await new Promise(resolve => setTimeout(resolve, 350));
40
-
41
- expect(wrapper.emitted('update:value')).toBeTruthy();
42
- expect(wrapper.emitted('update:value')[0]).toEqual(['Test Input']);
43
- });
44
-
45
- it('applies formInput styles when type is formInput', () => {
46
- const wrapper = mount(BaseInput, {
47
- props: {
48
- type: 'formInput',
49
- invalid: false
50
- }
51
- });
52
- const inputElement = wrapper.find('input');
53
- expect(inputElement.classes()).toContain('border');
54
- expect(inputElement.classes()).toContain('rounded-lg');
55
- expect(inputElement.classes()).toContain('text-secondary');
56
- expect(inputElement.classes()).toContain('placeholder:text-xs');
57
- expect(inputElement.classes()).toContain('text-sm');
58
- expect(inputElement.classes()).toContain('p-2');
59
- expect(inputElement.classes()).toContain('w-full');
60
- expect(inputElement.classes()).toContain('border-dropdownSelect');
61
- });
62
-
63
- it('applies border-alarm class when invalid is true', () => {
64
- const wrapper = mount(BaseInput, {
65
- props: {
66
- type: 'formInput',
67
- invalid: true
68
- }
69
- });
70
- const inputElement = wrapper.find('input');
71
- expect(inputElement.classes()).toContain('border-alarm');
72
- });
73
-
74
- it('does not apply border-alarm class when invalid is false', () => {
75
- const wrapper = mount(BaseInput, {
76
- props: {
77
- type: 'formInput',
78
- invalid: false
79
- }
80
- });
81
- const inputElement = wrapper.find('input');
82
- expect(inputElement.classes()).not.toContain('border-alarm');
83
- expect(inputElement.classes()).toContain('border-dropdownSelect');
84
- });
85
- });
1
+ import BaseInput from './BaseInput.vue';
2
+ import { mount } from '@vue/test-utils';
3
+ import { describe, expect, test, it } from 'vitest';
4
+
5
+ describe('BaseInput.vue', () => {
6
+ it('renders with default props', () => {
7
+ const wrapper = mount(BaseInput);
8
+ const inputElement = wrapper.find('input');
9
+
10
+ expect(inputElement.attributes('placeholder')).toBe('');
11
+ expect(wrapper.vm.internalValue).toBe('');
12
+ });
13
+
14
+ it('initializes with the correct value prop', () => {
15
+ const initialValue = 'Hello, World!';
16
+ const wrapper = mount(BaseInput, {
17
+ props: {
18
+ value: initialValue
19
+ }
20
+ });
21
+
22
+ expect(wrapper.vm.internalValue).toBe(initialValue);
23
+ });
24
+
25
+ it('updates internalValue when value prop changes', async () => {
26
+ const wrapper = mount(BaseInput);
27
+ await wrapper.setProps({ value: 'New Value' });
28
+
29
+ expect(wrapper.vm.internalValue).toBe('New Value');
30
+ });
31
+
32
+ it('emits the latest value synchronously before the next action', () => {
33
+ const wrapper = mount(BaseInput);
34
+ const inputElement = wrapper.find('input');
35
+
36
+ inputElement.element.value = 'Test Input';
37
+ inputElement.element.dispatchEvent(new Event('input', { bubbles: true }));
38
+ expect(wrapper.emitted('update:value')).toEqual([['Test Input']]);
39
+ });
40
+
41
+ it('applies input border styles when addBorder is enabled', () => {
42
+ const wrapper = mount(BaseInput, {
43
+ props: {
44
+ addBorder: true,
45
+ invalid: false
46
+ }
47
+ });
48
+ const inputElement = wrapper.find('input');
49
+ expect(inputElement.classes()).toContain('border');
50
+ expect(inputElement.classes()).toContain('rounded-lg');
51
+ expect(inputElement.classes()).toContain('text-quinary');
52
+ expect(inputElement.classes()).toContain('text-sm');
53
+ expect(inputElement.classes()).toContain('p-2');
54
+ expect(inputElement.classes()).toContain('w-full');
55
+ expect(inputElement.classes()).toContain('border-dropdownSelect');
56
+ });
57
+
58
+ it('applies border-alarm class when invalid is true', () => {
59
+ const wrapper = mount(BaseInput, {
60
+ props: {
61
+ addBorder: true,
62
+ invalid: true
63
+ }
64
+ });
65
+ const inputElement = wrapper.find('input');
66
+ expect(inputElement.classes()).toContain('border-alarm');
67
+ });
68
+
69
+ it('does not apply border-alarm class when invalid is false', () => {
70
+ const wrapper = mount(BaseInput, {
71
+ props: {
72
+ addBorder: true,
73
+ invalid: false
74
+ }
75
+ });
76
+ const inputElement = wrapper.find('input');
77
+ expect(inputElement.classes()).not.toContain('border-alarm');
78
+ expect(inputElement.classes()).toContain('border-dropdownSelect');
79
+ });
80
+
81
+ it('delivers a cleared value before the input is unmounted', () => {
82
+ const wrapper = mount(BaseInput, { props: { value: '123', inputType: 'number' } });
83
+ const input = wrapper.find('input');
84
+ input.element.value = '';
85
+ input.element.dispatchEvent(new Event('input', { bubbles: true }));
86
+ expect(wrapper.emitted('update:value')).toEqual([['']]);
87
+ wrapper.unmount();
88
+ });
89
+
90
+ it('does not emit edits while disabled', () => {
91
+ const wrapper = mount(BaseInput, { props: { disabled: true, value: 'original' } });
92
+ const input = wrapper.find('input');
93
+ input.element.value = 'changed';
94
+ input.element.dispatchEvent(new Event('input', { bubbles: true }));
95
+ expect(wrapper.emitted('update:value')).toBeUndefined();
96
+ });
97
+ });
@@ -1,150 +1,149 @@
1
- <template>
2
- <div :class="iconName ? '' : ''">
3
- <input
4
- ref="input"
5
- v-model="internalValue"
6
- :class="baseClasses"
7
- :placeholder="placeholder"
8
- :type="inputType"
9
- :disabled="disabled"
10
- @input="onInput"
11
- @focus="onFocus"
12
- @blur="onBlur"
13
- />
14
- </div>
15
- </template>
16
-
17
- <script>
18
- const sizeClasses = {
19
- xs: ' text-xs',
20
- sm: ' text-sm',
21
- md: ' text-md',
22
- lg: ' text-lg',
23
- xl: ' text-xl',
24
- '2xl': ' text-2xl',
25
- '3xl': ' text-3xl',
26
- '4xl': ' text-4xl',
27
- '5xl': ' text-5xl'
28
- };
29
-
30
- export default {
31
- name: 'BaseInput',
32
- emits: ['update:value'],
33
- props: {
34
- placeholder: {
35
- type: [String, Number],
36
- default: ''
37
- },
38
- value: {
39
- type: [String, Number],
40
- default: ''
41
- },
42
- inputType: {
43
- type: String,
44
- default: 'text'
45
- },
46
- invalid: {
47
- type: Boolean,
48
- default: false
49
- },
50
- addBorder: {
51
- type: Boolean,
52
- default: false
53
- },
54
- iconName: {
55
- type: String,
56
- default: ''
57
- },
58
- disabled: {
59
- type: Boolean,
60
- default: false
61
- },
62
- iconStyle: {
63
- type: String,
64
- default: 'fa-solid',
65
- validator: value => ['fa-solid', 'fa-regular', 'fa-light', 'fa-thing'].includes(value)
66
- },
67
- size: {
68
- type: String,
69
- default: 'sm',
70
- validator: value => ['', ' ', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'].includes(value)
71
- },
72
- centerInput: {
73
- type: Boolean,
74
- default: false
75
- },
76
- iconColor: {
77
- type: String,
78
- default: 'primary',
79
- validator: value =>
80
- ['neutral', 'primary', 'secondary', 'tertiary', 'quaternary', 'quinary', 'bright', 'white', 'alarm'].includes(
81
- value
82
- )
83
- },
84
- allowPercent: {
85
- type: Boolean,
86
- default: false
87
- }
88
- },
89
- data() {
90
- return {
91
- internalValue: this.value,
92
- currentPlaceholder: this.placeholder,
93
- timeout: null
94
- };
95
- },
96
- computed: {
97
- baseClasses() {
98
- let classes = 'appearance-none focus:outline-none w-full text-sm rounded-lg text-quinary';
99
- if (this.addBorder) {
100
- classes += this.invalid ? ' border border-alarm p-2' : ' border border-dropdownSelect p-2';
101
- }
102
-
103
- if (this.centerInput) classes += ' text-center';
104
-
105
- classes += sizeClasses[this.size] || '';
106
-
107
- return classes;
108
- }
109
- },
110
- watch: {
111
- value(newValue) {
112
- this.internalValue = newValue;
113
- }
114
- },
115
- methods: {
116
- onInput(event) {
117
- let sanitizedValue = event.target.value;
118
-
119
- if (this.inputType === 'number') {
120
- sanitizedValue = sanitizedValue.replace(/\D/g, '');
121
- }
122
- if (this.inputType === 'text') {
123
- this.allowPercent
124
- ? (sanitizedValue = sanitizedValue.replace(/[\\'"=*<>|#$^(){}\[\]]/g, ''))
125
- : (sanitizedValue = sanitizedValue.replace(/[\\'"=*<>|#$%^(){}\[\]]/g, ''));
126
- }
127
-
128
- this.internalValue = sanitizedValue;
129
-
130
- clearTimeout(this.timeout);
131
- this.timeout = setTimeout(() => {
132
- this.$emit('update:value', this.internalValue);
133
- }, 300);
134
- },
135
- onFocus() {
136
- this.currentPlaceholder = '';
137
- },
138
- onBlur() {
139
- if (!this.internalValue) {
140
- this.currentPlaceholder = this.placeholder;
141
- }
142
- },
143
- focus() {
144
- if (this.$refs.input) {
145
- this.$refs.input.focus();
146
- }
147
- }
148
- }
149
- };
150
- </script>
1
+ <template>
2
+ <div :class="iconName ? '' : ''">
3
+ <input
4
+ ref="input"
5
+ :value="internalValue"
6
+ :class="baseClasses"
7
+ :placeholder="placeholder"
8
+ :type="inputType"
9
+ :disabled="disabled"
10
+ :aria-invalid="invalid"
11
+ @input="onInput"
12
+ @focus="onFocus"
13
+ @blur="onBlur"
14
+ />
15
+ </div>
16
+ </template>
17
+
18
+ <script>
19
+ const sizeClasses = {
20
+ xs: ' text-xs',
21
+ sm: ' text-sm',
22
+ md: ' text-md',
23
+ lg: ' text-lg',
24
+ xl: ' text-xl',
25
+ '2xl': ' text-2xl',
26
+ '3xl': ' text-3xl',
27
+ '4xl': ' text-4xl',
28
+ '5xl': ' text-5xl'
29
+ };
30
+
31
+ export default {
32
+ name: 'BaseInput',
33
+ emits: ['update:value'],
34
+ props: {
35
+ placeholder: {
36
+ type: [String, Number],
37
+ default: ''
38
+ },
39
+ value: {
40
+ type: [String, Number],
41
+ default: ''
42
+ },
43
+ inputType: {
44
+ type: String,
45
+ default: 'text'
46
+ },
47
+ invalid: {
48
+ type: Boolean,
49
+ default: false
50
+ },
51
+ addBorder: {
52
+ type: Boolean,
53
+ default: false
54
+ },
55
+ iconName: {
56
+ type: String,
57
+ default: ''
58
+ },
59
+ disabled: {
60
+ type: Boolean,
61
+ default: false
62
+ },
63
+ iconStyle: {
64
+ type: String,
65
+ default: 'fa-solid',
66
+ validator: value => ['fa-solid', 'fa-regular', 'fa-light', 'fa-thing'].includes(value)
67
+ },
68
+ size: {
69
+ type: String,
70
+ default: 'sm',
71
+ validator: value => ['', ' ', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'].includes(value)
72
+ },
73
+ centerInput: {
74
+ type: Boolean,
75
+ default: false
76
+ },
77
+ iconColor: {
78
+ type: String,
79
+ default: 'primary',
80
+ validator: value =>
81
+ ['neutral', 'primary', 'secondary', 'tertiary', 'quaternary', 'quinary', 'bright', 'white', 'alarm'].includes(
82
+ value
83
+ )
84
+ },
85
+ allowPercent: {
86
+ type: Boolean,
87
+ default: false
88
+ }
89
+ },
90
+ data() {
91
+ return {
92
+ internalValue: this.value,
93
+ currentPlaceholder: this.placeholder
94
+ };
95
+ },
96
+ computed: {
97
+ baseClasses() {
98
+ let classes = 'appearance-none focus:outline-none w-full text-sm rounded-lg text-quinary';
99
+ if (this.addBorder) {
100
+ classes += this.invalid ? ' border border-alarm p-2' : ' border border-dropdownSelect p-2';
101
+ }
102
+
103
+ if (this.centerInput) classes += ' text-center';
104
+
105
+ classes += sizeClasses[this.size] || '';
106
+
107
+ return classes;
108
+ }
109
+ },
110
+ watch: {
111
+ value(newValue) {
112
+ this.internalValue = newValue;
113
+ }
114
+ },
115
+ methods: {
116
+ onInput(event) {
117
+ if (this.disabled) return;
118
+ const input = event.target;
119
+ let sanitizedValue = input.value;
120
+
121
+ if (this.inputType === 'number') {
122
+ sanitizedValue = sanitizedValue.replace(/\D/g, '');
123
+ }
124
+ if (this.inputType === 'text') {
125
+ this.allowPercent
126
+ ? (sanitizedValue = sanitizedValue.replace(/[\\'"=*<>|#$^(){}\[\]]/g, ''))
127
+ : (sanitizedValue = sanitizedValue.replace(/[\\'"=*<>|#$%^(){}\[\]]/g, ''));
128
+ }
129
+
130
+ this.internalValue = sanitizedValue;
131
+ input.value = sanitizedValue;
132
+ this.$emit('update:value', sanitizedValue);
133
+ },
134
+ onFocus() {
135
+ this.currentPlaceholder = '';
136
+ },
137
+ onBlur() {
138
+ if (!this.internalValue) {
139
+ this.currentPlaceholder = this.placeholder;
140
+ }
141
+ },
142
+ focus() {
143
+ if (this.$refs.input) {
144
+ this.$refs.input.focus();
145
+ }
146
+ }
147
+ }
148
+ };
149
+ </script>
@@ -1,20 +1,31 @@
1
- import GenericImageCropper from './ImageCropper.vue';
2
-
3
- export default {
4
- title: 'Organisms/ComplexInputs/ImageCropper',
5
- component: GenericImageCropper,
6
- tags: ['autodocs'],
7
- args: {},
8
- argTypes: {
9
- personID: {
10
- control: 'number',
11
- description: 'The ID of the person for the image cropper'
12
- }
13
- }
14
- };
15
-
16
- export const Default = {
17
- args: {
18
- personID: 1
19
- }
20
- };
1
+ import GenericImageCropper from './ImageCropper.vue';
2
+
3
+ export default {
4
+ title: 'Organisms/ComplexInputs/ImageCropper',
5
+ component: GenericImageCropper,
6
+ tags: ['autodocs'],
7
+ args: { urlToImage: '', isProfile: true, disabled: false },
8
+ argTypes: {
9
+ urlToImage: { control: 'text' },
10
+ uploadImageName: { control: 'text' },
11
+ uploadServer: { control: 'text' },
12
+ imageServer: { control: 'text' },
13
+ isProfile: { control: 'boolean' },
14
+ disabled: { control: 'boolean' },
15
+ 'update:url': { action: 'update:url' },
16
+ 'update:uploading': { action: 'update:uploading' },
17
+ 'error:load': { action: 'error:load' },
18
+ 'error:upload': { action: 'error:upload' }
19
+ }
20
+ };
21
+
22
+ export const Default = {
23
+ args: {
24
+ urlToImage: '',
25
+ isProfile: true
26
+ }
27
+ };
28
+
29
+ export const Disabled = {
30
+ args: { urlToImage: '', isProfile: true, disabled: true }
31
+ };