@fishawack/lab-velocity 0.1.0 → 0.1.1

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/Icon.vue ADDED
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div class="vel-icon">
3
+ <VSvg v-bind="$props" />
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ import VSvg from "../components/Svg.vue";
9
+
10
+ export default {
11
+ props: {
12
+ name: {
13
+ type: String,
14
+ required: true,
15
+ },
16
+ embed: {
17
+ type: Boolean,
18
+ default: false,
19
+ },
20
+ asis: {
21
+ type: Boolean,
22
+ default: false,
23
+ },
24
+ artboard: {
25
+ type: Boolean,
26
+ default: false,
27
+ },
28
+ },
29
+ components: {
30
+ VSvg
31
+ },
32
+ }
33
+ </script>
package/Svg.vue ADDED
@@ -0,0 +1,41 @@
1
+ <template>
2
+ <component v-if="embed" :is="icon" class="vel-svg" />
3
+ <svg v-else class="vel-svg">
4
+ <use :xlink:href="`#${name}${artboard ? '--artboard' : ''}`" />
5
+ </svg>
6
+ </template>
7
+
8
+ <script>
9
+ import { defineAsyncComponent } from 'vue';
10
+ export default {
11
+
12
+ props: {
13
+ name: {
14
+ type: String,
15
+ required: true,
16
+ },
17
+ embed: {
18
+ type: Boolean,
19
+ default: false,
20
+ },
21
+ asis: {
22
+ type: Boolean,
23
+ default: false,
24
+ },
25
+ artboard: {
26
+ type: Boolean,
27
+ default: false,
28
+ }
29
+ },
30
+ data() {
31
+ return {
32
+ icons: import.meta.glob(`../../handlebars/generated/embed/**/*.svg`, { query: '?component' })
33
+ }
34
+ },
35
+ computed: {
36
+ icon() {
37
+ return defineAsyncComponent(() => this.icons[`../../handlebars/generated/embed/svg${this.asis ? '--asis' : ''}--${this.name}${this.artboard ? '--artboard' : ''}.svg`]())
38
+ },
39
+ }
40
+ }
41
+ </script>
package/_base.scss ADDED
@@ -0,0 +1 @@
1
+ @import "element-plus/theme-chalk/base.css";
package/_defaults.scss ADDED
@@ -0,0 +1,7 @@
1
+ @use "_variables.scss";
2
+
3
+ @import "@fishawack/lab-ui/_defaults.scss";
4
+
5
+ $colors: variables.dynamic('color', module-variables("variables"));
6
+
7
+ // Override lab-ui defaults here, e.g $button: $color6;
@@ -0,0 +1,3 @@
1
+ @import "@fishawack/lab-ui/_variables.scss";
2
+
3
+ // Set global variables here, e.g $color6: red;
@@ -0,0 +1 @@
1
+ @import "element-plus/theme-chalk/el-input.css";
@@ -0,0 +1,27 @@
1
+ @import "element-plus/theme-chalk/el-button.css";
2
+
3
+ .vel-button {
4
+ &[disabled=true] {
5
+ pointer-events: none !important;
6
+ }
7
+ &--iconRight {
8
+ .vel-button__button {
9
+ .el-icon {
10
+ order: 2;
11
+ }
12
+ >span {
13
+ order: 1;
14
+ margin: 0 0.5rem 0 0;
15
+ }
16
+ }
17
+ }
18
+ &--iconOnly {
19
+ .vel-button__button {
20
+ >span {
21
+ margin: 0;
22
+ display: none;
23
+ }
24
+ }
25
+ }
26
+
27
+ }
@@ -0,0 +1,37 @@
1
+ @import "element-plus/theme-chalk/el-checkbox.css";
2
+ @import "element-plus/theme-chalk/el-checkbox-button.css";
3
+
4
+ .vel-checkbox {
5
+ display: flex;
6
+ flex-direction: row;
7
+ align-items: center;
8
+ gap: .5rem;
9
+ flex-wrap: wrap ;
10
+ &__label{
11
+ order: 2;
12
+ }
13
+ &__checkbox {
14
+ order: 1;
15
+ .el-checkbox__input {
16
+ &.is-checked {
17
+ .el-checkbox__inner {
18
+ background-color: black;
19
+ }
20
+ }
21
+ }
22
+ }
23
+ &__error {
24
+ order: 3;
25
+ flex-basis: 100%;
26
+ }
27
+ }
28
+
29
+ .vel-checkbox-group {
30
+ &--vertical {
31
+ .vel-checkbox-group__wrapper {
32
+ display: flex;
33
+ flex-direction: column;
34
+ }
35
+ }
36
+
37
+ }
@@ -0,0 +1,8 @@
1
+ @import "element-plus/theme-chalk/el-date-picker.css";
2
+
3
+ .vel-datepicker {
4
+ }
5
+
6
+ .vel-popper {
7
+ border-color: red !important;
8
+ }
@@ -0,0 +1 @@
1
+ @import "@fishawack/lab-ui/_icon.scss";
@@ -0,0 +1,5 @@
1
+ @import "element-plus/theme-chalk/el-select.css";
2
+ @import "element-plus/theme-chalk/el-tag.css";
3
+
4
+ .vel-select {
5
+ }
@@ -0,0 +1 @@
1
+ @import "element-plus/theme-chalk/el-switch.css";
@@ -0,0 +1,122 @@
1
+ <template>
2
+ <XInput v-bind="$props">
3
+ <el-button
4
+ :class="[`button ${baseClass}__button`]"
5
+ :name="name"
6
+ :label="label"
7
+ :id="name"
8
+ :disabled="disabled"
9
+ :round="round"
10
+ :circle="circle"
11
+ :size="size"
12
+ :text="text"
13
+ :tag="tag"
14
+ :autofocus="autofocus"
15
+ :native-type="nativeType"
16
+ :type="type"
17
+ :link="link"
18
+ :plain="plain"
19
+ :loading="loading"
20
+ :customIcon="customIcon"
21
+ v-model="content"
22
+ @input="handleInput">
23
+
24
+ <template v-if="icon || customIcon " #icon>
25
+ <component :is="icon" v-if="icon" :class="iconClasses" />
26
+ <VIcon v-if="customIcon" :name="customIcon" :class="iconClasses" embed></VIcon>
27
+ </template>
28
+ <span v-if="label" v-html="label" :class="[`${baseClass}__label`]" />
29
+
30
+ </el-button>
31
+ </XInput>
32
+ </template>
33
+
34
+ <script>
35
+ import { ElButton } from "element-plus";
36
+ import { ElIcon } from "element-plus";
37
+ import input from "./input.js";
38
+ import XInput from "./input.vue";
39
+ import VIcon from "../../components/Icon.vue";
40
+ import {
41
+ Check,
42
+ Delete,
43
+ Edit,
44
+ Message,
45
+ Search,
46
+ Star,
47
+ } from '@element-plus/icons-vue'
48
+
49
+ export default {
50
+ mixins: [input],
51
+ props: {
52
+ ...input.props,
53
+ baseClass: {
54
+ type: String,
55
+ default: "vel-button",
56
+ },
57
+ inputType: {
58
+ type: String,
59
+ default: "button",
60
+ },
61
+ type: {
62
+ type: String,
63
+ default: null,
64
+ },
65
+ nativeType: {
66
+ type: String,
67
+ default: "button",
68
+ },
69
+ size: {
70
+ type: String,
71
+ default: "default",
72
+ },
73
+ round: {
74
+ type: Boolean,
75
+ default: false,
76
+ },
77
+ circle: {
78
+ type: Boolean,
79
+ default: false,
80
+ },
81
+ text: {
82
+ type: Boolean,
83
+ default: false,
84
+ },
85
+ link: {
86
+ type: Boolean,
87
+ default: false,
88
+ },
89
+ plain: {
90
+ type: Boolean,
91
+ default: false,
92
+ },
93
+ tag: {
94
+ type: String,
95
+ default: "button",
96
+ },
97
+ loading: {
98
+ type: Boolean,
99
+ default: false,
100
+ },
101
+ icon: {
102
+ type: ElIcon,
103
+ default: null,
104
+ },
105
+ customIcon: {
106
+ type: String,
107
+ default: null,
108
+ },
109
+ iconClasses: {
110
+ type: String,
111
+ default: "",
112
+ }
113
+ },
114
+
115
+ components: {
116
+ XInput,
117
+ ElButton,
118
+ VIcon,
119
+ ElIcon
120
+ },
121
+ };
122
+ </script>
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <XInput v-bind="$props">
3
+ <el-checkbox
4
+ :class="[`${baseClass}__checkbox`]"
5
+ :id="name"
6
+ :disabled="disabled"
7
+ v-model="content"
8
+ :required="required"
9
+ @change="handleInput"
10
+ >
11
+ </el-checkbox>
12
+ </XInput>
13
+ </template>
14
+
15
+ <script>
16
+ import { ElCheckbox } from "element-plus";
17
+ import input from "./input.js";
18
+ import XInput from "./input.vue";
19
+
20
+ export default {
21
+ mixins: [input],
22
+ props: {
23
+ ...input.props,
24
+ modelValue: {
25
+ type: Boolean,
26
+ default: null,
27
+ },
28
+ baseClass: {
29
+ type: String,
30
+ default: "vel-checkbox",
31
+ },
32
+ },
33
+
34
+ components: {
35
+ XInput,
36
+ ElCheckbox,
37
+ },
38
+ };
39
+ </script>
@@ -0,0 +1,69 @@
1
+ <template>
2
+ <XInput v-bind="$props">
3
+ <el-checkbox-group :class="[`${baseClass}__wrapper`]" :id="name" :disabled="disabled" :size="size" :min="min"
4
+ :max="max" v-model="content" :required="required" @change="handleInput" :checkboxButton="checkboxButton">
5
+ <el-checkbox v-if="!checkboxButton" :key="index" v-for="({ label, value, disabled }, index) in options"
6
+ :label="label" :value="value" :disabled="disabled">
7
+ <slot name="label" :label="label" :value="value">
8
+ <span v-html="label"></span>
9
+ </slot>
10
+ </el-checkbox>
11
+ <el-checkbox-button v-else :key="indexB" v-for="({ label, value, disabled }, indexB) in options"
12
+ :label="label" :value="value" :disabled="disabled">
13
+ <slot name="label" :label="label" :value="value">
14
+ <span v-html="label"></span>
15
+ </slot>
16
+ </el-checkbox-button>
17
+ </el-checkbox-group>
18
+ </XInput>
19
+ </template>
20
+
21
+ <script>
22
+ import { ElCheckbox } from "element-plus";
23
+ import { ElCheckboxButton } from "element-plus";
24
+ import { ElCheckboxGroup } from "element-plus";
25
+ import input from "./input.js";
26
+ import XInput from "./input.vue";
27
+
28
+ export default {
29
+ mixins: [input],
30
+ props: {
31
+ ...input.props,
32
+ modelValue: {
33
+ type: Array,
34
+ default: [],
35
+ },
36
+ baseClass: {
37
+ type: String,
38
+ default: "vel-checkbox-group",
39
+ },
40
+ checkboxButton: {
41
+ type: Boolean,
42
+ default: false,
43
+ },
44
+ size: {
45
+ type: String,
46
+ default: "default",
47
+ },
48
+ min: {
49
+ type: Number,
50
+ default: 0,
51
+ },
52
+ max: {
53
+ type: Number,
54
+ default: 100,
55
+ },
56
+ options: {
57
+ type: Array,
58
+ default: [],
59
+ },
60
+ },
61
+
62
+ components: {
63
+ XInput,
64
+ ElCheckbox,
65
+ ElCheckboxButton,
66
+ ElCheckboxGroup,
67
+ },
68
+ };
69
+ </script>
@@ -0,0 +1,78 @@
1
+ <template>
2
+ <XInput v-bind="$props">
3
+ <template #label>
4
+ <slot name="label" />
5
+ </template>
6
+
7
+ <el-date-picker v-bind="$attrs"
8
+ :type="type"
9
+ :disabled="disabled"
10
+ :disabled-date="disabledDate"
11
+ - :placeholder="placeholder"
12
+ :shortcuts="shortcuts"
13
+ class="w-100"
14
+ v-model="content"
15
+ @change="handleInput"
16
+ :value-format="valueFormat"
17
+ :format="format"
18
+ />
19
+ </XInput>
20
+ </template>
21
+
22
+ <script>
23
+ import dayjs from "dayjs";
24
+ import { ElDatePicker } from "element-plus";
25
+
26
+ import input from "./input.js";
27
+ import XInput from "./input.vue";
28
+
29
+ export default {
30
+ mixins: [input],
31
+ props: {
32
+ ...input.props,
33
+ type: {
34
+ type: String,
35
+ validator: (value) => ['date', 'year', 'years', 'month', 'months', 'date', 'dates', 'datetime', 'week', 'datetimerange', 'daterange', 'monthrange', 'yearrange'].includes(value),
36
+ default: "date",
37
+ },
38
+ format: {
39
+ type: String
40
+ },
41
+ valueFormat: {
42
+ type: String
43
+ },
44
+ baseClass: {
45
+ type: String,
46
+ default: "vel-datepicker",
47
+ },
48
+ minDate: {
49
+ type: [Date, String],
50
+ },
51
+ maxDate: {
52
+ type: [Date, String],
53
+ },
54
+ shortcuts: {
55
+ type: Array,
56
+ default: [],
57
+ },
58
+ },
59
+ components: {
60
+ XInput,
61
+ ElDatePicker,
62
+ },
63
+
64
+ methods: {
65
+ disabledDate(date) {
66
+ if (this.minDate && dayjs(date).isBefore(this.minDate)) {
67
+ return true;
68
+ }
69
+
70
+ if (this.maxDate && dayjs(date).isAfter(this.maxDate)) {
71
+ return true;
72
+ }
73
+
74
+ return false;
75
+ },
76
+ },
77
+ };
78
+ </script>
@@ -0,0 +1,111 @@
1
+ <template>
2
+ <XInput v-bind="$props">
3
+ <template #label>
4
+ <slot name="label" />
5
+ </template>
6
+
7
+ <el-select
8
+ v-model="content"
9
+ class="block"
10
+ :multiple="multiple"
11
+ :placeholder="placeholder"
12
+ :disabled="disabled"
13
+ :clearable="clearable"
14
+ :collapse-tags="collapseTags"
15
+ :filterable="filterable"
16
+ :value-on-clear="null"
17
+ @change="handleInput"
18
+ @clear="this.$emit('clear')"
19
+ @blur="this.$emit('blur')"
20
+ >
21
+ <el-option
22
+ v-if="!object"
23
+ v-for="(label, value) in options"
24
+ :key="value"
25
+ :label="label"
26
+ :value="castValue(value)"
27
+ >
28
+ </el-option>
29
+ <el-option
30
+ v-else-if="object"
31
+ v-for="option in options"
32
+ :key="option.value"
33
+ :label="option.label"
34
+ :disabled="option.disabled"
35
+ :value="castValue(option.value)"
36
+ >
37
+ </el-option>
38
+ </el-select>
39
+ </XInput>
40
+ </template>
41
+
42
+ <script>
43
+ import { ElSelect } from "element-plus";
44
+ import { ElOption } from "element-plus";
45
+ import input from "./input.js";
46
+ import XInput from "./input.vue";
47
+ import _ from 'lodash';
48
+
49
+ export default {
50
+ mixins: [input],
51
+ props: {
52
+ ...input.props,
53
+ modelValue: {
54
+ type: Array,
55
+ default: [],
56
+ },
57
+ baseClass: {
58
+ type: String,
59
+ default: "vel-select",
60
+ },
61
+ clearable: {
62
+ type: Boolean,
63
+ default: false,
64
+ },
65
+ collapseTags: {
66
+ type: Boolean,
67
+ default: false,
68
+ },
69
+ filterable: {
70
+ type: Boolean,
71
+ default: false,
72
+ },
73
+ options: {
74
+ type: Array,
75
+ default: [],
76
+ },
77
+ multiple: {
78
+ type: Boolean,
79
+ default: false,
80
+ },
81
+ object: {
82
+ type: Boolean,
83
+ default: false,
84
+ },
85
+ },
86
+
87
+ components: {
88
+ XInput,
89
+ ElOption,
90
+ ElSelect,
91
+ },
92
+
93
+ emits: ['change', 'clear', 'blur'],
94
+ methods: {
95
+ castValue(value) {
96
+ if (
97
+ !_.isNull(value) &&
98
+ typeof value === "string" &&
99
+ !isNaN(Number(value))
100
+ ) {
101
+ return parseInt(value);
102
+ }
103
+ return value;
104
+ },
105
+ handleInput(value, $event) {
106
+ this.$emit('change', value);
107
+ }
108
+ },
109
+
110
+ };
111
+ </script>
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <XInput v-bind="$props">
3
+ <template #label>
4
+ <slot name="label" />
5
+ </template>
6
+
7
+ <el-switch
8
+ :class="[`${baseClass}__control`]"
9
+ :name="name"
10
+ :id="name"
11
+ :disabled="disabled"
12
+ v-model="content"
13
+ :required="required"
14
+ @input="handleInput"
15
+ />
16
+ </XInput>
17
+ </template>
18
+
19
+ <script>
20
+ import { ElSwitch } from "element-plus";
21
+ import input from "./input.js";
22
+ import XInput from "./input.vue";
23
+
24
+ export default {
25
+ mixins: [input],
26
+ props: {
27
+ ...input.props,
28
+ modelValue: {
29
+ type: Boolean,
30
+ default: null,
31
+ },
32
+ baseClass: {
33
+ type: String,
34
+ default: "vel-switch",
35
+ },
36
+ },
37
+
38
+ components: {
39
+ XInput,
40
+ ElSwitch,
41
+ },
42
+ };
43
+ </script>
package/form/basic.vue ADDED
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <XInput v-bind="$props">
3
+ <template #label>
4
+ <slot name="label" />
5
+ </template>
6
+
7
+ <el-input
8
+ :class="[`${baseClass}__textbox`]"
9
+ :name="name"
10
+ :id="name"
11
+ :disabled="disabled"
12
+ :minlength="minlength"
13
+ :maxlength="maxlength"
14
+ :type="type"
15
+ :placeholder="placeholder"
16
+ v-model="content"
17
+ :required="required"
18
+ @input="handleInput"
19
+ >
20
+ <template v-if="prepend" #prepend>{{ prepend }}</template>
21
+ <template v-if="append" #append>{{ append }}</template>
22
+ </el-input>
23
+ </XInput>
24
+ </template>
25
+
26
+ <script>
27
+ import { ElInput } from "element-plus";
28
+ import input from "./input.js";
29
+ import XInput from "./input.vue";
30
+
31
+ export default {
32
+ mixins: [input],
33
+ props: {
34
+ ...input.props,
35
+ baseClass: {
36
+ type: String,
37
+ default: "vel-basic",
38
+ },
39
+ minlength: {
40
+ type: Number,
41
+ default: null,
42
+ },
43
+ maxlength: {
44
+ type: Number,
45
+ default: null,
46
+ },
47
+ prepend: {
48
+ type: String,
49
+ default: null,
50
+ },
51
+ append: {
52
+ type: String,
53
+ default: null,
54
+ },
55
+ },
56
+
57
+ components: {
58
+ XInput,
59
+ ElInput,
60
+ },
61
+ };
62
+ </script>
package/form/color.vue ADDED
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <XInput v-bind="$props">
3
+ <template #label>
4
+ <slot name="label" />
5
+ </template>
6
+
7
+ <el-color-picker v-model="content" @change="handleInput" />
8
+ </XInput>
9
+ </template>
10
+
11
+ <script>
12
+ import input from "./input.js";
13
+ import XInput from "./input.vue";
14
+
15
+ export default {
16
+ mixins: [input],
17
+
18
+ components: {
19
+ XInput,
20
+ },
21
+ };
22
+ </script>
package/form/file.vue ADDED
@@ -0,0 +1,89 @@
1
+ <template>
2
+ <XInput v-bind="$props">
3
+ <template #label>
4
+ <slot name="label" />
5
+ </template>
6
+
7
+ <input
8
+ ref="input"
9
+ type="file"
10
+ class="absolute invisible top-0 left-0"
11
+ @change="onImageChange"
12
+ />
13
+ <div class="border-solid border border-color-6">
14
+ <el-empty
15
+ @click.prevent="$refs.input.click()"
16
+ class="p-0 w-100 block mx-auto cursor"
17
+ style="max-width: 150px"
18
+ :image="hasPreview && imgSrc"
19
+ :description="hasPreview ? 'Preview' : 'No preview available'"
20
+ />
21
+ </div>
22
+ <div class="text-center mt-0.5">
23
+ <el-button v-if="content" type="danger" @click="cancel"
24
+ >Clear</el-button
25
+ >
26
+ </div>
27
+ </XInput>
28
+ </template>
29
+
30
+ <script>
31
+ import input from "./input.js";
32
+ import XInput from "./input.vue";
33
+
34
+ export default {
35
+ mixins: [input],
36
+
37
+ components: { XInput },
38
+
39
+ props: {
40
+ preview: {},
41
+ },
42
+
43
+ data() {
44
+ return {
45
+ imgSrc: null,
46
+ };
47
+ },
48
+
49
+ mounted() {
50
+ this.imgSrc = this.preview;
51
+ },
52
+
53
+ computed: {
54
+ hasPreview() {
55
+ return this.imgSrc &&
56
+ [".svg", ".jpg", ".png", "data:image/"].some((d) =>
57
+ this.imgSrc.includes(d)
58
+ )
59
+ ? this.imgSrc
60
+ : "";
61
+ },
62
+ },
63
+
64
+ methods: {
65
+ onImageChange(e) {
66
+ if (!e.target.files.length) return;
67
+
68
+ let file = e.target.files[0];
69
+ let reader = new FileReader();
70
+
71
+ reader.readAsDataURL(file);
72
+
73
+ reader.onload = (e) => {
74
+ this.imgSrc = reader.result;
75
+ };
76
+
77
+ this.content = file;
78
+
79
+ this.handleInput();
80
+ },
81
+ cancel() {
82
+ this.$refs.input.value = null;
83
+ this.content = null;
84
+ this.imgSrc = this.preview;
85
+ this.handleInput();
86
+ },
87
+ },
88
+ };
89
+ </script>
package/form/input.js ADDED
@@ -0,0 +1,71 @@
1
+ export default {
2
+ props: {
3
+ type: {
4
+ type: String,
5
+ default: "text",
6
+ },
7
+ placeholder: {
8
+ type: String,
9
+ default: null,
10
+ },
11
+ required: {
12
+ type: Boolean,
13
+ default: false,
14
+ },
15
+ disabled: {
16
+ type: Boolean,
17
+ default: false,
18
+ },
19
+ autofocus: {
20
+ type: Boolean,
21
+ default: false,
22
+ },
23
+ modelValue: {
24
+ type: String,
25
+ default: null,
26
+ },
27
+ label: {
28
+ type: String,
29
+ default: null,
30
+ },
31
+ name: {
32
+ type: String,
33
+ default: null,
34
+ },
35
+ error: {
36
+ type: String,
37
+ default: null,
38
+ },
39
+ baseClass: {
40
+ type: String,
41
+ default: null,
42
+ },
43
+ classes: {
44
+ type: String,
45
+ default: null,
46
+ },
47
+ },
48
+
49
+ emits: ["update:modelValue"],
50
+
51
+ data() {
52
+ return {
53
+ content: "",
54
+ };
55
+ },
56
+
57
+ watch: {
58
+ modelValue: {
59
+ immediate: true,
60
+ handler(val) {
61
+ this.content = val;
62
+ },
63
+ },
64
+ },
65
+
66
+ methods: {
67
+ handleInput() {
68
+ this.$emit("update:modelValue", this.content);
69
+ },
70
+ },
71
+ };
package/form/input.vue ADDED
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <div class="form__group" :class="{ [baseClass]: baseClass, 'form__group--error': error, [classes]: classes }">
3
+ <label v-if="(label || $slots.label) && inputType !== 'button'" :class="{ [baseClass + '__label']: baseClass }"
4
+ :for="name">
5
+ <slot name="label">
6
+ <span v-html="label"></span>
7
+ </slot>
8
+ </label>
9
+
10
+ <slot />
11
+
12
+ <div v-if="error" class="form__error" :class="{ [baseClass + '__error']: baseClass }">
13
+ <small v-text="error"></small>
14
+ </div>
15
+ </div>
16
+ </template>
17
+
18
+ <script>
19
+ export default {
20
+ props: {
21
+ label: {
22
+ type: String,
23
+ default: null,
24
+ },
25
+ name: {
26
+ type: String,
27
+ default: null,
28
+ },
29
+ error: {
30
+ type: String,
31
+ default: null,
32
+ },
33
+ baseClass: {
34
+ type: String,
35
+ default: null,
36
+ },
37
+ classes: {
38
+ type: String,
39
+ default: null,
40
+ },
41
+ type: {
42
+ type: String,
43
+ default: null,
44
+ },
45
+ inputType: {
46
+ type: String,
47
+ default: "text",
48
+ },
49
+ },
50
+ };
51
+ </script>
@@ -0,0 +1,105 @@
1
+ <template>
2
+ <XInput v-bind="$props">
3
+ <template #label>
4
+ <slot name="label" />
5
+ </template>
6
+ <div class="el-input__inner px-0" ref="input" />
7
+ </XInput>
8
+ </template>
9
+
10
+ <script>
11
+ import Quill from "quill";
12
+ import input from "./input.js";
13
+ import XInput from "./input.vue";
14
+
15
+ export default {
16
+ mixins: [input],
17
+
18
+ components: {
19
+ XInput,
20
+ },
21
+
22
+ props: {
23
+ simple: {
24
+ type: Boolean,
25
+ default: false,
26
+ },
27
+ },
28
+
29
+ data: () => ({
30
+ editor: null,
31
+ hold: null,
32
+ }),
33
+
34
+ watch: {
35
+ modelValue: {
36
+ handler(val) {
37
+ if (val !== this.hold) {
38
+ this.setValue();
39
+ }
40
+ },
41
+ },
42
+ },
43
+
44
+ methods: {
45
+ getValue() {
46
+ return this.editor.getText().trim() === "" // Quill leaves <p></br></p> on empty input so ignore
47
+ ? ""
48
+ : this.simple // Simple editor removes outer tags and only allows inner phrasing tags
49
+ ? [...this.editor.root.children]
50
+ .map((d) => d.innerHTML)
51
+ .join("\n")
52
+ : this.editor.root.innerHTML;
53
+ },
54
+ setValue() {
55
+ this.editor.root.innerHTML =
56
+ this.simple && this.modelValue // Surround text in p tags to keep it grouped correctly on simple strings. Ignore if modelValue empty otherwise you'll end up with <p>null</p>
57
+ ? `<p>${this.modelValue}</p>`
58
+ : this.modelValue;
59
+ },
60
+ },
61
+
62
+ mounted() {
63
+ this.editor = new Quill(this.$refs.input, {
64
+ modules: {
65
+ clipboard: {
66
+ matchVisual: false,
67
+ },
68
+ toolbar: [
69
+ [
70
+ this.simple
71
+ ? undefined
72
+ : { header: [1, 2, 3, 4, 5, 6, false] },
73
+ "bold",
74
+ "italic",
75
+ "underline",
76
+ "strike",
77
+ { script: "sub" },
78
+ { script: "super" },
79
+ this.simple ? undefined : { list: "ordered" },
80
+ this.simple ? undefined : { list: "bullet" },
81
+ "clean",
82
+ ],
83
+ ],
84
+ },
85
+ placeholder: this.placeholder,
86
+ theme: "snow",
87
+ });
88
+
89
+ this.setValue();
90
+
91
+ this.editor.on("text-change", (delta, oldDelta, source) => {
92
+ this.hold = this.getValue();
93
+ this.$emit("update:modelValue", this.hold);
94
+ });
95
+
96
+ // Disable tab
97
+ delete this.editor.getModule("keyboard").bindings["9"];
98
+
99
+ // Disable tab index on toolbar buttons
100
+ [...this.$el.querySelectorAll(".ql-toolbar button")].forEach((d) =>
101
+ d.setAttribute("tabindex", -1)
102
+ );
103
+ },
104
+ };
105
+ </script>
package/general.scss ADDED
@@ -0,0 +1,12 @@
1
+ @import "_variables.scss";
2
+
3
+ @import "_defaults.scss";
4
+
5
+ // Local project imports
6
+ @import "./components/_switch.scss";
7
+ @import "./components/_basic.scss";
8
+ @import "./components/_checkbox.scss";
9
+ @import "./components/_icon.scss";
10
+ @import "./components/_button.scss";
11
+ @import "./components/_select.scss";
12
+ @import "./components/_datepicker.scss";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fishawack/lab-velocity",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Avalere Health branded style system",
5
5
  "scripts": {
6
6
  "setup": "npm ci || npm i && npm run content",
@@ -13,7 +13,7 @@
13
13
  "mail": "npm run mail --prefix node_modules/@fishawack/core/",
14
14
  "story:dev": "histoire dev",
15
15
  "story:build": "histoire build",
16
- "pretest": "cp -r _Build/sass/** ./ && cp -r _Build/vue/components/** ./"
16
+ "preversion": "cp -r _Build/sass/** ./ && cp -r _Build/vue/components/** ./"
17
17
  },
18
18
  "license": "BSD-3-Clause",
19
19
  "author": {
package/vendor.scss ADDED
@@ -0,0 +1,22 @@
1
+ @import "_variables.scss";
2
+
3
+ @import "_defaults.scss";
4
+
5
+ @import "normalize.css/normalize";
6
+
7
+ #svgSprite{
8
+ position: absolute;
9
+ width: 0;
10
+ height: 0;
11
+ z-index: -1;
12
+ }
13
+
14
+ // Vendor imports / Lab-ui imports
15
+ @import "@fishawack/lab-ui/_typography.scss";
16
+ @import "@fishawack/lab-ui/_grid.scss";
17
+ @import "@fishawack/lab-ui/_button.scss";
18
+
19
+ @import "@fishawack/lab-ui/_utilities.scss";
20
+
21
+ // Element-plus base style
22
+ @import "./_base.scss";