@globalbrain/sefirot 2.2.1 → 2.3.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/lib/components/SButton.vue +0 -1
- package/lib/components/SButtonGroup.vue +17 -17
- package/lib/components/SDropdownSectionFilter.vue +5 -5
- package/lib/components/SIcon.vue +2 -2
- package/lib/components/SInputBase.vue +4 -5
- package/lib/components/SInputCheckbox.vue +23 -23
- package/lib/components/SInputCheckboxes.vue +23 -23
- package/lib/components/SInputDate.vue +55 -132
- package/lib/components/SInputDropdown.vue +3 -3
- package/lib/components/SInputFile.vue +1 -1
- package/lib/components/SInputSelect.vue +48 -48
- package/lib/components/SInputSwitch.vue +68 -142
- package/lib/components/SInputSwitches.vue +51 -58
- package/lib/components/SInputText.vue +1 -1
- package/lib/components/SInputTextarea.vue +24 -24
- package/lib/components/SLink.vue +14 -14
- package/lib/components/SMarkdown.vue +3 -3
- package/lib/components/SMount.vue +1 -1
- package/lib/components/SSheetFooterAction.vue +1 -1
- package/lib/components/SSpinner.vue +28 -12
- package/lib/components/SStep.vue +15 -15
- package/lib/components/SSteps.vue +16 -16
- package/lib/components/STable.vue +2 -2
- package/lib/components/STableCellAvatar.vue +1 -1
- package/lib/components/STableCellAvatars.vue +1 -1
- package/lib/components/STableCellDay.vue +1 -1
- package/lib/components/STableColumn.vue +4 -4
- package/lib/components/STooltip.vue +17 -17
- package/lib/composables/Form.ts +7 -5
- package/lib/composables/Grid.ts +3 -3
- package/lib/composables/Markdown.ts +2 -2
- package/lib/composables/Tooltip.ts +2 -1
- package/lib/composables/Validation.ts +2 -2
- package/lib/support/Day.ts +1 -1
- package/lib/validation/rules/email.ts +1 -1
- package/lib/validation/rules/hms.ts +1 -1
- package/lib/validation/rules/maxLength.ts +1 -1
- package/lib/validation/rules/maxValue.ts +1 -1
- package/lib/validation/rules/minLength.ts +1 -1
- package/lib/validation/rules/minValue.ts +1 -1
- package/lib/validation/rules/required.ts +1 -1
- package/lib/validation/rules/requiredHms.ts +1 -1
- package/lib/validation/rules/requiredIf.ts +1 -1
- package/lib/validation/rules/requiredYmd.ts +1 -1
- package/lib/validation/rules/url.ts +1 -1
- package/lib/validation/rules/ymd.ts +1 -1
- package/lib/validation/validators/requiredYmd.ts +1 -1
- package/package.json +12 -15
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="SButtonGroup" :class="classes">
|
|
3
|
-
<button
|
|
4
|
-
v-for="item in items"
|
|
5
|
-
:key="item.value"
|
|
6
|
-
class="button"
|
|
7
|
-
:class="getButtonClasses(item)"
|
|
8
|
-
@click="handleClick(item.value)"
|
|
9
|
-
>
|
|
10
|
-
<span class="content">
|
|
11
|
-
{{ item.label }}
|
|
12
|
-
</span>
|
|
13
|
-
</button>
|
|
14
|
-
</div>
|
|
15
|
-
</template>
|
|
16
|
-
|
|
17
1
|
<script setup lang="ts">
|
|
18
|
-
import {
|
|
2
|
+
import { PropType, computed } from 'vue'
|
|
19
3
|
|
|
20
4
|
export interface ButtonGroupItem {
|
|
21
5
|
label: string
|
|
@@ -48,6 +32,22 @@ function handleClick(value: string) {
|
|
|
48
32
|
}
|
|
49
33
|
</script>
|
|
50
34
|
|
|
35
|
+
<template>
|
|
36
|
+
<div class="SButtonGroup" :class="classes">
|
|
37
|
+
<button
|
|
38
|
+
v-for="item in items"
|
|
39
|
+
:key="item.value"
|
|
40
|
+
class="button"
|
|
41
|
+
:class="getButtonClasses(item)"
|
|
42
|
+
@click="handleClick(item.value)"
|
|
43
|
+
>
|
|
44
|
+
<span class="content">
|
|
45
|
+
{{ item.label }}
|
|
46
|
+
</span>
|
|
47
|
+
</button>
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
51
|
<style lang="postcss" scoped>
|
|
52
52
|
.SButtonGroup {
|
|
53
53
|
display: flex;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import IconCheck from '@iconify-icons/ph/check'
|
|
3
|
-
import
|
|
3
|
+
import { MaybeRef } from '@vueuse/core'
|
|
4
4
|
import Fuse from 'fuse.js'
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { computed, onMounted, ref, unref } from 'vue'
|
|
6
|
+
import { DropdownSectionFilterOption, DropdownSectionFilterSelectedValue } from '../composables/Dropdown'
|
|
7
7
|
import { isArray } from '../support/Utils'
|
|
8
8
|
import SDropdownSectionFilterItem from './SDropdownSectionFilterItem.vue'
|
|
9
9
|
import SIcon from './SIcon.vue'
|
|
@@ -25,7 +25,7 @@ const fuse = computed(() => {
|
|
|
25
25
|
const filteredOptions = computed(() => {
|
|
26
26
|
return !props.search || !query.value
|
|
27
27
|
? unref(props.options)
|
|
28
|
-
: fuse.value.search(query.value).map(
|
|
28
|
+
: fuse.value.search(query.value).map(r => r.item)
|
|
29
29
|
})
|
|
30
30
|
|
|
31
31
|
onMounted(() => {
|
|
@@ -36,7 +36,7 @@ function isActive(value: string | number | boolean) {
|
|
|
36
36
|
const selected = unref(props.selected)
|
|
37
37
|
|
|
38
38
|
return isArray(selected)
|
|
39
|
-
? selected.
|
|
39
|
+
? selected.includes(value)
|
|
40
40
|
: selected === value
|
|
41
41
|
}
|
|
42
42
|
|
package/lib/components/SIcon.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { Icon, IconifyIcon } from '@iconify/vue/dist/offline'
|
|
3
|
-
import
|
|
3
|
+
import { DefineComponent } from 'vue'
|
|
4
4
|
|
|
5
5
|
defineProps<{
|
|
6
6
|
icon: IconifyIcon | DefineComponent
|
|
@@ -8,6 +8,6 @@ defineProps<{
|
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<template>
|
|
11
|
-
<Icon v-if="typeof icon
|
|
11
|
+
<Icon v-if="typeof icon.body === 'string'" :icon="icon as IconifyIcon" />
|
|
12
12
|
<component v-else :is="icon" />
|
|
13
13
|
</template>
|
|
@@ -3,10 +3,10 @@ import { computed, unref } from 'vue'
|
|
|
3
3
|
import { Validatable } from '../composables/Validation'
|
|
4
4
|
|
|
5
5
|
const props = defineProps<{
|
|
6
|
-
name?: string
|
|
7
|
-
note?: string
|
|
8
|
-
label?: string
|
|
9
|
-
help?: string
|
|
6
|
+
name?: string
|
|
7
|
+
note?: string
|
|
8
|
+
label?: string
|
|
9
|
+
help?: string
|
|
10
10
|
hideError?: boolean
|
|
11
11
|
validation?: Validatable
|
|
12
12
|
}>()
|
|
@@ -98,7 +98,6 @@ const showError = computed(() => {
|
|
|
98
98
|
|
|
99
99
|
.help {
|
|
100
100
|
position: relative;
|
|
101
|
-
word-break: break-all;
|
|
102
101
|
}
|
|
103
102
|
|
|
104
103
|
.help-error {
|
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<SInputBase
|
|
3
|
-
class="SInputCheckbox"
|
|
4
|
-
:class="[size]"
|
|
5
|
-
:label="label"
|
|
6
|
-
:note="note"
|
|
7
|
-
:help="help"
|
|
8
|
-
:validation="validation"
|
|
9
|
-
>
|
|
10
|
-
<div class="container">
|
|
11
|
-
<div class="input" :class="{ on: modelValue }" role="button" @click="emitChange">
|
|
12
|
-
<div class="box">
|
|
13
|
-
<div class="check">
|
|
14
|
-
<SIcon :icon="IconCheck" class="check-icon" />
|
|
15
|
-
</div>
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
<p class="text">{{ text }}</p>
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
21
|
-
</SInputBase>
|
|
22
|
-
</template>
|
|
23
|
-
|
|
24
1
|
<script setup lang="ts">
|
|
25
2
|
import IconCheck from '@iconify-icons/ph/check'
|
|
26
3
|
import { PropType } from 'vue'
|
|
@@ -47,6 +24,29 @@ function emitChange() {
|
|
|
47
24
|
}
|
|
48
25
|
</script>
|
|
49
26
|
|
|
27
|
+
<template>
|
|
28
|
+
<SInputBase
|
|
29
|
+
class="SInputCheckbox"
|
|
30
|
+
:class="[size]"
|
|
31
|
+
:label="label"
|
|
32
|
+
:note="note"
|
|
33
|
+
:help="help"
|
|
34
|
+
:validation="validation"
|
|
35
|
+
>
|
|
36
|
+
<div class="container">
|
|
37
|
+
<div class="input" :class="{ on: modelValue }" role="button" @click="emitChange">
|
|
38
|
+
<div class="box">
|
|
39
|
+
<div class="check">
|
|
40
|
+
<SIcon :icon="IconCheck" class="check-icon" />
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<p class="text">{{ text }}</p>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</SInputBase>
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
50
|
<style lang="postcss" scoped>
|
|
51
51
|
.container {
|
|
52
52
|
display: flex;
|
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<SInputBase
|
|
3
|
-
class="SInputCheckboxes"
|
|
4
|
-
:class="[size]"
|
|
5
|
-
:name="name"
|
|
6
|
-
:label="label"
|
|
7
|
-
:note="note"
|
|
8
|
-
:help="help"
|
|
9
|
-
>
|
|
10
|
-
<div class="container">
|
|
11
|
-
<div class="row">
|
|
12
|
-
<div v-for="option in options" :key="option.value" class="col">
|
|
13
|
-
<SInputCheckbox
|
|
14
|
-
:text="option.label"
|
|
15
|
-
:model-value="isChecked(option.value)"
|
|
16
|
-
@update:model-value="handleChange(option.value)"
|
|
17
|
-
/>
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
21
|
-
</SInputBase>
|
|
22
|
-
</template>
|
|
23
|
-
|
|
24
1
|
<script setup lang="ts">
|
|
25
2
|
import { PropType } from 'vue'
|
|
26
3
|
import SInputBase from './SInputBase.vue'
|
|
@@ -58,6 +35,29 @@ function handleChange(value: unknown): void {
|
|
|
58
35
|
}
|
|
59
36
|
</script>
|
|
60
37
|
|
|
38
|
+
<template>
|
|
39
|
+
<SInputBase
|
|
40
|
+
class="SInputCheckboxes"
|
|
41
|
+
:class="[size]"
|
|
42
|
+
:name="name"
|
|
43
|
+
:label="label"
|
|
44
|
+
:note="note"
|
|
45
|
+
:help="help"
|
|
46
|
+
>
|
|
47
|
+
<div class="container">
|
|
48
|
+
<div class="row">
|
|
49
|
+
<div v-for="option in options" :key="option.value" class="col">
|
|
50
|
+
<SInputCheckbox
|
|
51
|
+
:text="option.label"
|
|
52
|
+
:model-value="isChecked(option.value)"
|
|
53
|
+
@update:model-value="handleChange(option.value)"
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</SInputBase>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
61
|
<style lang="postcss" scoped>
|
|
62
62
|
.container {
|
|
63
63
|
display: flex;
|
|
@@ -1,30 +1,67 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { DatePicker } from 'v-calendar'
|
|
3
|
+
import { computed } from 'vue'
|
|
4
|
+
import { Validatable } from '../composables/Validation'
|
|
5
|
+
import { Day, day } from '../support/Day'
|
|
6
|
+
import SInputBase from './SInputBase.vue'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<{
|
|
9
|
+
name?: string
|
|
10
|
+
label?: string
|
|
11
|
+
note?: string
|
|
12
|
+
help?: string
|
|
13
|
+
hideError?: boolean
|
|
14
|
+
modelValue: Day | null
|
|
15
|
+
validation?: Validatable
|
|
16
|
+
}>()
|
|
17
|
+
|
|
18
|
+
const emit = defineEmits<{
|
|
19
|
+
(e: 'update:modelValue', value: Day | null): void
|
|
20
|
+
}>()
|
|
21
|
+
|
|
22
|
+
const value = computed(() => {
|
|
23
|
+
return props.modelValue
|
|
24
|
+
? props.modelValue.format('YYYY-MM-DD')
|
|
25
|
+
: null
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
function emitInput(date?: string) {
|
|
29
|
+
emit('update:modelValue', date ? day(date) : null)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function emitBlur(e: FocusEvent) {
|
|
33
|
+
setTimeout(() => {
|
|
34
|
+
props.validation && props.validation.$touch()
|
|
35
|
+
}, 100)
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
|
|
1
39
|
<template>
|
|
2
40
|
<SInputBase
|
|
3
|
-
class="SInputDate"
|
|
4
|
-
:class="classes"
|
|
41
|
+
class="SInputDate small"
|
|
5
42
|
:name="name"
|
|
6
43
|
:label="label"
|
|
7
44
|
:note="note"
|
|
8
45
|
:help="help"
|
|
46
|
+
:hide-error="hideError"
|
|
9
47
|
:validation="validation"
|
|
10
48
|
>
|
|
11
49
|
<div class="container">
|
|
12
50
|
<DatePicker
|
|
13
51
|
v-slot="{ inputValue, inputEvents }"
|
|
14
|
-
:value="modelValue"
|
|
15
52
|
color="blue"
|
|
16
53
|
is-dark
|
|
17
54
|
:masks="{ input: 'YYYY-MM-DD' }"
|
|
18
55
|
:model-config="{ type: 'string', mask: 'YYYY-MM-DD' }"
|
|
19
56
|
:popover="{ placement: 'bottom', visibility: 'click' }"
|
|
20
|
-
|
|
57
|
+
:model-value="value"
|
|
58
|
+
@update:model-value="emitInput"
|
|
21
59
|
>
|
|
22
60
|
<input
|
|
23
61
|
:id="name"
|
|
24
62
|
class="input"
|
|
25
63
|
type="text"
|
|
26
|
-
|
|
27
|
-
:disabled="disabled"
|
|
64
|
+
placeholder="YYYY-MM-DD"
|
|
28
65
|
:value="inputValue"
|
|
29
66
|
autocomplete="off"
|
|
30
67
|
v-on="inputEvents"
|
|
@@ -35,78 +72,7 @@
|
|
|
35
72
|
</SInputBase>
|
|
36
73
|
</template>
|
|
37
74
|
|
|
38
|
-
<script setup lang="ts">
|
|
39
|
-
import { DatePicker } from 'v-calendar'
|
|
40
|
-
import { PropType, computed } from 'vue'
|
|
41
|
-
import { Validation } from '../composables/Validation'
|
|
42
|
-
import SInputBase from './SInputBase.vue'
|
|
43
|
-
|
|
44
|
-
type Size = 'medium' | 'mini'
|
|
45
|
-
type Mode = 'filled' | 'outlined'
|
|
46
|
-
|
|
47
|
-
const props = defineProps({
|
|
48
|
-
size: { type: String as PropType<Size>, default: 'medium' },
|
|
49
|
-
mode: { type: String as PropType<Mode>, default: 'filled' },
|
|
50
|
-
name: { type: String, default: null },
|
|
51
|
-
label: { type: String, default: null },
|
|
52
|
-
note: { type: String, default: null },
|
|
53
|
-
help: { type: String, default: null },
|
|
54
|
-
placeholder: { type: String, default: 'YYYY-MM-DD' },
|
|
55
|
-
disabled: { type: Boolean, default: false },
|
|
56
|
-
modelValue: { type: String, default: null },
|
|
57
|
-
validation: { type: Object as PropType<Validation>, default: null }
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
const emit = defineEmits(['update:modelValue', 'blur'])
|
|
61
|
-
|
|
62
|
-
const classes = computed(() => [
|
|
63
|
-
props.size,
|
|
64
|
-
props.mode,
|
|
65
|
-
{
|
|
66
|
-
disabled: props.disabled
|
|
67
|
-
}
|
|
68
|
-
])
|
|
69
|
-
|
|
70
|
-
function emitInput(date: string | null) {
|
|
71
|
-
emit('update:modelValue', date)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function emitBlur(e: FocusEvent) {
|
|
75
|
-
setTimeout(() => {
|
|
76
|
-
props.validation && props.validation.$touch()
|
|
77
|
-
|
|
78
|
-
emit('blur', (e.target as HTMLInputElement).value)
|
|
79
|
-
}, 100)
|
|
80
|
-
}
|
|
81
|
-
</script>
|
|
82
|
-
|
|
83
75
|
<style lang="postcss" scoped>
|
|
84
|
-
.SInputDate.mini {
|
|
85
|
-
.input {
|
|
86
|
-
padding: 3px 12px;
|
|
87
|
-
width: 100%;
|
|
88
|
-
line-height: 24px;
|
|
89
|
-
font-size: 14px;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.container {
|
|
93
|
-
height: 32px;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.SInputDate.medium {
|
|
98
|
-
.input {
|
|
99
|
-
padding: 11px 16px;
|
|
100
|
-
width: 100%;
|
|
101
|
-
line-height: 24px;
|
|
102
|
-
font-size: 16px;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.container {
|
|
106
|
-
height: 48px;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
76
|
.SInputDate.has-error {
|
|
111
77
|
.input {
|
|
112
78
|
border-color: var(--c-danger);
|
|
@@ -117,66 +83,23 @@ function emitBlur(e: FocusEvent) {
|
|
|
117
83
|
}
|
|
118
84
|
}
|
|
119
85
|
|
|
120
|
-
.SInputDate.filled {
|
|
121
|
-
.input {
|
|
122
|
-
background-color: var(--input-filled-bg);
|
|
123
|
-
|
|
124
|
-
&:hover {
|
|
125
|
-
border-color: var(--input-focus-border);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
&:focus {
|
|
129
|
-
border-color: var(--input-focus-border);
|
|
130
|
-
background-color: var(--input-filled-bg-focus);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
&.disabled .input {
|
|
135
|
-
background-color: var(--input-filled-bg-disabled);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.SInputDate.outlined {
|
|
140
|
-
.input {
|
|
141
|
-
border-color: var(--input-outlined-border);
|
|
142
|
-
background-color: transparent;
|
|
143
|
-
|
|
144
|
-
&:hover {
|
|
145
|
-
border-color: var(--input-focus-border);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
&:focus {
|
|
149
|
-
border-color: var(--input-focus-border);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
&.disabled .input:hover {
|
|
154
|
-
border-color: var(--input-outlined-border);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
&.disabled .input {
|
|
158
|
-
background-color: var(--input-outlined-bg-disabled);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
.SInputDate.disabled {
|
|
163
|
-
.input:hover {
|
|
164
|
-
cursor: not-allowed;
|
|
165
|
-
border-color: transparent;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
86
|
.input {
|
|
171
87
|
display: block;
|
|
172
|
-
border: 1px solid
|
|
173
|
-
border-radius:
|
|
88
|
+
border: 1px solid var(--c-divider);
|
|
89
|
+
border-radius: 6px;
|
|
90
|
+
padding: 5px 12px;
|
|
174
91
|
width: 100%;
|
|
175
|
-
|
|
176
|
-
|
|
92
|
+
max-width: 144px;
|
|
93
|
+
height: 40px;
|
|
94
|
+
letter-spacing: 0;
|
|
95
|
+
line-height: 24px;
|
|
96
|
+
font-size: 16px;
|
|
97
|
+
background-color: var(--c-bg);
|
|
98
|
+
transition: border-color 0.25s, background-color 0.25s;
|
|
177
99
|
|
|
178
100
|
&::placeholder {
|
|
179
|
-
|
|
101
|
+
font-weight: 500;
|
|
102
|
+
color: var(--c-text-3);
|
|
180
103
|
}
|
|
181
104
|
}
|
|
182
105
|
</style>
|
|
@@ -3,7 +3,7 @@ import IconCaretDown from '@iconify-icons/ph/caret-down'
|
|
|
3
3
|
import IconCaretUp from '@iconify-icons/ph/caret-up'
|
|
4
4
|
import xor from 'lodash-es/xor'
|
|
5
5
|
import { computed } from 'vue'
|
|
6
|
-
import
|
|
6
|
+
import { DropdownSectionFilter } from '../composables/Dropdown'
|
|
7
7
|
import { useFlyout } from '../composables/Flyout'
|
|
8
8
|
import { Validatable } from '../composables/Validation'
|
|
9
9
|
import { isArray } from '../support/Utils'
|
|
@@ -71,10 +71,10 @@ const dropdownOptions = computed<DropdownSectionFilter[]>(() => [{
|
|
|
71
71
|
|
|
72
72
|
const selected = computed(() => {
|
|
73
73
|
if (isArray(props.modelValue)) {
|
|
74
|
-
return props.options.filter(
|
|
74
|
+
return props.options.filter(o => (props.modelValue as ArrayValue).includes(o.value))
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
const item = props.options.find(
|
|
77
|
+
const item = props.options.find(o => o.value === props.modelValue)
|
|
78
78
|
|
|
79
79
|
return item ? [item] : []
|
|
80
80
|
})
|
|
@@ -1,54 +1,7 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<SInputBase
|
|
3
|
-
class="SInputSelect"
|
|
4
|
-
:class="classes"
|
|
5
|
-
:label="label"
|
|
6
|
-
:note="note"
|
|
7
|
-
:help="help"
|
|
8
|
-
:error-message="errorMessage ?? true"
|
|
9
|
-
:validation="validation"
|
|
10
|
-
>
|
|
11
|
-
<div class="box" :class="{ focus: isFocused }">
|
|
12
|
-
<select
|
|
13
|
-
class="select"
|
|
14
|
-
:class="{ 'is-not-selected': isNotSelected }"
|
|
15
|
-
:disabled="disabled"
|
|
16
|
-
@focus="focus"
|
|
17
|
-
@blur="blur"
|
|
18
|
-
@change="emitChange"
|
|
19
|
-
>
|
|
20
|
-
<option
|
|
21
|
-
v-if="placeholder || nullable"
|
|
22
|
-
:value="JSON.stringify({ value: null })"
|
|
23
|
-
:selected="isNotSelected"
|
|
24
|
-
:disabled="!nullable"
|
|
25
|
-
>
|
|
26
|
-
{{ placeholder || 'Please select' }}
|
|
27
|
-
</option>
|
|
28
|
-
|
|
29
|
-
<option
|
|
30
|
-
v-for="(option, index) in options"
|
|
31
|
-
:key="index"
|
|
32
|
-
:style="{ display: option.disabled ? 'none' : undefined }"
|
|
33
|
-
:value="JSON.stringify(option)"
|
|
34
|
-
:selected="isSelectedOption(option)"
|
|
35
|
-
>
|
|
36
|
-
{{ option.label }}
|
|
37
|
-
</option>
|
|
38
|
-
</select>
|
|
39
|
-
|
|
40
|
-
<div class="icon" role="button">
|
|
41
|
-
<SIcon :icon="IconCaretUp" class="icon-svg up" />
|
|
42
|
-
<SIcon :icon="IconCaretDown" class="icon-svg down" />
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
</SInputBase>
|
|
46
|
-
</template>
|
|
47
|
-
|
|
48
1
|
<script setup lang="ts">
|
|
49
2
|
import IconCaretDown from '@iconify-icons/ph/caret-down'
|
|
50
3
|
import IconCaretUp from '@iconify-icons/ph/caret-up'
|
|
51
|
-
import { PropType,
|
|
4
|
+
import { PropType, computed, ref } from 'vue'
|
|
52
5
|
import { Validatable } from '../composables/Validation'
|
|
53
6
|
import SIcon from './SIcon.vue'
|
|
54
7
|
import SInputBase from './SInputBase.vue'
|
|
@@ -109,6 +62,53 @@ function emitChange(e: any): void {
|
|
|
109
62
|
}
|
|
110
63
|
</script>
|
|
111
64
|
|
|
65
|
+
<template>
|
|
66
|
+
<SInputBase
|
|
67
|
+
class="SInputSelect"
|
|
68
|
+
:class="classes"
|
|
69
|
+
:label="label"
|
|
70
|
+
:note="note"
|
|
71
|
+
:help="help"
|
|
72
|
+
:error-message="errorMessage ?? true"
|
|
73
|
+
:validation="validation"
|
|
74
|
+
>
|
|
75
|
+
<div class="box" :class="{ focus: isFocused }">
|
|
76
|
+
<select
|
|
77
|
+
class="select"
|
|
78
|
+
:class="{ 'is-not-selected': isNotSelected }"
|
|
79
|
+
:disabled="disabled"
|
|
80
|
+
@focus="focus"
|
|
81
|
+
@blur="blur"
|
|
82
|
+
@change="emitChange"
|
|
83
|
+
>
|
|
84
|
+
<Option
|
|
85
|
+
v-if="placeholder || nullable"
|
|
86
|
+
:value="JSON.stringify({ value: null })"
|
|
87
|
+
:selected="isNotSelected"
|
|
88
|
+
:disabled="!nullable"
|
|
89
|
+
>
|
|
90
|
+
{{ placeholder || 'Please select' }}
|
|
91
|
+
</Option>
|
|
92
|
+
|
|
93
|
+
<Option
|
|
94
|
+
v-for="(option, index) in options"
|
|
95
|
+
:key="index"
|
|
96
|
+
:style="{ display: option.disabled ? 'none' : undefined }"
|
|
97
|
+
:value="JSON.stringify(option)"
|
|
98
|
+
:selected="isSelectedOption(option)"
|
|
99
|
+
>
|
|
100
|
+
{{ option.label }}
|
|
101
|
+
</Option>
|
|
102
|
+
</select>
|
|
103
|
+
|
|
104
|
+
<div class="icon" role="button">
|
|
105
|
+
<SIcon :icon="IconCaretUp" class="icon-svg up" />
|
|
106
|
+
<SIcon :icon="IconCaretDown" class="icon-svg down" />
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</SInputBase>
|
|
110
|
+
</template>
|
|
111
|
+
|
|
112
112
|
<style scoped lang="postcss">
|
|
113
113
|
.SInputSelect.mini {
|
|
114
114
|
.box {
|