@globalbrain/sefirot 2.14.1 → 2.16.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.
@@ -1,9 +1,11 @@
1
1
  <script setup lang="ts">
2
- import { computed } from 'vue'
2
+ import { IconifyIcon } from '@iconify/vue/dist/offline'
3
+ import { DefineComponent, computed } from 'vue'
3
4
  import { Validatable } from '../composables/Validation'
4
5
  import SInputBase from './SInputBase.vue'
5
6
 
6
7
  export type Size = 'mini' | 'small' | 'medium'
8
+ export type Color = 'neutral' | 'mute' | 'info' | 'success' | 'warning' | 'danger'
7
9
 
8
10
  const props = defineProps<{
9
11
  size?: Size
@@ -13,6 +15,9 @@ const props = defineProps<{
13
15
  note?: string
14
16
  text?: string
15
17
  help?: string
18
+ checkIcon?: IconifyIcon | DefineComponent
19
+ checkText?: string
20
+ checkColor?: Color
16
21
  disabled?: boolean
17
22
  modelValue: boolean
18
23
  hideError?: boolean
@@ -41,6 +46,9 @@ function emitChange(): void {
41
46
  :label="label"
42
47
  :note="note"
43
48
  :info="info"
49
+ :check-icon="checkIcon"
50
+ :check-text="checkText"
51
+ :check-color="checkColor"
44
52
  :help="help"
45
53
  :hide-error="hideError"
46
54
  >
@@ -1,10 +1,12 @@
1
1
  <script setup lang="ts">
2
- import { computed } from 'vue'
2
+ import { IconifyIcon } from '@iconify/vue/dist/offline'
3
+ import { DefineComponent, computed } from 'vue'
3
4
  import { Validatable } from '../composables/Validation'
4
5
  import SInputBase from './SInputBase.vue'
5
6
  import SInputSwitch from './SInputSwitch.vue'
6
7
 
7
8
  export type Size = 'mini' | 'small' | 'medium'
9
+ export type Color = 'neutral' | 'mute' | 'info' | 'success' | 'warning' | 'danger'
8
10
 
9
11
  export interface Option {
10
12
  label: string
@@ -18,6 +20,9 @@ const props = defineProps<{
18
20
  info?: string
19
21
  note?: string
20
22
  help?: string
23
+ checkIcon?: IconifyIcon | DefineComponent
24
+ checkText?: string
25
+ checkColor?: Color
21
26
  options: Option[]
22
27
  disabled?: boolean
23
28
  modelValue: (string | number | boolean)[]
@@ -55,6 +60,9 @@ function handleChange(value: string | number | boolean): void {
55
60
  :note="note"
56
61
  :info="info"
57
62
  :help="help"
63
+ :check-icon="checkIcon"
64
+ :check-text="checkText"
65
+ :check-color="checkColor"
58
66
  :hide-error="hideError"
59
67
  >
60
68
  <div class="container">
@@ -1,11 +1,13 @@
1
1
  <script setup lang="ts">
2
- import { computed, ref } from 'vue'
2
+ import { IconifyIcon } from '@iconify/vue/dist/offline'
3
+ import { DefineComponent, computed, ref } from 'vue'
3
4
  import { Validatable } from '../composables/Validation'
4
5
  import SIcon from './SIcon.vue'
5
6
  import SInputBase from './SInputBase.vue'
6
7
 
7
8
  export type Size = 'mini' | 'small' | 'medium'
8
9
  export type Align = 'left' | 'center' | 'right'
10
+ export type Color = 'neutral' | 'mute' | 'info' | 'success' | 'warning' | 'danger'
9
11
 
10
12
  const props = defineProps<{
11
13
  size?: Size
@@ -16,6 +18,11 @@ const props = defineProps<{
16
18
  help?: string
17
19
  type?: string
18
20
  placeholder?: string
21
+ unitBefore?: string
22
+ unitAfter?: string
23
+ checkIcon?: IconifyIcon | DefineComponent
24
+ checkText?: string
25
+ checkColor?: Color
19
26
  icon?: any
20
27
  align?: Align
21
28
  disabled?: boolean
@@ -26,7 +33,7 @@ const props = defineProps<{
26
33
  }>()
27
34
 
28
35
  const emit = defineEmits<{
29
- (e: 'update:modelValue', value: string | null): void
36
+ (e: 'update:model-value', value: string | null): void
30
37
  (e: 'input', value: string | null): void
31
38
  (e: 'blur', value: string | null): void
32
39
  (e: 'enter', value: string | null): void
@@ -58,7 +65,7 @@ function emitBlur(e: FocusEvent): void {
58
65
 
59
66
  props.validation?.$touch()
60
67
 
61
- emit('update:modelValue', value)
68
+ emit('update:model-value', value)
62
69
  emit('blur', value)
63
70
 
64
71
  isFocused.value = false
@@ -66,7 +73,7 @@ function emitBlur(e: FocusEvent): void {
66
73
 
67
74
  function emitInput(e: Event): void {
68
75
  const v = getValue(e)
69
- emit('update:modelValue', v)
76
+ emit('update:model-value', v)
70
77
  emit('input', v)
71
78
  }
72
79
 
@@ -75,7 +82,7 @@ function emitEnter(e: KeyboardEvent): void {
75
82
 
76
83
  props.validation?.$touch()
77
84
 
78
- emit('update:modelValue', value)
85
+ emit('update:model-value', value)
79
86
  emit('enter', value)
80
87
  }
81
88
 
@@ -95,63 +102,84 @@ function getValue(e: Event | FocusEvent | KeyboardEvent): string | null {
95
102
  :note="note"
96
103
  :info="info"
97
104
  :help="help"
105
+ :check-icon="checkIcon"
106
+ :check-text="checkText"
107
+ :check-color="checkColor"
98
108
  :hide-error="hideError"
99
109
  :validation="validation"
100
110
  >
101
111
  <div class="box" :class="{ focus: isFocused }" @click="focus">
112
+ <div v-if="$slots['addon-before']" class="addon before">
113
+ <slot name="addon-before" />
114
+ </div>
115
+
102
116
  <div v-if="icon" class="icon">
103
117
  <SIcon :icon="icon" class="icon-svg" />
104
118
  </div>
105
119
 
106
120
  <div class="value">
107
- <input
108
- class="input"
109
- :class="{ hide: showDisplay }"
110
- :id="name"
111
- :type="type ?? 'text'"
112
- :placeholder="placeholder"
113
- :disabled="disabled"
114
- :value="modelValue"
115
- ref="input"
116
- @focus="onFocus"
117
- @blur="emitBlur"
118
- @input="emitInput"
119
- @keypress.enter="emitEnter"
120
- >
121
- <div v-if="showDisplay" class="display">
122
- {{ displayValue }}
121
+ <div v-if="props.unitBefore" class="unit before">
122
+ {{ props.unitBefore }}
123
+ </div>
124
+
125
+ <div class="area">
126
+ <input
127
+ class="input entity"
128
+ :class="{ hide: showDisplay }"
129
+ :id="name"
130
+ :type="type ?? 'text'"
131
+ :placeholder="placeholder"
132
+ :disabled="disabled"
133
+ :value="modelValue"
134
+ ref="input"
135
+ @focus="onFocus"
136
+ @blur="emitBlur"
137
+ @input="emitInput"
138
+ @keypress.enter="emitEnter"
139
+ >
140
+ <div v-if="showDisplay" class="input display">
141
+ {{ displayValue }}
142
+ </div>
143
+ </div>
144
+
145
+ <div v-if="props.unitAfter" class="unit after">
146
+ {{ props.unitAfter }}
123
147
  </div>
124
148
  </div>
149
+
150
+ <div v-if="$slots['addon-after']" class="addon after">
151
+ <slot name="addon-after" />
152
+ </div>
125
153
  </div>
126
154
  <template v-if="$slots.info" #info><slot name="info" /></template>
127
155
  </SInputBase>
128
156
  </template>
129
157
 
130
- <style lang="postcss" scoped>
158
+ <style scoped lang="postcss">
131
159
  .SInputText.mini {
132
- .box {
133
- padding: 0 8px;
134
- min-height: 32px;
135
- }
160
+ .box { min-height: 32px; }
161
+ .value { min-height: 30px; }
162
+ .area { min-height: 30px; }
136
163
 
137
- .value,
138
- .input,
139
- .display {
140
- min-height: 30px;
141
- }
142
-
143
- .input,
144
- .display {
145
- padding: 3px 0;
164
+ .input {
165
+ padding: 3px 8px;
146
166
  letter-spacing: 0;
147
167
  line-height: 24px;
148
- font-size: 14px;
168
+ font-size: var(--input-font-size, var(--input-mini-font-size));
149
169
  }
150
170
 
151
- .display {
152
- top: 0;
171
+ .unit + .area .input { padding-left: 6px; }
172
+ .area:has(+ .unit) .input { padding-right: 6px; }
173
+
174
+ .unit {
175
+ padding: 3px 8px;
176
+ line-height: 24px;
177
+ font-size: var(--input-font-size, var(--input-mini-font-size));
153
178
  }
154
179
 
180
+ .unit.before { padding-right: 0; }
181
+ .unit.after { padding-left: 0; }
182
+
155
183
  .icon {
156
184
  width: 22px;
157
185
  height: 30px;
@@ -161,32 +189,50 @@ function getValue(e: Event | FocusEvent | KeyboardEvent): string | null {
161
189
  width: 16px;
162
190
  height: 16px;
163
191
  }
164
- }
165
192
 
166
- .SInputText.small {
167
- .box {
168
- padding: 0 12px;
169
- min-height: 40px;
193
+ :slotted(.SInputAddon) .action {
194
+ padding: 0 10px;
195
+ font-size: 12px;
196
+ font-weight: 500;
170
197
  }
171
198
 
172
- .value,
173
- .input,
174
- .display {
175
- min-height: 38px;
199
+ :slotted(.SInputAddon) .action-icon {
200
+ width: 16px;
201
+ height: 16px;
176
202
  }
177
203
 
178
- .input,
179
- .display {
180
- padding: 5px 0;
204
+ :slotted(.SInputAddon) .caret {
205
+ margin-left: 4px;
206
+ margin-right: -2px;
207
+ width: 10px;
208
+ height: 10px;
209
+ }
210
+ }
211
+
212
+ .SInputText.small {
213
+ .box { min-height: 40px; }
214
+ .value { min-height: 38px; }
215
+ .area { min-height: 38px; }
216
+
217
+ .input {
218
+ padding: 7px 12px;
181
219
  letter-spacing: 0;
182
220
  line-height: 24px;
183
- font-size: 16px;
221
+ font-size: var(--input-font-size, var(--input-small-font-size));
184
222
  }
185
223
 
186
- .display {
187
- top: 2px;
224
+ .unit + .area .input { padding-left: 8px; }
225
+ .area:has(+ .unit) .input { padding-right: 8px; }
226
+
227
+ .unit {
228
+ padding: 7px 12px;
229
+ line-height: 24px;
230
+ font-size: var(--input-font-size, var(--input-small-font-size));
188
231
  }
189
232
 
233
+ .unit.before { padding-right: 0; }
234
+ .unit.after { padding-left: 0; }
235
+
190
236
  .icon {
191
237
  width: 26px;
192
238
  height: 38px;
@@ -196,32 +242,50 @@ function getValue(e: Event | FocusEvent | KeyboardEvent): string | null {
196
242
  width: 16px;
197
243
  height: 16px;
198
244
  }
199
- }
200
245
 
201
- .SInputText.medium {
202
- .box {
246
+ :slotted(.SInputAddon) .action {
203
247
  padding: 0 12px;
204
- min-height: 48px;
248
+ font-size: 14px;
249
+ font-weight: 500;
250
+ }
251
+
252
+ :slotted(.SInputAddon) .action-icon {
253
+ width: 16px;
254
+ height: 16px;
205
255
  }
206
256
 
207
- .value,
208
- .input,
209
- .display {
210
- min-height: 46px;
257
+ :slotted(.SInputAddon) .caret {
258
+ margin-left: 6px;
259
+ margin-right: -2px;
260
+ width: 12px;
261
+ height: 12px;
211
262
  }
263
+ }
212
264
 
213
- .input,
214
- .display {
215
- padding: 11px 0;
265
+ .SInputText.medium {
266
+ .box { min-height: 48px; }
267
+ .value { min-height: 46px; }
268
+ .area { min-height: 46px; }
269
+
270
+ .input {
271
+ padding: 11px 12px;
216
272
  letter-spacing: 0;
217
273
  line-height: 24px;
218
- font-size: 16px;
274
+ font-size: var(--input-font-size, var(--input-medium-font-size));
219
275
  }
220
276
 
221
- .display {
222
- top: 0;
277
+ .unit + .area .input { padding-left: 8px; }
278
+ .area:has(+ .unit) .input { padding-right: 8px; }
279
+
280
+ .unit {
281
+ padding: 11px 12px;
282
+ line-height: 24px;
283
+ font-size: var(--input-font-size, var(--input-medium-font-size));
223
284
  }
224
285
 
286
+ .unit.before { padding-right: 0; }
287
+ .unit.after { padding-left: 0; }
288
+
225
289
  .icon {
226
290
  width: 28px;
227
291
  height: 46px;
@@ -231,48 +295,52 @@ function getValue(e: Event | FocusEvent | KeyboardEvent): string | null {
231
295
  width: 18px;
232
296
  height: 18px;
233
297
  }
234
- }
235
298
 
236
- .SInputText.disabled {
237
- .input {
238
- background-color: var(--input-outlined-bg-disabled);
299
+ :slotted(.SInputAddon) .action {
300
+ padding: 0 14px;
301
+ font-size: 14px;
302
+ font-weight: 500;
239
303
  }
240
304
 
241
- .box:hover .input {
242
- cursor: not-allowed;
243
- border-color: var(--input-outlined-border);
305
+ :slotted(.SInputAddon) .action-icon {
306
+ width: 16px;
307
+ height: 16px;
244
308
  }
245
- }
246
309
 
247
- .SInputText.left {
248
- .input,
249
- .display {
250
- text-align: left;
310
+ :slotted(.SInputAddon) .caret {
311
+ margin-left: 6px;
312
+ margin-right: -2px;
313
+ width: 12px;
314
+ height: 12px;
251
315
  }
252
316
  }
253
317
 
254
- .SInputText.center {
255
- .input,
256
- .display {
257
- text-align: center;
318
+ .SInputText.disabled {
319
+ .box,
320
+ .box:hover,
321
+ .box:hover:has(.SInputAddon:is(.focused, :hover)),
322
+ .box:hover.focus,
323
+ .box.focus:has(.SInputAddon:is(.focused, :hover)),
324
+ .box:hover.focus:has(.SInputAddon:is(.focused, :hover)) {
325
+ border-color: var(--input-disabled-border-color);
326
+ background-color: var(--input-disabled-bg-color);
258
327
  }
259
- }
260
328
 
261
- .SInputText.right {
262
- .input,
263
- .display {
264
- text-align: right;
329
+ .box:hover .input,
330
+ .box:hover .unit {
331
+ cursor: not-allowed;
265
332
  }
266
333
  }
267
334
 
268
- .SInputText.has-error {
269
- .box {
270
- border-color: var(--c-danger);
335
+ .SInputText.left .input { text-align: left; }
336
+ .SInputText.center .input { text-align: center; }
337
+ .SInputText.right .input { text-align: right; }
271
338
 
272
- &:hover,
273
- &:focus {
274
- border-color: var(--c-danger);
275
- }
339
+ .SInputText.has-error {
340
+ .box,
341
+ .box:hover,
342
+ .box:focus {
343
+ border-color: var(--input-error-border-color);
276
344
  }
277
345
  }
278
346
 
@@ -281,39 +349,45 @@ function getValue(e: Event | FocusEvent | KeyboardEvent): string | null {
281
349
  display: flex;
282
350
  flex-grow: 1;
283
351
  max-width: 100%;
284
- border: 1px solid var(--c-divider);
352
+ border: 1px solid var(--input-border-color);
285
353
  border-radius: 6px;
286
- background-color: var(--c-bg);
287
- cursor: text;
354
+ background-color: var(--input-bg-color);
288
355
  transition: border-color 0.25s;
289
356
 
290
357
  &:hover {
291
- border-color: var(--c-black);
358
+ border-color: var(--input-hover-border-color);
292
359
  }
293
360
 
294
- &.focus,
295
- &:hover.focus {
296
- border-color: var(--c-info);
361
+ &:hover:has(.SInputAddon:is(.focused, :hover)) {
362
+ border-color: var(--input-border-color);
297
363
  }
298
364
 
299
- .dark &:hover {
300
- border-color: var(--c-gray);
301
- }
302
-
303
- .dark &.focus,
304
- .dark &:hover.focus {
305
- border-color: var(--c-info);
365
+ &.focus,
366
+ &:hover.focus,
367
+ &.focus:has(.SInputAddon:is(.focused, :hover)),
368
+ &:hover.focus:has(.SInputAddon:is(.focused, :hover)) {
369
+ border-color: var(--input-focus-border-color);
306
370
  }
307
371
  }
308
372
 
309
- .value {
373
+ .value,
374
+ .area {
310
375
  position: relative;
376
+ display: flex;
377
+ align-items: center;
311
378
  flex-grow: 1;
312
379
  }
313
380
 
314
381
  .input {
382
+ position: absolute;
383
+ top: 0;
384
+ right: 0;
385
+ bottom: 0;
386
+ left: 0;
315
387
  width: 100%;
388
+ color: var(--input-value-color);
316
389
  background-color: transparent;
390
+ cursor: text;
317
391
 
318
392
  &.hide,
319
393
  &.hide::placeholder {
@@ -321,17 +395,24 @@ function getValue(e: Event | FocusEvent | KeyboardEvent): string | null {
321
395
  }
322
396
 
323
397
  &::placeholder {
324
- font-weight: 500;
325
- color: var(--c-text-3);
398
+ color: var(--input-placeholder-color);
326
399
  }
327
400
  }
328
401
 
329
402
  .display {
330
403
  position: absolute;
404
+ top: 0;
405
+ right: 0;
406
+ bottom: 0;
331
407
  left: 0;
332
408
  width: 100%;
333
409
  }
334
410
 
411
+ .unit {
412
+ font-weight: 500;
413
+ color: var(--c-text-2);
414
+ }
415
+
335
416
  .icon {
336
417
  display: flex;
337
418
  align-items: center;
@@ -342,4 +423,35 @@ function getValue(e: Event | FocusEvent | KeyboardEvent): string | null {
342
423
  .icon-svg {
343
424
  fill: currentColor;
344
425
  }
426
+
427
+ .addon {
428
+ display: flex;
429
+ flex-shrink: 0;
430
+ }
431
+
432
+ .addon :slotted(.SInputAddon) .caret {
433
+ color: var(--c-text-2);
434
+ }
435
+
436
+ .addon.before :slotted(.SInputAddon) {
437
+ .action {
438
+ border-right: 1px solid var(--input-border-color);
439
+ border-radius: 5px 0 0 5px;
440
+ }
441
+
442
+ .dialog {
443
+ left: 0;
444
+ }
445
+ }
446
+
447
+ .addon.after :slotted(.SInputAddon) {
448
+ .action {
449
+ border-left: 1px solid var(--input-border-color);
450
+ border-radius: 0 5px 5px 0;
451
+ }
452
+
453
+ .dialog {
454
+ right: 0;
455
+ }
456
+ }
345
457
  </style>
@@ -1,9 +1,11 @@
1
1
  <script setup lang="ts">
2
- import { computed } from 'vue'
2
+ import { IconifyIcon } from '@iconify/vue/dist/offline'
3
+ import { DefineComponent, computed } from 'vue'
3
4
  import { Validatable } from '../composables/Validation'
4
5
  import SInputBase from './SInputBase.vue'
5
6
 
6
7
  export type Size = 'mini' | 'small' | 'medium'
8
+ export type Color = 'neutral' | 'mute' | 'info' | 'success' | 'warning' | 'danger'
7
9
 
8
10
  const props = defineProps<{
9
11
  size?: Size
@@ -12,6 +14,9 @@ const props = defineProps<{
12
14
  info?: string
13
15
  note?: string
14
16
  help?: string
17
+ checkIcon?: IconifyIcon | DefineComponent
18
+ checkText?: string
19
+ checkColor?: Color
15
20
  placeholder?: string
16
21
  disabled?: boolean
17
22
  rows?: number
@@ -48,6 +53,9 @@ function emitBlur(e: FocusEvent): void {
48
53
  :note="note"
49
54
  :info="info"
50
55
  :help="help"
56
+ :check-icon="checkIcon"
57
+ :check-text="checkText"
58
+ :check-color="checkColor"
51
59
  :hide-error="hideError"
52
60
  :validation="validation"
53
61
  >
@@ -1,9 +1,11 @@
1
1
  <script setup lang="ts">
2
- import { ref } from 'vue'
2
+ import { IconifyIcon } from '@iconify/vue/dist/offline'
3
+ import { DefineComponent, ref } from 'vue'
3
4
  import { Validatable } from '../composables/Validation'
4
5
  import SInputBase from './SInputBase.vue'
5
6
 
6
7
  export type Size = 'mini' | 'small' | 'medium'
8
+ export type Color = 'neutral' | 'mute' | 'info' | 'success' | 'warning' | 'danger'
7
9
 
8
10
  export interface Value {
9
11
  year: number | null
@@ -19,6 +21,9 @@ const props = defineProps<{
19
21
  info?: string
20
22
  note?: string
21
23
  help?: string
24
+ checkIcon?: IconifyIcon | DefineComponent
25
+ checkText?: string
26
+ checkColor?: Color
22
27
  noYear?: boolean
23
28
  noMonth?: boolean
24
29
  noDate?: boolean
@@ -104,6 +109,9 @@ function createRequiredTouched(): boolean[] {
104
109
  :note="note"
105
110
  :info="info"
106
111
  :help="help"
112
+ :check-icon="checkIcon"
113
+ :check-text="checkText"
114
+ :check-color="checkColor"
107
115
  :hide-error="hideError"
108
116
  :validation="validation"
109
117
  >