@globalbrain/sefirot 3.3.0 → 3.5.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/SCard.vue +15 -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/SInputDropdownItemAvatar.vue +1 -1
- package/lib/components/SInputDropdownItemText.vue +1 -1
- 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/components/SSheet.vue +1 -1
- package/lib/components/SSheetFooter.vue +1 -1
- package/lib/components/SSnackbar.vue +1 -1
- package/lib/components/SStep.vue +1 -1
- package/lib/components/STable.vue +48 -1
- package/lib/components/STableCellActions.vue +1 -1
- package/lib/components/STableColumn.vue +1 -1
- package/lib/components/STableFooter.vue +1 -1
- package/lib/components/STableHeaderMenu.vue +1 -1
- package/lib/components/STableItem.vue +4 -1
- package/lib/mixins/Desc.ts +3 -0
- package/lib/styles/variables.css +7 -5
- package/lib/support/Text.ts +25 -0
- package/lib/types/shims.d.ts +6 -2
- package/package.json +26 -29
- package/lib/types/vue-shims.d.ts +0 -7
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.
|
package/lib/components/SCard.vue
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { computed } from 'vue'
|
|
3
3
|
import { provideCardState } from '../composables/Card'
|
|
4
4
|
|
|
5
|
-
export type Size = 'small' | 'medium' | 'large'
|
|
5
|
+
export type Size = 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge'
|
|
6
6
|
export type Mode = 'neutral' | 'info' | 'success' | 'warning' | 'danger'
|
|
7
7
|
|
|
8
8
|
const props = defineProps<{
|
|
@@ -83,6 +83,20 @@ const classes = computed(() => [
|
|
|
83
83
|
max-width: 768px;
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
+
|
|
87
|
+
&.xlarge {
|
|
88
|
+
@media (min-width: 1056px) {
|
|
89
|
+
margin: 48px auto 128px;
|
|
90
|
+
max-width: 960px;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
&.xxlarge {
|
|
95
|
+
@media (min-width: 1248px) {
|
|
96
|
+
margin: 48px auto 128px;
|
|
97
|
+
max-width: 1152px;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
86
100
|
}
|
|
87
101
|
|
|
88
102
|
.SModal.fade-enter-from > .SCard,
|
|
@@ -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
|
}
|
|
@@ -36,7 +36,7 @@ defineEmits<{
|
|
|
36
36
|
<style lang="postcss" scoped>
|
|
37
37
|
.SInputDropdownItemAvatar {
|
|
38
38
|
display: flex;
|
|
39
|
-
border: 1px solid var(--c-divider
|
|
39
|
+
border: 1px solid var(--c-divider);
|
|
40
40
|
border-radius: 14px;
|
|
41
41
|
padding: 0 12px 0 0;
|
|
42
42
|
background-color: var(--c-bg-mute);
|
|
@@ -29,7 +29,7 @@ defineEmits<{
|
|
|
29
29
|
<style lang="postcss" scoped>
|
|
30
30
|
.SInputDropdownItemText {
|
|
31
31
|
display: flex;
|
|
32
|
-
border: 1px solid var(--c-divider
|
|
32
|
+
border: 1px solid var(--c-divider);
|
|
33
33
|
border-radius: 14px;
|
|
34
34
|
padding: 0 12px;
|
|
35
35
|
background-color: var(--c-bg-mute);
|
|
@@ -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
|
|
|
@@ -31,7 +31,7 @@ defineEmits<{
|
|
|
31
31
|
<style scoped lang="postcss">
|
|
32
32
|
.SSheet {
|
|
33
33
|
position: relative;
|
|
34
|
-
border: 1px solid var(--c-divider
|
|
34
|
+
border: 1px solid var(--c-divider);
|
|
35
35
|
border-radius: 16px;
|
|
36
36
|
background-color: var(--c-bg);
|
|
37
37
|
transition: opacity 0.25s, transform 0.25s;
|
package/lib/components/SStep.vue
CHANGED
|
@@ -92,7 +92,7 @@ defineProps({
|
|
|
92
92
|
height: 2px;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
.bar.mute { background-color: var(--c-divider
|
|
95
|
+
.bar.mute { background-color: var(--c-divider); }
|
|
96
96
|
.bar.active { background-color: var(--c-success); }
|
|
97
97
|
.bar.failed { background-color: var(--c-danger); }
|
|
98
98
|
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
watch
|
|
13
13
|
} from 'vue'
|
|
14
14
|
import { type Table } from '../composables/Table'
|
|
15
|
+
import { getTextWidth } from '../support/Text'
|
|
15
16
|
import SInputCheckbox from './SInputCheckbox.vue'
|
|
16
17
|
import SSpinner from './SSpinner.vue'
|
|
17
18
|
import STableCell from './STableCell.vue'
|
|
@@ -204,6 +205,52 @@ useResizeObserver(block, ([entry]) => {
|
|
|
204
205
|
|
|
205
206
|
const resizeObserver = useResizeObserver(head, handleResize)
|
|
206
207
|
|
|
208
|
+
const font = typeof document !== 'undefined'
|
|
209
|
+
? `500 12px ${getComputedStyle(document.body).fontFamily}`
|
|
210
|
+
: '500 12px Inter'
|
|
211
|
+
|
|
212
|
+
const actionsColumnWidth = computed(() => {
|
|
213
|
+
const { cell } = unref(props.options.columns).actions ?? {}
|
|
214
|
+
|
|
215
|
+
if (
|
|
216
|
+
typeof document === 'undefined'
|
|
217
|
+
|| !cell
|
|
218
|
+
|| typeof cell === 'function'
|
|
219
|
+
|| cell.type !== 'actions'
|
|
220
|
+
) {
|
|
221
|
+
return undefined
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const { actions } = cell
|
|
225
|
+
|
|
226
|
+
const widths = actions.map(({ icon, label }) => {
|
|
227
|
+
// has only icon
|
|
228
|
+
if (icon && !label) {
|
|
229
|
+
return 1 /* border */ + 5 /* padding */ + 16 /* icon */ + 5 /* padding */ + 1 /* border */
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// has only label
|
|
233
|
+
if (label && !icon) {
|
|
234
|
+
return 1 /* border */ + 12 /* padding */ + getTextWidth(label, font) + 12 /* padding */ + 1 /* border */
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// has both icon and label
|
|
238
|
+
if (icon && label) {
|
|
239
|
+
return 1 /* border */ + 8 /* padding */ + 16 /* icon */ + 4 /* padding */ + getTextWidth(label, font) + 10 /* padding */ + 1 /* border */
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return 0
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
return 8 /* padding */ + widths.reduce((a, b) => a + b, 0) + 8 /* padding */
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
watch(actionsColumnWidth, (newValue) => {
|
|
249
|
+
if (newValue) {
|
|
250
|
+
updateColWidth('actions', `${newValue}px`)
|
|
251
|
+
}
|
|
252
|
+
}, { immediate: true, flush: 'post' })
|
|
253
|
+
|
|
207
254
|
function stopObserving() {
|
|
208
255
|
const orders = ordersToShow.value
|
|
209
256
|
const lastOrder
|
|
@@ -496,7 +543,7 @@ function updateSelected(selected: unknown[]) {
|
|
|
496
543
|
|
|
497
544
|
:deep(.row) {
|
|
498
545
|
display: flex;
|
|
499
|
-
border-bottom: 1px solid var(--c-
|
|
546
|
+
border-bottom: 1px solid var(--c-gutter);
|
|
500
547
|
}
|
|
501
548
|
|
|
502
549
|
:deep(.row.last),
|
|
@@ -56,7 +56,7 @@ const hasNext = computed(() => {
|
|
|
56
56
|
|
|
57
57
|
<style scoped lang="postcss">
|
|
58
58
|
.STableFooter {
|
|
59
|
-
border-top: 1px solid var(--c-
|
|
59
|
+
border-top: 1px solid var(--c-gutter);
|
|
60
60
|
border-radius: 0 0 calc(var(--table-border-radius) - 1px) calc(var(--table-border-radius) - 1px);
|
|
61
61
|
padding-right: var(--table-padding-right);
|
|
62
62
|
padding-left: var(--table-padding-left);
|
|
@@ -26,10 +26,13 @@ const classes = computed(() => [
|
|
|
26
26
|
.STableItem {
|
|
27
27
|
position: var(--table-col-position, relative);
|
|
28
28
|
left: var(--table-col-left, 0);
|
|
29
|
+
right: var(--table-col-right, auto);
|
|
29
30
|
z-index: var(--table-col-z-index, auto);
|
|
30
31
|
flex-shrink: 0;
|
|
31
32
|
flex-grow: 1;
|
|
32
|
-
border-
|
|
33
|
+
border-left: var(--table-col-border-left, 0) solid var(--c-gutter);
|
|
34
|
+
border-right: 1px solid var(--c-gutter);
|
|
35
|
+
margin-left: calc(var(--table-col-border-left, 0) * -1);
|
|
33
36
|
min-width: var(--table-col-width);
|
|
34
37
|
max-width: var(--table-col-width);
|
|
35
38
|
|
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);
|
|
@@ -441,7 +443,7 @@
|
|
|
441
443
|
--button-fill-mute-active-border-color: var(--c-border-mute-3);
|
|
442
444
|
--button-fill-mute-active-text-color: var(--c-text-2);
|
|
443
445
|
--button-fill-mute-active-bg-color: var(--c-bg-mute-3);
|
|
444
|
-
--button-fill-mute-disabled-border-color: var(--c-
|
|
446
|
+
--button-fill-mute-disabled-border-color: var(--c-border-mute-1);
|
|
445
447
|
--button-fill-mute-disabled-text-color: var(--c-text-3);
|
|
446
448
|
--button-fill-mute-disabled-content-color: var(--c-text-3);
|
|
447
449
|
--button-fill-mute-disabled-bg-color: var(--c-bg-mute-1);
|
|
@@ -508,11 +510,11 @@
|
|
|
508
510
|
--button-fill-info-disabled-border-color: var(--c-border-info-1);
|
|
509
511
|
--button-fill-info-disabled-text-color: var(--c-white-a3);
|
|
510
512
|
--button-fill-info-disabled-content-color: var(--c-white-a3);
|
|
511
|
-
--button-fill-info-disabled-bg-color: var(--c-
|
|
513
|
+
--button-fill-info-disabled-bg-color: var(--c-blue-8);
|
|
512
514
|
|
|
513
515
|
--button-fill-success-border-color: var(--c-border-success-1);
|
|
514
516
|
--button-fill-success-text-color: var(--c-white-1);
|
|
515
|
-
--button-fill-success-content-color: var(--c-
|
|
517
|
+
--button-fill-success-content-color: var(--c-white-1);
|
|
516
518
|
--button-fill-success-bg-color: var(--c-bg-success-1);
|
|
517
519
|
--button-fill-success-loader-color: var(--c-white);
|
|
518
520
|
--button-fill-success-hover-border-color: var(--c-border-success-2);
|
|
@@ -524,7 +526,7 @@
|
|
|
524
526
|
--button-fill-success-disabled-border-color: var(--c-border-success-1);
|
|
525
527
|
--button-fill-success-disabled-text-color: var(--c-white-a3);
|
|
526
528
|
--button-fill-success-disabled-content-color: var(--c-white-a3);
|
|
527
|
-
--button-fill-success-disabled-bg-color: var(--c-
|
|
529
|
+
--button-fill-success-disabled-bg-color: var(--c-green-8);
|
|
528
530
|
|
|
529
531
|
--button-fill-warning-border-color: var(--c-border-mute-1);
|
|
530
532
|
--button-fill-warning-text-color: var(--c-text-warning-1);
|
|
@@ -826,7 +828,7 @@
|
|
|
826
828
|
* -------------------------------------------------------------------------- */
|
|
827
829
|
|
|
828
830
|
:root {
|
|
829
|
-
--table-border: 1px solid var(--c-divider
|
|
831
|
+
--table-border: 1px solid var(--c-divider);
|
|
830
832
|
--table-border-top: var(--table-border);
|
|
831
833
|
--table-border-right: var(--table-border);
|
|
832
834
|
--table-border-bottom: var(--table-border);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Adapted from https://stackoverflow.com/a/21015393/11613622
|
|
2
|
+
|
|
3
|
+
let _canvas: HTMLCanvasElement
|
|
4
|
+
|
|
5
|
+
export function getTextWidth(text: string, font: string): number
|
|
6
|
+
export function getTextWidth(text: string, el: HTMLElement): number
|
|
7
|
+
|
|
8
|
+
export function getTextWidth(text: string, fontOrEl: string | HTMLElement): number {
|
|
9
|
+
const canvas = _canvas || (_canvas = document.createElement('canvas'))
|
|
10
|
+
const context = canvas.getContext('2d')!
|
|
11
|
+
context.font = typeof fontOrEl === 'string' ? fontOrEl : getCanvasFont(fontOrEl)
|
|
12
|
+
const metrics = context.measureText(text)
|
|
13
|
+
|
|
14
|
+
return metrics.width
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getCanvasFont(el: HTMLElement) {
|
|
18
|
+
const {
|
|
19
|
+
fontWeight = 'normal',
|
|
20
|
+
fontSize = '16px',
|
|
21
|
+
fontFamily = 'Times New Roman'
|
|
22
|
+
} = getComputedStyle(el)
|
|
23
|
+
|
|
24
|
+
return `${fontWeight} ${fontSize} ${fontFamily}`
|
|
25
|
+
}
|
package/lib/types/shims.d.ts
CHANGED
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.5.0",
|
|
4
|
+
"packageManager": "pnpm@8.10.4",
|
|
5
5
|
"description": "Vue Components for Global Brain Design System.",
|
|
6
6
|
"author": "Kia Ishii <ka.ishii@globalbrains.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -20,6 +20,23 @@
|
|
|
20
20
|
"files": [
|
|
21
21
|
"lib"
|
|
22
22
|
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"docs": "vitepress dev docs --port 4000",
|
|
25
|
+
"docs:build": "vitepress build docs",
|
|
26
|
+
"docs:preview": "vitepress serve docs --port 3000",
|
|
27
|
+
"story": "histoire dev --port 3000",
|
|
28
|
+
"story:build": "histoire build",
|
|
29
|
+
"story:preview": "histoire preview --port 3000",
|
|
30
|
+
"type": "vue-tsc --noEmit",
|
|
31
|
+
"lint": "eslint --fix .",
|
|
32
|
+
"lint:fail": "eslint .",
|
|
33
|
+
"vitest": "vitest",
|
|
34
|
+
"vitest:run": "vitest run",
|
|
35
|
+
"coverage": "vitest run --coverage",
|
|
36
|
+
"test": "pnpm run type && pnpm run lint && pnpm run coverage",
|
|
37
|
+
"test:fail": "pnpm run type && pnpm run lint:fail && pnpm run coverage",
|
|
38
|
+
"release": "release-it"
|
|
39
|
+
},
|
|
23
40
|
"peerDependencies": {
|
|
24
41
|
"@iconify-icons/ph": "^1.2.5",
|
|
25
42
|
"@iconify/vue": "^4.1.1",
|
|
@@ -29,7 +46,7 @@
|
|
|
29
46
|
"@types/markdown-it": "^13.0.6",
|
|
30
47
|
"@vuelidate/core": "^2.0.3",
|
|
31
48
|
"@vuelidate/validators": "^2.0.4",
|
|
32
|
-
"@vueuse/core": "^10.6.
|
|
49
|
+
"@vueuse/core": "^10.6.1",
|
|
33
50
|
"body-scroll-lock": "4.0.0-beta.0",
|
|
34
51
|
"fuse.js": "^7.0.0",
|
|
35
52
|
"lodash-es": "^4.17.21",
|
|
@@ -47,9 +64,10 @@
|
|
|
47
64
|
},
|
|
48
65
|
"devDependencies": {
|
|
49
66
|
"@globalbrain/eslint-config": "^1.5.2",
|
|
50
|
-
"@histoire/plugin-vue": "^0.17.
|
|
67
|
+
"@histoire/plugin-vue": "^0.17.5",
|
|
51
68
|
"@iconify-icons/ph": "^1.2.5",
|
|
52
69
|
"@iconify/vue": "^4.1.1",
|
|
70
|
+
"@release-it/conventional-changelog": "^8.0.1",
|
|
53
71
|
"@tanstack/vue-virtual": "3.0.0-beta.62",
|
|
54
72
|
"@types/body-scroll-lock": "^3.1.2",
|
|
55
73
|
"@types/lodash-es": "^4.17.11",
|
|
@@ -60,23 +78,19 @@
|
|
|
60
78
|
"@vue/test-utils": "^2.4.1",
|
|
61
79
|
"@vuelidate/core": "^2.0.3",
|
|
62
80
|
"@vuelidate/validators": "^2.0.4",
|
|
63
|
-
"@vueuse/core": "^10.6.
|
|
81
|
+
"@vueuse/core": "^10.6.1",
|
|
64
82
|
"body-scroll-lock": "4.0.0-beta.0",
|
|
65
|
-
"chalk": "^4.1.2",
|
|
66
|
-
"conventional-changelog-cli": "^4.1.0",
|
|
67
|
-
"enquirer": "^2.4.1",
|
|
68
83
|
"eslint": "^8.53.0",
|
|
69
|
-
"execa": "^5.1.1",
|
|
70
84
|
"fuse.js": "^7.0.0",
|
|
71
85
|
"happy-dom": "^12.10.3",
|
|
72
|
-
"histoire": "^0.17.
|
|
86
|
+
"histoire": "^0.17.5",
|
|
73
87
|
"lodash-es": "^4.17.21",
|
|
74
88
|
"markdown-it": "^13.0.2",
|
|
75
89
|
"normalize.css": "^8.0.1",
|
|
76
90
|
"pinia": "^2.1.7",
|
|
77
91
|
"postcss": "^8.4.31",
|
|
78
92
|
"postcss-nested": "^6.0.1",
|
|
79
|
-
"
|
|
93
|
+
"release-it": "^17.0.0",
|
|
80
94
|
"typescript": "~5.2.2",
|
|
81
95
|
"v-calendar": "^3.1.2",
|
|
82
96
|
"vite": "^4.5.0",
|
|
@@ -85,22 +99,5 @@
|
|
|
85
99
|
"vue": "^3.3.8",
|
|
86
100
|
"vue-router": "^4.2.5",
|
|
87
101
|
"vue-tsc": "^1.8.22"
|
|
88
|
-
},
|
|
89
|
-
"scripts": {
|
|
90
|
-
"docs": "vitepress dev docs --port 4000",
|
|
91
|
-
"docs:build": "vitepress build docs",
|
|
92
|
-
"docs:preview": "vitepress serve docs --port 3000",
|
|
93
|
-
"story": "histoire dev --port 3000",
|
|
94
|
-
"story:build": "histoire build",
|
|
95
|
-
"story:preview": "histoire preview --port 3000",
|
|
96
|
-
"type": "vue-tsc --noEmit",
|
|
97
|
-
"lint": "eslint --fix .",
|
|
98
|
-
"lint:fail": "eslint .",
|
|
99
|
-
"vitest": "vitest",
|
|
100
|
-
"coverage": "vitest run --coverage",
|
|
101
|
-
"test": "pnpm run type && pnpm run lint && pnpm run coverage",
|
|
102
|
-
"test:fail": "pnpm run type && pnpm run lint:fail && pnpm run coverage",
|
|
103
|
-
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
|
104
|
-
"release": "node scripts/release.js"
|
|
105
102
|
}
|
|
106
|
-
}
|
|
103
|
+
}
|