@globalbrain/sefirot 2.2.0 → 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 +16 -5
- package/lib/components/SInputDropdownItem.vue +3 -0
- package/lib/components/SInputDropdownItemAvatar.vue +8 -3
- package/lib/components/SInputDropdownItemText.vue +9 -4
- package/lib/components/SInputFile.vue +1 -1
- package/lib/components/SInputNumber.vue +51 -50
- 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 +13 -2
- package/lib/components/SInputTextarea.vue +24 -24
- package/lib/components/SInputYMD.vue +1 -1
- 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/STableCellPill.vue +3 -2
- 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
|
})
|
|
@@ -83,6 +83,14 @@ const hasSelected = computed(() => {
|
|
|
83
83
|
return selected.value.length > 0
|
|
84
84
|
})
|
|
85
85
|
|
|
86
|
+
const removable = computed(() => {
|
|
87
|
+
if (isArray(props.modelValue)) {
|
|
88
|
+
return props.nullable || selected.value.length > 1
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return !!props.nullable
|
|
92
|
+
})
|
|
93
|
+
|
|
86
94
|
async function handleOpen() {
|
|
87
95
|
!props.disabled && open()
|
|
88
96
|
}
|
|
@@ -137,6 +145,7 @@ function handleArray(value: OptionValue) {
|
|
|
137
145
|
<SInputDropdownItem
|
|
138
146
|
v-if="hasSelected"
|
|
139
147
|
:items="selected"
|
|
148
|
+
:removable="removable"
|
|
140
149
|
:disabled="disabled ?? false"
|
|
141
150
|
@remove="handleSelect"
|
|
142
151
|
/>
|
|
@@ -223,8 +232,8 @@ function handleArray(value: OptionValue) {
|
|
|
223
232
|
}
|
|
224
233
|
}
|
|
225
234
|
|
|
226
|
-
.
|
|
227
|
-
.
|
|
235
|
+
.SInputDropdown.has-error {
|
|
236
|
+
.box {
|
|
228
237
|
border-color: var(--c-danger);
|
|
229
238
|
}
|
|
230
239
|
}
|
|
@@ -266,6 +275,8 @@ function handleArray(value: OptionValue) {
|
|
|
266
275
|
padding: 2px 4px;
|
|
267
276
|
font-weight: 500;
|
|
268
277
|
color: var(--c-text-3);
|
|
278
|
+
overflow: hidden;
|
|
279
|
+
white-space: nowrap;
|
|
269
280
|
}
|
|
270
281
|
|
|
271
282
|
.box-icon {
|
|
@@ -22,6 +22,7 @@ export interface ItemAvatar extends ItemBase {
|
|
|
22
22
|
|
|
23
23
|
defineProps<{
|
|
24
24
|
items: Item[]
|
|
25
|
+
removable: boolean
|
|
25
26
|
disabled: boolean
|
|
26
27
|
}>()
|
|
27
28
|
|
|
@@ -37,6 +38,7 @@ defineEmits<{
|
|
|
37
38
|
v-if="item.type === 'text' || item.type === undefined"
|
|
38
39
|
:label="item.label"
|
|
39
40
|
:value="item.value"
|
|
41
|
+
:removable="removable"
|
|
40
42
|
:disabled="disabled"
|
|
41
43
|
@remove="(v) => $emit('remove', v)"
|
|
42
44
|
/>
|
|
@@ -45,6 +47,7 @@ defineEmits<{
|
|
|
45
47
|
:label="item.label"
|
|
46
48
|
:image="item.image"
|
|
47
49
|
:value="item.value"
|
|
50
|
+
:removable="removable"
|
|
48
51
|
:disabled="disabled"
|
|
49
52
|
@remove="(v) => $emit('remove', v)"
|
|
50
53
|
/>
|
|
@@ -7,6 +7,7 @@ defineProps<{
|
|
|
7
7
|
label: string
|
|
8
8
|
image?: string | null
|
|
9
9
|
value: string | number | boolean
|
|
10
|
+
removable: boolean
|
|
10
11
|
disabled: boolean
|
|
11
12
|
}>()
|
|
12
13
|
|
|
@@ -16,7 +17,7 @@ defineEmits<{
|
|
|
16
17
|
</script>
|
|
17
18
|
|
|
18
19
|
<template>
|
|
19
|
-
<div class="SInputDropdownItemAvatar" :class="{ disabled }">
|
|
20
|
+
<div class="SInputDropdownItemAvatar" :class="{ disabled, removable }">
|
|
20
21
|
<div class="user">
|
|
21
22
|
<div class="avatar">
|
|
22
23
|
<SAvatar size="nano" :avatar="image" :name="label" />
|
|
@@ -24,7 +25,7 @@ defineEmits<{
|
|
|
24
25
|
<p class="name">{{ label }}</p>
|
|
25
26
|
</div>
|
|
26
27
|
|
|
27
|
-
<div v-if="!disabled" class="remove" role="button" @click="$emit('remove', value)">
|
|
28
|
+
<div v-if="!disabled && removable" class="remove" role="button" @click="$emit('remove', value)">
|
|
28
29
|
<div class="remove-box">
|
|
29
30
|
<SIcon :icon="IconX" class="remove-icon" />
|
|
30
31
|
</div>
|
|
@@ -37,10 +38,14 @@ defineEmits<{
|
|
|
37
38
|
display: flex;
|
|
38
39
|
border: 1px solid var(--c-divider-light);
|
|
39
40
|
border-radius: 14px;
|
|
40
|
-
padding: 0;
|
|
41
|
+
padding: 0 12px 0 0;
|
|
41
42
|
background-color: var(--c-bg-mute);
|
|
42
43
|
}
|
|
43
44
|
|
|
45
|
+
.SInputDropdownItemAvatar.removable {
|
|
46
|
+
padding: 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
44
49
|
.SInputDropdownItemUserAvatar.disabled {
|
|
45
50
|
padding: 0 10px 0 0;
|
|
46
51
|
background-color: var(--c-gray-light-4);
|
|
@@ -5,6 +5,7 @@ import SIcon from './SIcon.vue'
|
|
|
5
5
|
defineProps<{
|
|
6
6
|
label: string
|
|
7
7
|
value: string | number | boolean
|
|
8
|
+
removable: boolean
|
|
8
9
|
disabled: boolean
|
|
9
10
|
}>()
|
|
10
11
|
|
|
@@ -14,10 +15,10 @@ defineEmits<{
|
|
|
14
15
|
</script>
|
|
15
16
|
|
|
16
17
|
<template>
|
|
17
|
-
<div class="SInputDropdownItemText" :class="{ disabled }">
|
|
18
|
+
<div class="SInputDropdownItemText" :class="{ disabled, removable }">
|
|
18
19
|
<p class="text">{{ label }}</p>
|
|
19
20
|
|
|
20
|
-
<div v-if="!disabled" class="remove" role="button" @click.stop="$emit('remove', value)">
|
|
21
|
+
<div v-if="!disabled && removable" class="remove" role="button" @click.stop="$emit('remove', value)">
|
|
21
22
|
<div class="remove-box">
|
|
22
23
|
<SIcon :icon="IconX" class="remove-icon" />
|
|
23
24
|
</div>
|
|
@@ -30,12 +31,16 @@ defineEmits<{
|
|
|
30
31
|
display: flex;
|
|
31
32
|
border: 1px solid var(--c-divider-light);
|
|
32
33
|
border-radius: 14px;
|
|
33
|
-
padding: 0
|
|
34
|
+
padding: 0 12px;
|
|
34
35
|
background-color: var(--c-bg-mute);
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
.SInputDropdownItemText.removable {
|
|
39
|
+
padding: 0 0 0 12px;
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
.SInputDropdownItemText.disabled {
|
|
38
|
-
padding: 0 10px
|
|
43
|
+
padding: 0 10px;
|
|
39
44
|
background-color: var(--c-gray-light-4);
|
|
40
45
|
|
|
41
46
|
.text {
|