@globalbrain/sefirot 3.4.0 → 3.6.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/README.md +0 -1
- package/lib/components/SDescFile.vue +98 -0
- package/lib/components/SDescItem.vue +3 -2
- package/lib/components/SInputBase.vue +39 -14
- package/lib/components/SInputDate.vue +8 -0
- package/lib/components/SInputDropdown.vue +9 -24
- package/lib/components/SInputFile.vue +11 -6
- package/lib/components/SInputHMS.vue +2 -1
- package/lib/components/SInputSegments.vue +4 -3
- package/lib/components/SInputSegmentsOption.vue +13 -7
- package/lib/components/SInputYMD.vue +1 -1
- package/lib/components/SMFade.vue +2 -1
- package/lib/composables/Image.ts +8 -1
- package/lib/mixins/Desc.ts +3 -0
- package/lib/styles/variables.css +2 -0
- package/lib/validation/rules/decimal.ts +3 -2
- package/lib/validation/rules/decimalOrHyphen.ts +8 -0
- package/lib/validation/rules/index.ts +5 -0
- package/lib/validation/rules/negativeInteger.ts +9 -0
- package/lib/validation/rules/positiveInteger.ts +9 -0
- package/lib/validation/rules/zeroOrNegativeInteger.ts +9 -0
- package/lib/validation/rules/zeroOrPositiveInteger.ts +9 -0
- package/lib/validation/validators/hyphen.ts +3 -0
- package/lib/validation/validators/index.ts +4 -0
- package/lib/validation/validators/negativeInteger.ts +3 -0
- package/lib/validation/validators/positiveInteger.ts +3 -0
- package/lib/validation/validators/zero.ts +3 -0
- package/package.json +12 -10
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Sefirot
|
|
2
2
|
|
|
3
3
|
[](https://github.com/globalbrain/sefirot/actions)
|
|
4
|
-
[](https://codecov.io/gh/globalbrain/sefirot)
|
|
5
4
|
[](https://github.com/globalbrain/sefirot/blob/main/LICENSE.md)
|
|
6
5
|
|
|
7
6
|
Sefirot is a collection of Vue Components for Global Brain Design System. Components are meant to be clean, sophisticated, and scalable.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import IconDownloadSimple from '@iconify-icons/ph/download-simple-bold'
|
|
3
|
+
import IconFileText from '@iconify-icons/ph/file-text-bold'
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
import { isArray } from '../support/Utils'
|
|
6
|
+
import SButton from './SButton.vue'
|
|
7
|
+
import SDescEmpty from './SDescEmpty.vue'
|
|
8
|
+
import SIcon from './SIcon.vue'
|
|
9
|
+
|
|
10
|
+
export interface Item {
|
|
11
|
+
name: string
|
|
12
|
+
onDownload(): void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const props = defineProps<{
|
|
16
|
+
item?: Item | Item[] | null
|
|
17
|
+
}>()
|
|
18
|
+
|
|
19
|
+
const items = computed(() => {
|
|
20
|
+
return props.item
|
|
21
|
+
? isArray(props.item) ? props.item : [props.item]
|
|
22
|
+
: null
|
|
23
|
+
})
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<div v-if="items && items.length" class="SDescFile">
|
|
28
|
+
<div class="value">
|
|
29
|
+
<div v-for="item, index in items" :key="index" class="item">
|
|
30
|
+
<div class="data">
|
|
31
|
+
<div class="icon"><SIcon class="icon-svg" :icon="IconFileText" /></div>
|
|
32
|
+
<div class="name">{{ item.name }}</div>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="actions">
|
|
35
|
+
<SButton
|
|
36
|
+
size="small"
|
|
37
|
+
type="text"
|
|
38
|
+
mode="info"
|
|
39
|
+
:icon="IconDownloadSimple"
|
|
40
|
+
label="Download"
|
|
41
|
+
@click="item.onDownload"
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<SDescEmpty v-else />
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
<style scoped lang="postcss">
|
|
51
|
+
.value {
|
|
52
|
+
display: flex;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
gap: 1px;
|
|
55
|
+
border: 1px solid var(--c-divider);
|
|
56
|
+
border-radius: 6px;
|
|
57
|
+
margin-top: 2px;
|
|
58
|
+
background-color: var(--c-gutter);
|
|
59
|
+
overflow: hidden;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.item {
|
|
63
|
+
display: flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: 8px;
|
|
66
|
+
padding: 0 8px 0 12px;
|
|
67
|
+
width: 100%;
|
|
68
|
+
height: 48px;
|
|
69
|
+
background-color: var(--c-bg-elv-4);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.data {
|
|
73
|
+
display: flex;
|
|
74
|
+
gap: 8px;
|
|
75
|
+
flex-grow: 1;
|
|
76
|
+
align-items: center;
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.icon-svg {
|
|
81
|
+
width: 18px;
|
|
82
|
+
height: 18px;
|
|
83
|
+
color: var(--c-text-2);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.name {
|
|
87
|
+
line-height: 24px;
|
|
88
|
+
font-size: 14px;
|
|
89
|
+
color: var(--c-text-1);
|
|
90
|
+
white-space: nowrap;
|
|
91
|
+
overflow: hidden;
|
|
92
|
+
text-overflow: ellipsis;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.actions {
|
|
96
|
+
flex-shrink: 0;
|
|
97
|
+
}
|
|
98
|
+
</style>
|
|
@@ -25,13 +25,14 @@ const labelWidth = computed(() => {
|
|
|
25
25
|
<style scoped lang="postcss">
|
|
26
26
|
.SDescItem {
|
|
27
27
|
display: grid;
|
|
28
|
+
grid-template-columns: minmax(0, 1fr);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
.SDesc.row > .SDescItem {
|
|
31
|
-
grid-template-columns: var(--desc-label-width, v-bind(labelWidth)) 1fr;
|
|
32
|
+
grid-template-columns: var(--desc-label-width, v-bind(labelWidth)) minmax(0, 1fr);
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
.SDesc.divider > .SDescItem {
|
|
35
|
+
.SDesc.divider > .SDescItem:not(:has(> .SDescFile)) {
|
|
35
36
|
border-bottom: 1px dashed var(--c-divider);
|
|
36
37
|
padding-bottom: 7px;
|
|
37
38
|
}
|
|
@@ -60,11 +60,13 @@ function getErrorMsg(validation: Validatable) {
|
|
|
60
60
|
<span class="label-text">{{ label }}</span>
|
|
61
61
|
|
|
62
62
|
<STooltip v-if="hasInfo" :text="info" trigger="focus" @click.prevent>
|
|
63
|
-
<
|
|
63
|
+
<div class="label-info">
|
|
64
|
+
<SIcon class="label-info-icon" :icon="IconQuestion" />
|
|
65
|
+
</div>
|
|
64
66
|
<template v-if="$slots.info" #text><slot name="info" /></template>
|
|
65
67
|
</STooltip>
|
|
66
68
|
|
|
67
|
-
<span class="label-note">{{ note }}</span>
|
|
69
|
+
<span class="label-note" :class="{ 'has-info': hasInfo }">{{ note }}</span>
|
|
68
70
|
|
|
69
71
|
<span v-if="checkIcon || checkText" class="check" :class="checkColor || 'neutral'">
|
|
70
72
|
<SIcon v-if="checkIcon" class="check-icon" :icon="checkIcon" />
|
|
@@ -84,18 +86,21 @@ function getErrorMsg(validation: Validatable) {
|
|
|
84
86
|
|
|
85
87
|
<style scoped lang="postcss">
|
|
86
88
|
.SInputBase.mini {
|
|
87
|
-
.label
|
|
88
|
-
.label-text
|
|
89
|
-
.label-info
|
|
89
|
+
.label { padding-bottom: 4px; min-height: 24px; }
|
|
90
|
+
.label-text { font-size: var(--input-label-font-size, var(--input-mini-label-font-size)); }
|
|
91
|
+
.label-info { margin-top: 0; margin-bottom: 0; width: 20px; height: 20px; }
|
|
92
|
+
.label-info-icon { width: 14px; height: 14px; }
|
|
93
|
+
.label-note { padding-top: 0; line-height: 20px; }
|
|
94
|
+
.check { padding-top: 0; line-height: 20px; }
|
|
90
95
|
}
|
|
91
96
|
|
|
92
97
|
.SInputBase.small {
|
|
93
|
-
.label { padding-bottom:
|
|
98
|
+
.label { padding-bottom: 6px; min-height: 26px; }
|
|
94
99
|
.label-text { font-size: var(--input-label-font-size, var(--input-small-label-font-size)); }
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
.SInputBase.medium {
|
|
98
|
-
.label { padding-bottom:
|
|
103
|
+
.label { padding-bottom: 6px; min-height: 26px; }
|
|
99
104
|
.label-text { font-size: var(--input-label-font-size, var(--input-medium-label-font-size)); }
|
|
100
105
|
}
|
|
101
106
|
|
|
@@ -107,9 +112,9 @@ function getErrorMsg(validation: Validatable) {
|
|
|
107
112
|
|
|
108
113
|
.label {
|
|
109
114
|
display: flex;
|
|
110
|
-
align-items:
|
|
115
|
+
align-items: flex-start;
|
|
111
116
|
width: 100%;
|
|
112
|
-
line-height:
|
|
117
|
+
line-height: 20px;
|
|
113
118
|
cursor: pointer;
|
|
114
119
|
transition: color 0.25s;
|
|
115
120
|
}
|
|
@@ -122,8 +127,18 @@ function getErrorMsg(validation: Validatable) {
|
|
|
122
127
|
|
|
123
128
|
:deep(.STooltip) {
|
|
124
129
|
.label-info {
|
|
125
|
-
display:
|
|
126
|
-
|
|
130
|
+
display: flex;
|
|
131
|
+
justify-content: center;
|
|
132
|
+
align-items: center;
|
|
133
|
+
flex-shrink: 0;
|
|
134
|
+
margin-top: -2px;
|
|
135
|
+
margin-left: 2px;
|
|
136
|
+
margin-bottom: -2px;
|
|
137
|
+
width: 24px;
|
|
138
|
+
height: 24px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.label-info-icon {
|
|
127
142
|
width: 16px;
|
|
128
143
|
height: 16px;
|
|
129
144
|
color: var(--c-text-2);
|
|
@@ -131,7 +146,7 @@ function getErrorMsg(validation: Validatable) {
|
|
|
131
146
|
}
|
|
132
147
|
|
|
133
148
|
&:hover, &:focus, &:focus-within {
|
|
134
|
-
.label-info {
|
|
149
|
+
.label-info-icon {
|
|
135
150
|
color: var(--c-text-info-1);
|
|
136
151
|
}
|
|
137
152
|
}
|
|
@@ -143,10 +158,17 @@ function getErrorMsg(validation: Validatable) {
|
|
|
143
158
|
|
|
144
159
|
.label-note {
|
|
145
160
|
display: inline-block;
|
|
161
|
+
flex-shrink: 0;
|
|
146
162
|
margin-left: 8px;
|
|
163
|
+
padding-top: 1px;
|
|
164
|
+
line-height: 19px;
|
|
147
165
|
font-size: 12px;
|
|
148
166
|
font-weight: 400;
|
|
149
167
|
color: var(--c-text-2);
|
|
168
|
+
|
|
169
|
+
&.has-info {
|
|
170
|
+
margin-left: 4px;
|
|
171
|
+
}
|
|
150
172
|
}
|
|
151
173
|
|
|
152
174
|
.help {
|
|
@@ -168,7 +190,7 @@ function getErrorMsg(validation: Validatable) {
|
|
|
168
190
|
.help-text {
|
|
169
191
|
max-width: 65ch;
|
|
170
192
|
margin: 0;
|
|
171
|
-
padding:
|
|
193
|
+
padding: 6px 0 0;
|
|
172
194
|
line-height: 20px;
|
|
173
195
|
font-size: 12px;
|
|
174
196
|
font-weight: 400;
|
|
@@ -183,10 +205,13 @@ function getErrorMsg(validation: Validatable) {
|
|
|
183
205
|
|
|
184
206
|
.check {
|
|
185
207
|
display: inline-flex;
|
|
208
|
+
flex-shrink: 0;
|
|
186
209
|
align-items: center;
|
|
187
210
|
gap: 4px;
|
|
188
211
|
margin-left: auto;
|
|
189
|
-
|
|
212
|
+
padding-top: 1px;
|
|
213
|
+
padding-left: 8px;
|
|
214
|
+
line-height: 19px;
|
|
190
215
|
font-size: 12px;
|
|
191
216
|
|
|
192
217
|
&.neutral { color: var(--c-text-1); }
|
|
@@ -162,6 +162,14 @@ function emitBlur() {
|
|
|
162
162
|
color: var(--input-placeholder-color);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
&:hover {
|
|
166
|
+
border-color: var(--input-hover-border-color);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
&:focus {
|
|
170
|
+
border-color: var(--input-focus-border-color);
|
|
171
|
+
}
|
|
172
|
+
|
|
165
173
|
&.disabled {
|
|
166
174
|
border-color: var(--input-disabled-border-color);
|
|
167
175
|
background-color: var(--input-disabled-bg-color);
|
|
@@ -195,7 +195,7 @@ function handleArray(value: OptionValue) {
|
|
|
195
195
|
.box-content {
|
|
196
196
|
padding: 3px 30px 3px 12px;
|
|
197
197
|
line-height: 24px;
|
|
198
|
-
font-size:
|
|
198
|
+
font-size: var(--input-font-size, var(--input-mini-font-size));
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
.box-icon {
|
|
@@ -212,7 +212,7 @@ function handleArray(value: OptionValue) {
|
|
|
212
212
|
.box-content {
|
|
213
213
|
padding: 5px 30px 5px 8px;
|
|
214
214
|
line-height: 24px;
|
|
215
|
-
font-size:
|
|
215
|
+
font-size: var(--input-font-size, var(--input-small-font-size));
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
.box-icon {
|
|
@@ -229,7 +229,7 @@ function handleArray(value: OptionValue) {
|
|
|
229
229
|
.box-content {
|
|
230
230
|
padding: 11px 44px 11px 16px;
|
|
231
231
|
line-height: 24px;
|
|
232
|
-
font-size:
|
|
232
|
+
font-size: var(--input-font-size, var(--input-medium-font-size));
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
.box-icon {
|
|
@@ -255,7 +255,7 @@ function handleArray(value: OptionValue) {
|
|
|
255
255
|
|
|
256
256
|
.SInputDropdown.has-error {
|
|
257
257
|
.box {
|
|
258
|
-
border-color: var(--
|
|
258
|
+
border-color: var(--input-error-border-color);
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
|
|
@@ -265,37 +265,22 @@ function handleArray(value: OptionValue) {
|
|
|
265
265
|
|
|
266
266
|
.box {
|
|
267
267
|
position: relative;
|
|
268
|
-
border: 1px solid var(--
|
|
268
|
+
border: 1px solid var(--input-border-color);
|
|
269
269
|
border-radius: 6px;
|
|
270
270
|
width: 100%;
|
|
271
271
|
color: var(--input-text);
|
|
272
|
-
background-color: var(--
|
|
272
|
+
background-color: var(--input-bg-color);;
|
|
273
273
|
cursor: pointer;
|
|
274
|
-
transition: border-color .25s, background-color .25s;
|
|
274
|
+
transition: border-color 0.25s, background-color 0.25s;
|
|
275
275
|
|
|
276
276
|
&:hover {
|
|
277
|
-
border-color: var(--
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
&:focus,
|
|
281
|
-
&:hover.focus {
|
|
282
|
-
border-color: var(--c-info);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
.dark &:hover {
|
|
286
|
-
border-color: var(--c-gray);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
.dark &:focus,
|
|
290
|
-
.dark &:hover:focus {
|
|
291
|
-
border-color: var(--c-info);
|
|
277
|
+
border-color: var(--input-hover-border-color);
|
|
292
278
|
}
|
|
293
279
|
}
|
|
294
280
|
|
|
295
281
|
.box-placeholder {
|
|
296
282
|
padding: 2px 4px;
|
|
297
|
-
|
|
298
|
-
color: var(--c-text-3);
|
|
283
|
+
color: var(--input-placeholder-color);
|
|
299
284
|
overflow: hidden;
|
|
300
285
|
white-space: nowrap;
|
|
301
286
|
}
|
|
@@ -130,7 +130,7 @@ function onChange(e: Event) {
|
|
|
130
130
|
.button {
|
|
131
131
|
padding: 0 8px;
|
|
132
132
|
line-height: 26px;
|
|
133
|
-
font-size:
|
|
133
|
+
font-size: 12px;
|
|
134
134
|
font-weight: 500;
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -150,7 +150,7 @@ function onChange(e: Event) {
|
|
|
150
150
|
.button {
|
|
151
151
|
padding: 0 12px;
|
|
152
152
|
line-height: 30px;
|
|
153
|
-
font-size:
|
|
153
|
+
font-size: 13px;
|
|
154
154
|
font-weight: 500;
|
|
155
155
|
}
|
|
156
156
|
|
|
@@ -184,6 +184,11 @@ function onChange(e: Event) {
|
|
|
184
184
|
&:hover {
|
|
185
185
|
border-color: var(--input-hover-border-color);
|
|
186
186
|
}
|
|
187
|
+
|
|
188
|
+
&:hover .button {
|
|
189
|
+
border-color: var(--c-border-mute-2);
|
|
190
|
+
background-color: var(--c-bg-mute-2);
|
|
191
|
+
}
|
|
187
192
|
}
|
|
188
193
|
|
|
189
194
|
.action {
|
|
@@ -191,11 +196,11 @@ function onChange(e: Event) {
|
|
|
191
196
|
}
|
|
192
197
|
|
|
193
198
|
.button {
|
|
194
|
-
border: 1px solid var(--c-
|
|
195
|
-
border-radius:
|
|
199
|
+
border: 1px solid var(--c-border-mute-1);
|
|
200
|
+
border-radius: 3px;
|
|
196
201
|
color: var(--c-text-1);
|
|
197
|
-
background-color: var(--c-mute);
|
|
198
|
-
transition: background-color 0.25s;
|
|
202
|
+
background-color: var(--c-bg-mute-1);
|
|
203
|
+
transition: border-color 0.25s, background-color 0.25s;
|
|
199
204
|
}
|
|
200
205
|
|
|
201
206
|
.text {
|
|
@@ -307,7 +307,8 @@ function createRequiredTouched(): boolean[] {
|
|
|
307
307
|
}
|
|
308
308
|
|
|
309
309
|
.input {
|
|
310
|
-
font-family: var(--input-value-font-family, var(--font-family-
|
|
310
|
+
font-family: var(--input-value-font-family, var(--font-family-base));
|
|
311
|
+
font-feature-settings: "tnum";
|
|
311
312
|
line-height: 24px;
|
|
312
313
|
background-color: transparent;
|
|
313
314
|
|
|
@@ -6,7 +6,8 @@ import SInputBase from './SInputBase.vue'
|
|
|
6
6
|
import SInputSegmentsOption, { type Mode } from './SInputSegmentsOption.vue'
|
|
7
7
|
|
|
8
8
|
export type Size = 'mini' | 'small' | 'medium'
|
|
9
|
-
export type Color = '
|
|
9
|
+
export type Color = 'default' | 'mute' | 'neutral' | 'info' | 'success' | 'warning' | 'danger'
|
|
10
|
+
export type CheckColor = 'neutral' | 'mute' | 'info' | 'success' | 'warning' | 'danger'
|
|
10
11
|
|
|
11
12
|
export interface Option<T extends string | number | boolean> {
|
|
12
13
|
label: string
|
|
@@ -24,7 +25,7 @@ const props = defineProps<{
|
|
|
24
25
|
help?: string
|
|
25
26
|
checkIcon?: IconifyIcon
|
|
26
27
|
checkText?: string
|
|
27
|
-
checkColor?:
|
|
28
|
+
checkColor?: CheckColor
|
|
28
29
|
options: Option<T>[]
|
|
29
30
|
block?: boolean
|
|
30
31
|
disabled?: boolean
|
|
@@ -78,7 +79,7 @@ function onSelect(value: T) {
|
|
|
78
79
|
:size="size ?? 'small'"
|
|
79
80
|
:label="option.label"
|
|
80
81
|
:value="option.value"
|
|
81
|
-
:mode="option.mode ?? '
|
|
82
|
+
:mode="option.mode ?? 'default'"
|
|
82
83
|
:active="_value === option.value"
|
|
83
84
|
:disabled="disabled ? true : option.disabled ?? false"
|
|
84
85
|
@click="onSelect(option.value)"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts" generic="T extends string | number | boolean">
|
|
2
2
|
export type Size = 'mini' | 'small' | 'medium'
|
|
3
|
-
export type Mode = '
|
|
3
|
+
export type Mode = 'default' | 'mute' | 'neutral' | 'info' | 'success' | 'warning' | 'danger'
|
|
4
4
|
|
|
5
5
|
const props = defineProps<{
|
|
6
6
|
size: Size
|
|
@@ -67,7 +67,7 @@ function onClick() {
|
|
|
67
67
|
width: 1px;
|
|
68
68
|
height: 16px;
|
|
69
69
|
border-radius: 4px;
|
|
70
|
-
background-color: var(--c-divider
|
|
70
|
+
background-color: var(--c-divider);
|
|
71
71
|
content: "";
|
|
72
72
|
transition: opacity 0.25s;
|
|
73
73
|
}
|
|
@@ -108,18 +108,24 @@ function onClick() {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
.SInputSegmentsOption.
|
|
112
|
-
border-color: var(--button-fill-
|
|
113
|
-
color: var(--button-fill-
|
|
114
|
-
background-color: var(--button-fill-
|
|
111
|
+
.SInputSegmentsOption.default.active {
|
|
112
|
+
border-color: var(--button-fill-default-border-color);
|
|
113
|
+
color: var(--button-fill-default-text-color);
|
|
114
|
+
background-color: var(--button-fill-default-bg-color);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
.SInputSegmentsOption.mute.active {
|
|
118
118
|
border-color: var(--button-fill-mute-border-color);
|
|
119
|
-
color: var(--
|
|
119
|
+
color: var(--button-fill-mute-text-color);
|
|
120
120
|
background-color: var(--button-fill-mute-bg-color);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
.SInputSegmentsOption.neutral.active {
|
|
124
|
+
border-color: var(--button-fill-neutral-border-color);
|
|
125
|
+
color: var(--button-fill-neutral-text-color);
|
|
126
|
+
background-color: var(--button-fill-neutral-bg-color);
|
|
127
|
+
}
|
|
128
|
+
|
|
123
129
|
.SInputSegmentsOption.info.active {
|
|
124
130
|
border-color: var(--button-fill-info-border-color);
|
|
125
131
|
color: var(--button-fill-info-text-color);
|
|
@@ -304,7 +304,7 @@ function createRequiredTouched(): boolean[] {
|
|
|
304
304
|
|
|
305
305
|
.input {
|
|
306
306
|
line-height: 24px;
|
|
307
|
-
font-family: var(--input-value-font-family, var(--font-family-
|
|
307
|
+
font-family: var(--input-value-font-family, var(--font-family-base));
|
|
308
308
|
font-feature-settings: "tnum";
|
|
309
309
|
background-color: transparent;
|
|
310
310
|
|
package/lib/composables/Image.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isClient } from '@vueuse/core'
|
|
1
2
|
import { type MaybeRefOrGetter, type Ref, ref, toValue, watchEffect } from 'vue'
|
|
2
3
|
import { isFile, isString } from '../support/Utils'
|
|
3
4
|
|
|
@@ -13,7 +14,13 @@ export interface ImageSrcFromFile {
|
|
|
13
14
|
export function useImageSrcFromFile(
|
|
14
15
|
file: MaybeRefOrGetter<File | string | null>
|
|
15
16
|
): ImageSrcFromFile {
|
|
16
|
-
|
|
17
|
+
if (!isClient) {
|
|
18
|
+
return {
|
|
19
|
+
src: ref(null)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const reader = new window.FileReader()
|
|
17
24
|
const src = ref<string | null>(null)
|
|
18
25
|
|
|
19
26
|
reader.onload = function () {
|
package/lib/mixins/Desc.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type App } from 'vue'
|
|
|
2
2
|
import SDesc from '../components/SDesc.vue'
|
|
3
3
|
import SDescDay from '../components/SDescDay.vue'
|
|
4
4
|
import SDescEmpty from '../components/SDescEmpty.vue'
|
|
5
|
+
import SDescFile from '../components/SDescFile.vue'
|
|
5
6
|
import SDescItem from '../components/SDescItem.vue'
|
|
6
7
|
import SDescLabel from '../components/SDescLabel.vue'
|
|
7
8
|
import SDescLink from '../components/SDescLink.vue'
|
|
@@ -14,6 +15,7 @@ export function mixin(app: App): void {
|
|
|
14
15
|
app.component('SDesc', SDesc)
|
|
15
16
|
app.component('SDescDay', SDescDay)
|
|
16
17
|
app.component('SDescEmpty', SDescEmpty)
|
|
18
|
+
app.component('SDescFile', SDescFile)
|
|
17
19
|
app.component('SDescItem', SDescItem)
|
|
18
20
|
app.component('SDescLabel', SDescLabel)
|
|
19
21
|
app.component('SDescLink', SDescLink)
|
|
@@ -28,6 +30,7 @@ declare module 'vue' {
|
|
|
28
30
|
SDesc: typeof SDesc
|
|
29
31
|
SDescDay: typeof SDescDay
|
|
30
32
|
SDescEmpty: typeof SDescEmpty
|
|
33
|
+
SDescFile: typeof SDescFile
|
|
31
34
|
SDescItem: typeof SDescItem
|
|
32
35
|
SDescLabel: typeof SDescLabel
|
|
33
36
|
SDescLink: typeof SDescLink
|
package/lib/styles/variables.css
CHANGED
|
@@ -153,6 +153,7 @@
|
|
|
153
153
|
/**
|
|
154
154
|
* Color: Divider and Gutter
|
|
155
155
|
* -------------------------------------------------------------------------- */
|
|
156
|
+
|
|
156
157
|
:root {
|
|
157
158
|
--c-divider: #e0e0e1;
|
|
158
159
|
--c-gutter: #e2e2e3;
|
|
@@ -166,6 +167,7 @@
|
|
|
166
167
|
/**
|
|
167
168
|
* Color: Neutral
|
|
168
169
|
* -------------------------------------------------------------------------- */
|
|
170
|
+
|
|
169
171
|
:root {
|
|
170
172
|
--c-neutral-1: var(--c-neutral-light-1);
|
|
171
173
|
--c-neutral-2: var(--c-neutral-light-2);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { decimal as baseDecimal, helpers } from '@vuelidate/validators'
|
|
1
|
+
import { and, decimal as baseDecimal, helpers, not } from '@vuelidate/validators'
|
|
2
|
+
import { hyphen } from '../validators'
|
|
2
3
|
|
|
3
4
|
export function decimal(msg?: string) {
|
|
4
5
|
return helpers.withMessage(
|
|
5
6
|
() => msg ?? 'The value must be valid decimal numbers.',
|
|
6
|
-
baseDecimal
|
|
7
|
+
and(not(hyphen), baseDecimal)
|
|
7
8
|
)
|
|
8
9
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { and, not, or } from '@vuelidate/validators'
|
|
2
2
|
export * from './checked'
|
|
3
3
|
export * from './decimal'
|
|
4
|
+
export * from './decimalOrHyphen'
|
|
4
5
|
export * from './email'
|
|
5
6
|
export * from './fileExtension'
|
|
6
7
|
export * from './hms'
|
|
@@ -11,6 +12,8 @@ export * from './maxValue'
|
|
|
11
12
|
export * from './minLength'
|
|
12
13
|
export * from './minValue'
|
|
13
14
|
export * from './month'
|
|
15
|
+
export * from './negativeInteger'
|
|
16
|
+
export * from './positiveInteger'
|
|
14
17
|
export * from './required'
|
|
15
18
|
export * from './requiredHms'
|
|
16
19
|
export * from './requiredIf'
|
|
@@ -18,3 +21,5 @@ export * from './requiredYmd'
|
|
|
18
21
|
export * from './rule'
|
|
19
22
|
export * from './url'
|
|
20
23
|
export * from './ymd'
|
|
24
|
+
export * from './zeroOrNegativeInteger'
|
|
25
|
+
export * from './zeroOrPositiveInteger'
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { helpers } from '@vuelidate/validators'
|
|
2
|
+
import { negativeInteger as baseNegativeInteger } from '../validators'
|
|
3
|
+
|
|
4
|
+
export function negativeInteger(msg?: string) {
|
|
5
|
+
return helpers.withMessage(
|
|
6
|
+
() => msg ?? 'The value must be valid negative integer.',
|
|
7
|
+
baseNegativeInteger
|
|
8
|
+
)
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { helpers } from '@vuelidate/validators'
|
|
2
|
+
import { positiveInteger as basePositiveInteger } from '../validators'
|
|
3
|
+
|
|
4
|
+
export function positiveInteger(msg?: string) {
|
|
5
|
+
return helpers.withMessage(
|
|
6
|
+
() => msg ?? 'The value must be valid positive integer.',
|
|
7
|
+
basePositiveInteger
|
|
8
|
+
)
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { helpers, or } from '@vuelidate/validators'
|
|
2
|
+
import { negativeInteger, zero } from '../validators'
|
|
3
|
+
|
|
4
|
+
export function zeroOrNegativeInteger(msg?: string) {
|
|
5
|
+
return helpers.withMessage(
|
|
6
|
+
() => msg ?? 'The value must be zero or valid negative integer.',
|
|
7
|
+
or(zero, negativeInteger)
|
|
8
|
+
)
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { helpers, or } from '@vuelidate/validators'
|
|
2
|
+
import { positiveInteger, zero } from '../validators'
|
|
3
|
+
|
|
4
|
+
export function zeroOrPositiveInteger(msg?: string) {
|
|
5
|
+
return helpers.withMessage(
|
|
6
|
+
() => msg ?? 'The value must be zero or valid positive integer.',
|
|
7
|
+
or(zero, positiveInteger)
|
|
8
|
+
)
|
|
9
|
+
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export * from './checked'
|
|
2
2
|
export * from './fileExtension'
|
|
3
3
|
export * from './hms'
|
|
4
|
+
export * from './hyphen'
|
|
4
5
|
export * from './maxFileSize'
|
|
5
6
|
export * from './maxTotalFileSize'
|
|
6
7
|
export * from './month'
|
|
8
|
+
export * from './negativeInteger'
|
|
9
|
+
export * from './positiveInteger'
|
|
7
10
|
export * from './requiredHms'
|
|
8
11
|
export * from './requiredYmd'
|
|
9
12
|
export * from './ymd'
|
|
13
|
+
export * from './zero'
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@globalbrain/sefirot",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"packageManager": "pnpm@8.10.
|
|
3
|
+
"version": "3.6.0",
|
|
4
|
+
"packageManager": "pnpm@8.10.5",
|
|
5
5
|
"description": "Vue Components for Global Brain Design System.",
|
|
6
6
|
"author": "Kia Ishii <ka.ishii@globalbrains.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"lint": "eslint --fix .",
|
|
32
32
|
"lint:fail": "eslint .",
|
|
33
33
|
"vitest": "vitest",
|
|
34
|
+
"vitest:run": "vitest run",
|
|
34
35
|
"coverage": "vitest run --coverage",
|
|
35
36
|
"test": "pnpm run type && pnpm run lint && pnpm run coverage",
|
|
36
37
|
"test:fail": "pnpm run type && pnpm run lint:fail && pnpm run coverage",
|
|
@@ -71,15 +72,15 @@
|
|
|
71
72
|
"@types/body-scroll-lock": "^3.1.2",
|
|
72
73
|
"@types/lodash-es": "^4.17.11",
|
|
73
74
|
"@types/markdown-it": "^13.0.6",
|
|
74
|
-
"@types/node": "^20.9.
|
|
75
|
-
"@vitejs/plugin-vue": "^4.
|
|
76
|
-
"@vitest/coverage-v8": "^1.0.0-beta.
|
|
77
|
-
"@vue/test-utils": "^2.4.
|
|
75
|
+
"@types/node": "^20.9.2",
|
|
76
|
+
"@vitejs/plugin-vue": "^4.5.0",
|
|
77
|
+
"@vitest/coverage-v8": "^1.0.0-beta.5",
|
|
78
|
+
"@vue/test-utils": "^2.4.2",
|
|
78
79
|
"@vuelidate/core": "^2.0.3",
|
|
79
80
|
"@vuelidate/validators": "^2.0.4",
|
|
80
81
|
"@vueuse/core": "^10.6.1",
|
|
81
82
|
"body-scroll-lock": "4.0.0-beta.0",
|
|
82
|
-
"eslint": "^8.
|
|
83
|
+
"eslint": "^8.54.0",
|
|
83
84
|
"fuse.js": "^7.0.0",
|
|
84
85
|
"happy-dom": "^12.10.3",
|
|
85
86
|
"histoire": "^0.17.5",
|
|
@@ -89,12 +90,13 @@
|
|
|
89
90
|
"pinia": "^2.1.7",
|
|
90
91
|
"postcss": "^8.4.31",
|
|
91
92
|
"postcss-nested": "^6.0.1",
|
|
93
|
+
"punycode": "^2.3.1",
|
|
92
94
|
"release-it": "^17.0.0",
|
|
93
95
|
"typescript": "~5.2.2",
|
|
94
96
|
"v-calendar": "^3.1.2",
|
|
95
|
-
"vite": "^
|
|
96
|
-
"vitepress": "1.0.0-rc.
|
|
97
|
-
"vitest": "^1.0.0-beta.
|
|
97
|
+
"vite": "^5.0.0",
|
|
98
|
+
"vitepress": "1.0.0-rc.29",
|
|
99
|
+
"vitest": "^1.0.0-beta.5",
|
|
98
100
|
"vue": "^3.3.8",
|
|
99
101
|
"vue-router": "^4.2.5",
|
|
100
102
|
"vue-tsc": "^1.8.22"
|