@globalbrain/sefirot 0.71.0 → 2.0.0-draft.3

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 (173) hide show
  1. package/CHANGELOG.md +6 -804
  2. package/README.md +1 -1
  3. package/lib/assets/styles/bootstrap.css +1 -2
  4. package/lib/assets/styles/variables.css +14 -47
  5. package/lib/components/SAvatar.vue +9 -18
  6. package/lib/components/SButton.vue +35 -48
  7. package/lib/components/SDialog.vue +16 -34
  8. package/lib/components/SDropdown.vue +36 -55
  9. package/lib/components/SDropdownItem.vue +27 -39
  10. package/lib/components/SDropdownItemText.vue +4 -9
  11. package/lib/components/SDropdownItemUser.vue +4 -12
  12. package/lib/components/SInputBase.vue +33 -45
  13. package/lib/components/SInputCheckbox.vue +19 -35
  14. package/lib/components/SInputDropdown.vue +109 -171
  15. package/lib/components/SInputDropdownItem.vue +26 -32
  16. package/lib/components/SInputDropdownItemText.vue +6 -11
  17. package/lib/components/SInputDropdownItemTextTag.vue +10 -17
  18. package/lib/components/SInputDropdownItemUser.vue +5 -13
  19. package/lib/components/SInputDropdownItemUserTag.vue +9 -16
  20. package/lib/components/SInputFile.vue +38 -53
  21. package/lib/components/SInputHMS.vue +91 -114
  22. package/lib/components/SInputNumber.vue +27 -106
  23. package/lib/components/SInputRadio.vue +23 -33
  24. package/lib/components/SInputRadios.vue +37 -47
  25. package/lib/components/SInputText.vue +72 -628
  26. package/lib/components/SInputTextarea.vue +54 -113
  27. package/lib/components/SInputYMD.vue +94 -105
  28. package/lib/components/SLink.vue +16 -52
  29. package/lib/components/SModal.vue +53 -90
  30. package/lib/components/SPortalModals.vue +37 -53
  31. package/lib/components/SPortalSnackbars.vue +9 -24
  32. package/lib/components/SSheet.vue +10 -23
  33. package/lib/components/SSheetFooter.vue +0 -2
  34. package/lib/components/SSheetFooterAction.vue +9 -14
  35. package/lib/components/SSheetFooterActions.vue +1 -3
  36. package/lib/components/SSheetHeader.vue +9 -24
  37. package/lib/components/SSheetHeaderTitle.vue +1 -3
  38. package/lib/components/SSheetMedium.vue +13 -25
  39. package/lib/components/SSnackbar.vue +18 -28
  40. package/lib/composables/Dialog.ts +9 -17
  41. package/lib/composables/Dropdown.ts +2 -2
  42. package/lib/composables/{Menu.ts → Flyout.ts} +11 -4
  43. package/lib/composables/Form.ts +42 -44
  44. package/lib/composables/Modal.ts +9 -9
  45. package/lib/composables/Snackbar.ts +18 -0
  46. package/lib/composables/Validation.ts +28 -0
  47. package/lib/mixins/Sheet.ts +3 -3
  48. package/lib/store/Sefirot.ts +8 -13
  49. package/lib/store/dialog/index.ts +20 -10
  50. package/lib/store/modal/index.ts +11 -13
  51. package/lib/store/snackbars/index.ts +3 -4
  52. package/lib/support/{Util.ts → Utils.ts} +0 -2
  53. package/lib/types/Utils.ts +0 -7
  54. package/lib/types/vue-shims.d.ts +7 -0
  55. package/lib/validation/rules/checked.ts +6 -10
  56. package/lib/validation/rules/fileExtension.ts +9 -9
  57. package/lib/validation/rules/hms.ts +9 -9
  58. package/lib/validation/rules/index.ts +10 -74
  59. package/lib/validation/rules/maxLength.ts +10 -9
  60. package/lib/validation/rules/minLength.ts +12 -0
  61. package/lib/validation/rules/required.ts +2 -10
  62. package/lib/validation/rules/requiredHms.ts +11 -0
  63. package/lib/validation/rules/requiredIf.ts +3 -11
  64. package/lib/validation/rules/requiredYmd.ts +11 -0
  65. package/lib/validation/rules/ymd.ts +11 -0
  66. package/lib/validation/validators/checked.ts +1 -1
  67. package/lib/validation/validators/fileExtension.ts +1 -1
  68. package/lib/validation/validators/hms.ts +5 -5
  69. package/lib/validation/validators/requiredHms.ts +17 -0
  70. package/lib/validation/validators/requiredYmd.ts +7 -0
  71. package/lib/validation/validators/ymd.ts +41 -0
  72. package/package.json +45 -50
  73. package/lib/components/SAction.vue +0 -37
  74. package/lib/components/SActionAvatar.vue +0 -25
  75. package/lib/components/SActionButton.vue +0 -40
  76. package/lib/components/SActionPill.vue +0 -35
  77. package/lib/components/SActionSwitch.vue +0 -37
  78. package/lib/components/SAlert.vue +0 -145
  79. package/lib/components/SButtonGroup.vue +0 -160
  80. package/lib/components/SCard.vue +0 -111
  81. package/lib/components/SCardFooter.vue +0 -74
  82. package/lib/components/SCardHeader.vue +0 -213
  83. package/lib/components/SGrid.vue +0 -237
  84. package/lib/components/SGridActionLink.vue +0 -53
  85. package/lib/components/SGridActionMulti.vue +0 -139
  86. package/lib/components/SGridActionSingle.vue +0 -64
  87. package/lib/components/SHeader.vue +0 -180
  88. package/lib/components/SInputCheckboxes.vue +0 -83
  89. package/lib/components/SInputDate.vue +0 -192
  90. package/lib/components/SInputDay.vue +0 -87
  91. package/lib/components/SInputMonth.vue +0 -86
  92. package/lib/components/SInputSelect.vue +0 -282
  93. package/lib/components/SInputSwitch.vue +0 -212
  94. package/lib/components/SInputSwitches.vue +0 -108
  95. package/lib/components/SInputTime.vue +0 -255
  96. package/lib/components/SInputYear.vue +0 -60
  97. package/lib/components/SMarkdown.vue +0 -56
  98. package/lib/components/SPlaceholderBlank.vue +0 -113
  99. package/lib/components/SPlaceholderImage.vue +0 -83
  100. package/lib/components/SPortalScreens.vue +0 -62
  101. package/lib/components/SProgressBar.vue +0 -89
  102. package/lib/components/SResponsive.vue +0 -46
  103. package/lib/components/SScreen.vue +0 -81
  104. package/lib/components/SStep.vue +0 -107
  105. package/lib/components/SSteps.vue +0 -75
  106. package/lib/components/STag.vue +0 -67
  107. package/lib/components/STooltip.vue +0 -134
  108. package/lib/components/SWindow.vue +0 -158
  109. package/lib/composables/Action.ts +0 -141
  110. package/lib/composables/Alert.ts +0 -50
  111. package/lib/composables/Card.ts +0 -46
  112. package/lib/composables/FormValidation.ts +0 -150
  113. package/lib/composables/Header.ts +0 -72
  114. package/lib/composables/InputDropdown.ts +0 -6
  115. package/lib/composables/Markdown.ts +0 -138
  116. package/lib/composables/Router.ts +0 -20
  117. package/lib/composables/Step.ts +0 -7
  118. package/lib/composables/Store.ts +0 -9
  119. package/lib/composables/Tag.ts +0 -32
  120. package/lib/composables/Tooltip.ts +0 -91
  121. package/lib/composables/Utils.ts +0 -115
  122. package/lib/composables/markdown/LinkPlugin.ts +0 -45
  123. package/lib/compositions/useForm.ts +0 -17
  124. package/lib/compositions/useResizeObserver.ts +0 -25
  125. package/lib/compositions/useTime.ts +0 -26
  126. package/lib/store/alert/index.ts +0 -32
  127. package/lib/store/screen/index.ts +0 -46
  128. package/lib/types/v-calendar.d.ts +0 -5
  129. package/lib/validation/Validation.ts +0 -151
  130. package/lib/validation/rules/day.ts +0 -11
  131. package/lib/validation/rules/email.ts +0 -11
  132. package/lib/validation/rules/every.ts +0 -38
  133. package/lib/validation/rules/include.ts +0 -11
  134. package/lib/validation/rules/includeSome.ts +0 -11
  135. package/lib/validation/rules/integer.ts +0 -11
  136. package/lib/validation/rules/maxValue.ts +0 -11
  137. package/lib/validation/rules/minValue.ts +0 -11
  138. package/lib/validation/rules/month.ts +0 -11
  139. package/lib/validation/rules/not.ts +0 -10
  140. package/lib/validation/rules/regex.ts +0 -11
  141. package/lib/validation/rules/requiredHMS.ts +0 -11
  142. package/lib/validation/rules/requiredMonthDate.ts +0 -11
  143. package/lib/validation/rules/requiredYearMonth.ts +0 -11
  144. package/lib/validation/rules/requiredYearMonthDate.ts +0 -11
  145. package/lib/validation/rules/rule.ts +0 -5
  146. package/lib/validation/rules/sameAs.ts +0 -11
  147. package/lib/validation/rules/url.ts +0 -11
  148. package/lib/validation/rules/validateIf.ts +0 -27
  149. package/lib/validation/rules/year.ts +0 -11
  150. package/lib/validation/rules/yearMonth.ts +0 -11
  151. package/lib/validation/rules/yearMonthDate.ts +0 -11
  152. package/lib/validation/validators/day.ts +0 -29
  153. package/lib/validation/validators/email.ts +0 -5
  154. package/lib/validation/validators/include.ts +0 -5
  155. package/lib/validation/validators/includeSome.ts +0 -5
  156. package/lib/validation/validators/index.ts +0 -51
  157. package/lib/validation/validators/integer.ts +0 -6
  158. package/lib/validation/validators/maxLength.ts +0 -3
  159. package/lib/validation/validators/maxValue.ts +0 -3
  160. package/lib/validation/validators/minValue.ts +0 -3
  161. package/lib/validation/validators/month.ts +0 -3
  162. package/lib/validation/validators/monthDate.ts +0 -20
  163. package/lib/validation/validators/regex.ts +0 -3
  164. package/lib/validation/validators/required.ts +0 -27
  165. package/lib/validation/validators/requiredHMS.ts +0 -17
  166. package/lib/validation/validators/requiredMonthDate.ts +0 -8
  167. package/lib/validation/validators/requiredYearMonth.ts +0 -8
  168. package/lib/validation/validators/requiredYearMonthDate.ts +0 -9
  169. package/lib/validation/validators/sameAs.ts +0 -5
  170. package/lib/validation/validators/url.ts +0 -5
  171. package/lib/validation/validators/year.ts +0 -3
  172. package/lib/validation/validators/yearMonth.ts +0 -20
  173. package/lib/validation/validators/yearMonthDate.ts +0 -21
