quasar-ui-sellmate-ui-kit 2.3.1 → 3.0.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.
Files changed (68) hide show
  1. package/.eslintrc.cjs +73 -0
  2. package/.prettierrc +25 -0
  3. package/README.md +156 -142
  4. package/dist/index.common.js +2 -2
  5. package/dist/index.css +3 -8
  6. package/dist/index.esm.js +2 -2
  7. package/dist/index.min.css +2 -2
  8. package/dist/index.rtl.css +3 -8
  9. package/dist/index.rtl.min.css +2 -2
  10. package/dist/index.umd.js +3821 -3823
  11. package/dist/index.umd.min.js +2 -2
  12. package/package.json +83 -75
  13. package/src/assets/icons.js +28 -28
  14. package/src/components/SBreadcrumbs.vue +55 -55
  15. package/src/components/SButton.vue +206 -206
  16. package/src/components/SButtonGroup.vue +41 -41
  17. package/src/components/SButtonToggle.vue +200 -200
  18. package/src/components/SCaution.vue +102 -102
  19. package/src/components/SCheckbox.vue +123 -123
  20. package/src/components/SChip.vue +99 -99
  21. package/src/components/SDate.vue +717 -717
  22. package/src/components/SDateAutoRangePicker.vue +341 -341
  23. package/src/components/SDatePicker.vue +472 -472
  24. package/src/components/SDateRange.vue +470 -470
  25. package/src/components/SDateRangePicker.vue +660 -660
  26. package/src/components/SDateTimePicker.vue +349 -349
  27. package/src/components/SDialog.vue +250 -250
  28. package/src/components/SDropdown.vue +216 -216
  29. package/src/components/SEditor.vue +490 -490
  30. package/src/components/SFilePicker.vue +207 -207
  31. package/src/components/SHelp.vue +146 -146
  32. package/src/components/SInput.vue +343 -343
  33. package/src/components/SInputCounter.vue +46 -46
  34. package/src/components/SInputNumber.vue +179 -179
  35. package/src/components/SList.vue +29 -29
  36. package/src/components/SMarkupTable.vue +141 -141
  37. package/src/components/SPagination.vue +266 -266
  38. package/src/components/SRadio.vue +78 -78
  39. package/src/components/SRouteTab.vue +67 -67
  40. package/src/components/SSelect.vue +294 -294
  41. package/src/components/SSelectCheckbox.vue +222 -222
  42. package/src/components/SSelectCustom.vue +189 -189
  43. package/src/components/SSelectGroupCheckbox.vue +235 -235
  44. package/src/components/SSelectSearch.vue +261 -261
  45. package/src/components/SSelectSearchAutoComplete.vue +172 -172
  46. package/src/components/SSelectSearchCheckbox.vue +356 -356
  47. package/src/components/SStringToInput.vue +66 -66
  48. package/src/components/STab.vue +77 -80
  49. package/src/components/STable.vue +425 -425
  50. package/src/components/STableTree.vue +210 -208
  51. package/src/components/STabs.vue +32 -32
  52. package/src/components/STimePicker.vue +159 -159
  53. package/src/components/SToggle.vue +68 -68
  54. package/src/components/STooltip.vue +209 -209
  55. package/src/components/SelelctItem.vue +21 -21
  56. package/src/components/TimePickerCard.vue +352 -352
  57. package/src/composables/date.js +11 -11
  58. package/src/composables/modelBinder.js +13 -13
  59. package/src/composables/table/use-navigator.js +110 -110
  60. package/src/composables/table/use-resizable.js +80 -80
  61. package/src/css/app.scss +90 -90
  62. package/src/css/default.scss +875 -875
  63. package/src/css/extends.scss +154 -154
  64. package/src/css/quasar.variables.scss +189 -189
  65. package/src/directives/Directive.js +7 -8
  66. package/src/index.scss +3 -9
  67. package/src/vue-plugin.js +91 -92
  68. package/tsconfig.json +35 -0