@@ -8,61 +8,49 @@
8
8
 
9
9
  <div class="help">
10
10
  <slot name="before-help" />
11
- <p v-if="showError" :key="errorMsg" class="help-error">{{ errorMsg }}</p>
11
+ <p v-if="showError" class="help-error">{{ errorMsg }}</p>
12
12
  <p v-if="help" class="help-text">{{ help }}</p>
13
13
  </div>
14
14
  </div>
15
15
  </template>
16
16
 
17
- <script lang="ts">
18
- import { PropType, defineComponent, computed } from '@vue/composition-api'
19
- import { Validation } from '../validation/Validation'
20
-
21
- export default defineComponent({
22
- props: {
23
- name: { type: String, default: null },
24
- note: { type: String, default: null },
25
- label: { type: String, default: null },
26
- help: { type: String, default: null },
27
- errorMessage: { type: Boolean, default: true },
28
- validation: { type: Object as PropType<Validation>, default: null }
29
- },
30
-
31
- setup(props) {
32
- const hasError = computed(() => {
33
- if (!props.validation) {
34
- return false
35
- }
36
-
37
- return props.validation.$isDirty.value && !props.validation.$isValid.value
38
- })
39
-
40
- const errorMsg = computed(() => {
41
- if (!props.validation) {
42
- return null
43
- }
44
-
45
- const errors = props.validation.$errors.value
46
-
47
- return errors.length > 0 ? errors[0][1] : null
48
- })
49
-
50
- const showError = computed(() => {
51
- return props.errorMessage && hasError.value && errorMsg.value
52
- })
53
-
54
- return {
55
- hasError,
56
- errorMsg,
57
- showError
58
- }
17
+ <script setup lang="ts">
18
+ import { PropType, computed } from 'vue'
19
+ import { Validatable } from '../composables/Validation'
20
+
21
+ const props = defineProps({
22
+ name: { type: String, default: null },
23
+ note: { type: String, default: null },
24
+ label: { type: String, default: null },
25
+ help: { type: String, default: null },
26
+ errorMessage: { type: Boolean, default: true },
27
+ validation: { type: Object as PropType<Validatable>, default: null }
28
+ })
29
+
30
+ const hasError = computed(() => {
31
+ if (!props.validation) {
32
+ return false
59
33
  }
34
+
35
+ return props.validation.$dirty && props.validation.$invalid
36
+ })
37
+
38
+ const errorMsg = computed(() => {
39
+ if (!props.validation) {
40
+ return null
41
+ }
42
+
43
+ const errors = props.validation.$errors
44
+
45
+ return errors.length > 0 ? errors[0].$message : null
46
+ })
47
+
48
+ const showError = computed(() => {
49
+ return props.errorMessage && hasError.value && errorMsg.value
60
50
  })
61
51
  </script>
62
52
 
63
53
  <style lang="postcss" scoped>
64
- @import "@/assets/styles/variables";
65
-
66
54
  .SInputBase.mini {
67
55
  .label {
68
56
  padding-bottom: 6px;
@@ -1,14 +1,14 @@
1
1
  <template>
2
2
  <SInputBase
3
3
  class="SInputCheckbox"
4
- :name="name"
4
+ :class="[size]"
5
5
  :label="label"
6
6
  :note="note"
7
7
  :help="help"
8
8
  :validation="validation"
9
9
  >
10
10
  <div class="container">
11
- <div class="input" :class="{ on: value }" role="button" @click="emitChange">
11
+ <div class="input" :class="{ on: modelValue }" role="button" @click="emitChange">
12
12
  <div class="box">
13
13
  <div class="check">
14
14
  <SIconCheck class="check-icon" />
@@ -21,48 +21,32 @@
21
21
  </SInputBase>
22
22
  </template>
23
23
 
24
- <script lang="ts">
25
- import { PropType, defineComponent } from '@vue/composition-api'
26
- import { Validation } from '../validation/Validation'
24
+ <script setup lang="ts">
25
+ import { PropType } from 'vue'
26
+ import { Validatable } from '../composables/Validation'
27
27
  import SIconCheck from './icons/SIconCheck.vue'
28
28
  import SInputBase from './SInputBase.vue'
29
29
 
30
- export default defineComponent({
31
- components: {
32
- SIconCheck,
33
- SInputBase
34
- },
30
+ type Size = 'mini' | 'small' | 'medium'
35
31
 
36
- model: {
37
- prop: 'value',
38
- event: 'change'
39
- },
40
-
41
- props: {
42
- name: { type: String, default: null },
43
- label: { type: String, default: null },
44
- note: { type: String, default: null },
45
- help: { type: String, default: null },
46
- text: { type: String, required: true },
47
- value: { type: Boolean, required: true },
48
- validation: { type: Object as PropType<Validation>, default: null }
49
- },
32
+ const props = defineProps({
33
+ size: { type: String as PropType<Size>, default: 'small' },
34
+ label: { type: String, default: null },
35
+ note: { type: String, default: null },
36
+ help: { type: String, default: null },
37
+ text: { type: String, required: true },
38
+ modelValue: { type: Boolean, required: true },
39
+ validation: { type: Object as PropType<Validatable>, default: null }
40
+ })
50
41
 
51
- setup(props, { emit }) {
52
- function emitChange() {
53
- emit('change', !props.value)
54
- }
42
+ const emit = defineEmits(['update:modelValue'])
55
43
 
56
- return {
57
- emitChange
58
- }
59
- }
60
- })
44
+ function emitChange() {
45
+ emit('update:modelValue', !props.modelValue)
46
+ }
61
47
  </script>
62
48
 
63
49
  <style lang="postcss" scoped>
64
- @import "@/assets/styles/variables";
65
-
66
50
  .container {
67
51
  display: flex;
68
52
  }
@@ -2,7 +2,6 @@
2
2
  <SInputBase
3
3
  class="SInputDropdown"
4
4
  :class="classes"
5
- :name="name"
6
5
  :label="label"
7
6
  :note="note"
8
7
  :help="help"
@@ -42,10 +41,10 @@
42
41
  </SInputBase>
43
42
  </template>
44
43
 
45
- <script lang="ts">
46
- import { PropType, defineComponent, computed, nextTick } from '@vue/composition-api'
47
- import { isNullish, isArray, isEqual } from '../support/Util'
48
- import { useMenu } from '../composables/Menu'
44
+ <script setup lang="ts">
45
+ import { PropType, computed, nextTick } from 'vue'
46
+ import { isNullish, isArray, isEqual } from '../support/Utils'
47
+ import { useFlyout } from '../composables/Flyout'
49
48
  import { Search, Item, UseDropdownSearchOptions, useDropdown } from '../composables/Dropdown'
50
49
  import SIconChevronUp from './icons/SIconChevronUp.vue'
51
50
  import SIconChevronDown from './icons/SIconChevronDown.vue'
@@ -54,152 +53,119 @@ import SInputBase from './SInputBase.vue'
54
53
  import SInputDropdownItem from './SInputDropdownItem.vue'
55
54
 
56
55
  type Size = 'mini' | 'small' | 'medium'
57
- type Mode = 'outlined' | 'filled'
58
56
  type Value = string | number | boolean | unknown[]
59
57
 
60
- export default defineComponent({
61
- components: {
62
- SIconChevronUp,
63
- SIconChevronDown,
64
- SDropdown,
65
- SInputBase,
66
- SInputDropdownItem
67
- },
68
-
69
- model: {
70
- prop: 'value',
71
- event: 'change'
72
- },
73
-
74
- props: {
75
- size: { type: String as PropType<Size>, default: 'small' },
76
- mode: { type: String as PropType<Mode>, default: 'outlined' },
77
- name: { type: String, default: null },
78
- label: { type: String, default: null },
79
- note: { type: String, default: null },
80
- help: { type: String, default: null },
81
- placeholder: { type: String, default: null },
82
- search: { type: [Boolean, Object] as PropType<boolean | Search>, default: false },
83
- options: { type: Array as PropType<Item[]>, required: true },
84
- nullable: { type: Boolean, default: true },
85
- closeOnClick: { type: Boolean, default: false },
86
- disabled: { type: Boolean, default: false },
87
- validation: { type: Object, default: null },
88
- value: { type: [String, Number, Boolean, Array, Object] as PropType<Value>, default: null }
89
- },
90
-
91
- setup(props, { emit }) {
92
- const { container, isOpen, open, close } = useMenu()
93
-
94
- const classes = computed(() => [
95
- props.size,
96
- props.mode,
97
- { disabled: props.disabled }
98
- ])
99
-
100
- const enabledItems = computed(() => {
101
- return props.options.filter(option => !option.disabled)
102
- })
103
-
104
- const dropdownOptions = useDropdown({
105
- search: createDropdownSearchOptions(),
106
- items: enabledItems,
107
- closeOnClick: props.closeOnClick,
108
- selected: computed(() => props.value),
109
- callback: handleCallback
110
- })
111
-
112
- const selected = computed(() => {
113
- return isArray(props.value)
114
- ? props.options.filter(o => (props.value as unknown[]).includes(o.value))
115
- : props.options.find(o => isEqual(o.value, props.value))
116
- })
117
-
118
- const hasSelected = computed(() => {
119
- return isArray(selected.value)
120
- ? selected.value.length > 0
121
- : !isNullish(selected.value) && selected.value.value !== ''
122
- })
123
-
124
- function createDropdownSearchOptions(): UseDropdownSearchOptions | undefined {
125
- if (props.search === false) {
126
- return undefined
127
- }
128
-
129
- if (props.search === true) {
130
- return {
131
- placeholder: 'Search items',
132
- missing: 'No items found.'
133
- }
134
- }
135
-
136
- return props.search
137
- }
58
+ const props = defineProps({
59
+ size: { type: String as PropType<Size>, default: 'small' },
60
+ label: { type: String, default: null },
61
+ note: { type: String, default: null },
62
+ help: { type: String, default: null },
63
+ placeholder: { type: String, default: null },
64
+ search: { type: [Boolean, Object] as PropType<boolean | Search>, default: false },
65
+ options: { type: Array as PropType<Item[]>, required: true },
66
+ nullable: { type: Boolean, default: true },
67
+ closeOnClick: { type: Boolean, default: false },
68
+ disabled: { type: Boolean, default: false },
69
+ modelValue: { type: [String, Number, Boolean, Array, Object] as PropType<Value>, default: null },
70
+ validation: { type: Object as PropType<any>, default: null }
71
+ })
138
72
 
139
- async function handleOpen(): Promise<void> {
140
- if (!props.disabled) {
141
- open()
73
+ const emit = defineEmits(['update:modelValue'])
142
74
 
143
- await nextTick()
75
+ const { container, isOpen, open, close } = useFlyout()
144
76
 
145
- const el = document.querySelector<HTMLInputElement>('.SInputDropdown .SDropdown .search .SInputText input')
77
+ const classes = computed(() => [
78
+ props.size,
79
+ { disabled: props.disabled }
80
+ ])
146
81
 
147
- el && el.focus()
148
- }
149
- }
82
+ const enabledItems = computed(() => {
83
+ return props.options.filter(option => !option.disabled)
84
+ })
150
85
 
151
- function handleCallback(item: Item): void {
152
- props.validation && props.validation.$touch()
86
+ const dropdownOptions = useDropdown({
87
+ search: createDropdownSearchOptions(),
88
+ items: enabledItems,
89
+ closeOnClick: props.closeOnClick,
90
+ selected: computed(() => props.modelValue),
91
+ callback: handleCallback
92
+ })
153
93
 
154
- isArray(props.value) ? handleArray(item.value) : handlePrimitive(item.value)
155
- }
94
+ const selected = computed(() => {
95
+ return isArray(props.modelValue)
96
+ ? props.options.filter(o => (props.modelValue as unknown[]).includes(o.value))
97
+ : props.options.find(o => isEqual(o.value, props.modelValue))
98
+ })
156
99
 
157
- function handlePrimitive(value: unknown): void {
158
- if (!isEqual(props.value, value)) {
159
- emit('change', value)
100
+ const hasSelected = computed(() => {
101
+ return isArray(selected.value)
102
+ ? selected.value.length > 0
103
+ : !isNullish(selected.value) && selected.value.value !== ''
104
+ })
160
105
 
161
- return
162
- }
106
+ function createDropdownSearchOptions(): UseDropdownSearchOptions | undefined {
107
+ if (props.search === false) {
108
+ return undefined
109
+ }
163
110
 
164
- if (props.nullable) {
165
- emit('change', null)
166
- }
111
+ if (props.search === true) {
112
+ return {
113
+ placeholder: 'Search items',
114
+ missing: 'No items found.'
167
115
  }
116
+ }
168
117
 
169
- function handleArray(value: unknown[]): void {
170
- const difference = getDifference(props.value as unknown[], value)
118
+ return props.search
119
+ }
171
120
 
172
- if (!props.nullable && difference.length === 0) {
173
- return
174
- }
121
+ async function handleOpen(): Promise<void> {
122
+ if (!props.disabled) {
123
+ open()
175
124
 
176
- emit('change', difference)
177
- }
125
+ await nextTick()
178
126
 
179
- function getDifference(source: unknown[], value: unknown[]): unknown[] {
180
- return source
181
- .filter(item => !isEqual(item, value))
182
- .concat(source.includes(value) ? [] : [value])
183
- }
127
+ const el = document.querySelector<HTMLInputElement>('.SInputDropdown .SDropdown .search .SInputText input')
184
128
 
185
- return {
186
- classes,
187
- container,
188
- isOpen,
189
- close,
190
- dropdownOptions,
191
- selected,
192
- hasSelected,
193
- handleOpen,
194
- handleCallback
195
- }
129
+ el && el.focus()
196
130
  }
197
- })
131
+ }
132
+
133
+ function handleCallback(item: Item): void {
134
+ props.validation && props.validation.$touch()
135
+
136
+ isArray(props.modelValue) ? handleArray(item.value) : handlePrimitive(item.value)
137
+ }
138
+
139
+ function handlePrimitive(value: unknown): void {
140
+ if (!isEqual(props.modelValue, value)) {
141
+ emit('update:modelValue', value)
142
+
143
+ return
144
+ }
145
+
146
+ if (props.nullable) {
147
+ emit('update:modelValue', null)
148
+ }
149
+ }
150
+
151
+ function handleArray(value: unknown[]): void {
152
+ const difference = getDifference(props.modelValue as unknown[], value)
153
+
154
+ if (!props.nullable && difference.length === 0) {
155
+ return
156
+ }
157
+
158
+ emit('update:modelValue', difference)
159
+ }
160
+
161
+ function getDifference(source: unknown[], value: unknown[]): unknown[] {
162
+ return source
163
+ .filter(item => !isEqual(item, value))
164
+ .concat(source.includes(value) ? [] : [value])
165
+ }
198
166
  </script>
199
167
 
200
168
  <style lang="postcss" scoped>
201
- @import "@/assets/styles/variables";
202
-
203
169
  .SInputDropdown.mini {
204
170
  .SInputDropdown-box {
205
171
  min-height: 32px;
@@ -251,53 +217,15 @@ export default defineComponent({
251
217
  }
252
218
  }
253
219
 
254
- .SInputDropdown.outlined {
255
- .SInputDropdown-box {
256
- border-color: var(--input-outlined-border);
257
-
258
- &:hover {
259
- border-color: var(--input-focus-border);
260
- }
261
-
262
- &:focus:not(:focus-visible) {
263
- border-color: var(--input-focus-border);
264
- outline: 0;
265
- }
266
- }
267
-
268
- &.disabled .SInputDropdown-box {
269
- background-color: var(--input-outlined-bg-disabled);
270
- cursor: not-allowed;
271
-
272
- &:hover { border-color: var(--input-outlined-border); }
273
- &:focus:not(:focus-visible) { border-color: var(--input-outlined-border); }
274
- }
275
- }
276
-
277
- .SInputDropdown.filled {
220
+ .SInputDropdown.disabled {
278
221
  .SInputDropdown-box {
279
- background-color: var(--input-filled-bg);
280
-
281
- &:hover {
282
- border-color: var(--input-focus-border);
283
- }
284
-
285
- &:focus:not(:focus-visible) {
286
- border-color: var(--input-focus-border);
287
- outline: 0;
288
- }
289
- }
290
-
291
- &.disabled .SInputDropdown-box {
292
- background-color: var(--input-outlined-bg-disabled);
222
+ background-color: var(--input-disabled-bg);
293
223
  cursor: not-allowed;
294
224
 
295
225
  &:hover { border-color: var(--input-outlined-border); }
296
226
  &:focus:not(:focus-visible) { border-color: var(--input-outlined-border); }
297
227
  }
298
- }
299
228
 
300
- .SInputDropdown.disabled {
301
229
  .SInputDropdown-box-icon {
302
230
  cursor: not-allowed;
303
231
  }
@@ -315,12 +243,22 @@ export default defineComponent({
315
243
 
316
244
  .SInputDropdown-box {
317
245
  position: relative;
318
- border: 1px solid transparent;
246
+ border: 1px solid var(--input-border);
319
247
  border-radius: 4px;
320
248
  width: 100%;
321
249
  color: var(--input-text);
322
250
  cursor: pointer;
323
251
  transition: border-color .25s, background-color .25s;
252
+
253
+ &:hover {
254
+ border-color: var(--input-focus-border);
255
+ }
256
+
257
+ &:focus {
258
+ border-color: var(--input-focus-border);
259
+ outline: 0;
260
+ }
261
+
324
262
  }
325
263
 
326
264
  .SInputDropdown-box-placeholder {
@@ -3,7 +3,7 @@
3
3
  <div v-for="(i, index) in arrayItem" :key="index" class="item">
4
4
  <component
5
5
  :is="component(i)"
6
- :mute="i.value === null"
6
+ :mute="shouldMute(i)"
7
7
  :item="i"
8
8
  :disabled="disabled"
9
9
  @remove="$emit('remove', i)"
@@ -12,51 +12,45 @@
12
12
  </div>
13
13
  </template>
14
14
 
15
- <script lang="ts">
16
- import { PropType, defineComponent, computed } from '@vue/composition-api'
17
- import { isArray } from '../support/Util'
18
- import { Item } from '../composables/Dropdown'
15
+ <script setup lang="ts">
16
+ import { PropType, computed } from 'vue'
17
+ import { isArray } from '../support/Utils'
19
18
  import SInputDropdownItemText from './SInputDropdownItemText.vue'
20
19
  import SInputDropdownItemTextTag from './SInputDropdownItemTextTag.vue'
21
20
  import SInputDropdownItemUser from './SInputDropdownItemUser.vue'
22
21
  import SInputDropdownItemUserTag from './SInputDropdownItemUserTag.vue'
23
22
 
24
- export default defineComponent({
25
- props: {
26
- item: { type: [Object, Array] as PropType<Item | Item[]>, required: true },
27
- disabled: { type: Boolean, default: false }
28
- },
29
-
30
- setup(props) {
31
- const isItemArray = computed(() => isArray(props.item))
23
+ const props = defineProps({
24
+ item: { type: [Object, Array] as PropType<any>, default: null },
25
+ disabled: { type: Boolean, default: false }
26
+ })
32
27
 
33
- const arrayItem = computed(() => {
34
- return isArray(props.item) ? props.item : [props.item]
35
- })
28
+ defineEmits(['remove'])
36
29
 
37
- function component(item: Item) {
38
- if (item.type === 'text') {
39
- return isItemArray.value ? SInputDropdownItemTextTag : SInputDropdownItemText
40
- }
30
+ const isItemArray = computed(() => isArray(props.item))
41
31
 
42
- if (item.type === 'user') {
43
- return isItemArray.value ? SInputDropdownItemUserTag : SInputDropdownItemUser
44
- }
32
+ const arrayItem = computed(() => {
33
+ return isArray(props.item) ? props.item : [props.item]
34
+ })
45
35
 
46
- throw new Error('Invalid item type.')
47
- }
36
+ function component(item: any): any {
37
+ if (item.type === 'text') {
38
+ return isItemArray.value ? SInputDropdownItemTextTag : SInputDropdownItemText
39
+ }
48
40
 
49
- return {
50
- arrayItem,
51
- component
52
- }
41
+ if (item.type === 'user') {
42
+ return isItemArray.value ? SInputDropdownItemUserTag : SInputDropdownItemUser
53
43
  }
54
- })
44
+
45
+ throw new Error('Invalid item type.')
46
+ }
47
+
48
+ function shouldMute(item: any) {
49
+ return item.value === null
50
+ }
55
51
  </script>
56
52
 
57
53
  <style lang="postcss" scoped>
58
- @import "@/assets/styles/variables";
59
-
60
54
  .SInputDropdownItem {
61
55
  display: flex;
62
56
  flex-wrap: wrap;
@@ -4,22 +4,17 @@
4
4
  </div>
5
5
  </template>
6
6
 
7
- <script lang="ts">
8
- import { PropType, defineComponent } from '@vue/composition-api'
9
- import { Item } from '../composables/Dropdown'
7
+ <script setup lang="ts">
8
+ import { PropType } from 'vue'
10
9
 
11
- export default defineComponent({
12
- props: {
13
- mute: { type: Boolean, default: false },
14
- item: { type: Object as PropType<Item>, required: true },
15
- disabled: { type: Boolean, default: false }
16
- }
10
+ const props = defineProps({
11
+ mute: { type: Boolean, default: false },
12
+ item: { type: Object as PropType<any>, required: true },
13
+ disabled: { type: Boolean, default: false }
17
14
  })
18
15
  </script>
19
16
 
20
17
  <style lang="postcss" scoped>
21
- @import "@/assets/styles/variables";
22
-
23
18
  .SInputDropdownItemText.mute .text {
24
19
  color: var(--input-placeholder);
25
20
  }