@@ -1,356 +1,356 @@
1
- <template>
2
- <q-select
3
- outlined
4
- dense
5
- options-dense
6
- :dropdown-icon="selectDownArrowIcon"
7
- v-model="model"
8
- :options="filteredOptions"
9
- multiple
10
- emit-value
11
- map-options
12
- autocomplete="country"
13
- color="positive"
14
- :popup-content-class="
15
- ['s-select-checkbox-opts', popupContentClass].join(' ')
16
- "
17
- class="s-select-checkbox"
18
- :option-label="optionLabel"
19
- :option-value="optionValue"
20
- :option-group="optionGroup"
21
- @add="onAddChecked"
22
- @remove="onRemoveChecked"
23
- :menu-offset="[0, 4]"
24
- menu-self="top left"
25
- menu-anchor="bottom start"
26
- no-error-icon
27
- hide-bottom-space
28
- ref="sSelectRef"
29
- >
30
- <!-- TODO: 아무것도 선택되지 않았을 때 props 값으로 표기 해줘야함 기본 값은 "전체" -->
31
- <template v-slot:before-options>
32
- <div class="search-input-form-container">
33
- <form class="select-search-input-form">
34
- <q-icon :name="searchIcon" size="20px" />
35
- <input
36
- v-model="search"
37
- autofocus
38
- class="select-search-input"
39
- :placeholder="searchPlaceholder"
40
- @input="
41
- (data) => {
42
- onSearch(data.target.value);
43
- }
44
- "
45
- />
46
- </form>
47
- </div>
48
- </template>
49
- <template v-slot:option="{ itemProps, opt, selected, toggleOption }">
50
- <q-item v-bind="itemProps" class="custom-select-options">
51
- <q-item-section side v-if="!opt.disable">
52
- <s-checkbox
53
- :modelValue="selected"
54
- @update:modelValue="toggleOption(opt)"
55
- />
56
- </q-item-section>
57
- <q-item-section v-if="opt[optionGroup]" class="text-Grey_Darken-4">
58
- {{ opt[optionGroup] }}
59
- </q-item-section>
60
- <q-item-section avatar v-if="opt.logo">
61
- <q-img
62
- class="q-pa-none bg-Grey_Lighten-5"
63
- :src="opt.logo"
64
- width="60px"
65
- height="22px"
66
- />
67
- </q-item-section>
68
- <q-item-section>
69
- {{ opt[optionLabel] }}
70
- </q-item-section>
71
- </q-item>
72
- </template>
73
- <template v-if="useAll && model[0] === ''" v-slot:selected>
74
- <div>
75
- {{ placeholder }}
76
- </div>
77
- </template>
78
- <template v-slot:no-option>
79
- <div class="search-input-form-container">
80
- <form class="select-search-input-form">
81
- <q-icon :name="searchIcon" size="20px" />
82
- <input
83
- v-model="search"
84
- autofocus
85
- class="select-search-input"
86
- :placeholder="searchPlaceholder"
87
- @input="
88
- (data) => {
89
- onSearch(data.target.value);
90
- }
91
- "
92
- />
93
- </form>
94
- </div>
95
- <q-item class="s-select-no-option">
96
- <q-item-section class="text-grey">{{ noData }}</q-item-section>
97
- </q-item>
98
- </template>
99
- </q-select>
100
- </template>
101
-
102
- <script>
103
- import {
104
- QIcon, QImg, QItem, QItemSection, QSelect, debounce,
105
- } from 'quasar';
106
- import {
107
- defineComponent, nextTick, onBeforeMount, ref, watch,
108
- } from 'vue';
109
- import { searchIcon, selectDownArrowIcon } from '../assets/icons.js';
110
-
111
- export default defineComponent({
112
- name: 'SSelectSearchCheckbox',
113
- emits: ['update:modelValue'],
114
- components: {
115
- QSelect,
116
- QItem,
117
- QItemSection,
118
- QImg,
119
- QIcon,
120
- // QInput,
121
- },
122
- props: {
123
- searchPlaceholder: { type: String, default: '검색' },
124
- options: {
125
- type: Array,
126
- required: true,
127
- },
128
- modelValue: {
129
- type: Array,
130
- required: true,
131
- },
132
- optionLabel: {
133
- type: [String, Function],
134
- default: 'label',
135
- },
136
- optionValue: {
137
- type: String,
138
- default: 'value',
139
- },
140
- optionGroup: {
141
- type: String,
142
- default: 'group',
143
- },
144
- useAll: {
145
- type: Boolean,
146
- default: false,
147
- },
148
- placeholder: {
149
- type: String,
150
- default: '전체',
151
- },
152
- checkboxSearch: {
153
- type: String,
154
- default: '',
155
- },
156
- noData: {
157
- type: String,
158
- default: '데이터 없음',
159
- },
160
- popupContentClass: {
161
- type: String,
162
- },
163
- },
164
- setup(props, { emit }) {
165
- const model = ref(props.modelValue);
166
- const filteredOptions = ref(props.options);
167
- const searchInput = ref(null);
168
- const search = ref('');
169
- const isDisable = props.options.find((v) => Boolean(v.disable));
170
-
171
- function onRemoveChecked(detail) {
172
- const idx = model.value.findIndex((v) => v === '');
173
- if (detail[props.optionValue] === '') {
174
- nextTick(() => {
175
- model.value = [];
176
- });
177
- } else if (idx >= 0) {
178
- nextTick(() => {
179
- model.value.splice(idx, 1);
180
- });
181
- }
182
- }
183
- function onAddChecked(detail) {
184
- if (detail[props.optionValue] === '') {
185
- nextTick(() => {
186
- model.value = props.options
187
- .filter((v) => !v.category)
188
- .map((option) => option[props.optionValue]);
189
- });
190
- } else {
191
- nextTick(() => {
192
- if (model.value.length === props.options.length - 1) {
193
- model.value = props.options
194
- .filter((v) => !v.category)
195
- .map((option) => option[props.optionValue]);
196
- }
197
- });
198
- }
199
- }
200
-
201
- const onSearch = debounce((val) => {
202
- if (val === '') {
203
- filteredOptions.value = props.options;
204
- } else {
205
- filteredOptions.value = props.options.filter(
206
- (v) => (v[props.optionLabel] || v).toLowerCase().indexOf(val.toLowerCase()) > -1,
207
- );
208
- }
209
- }, 200);
210
-
211
- watch(
212
- () => props.modelValue,
213
- (val) => {
214
- model.value = val;
215
-
216
- if (
217
- props.options.filter((opt) => opt[props.optionValue] && !opt.category)
218
- .length === model.value.length
219
- && model.value.length
220
- ) {
221
- model.value = props.options
222
- .filter((v) => !v.category)
223
- .map((option) => option[props.optionValue]);
224
- }
225
- },
226
- );
227
-
228
- watch(model, (val) => {
229
- emit('update:modelValue', val);
230
- });
231
-
232
- watch(
233
- () => props.options,
234
- (val) => {
235
- filteredOptions.value = val;
236
- nextTick(() => {
237
- if (props.useAll && model.value.filter((v) => v).length < 1) {
238
- model.value = props.options
239
- .filter((v) => !v.category)
240
- .map((option) => option[props.optionValue]);
241
- }
242
- });
243
- },
244
- );
245
-
246
- onBeforeMount(() => {
247
- if (props.useAll && model.value.filter((v) => v).length < 1) {
248
- model.value = props.options
249
- .filter((v) => !v.category)
250
- .map((option) => option[props.optionValue]);
251
- }
252
- });
253
-
254
- return {
255
- model,
256
- selectDownArrowIcon,
257
- onRemoveChecked,
258
- onAddChecked,
259
- onSearch,
260
- isDisable,
261
- filteredOptions,
262
- search,
263
- searchInput,
264
- searchIcon,
265
- sSelectRef: ref(null),
266
- };
267
- },
268
- });
269
- </script>
270
-
271
- <style lang="scss">
272
- @import "../css/quasar.variables.scss";
273
- @import "../css/extends.scss";
274
-
275
- .s-select-checkbox {
276
- @extend %select;
277
-
278
- .q-field__native {
279
- display: block;
280
- min-height: 0;
281
- height: $default-height;
282
- width: 100%;
283
- padding: $select-padding !important;
284
- color: $Grey_Darken-4;
285
- white-space: nowrap;
286
- overflow: hidden;
287
- text-overflow: ellipsis;
288
-
289
- > span {
290
- max-height: $default-height;
291
- }
292
-
293
- > .s-checkbox {
294
- margin-right: $default-icon-margin;
295
- }
296
- }
297
- }
298
-
299
- .s-select-checkbox-opts {
300
- @extend %select-menu-list;
301
- }
302
-
303
- .custom-select-options {
304
- height: $default-height;
305
- }
306
-
307
- .disabled.s-select-checkbox-option {
308
- border: none;
309
- background: none !important;
310
- color: $Grey_Default !important;
311
- }
312
-
313
- .select-search-input-form {
314
- height: 28px;
315
- display: flex;
316
- align-items: center;
317
- padding-left: 8px;
318
- position: relative;
319
- border-radius: 2px;
320
- border: 1px solid $Grey_Lighten-1;
321
- background-color: white;
322
- position: sticky;
323
- top: 0;
324
- z-index: 1;
325
- margin: 4px;
326
-
327
- &::after {
328
- content: "";
329
- position: absolute;
330
- top: 0;
331
- right: 0;
332
- bottom: 0;
333
- left: 0;
334
- pointer-events: none;
335
- border: 1px solid transparent;
336
- border-radius: inherit;
337
- }
338
-
339
- &:hover,
340
- &:focus-within {
341
- &::after {
342
- border-color: #0075ff;
343
- box-shadow: 0 0 4px #0075ff;
344
- transition: border-color 0.36s cubic-bezier(0.4, 0, 0.2, 1);
345
- }
346
- }
347
-
348
- .select-search-input {
349
- font-size: 12px;
350
- margin-left: 8px;
351
- flex-grow: 1;
352
- border: none;
353
- outline: none;
354
- }
355
- }
356
- </style>
1
+ <template>
2
+ <q-select
3
+ outlined
4
+ dense
5
+ options-dense
6
+ :dropdown-icon="selectDownArrowIcon"
7
+ v-model="model"
8
+ :options="filteredOptions"
9
+ multiple
10
+ emit-value
11
+ map-options
12
+ autocomplete="country"
13
+ color="positive"
14
+ :popup-content-class="
15
+ ['s-select-checkbox-opts', popupContentClass].join(' ')
16
+ "
17
+ class="s-select-checkbox"
18
+ :option-label="optionLabel"
19
+ :option-value="optionValue"
20
+ :option-group="optionGroup"
21
+ @add="onAddChecked"
22
+ @remove="onRemoveChecked"
23
+ :menu-offset="[0, 4]"
24
+ menu-self="top left"
25
+ menu-anchor="bottom start"
26
+ no-error-icon
27
+ hide-bottom-space
28
+ ref="sSelectRef"
29
+ >
30
+ <!-- TODO: 아무것도 선택되지 않았을 때 props 값으로 표기 해줘야함 기본 값은 "전체" -->
31
+ <template v-slot:before-options>
32
+ <div class="search-input-form-container">
33
+ <form class="select-search-input-form">
34
+ <q-icon :name="searchIcon" size="20px" />
35
+ <input
36
+ v-model="search"
37
+ autofocus
38
+ class="select-search-input"
39
+ :placeholder="searchPlaceholder"
40
+ @input="
41
+ (data) => {
42
+ onSearch(data.target.value);
43
+ }
44
+ "
45
+ />
46
+ </form>
47
+ </div>
48
+ </template>
49
+ <template v-slot:option="{ itemProps, opt, selected, toggleOption }">
50
+ <q-item v-bind="itemProps" class="custom-select-options">
51
+ <q-item-section side v-if="!opt.disable">
52
+ <s-checkbox
53
+ :modelValue="selected"
54
+ @update:modelValue="toggleOption(opt)"
55
+ />
56
+ </q-item-section>
57
+ <q-item-section v-if="opt[optionGroup]" class="text-Grey_Darken-4">
58
+ {{ opt[optionGroup] }}
59
+ </q-item-section>
60
+ <q-item-section avatar v-if="opt.logo">
61
+ <q-img
62
+ class="q-pa-none bg-Grey_Lighten-5"
63
+ :src="opt.logo"
64
+ width="60px"
65
+ height="22px"
66
+ />
67
+ </q-item-section>
68
+ <q-item-section>
69
+ {{ opt[optionLabel] }}
70
+ </q-item-section>
71
+ </q-item>
72
+ </template>
73
+ <template v-if="useAll && model[0] === ''" v-slot:selected>
74
+ <div>
75
+ {{ placeholder }}
76
+ </div>
77
+ </template>
78
+ <template v-slot:no-option>
79
+ <div class="search-input-form-container">
80
+ <form class="select-search-input-form">
81
+ <q-icon :name="searchIcon" size="20px" />
82
+ <input
83
+ v-model="search"
84
+ autofocus
85
+ class="select-search-input"
86
+ :placeholder="searchPlaceholder"
87
+ @input="
88
+ (data) => {
89
+ onSearch(data.target.value);
90
+ }
91
+ "
92
+ />
93
+ </form>
94
+ </div>
95
+ <q-item class="s-select-no-option">
96
+ <q-item-section class="text-grey">{{ noData }}</q-item-section>
97
+ </q-item>
98
+ </template>
99
+ </q-select>
100
+ </template>
101
+
102
+ <script>
103
+ import {
104
+ QIcon, QImg, QItem, QItemSection, QSelect, debounce,
105
+ } from 'quasar';
106
+ import {
107
+ defineComponent, nextTick, onBeforeMount, ref, watch,
108
+ } from 'vue';
109
+ import { searchIcon, selectDownArrowIcon } from '../assets/icons.js';
110
+
111
+ export default defineComponent({
112
+ name: 'SSelectSearchCheckbox',
113
+ emits: ['update:modelValue'],
114
+ components: {
115
+ QSelect,
116
+ QItem,
117
+ QItemSection,
118
+ QImg,
119
+ QIcon,
120
+ // QInput,
121
+ },
122
+ props: {
123
+ searchPlaceholder: { type: String, default: '검색' },
124
+ options: {
125
+ type: Array,
126
+ required: true,
127
+ },
128
+ modelValue: {
129
+ type: Array,
130
+ required: true,
131
+ },
132
+ optionLabel: {
133
+ type: [String, Function],
134
+ default: 'label',
135
+ },
136
+ optionValue: {
137
+ type: String,
138
+ default: 'value',
139
+ },
140
+ optionGroup: {
141
+ type: String,
142
+ default: 'group',
143
+ },
144
+ useAll: {
145
+ type: Boolean,
146
+ default: false,
147
+ },
148
+ placeholder: {
149
+ type: String,
150
+ default: '전체',
151
+ },
152
+ checkboxSearch: {
153
+ type: String,
154
+ default: '',
155
+ },
156
+ noData: {
157
+ type: String,
158
+ default: '데이터 없음',
159
+ },
160
+ popupContentClass: {
161
+ type: String,
162
+ },
163
+ },
164
+ setup(props, { emit }) {
165
+ const model = ref(props.modelValue);
166
+ const filteredOptions = ref(props.options);
167
+ const searchInput = ref(null);
168
+ const search = ref('');
169
+ const isDisable = props.options.find((v) => Boolean(v.disable));
170
+
171
+ function onRemoveChecked(detail) {
172
+ const idx = model.value.findIndex((v) => v === '');
173
+ if (detail[props.optionValue] === '') {
174
+ nextTick(() => {
175
+ model.value = [];
176
+ });
177
+ } else if (idx >= 0) {
178
+ nextTick(() => {
179
+ model.value.splice(idx, 1);
180
+ });
181
+ }
182
+ }
183
+ function onAddChecked(detail) {
184
+ if (detail[props.optionValue] === '') {
185
+ nextTick(() => {
186
+ model.value = props.options
187
+ .filter((v) => !v.category)
188
+ .map((option) => option[props.optionValue]);
189
+ });
190
+ } else {
191
+ nextTick(() => {
192
+ if (model.value.length === props.options.length - 1) {
193
+ model.value = props.options
194
+ .filter((v) => !v.category)
195
+ .map((option) => option[props.optionValue]);
196
+ }
197
+ });
198
+ }
199
+ }
200
+
201
+ const onSearch = debounce((val) => {
202
+ if (val === '') {
203
+ filteredOptions.value = props.options;
204
+ } else {
205
+ filteredOptions.value = props.options.filter(
206
+ (v) => (v[props.optionLabel] || v).toLowerCase().indexOf(val.toLowerCase()) > -1,
207
+ );
208
+ }
209
+ }, 200);
210
+
211
+ watch(
212
+ () => props.modelValue,
213
+ (val) => {
214
+ model.value = val;
215
+
216
+ if (
217
+ props.options.filter((opt) => opt[props.optionValue] && !opt.category)
218
+ .length === model.value.length
219
+ && model.value.length
220
+ ) {
221
+ model.value = props.options
222
+ .filter((v) => !v.category)
223
+ .map((option) => option[props.optionValue]);
224
+ }
225
+ },
226
+ );
227
+
228
+ watch(model, (val) => {
229
+ emit('update:modelValue', val);
230
+ });
231
+
232
+ watch(
233
+ () => props.options,
234
+ (val) => {
235
+ filteredOptions.value = val;
236
+ nextTick(() => {
237
+ if (props.useAll && model.value.filter((v) => v).length < 1) {
238
+ model.value = props.options
239
+ .filter((v) => !v.category)
240
+ .map((option) => option[props.optionValue]);
241
+ }
242
+ });
243
+ },
244
+ );
245
+
246
+ onBeforeMount(() => {
247
+ if (props.useAll && model.value.filter((v) => v).length < 1) {
248
+ model.value = props.options
249
+ .filter((v) => !v.category)
250
+ .map((option) => option[props.optionValue]);
251
+ }
252
+ });
253
+
254
+ return {
255
+ model,
256
+ selectDownArrowIcon,
257
+ onRemoveChecked,
258
+ onAddChecked,
259
+ onSearch,
260
+ isDisable,
261
+ filteredOptions,
262
+ search,
263
+ searchInput,
264
+ searchIcon,
265
+ sSelectRef: ref(null),
266
+ };
267
+ },
268
+ });
269
+ </script>
270
+
271
+ <style lang="scss">
272
+ @import "../css/quasar.variables.scss";
273
+ @import "../css/extends.scss";
274
+
275
+ .s-select-checkbox {
276
+ @extend %select;
277
+
278
+ .q-field__native {
279
+ display: block;
280
+ min-height: 0;
281
+ height: $default-height;
282
+ width: 100%;
283
+ padding: $select-padding !important;
284
+ color: $Grey_Darken-4;
285
+ white-space: nowrap;
286
+ overflow: hidden;
287
+ text-overflow: ellipsis;
288
+
289
+ > span {
290
+ max-height: $default-height;
291
+ }
292
+
293
+ > .s-checkbox {
294
+ margin-right: $default-icon-margin;
295
+ }
296
+ }
297
+ }
298
+
299
+ .s-select-checkbox-opts {
300
+ @extend %select-menu-list;
301
+ }
302
+
303
+ .custom-select-options {
304
+ height: $default-height;
305
+ }
306
+
307
+ .disabled.s-select-checkbox-option {
308
+ border: none;
309
+ background: none !important;
310
+ color: $Grey_Default !important;
311
+ }
312
+
313
+ .select-search-input-form {
314
+ height: 28px;
315
+ display: flex;
316
+ align-items: center;
317
+ padding-left: 8px;
318
+ position: relative;
319
+ border-radius: 2px;
320
+ border: 1px solid $Grey_Lighten-1;
321
+ background-color: white;
322
+ position: sticky;
323
+ top: 0;
324
+ z-index: 1;
325
+ margin: 4px;
326
+
327
+ &::after {
328
+ content: "";
329
+ position: absolute;
330
+ top: 0;
331
+ right: 0;
332
+ bottom: 0;
333
+ left: 0;
334
+ pointer-events: none;
335
+ border: 1px solid transparent;
336
+ border-radius: inherit;
337
+ }
338
+
339
+ &:hover,
340
+ &:focus-within {
341
+ &::after {
342
+ border-color: #0075ff;
343
+ box-shadow: 0 0 4px #0075ff;
344
+ transition: border-color 0.36s cubic-bezier(0.4, 0, 0.2, 1);
345
+ }
346
+ }
347
+
348
+ .select-search-input {
349
+ font-size: 12px;
350
+ margin-left: 8px;
351
+ flex-grow: 1;
352
+ border: none;
353
+ outline: none;
354
+ }
355
+ }
356
+ </style>