@globalbrain/sefirot 2.48.0 → 2.49.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.
@@ -0,0 +1,132 @@
1
+ <script setup lang="ts" generic="T extends string | number | boolean">
2
+ import { type IconifyIcon } from '@iconify/vue/dist/offline'
3
+ import { computed } from 'vue'
4
+ import { type Validatable } from '../composables/Validation'
5
+ import SInputBase from './SInputBase.vue'
6
+ import SInputSegmentsOption, { type Mode } from './SInputSegmentsOption.vue'
7
+
8
+ export type Size = 'mini' | 'small' | 'medium'
9
+ export type Color = 'neutral' | 'mute' | 'info' | 'success' | 'warning' | 'danger'
10
+
11
+ export interface Option<T extends string | number | boolean> {
12
+ label: string
13
+ value: T
14
+ mode?: Mode
15
+ disabled?: boolean
16
+ }
17
+
18
+ const props = defineProps<{
19
+ size?: Size
20
+ name?: string
21
+ label?: string
22
+ info?: string
23
+ note?: string
24
+ help?: string
25
+ checkIcon?: IconifyIcon
26
+ checkText?: string
27
+ checkColor?: Color
28
+ options: Option<T>[]
29
+ block?: boolean
30
+ disabled?: boolean
31
+ value?: T
32
+ modelValue?: T
33
+ validation?: Validatable
34
+ hideError?: boolean
35
+ }>()
36
+
37
+ const emit = defineEmits<{
38
+ (e: 'update:model-value', value: T): void
39
+ (e: 'change', value: T): void
40
+ }>()
41
+
42
+ const _value = computed(() => {
43
+ const v = props.modelValue !== undefined
44
+ ? props.modelValue
45
+ : props.value
46
+
47
+ if (v === undefined) {
48
+ throw new Error('[sefirot] SInputSegments: `value` or `modelValue` is required.')
49
+ }
50
+
51
+ return v
52
+ })
53
+
54
+ function onSelect(value: T) {
55
+ emit('update:model-value', value)
56
+ emit('change', value)
57
+ }
58
+ </script>
59
+
60
+ <template>
61
+ <SInputBase
62
+ class="SInputSegments"
63
+ :class="[size ?? 'small', { block }]"
64
+ :label="label"
65
+ :note="note"
66
+ :info="info"
67
+ :help="help"
68
+ :check-icon="checkIcon"
69
+ :check-text="checkText"
70
+ :check-color="checkColor"
71
+ :hide-error="hideError"
72
+ :validation="validation"
73
+ >
74
+ <div class="box">
75
+ <SInputSegmentsOption
76
+ v-for="option, index in options"
77
+ :key="index"
78
+ :size="size ?? 'small'"
79
+ :label="option.label"
80
+ :value="option.value"
81
+ :mode="option.mode ?? 'neutral'"
82
+ :active="_value === option.value"
83
+ :disabled="disabled ? true : option.disabled ?? false"
84
+ @click="onSelect(option.value)"
85
+ />
86
+ </div>
87
+ <template v-if="$slots.info" #info><slot name="info" /></template>
88
+ </SInputBase>
89
+ </template>
90
+
91
+ <style scoped lang="postcss">
92
+ .SInputSegments.mini {
93
+ .box {
94
+ padding: 2px;
95
+ height: 32px;
96
+ }
97
+ }
98
+
99
+ .SInputSegments.small {
100
+ .box {
101
+ padding: 4px;
102
+ height: 40px;
103
+ }
104
+ }
105
+
106
+ .SInputSegments.medium {
107
+ .box {
108
+ padding: 4px;
109
+ height: 48px;
110
+ }
111
+ }
112
+
113
+ .SInputSegments.block {
114
+ .box {
115
+ display: flex;
116
+ }
117
+ }
118
+
119
+ .SInputSegments.has-error {
120
+ .box {
121
+ border-color: var(--input-error-border-color);
122
+ }
123
+ }
124
+
125
+ .box {
126
+ display: inline-flex;
127
+ border: 1px solid var(--input-border-color);
128
+ border-radius: 6px;
129
+ background-color: var(--input-bg-color);
130
+ transition: border-color 0.25s;
131
+ }
132
+ </style>
@@ -0,0 +1,150 @@
1
+ <script setup lang="ts" generic="T extends string | number | boolean">
2
+ export type Size = 'mini' | 'small' | 'medium'
3
+ export type Mode = 'neutral' | 'mute' | 'info' | 'success' | 'warning' | 'danger'
4
+
5
+ const props = defineProps<{
6
+ size: Size
7
+ label: string
8
+ value: T
9
+ mode: Mode
10
+ active: boolean
11
+ disabled: boolean
12
+ }>()
13
+
14
+ const emit = defineEmits<{
15
+ (e: 'click'): void
16
+ }>()
17
+
18
+ function onClick() {
19
+ if (!props.disabled) {
20
+ emit('click')
21
+ }
22
+ }
23
+ </script>
24
+
25
+ <template>
26
+ <button
27
+ class="SInputSegmentsOption"
28
+ :class="[size, mode, { active }, { disabled }]"
29
+ @click="onClick"
30
+ >
31
+ <span class="label">
32
+ {{ label }}
33
+ </span>
34
+ </button>
35
+ </template>
36
+
37
+ <style scoped lang="postcss">
38
+ .SInputSegmentsOption {
39
+ position: relative;
40
+ display: block;
41
+ flex-grow: 1;
42
+ justify-content: center;
43
+ align-items: center;
44
+ border: 1px solid transparent;
45
+ border-radius: 3px;
46
+ width: 100%;
47
+ height: 100%;
48
+ text-align: center;
49
+ font-size: 14px;
50
+ color: var(--c-text-2);
51
+ white-space: nowrap;
52
+ transition: border-color 0.25s, color 0.25s, background-color 0.25s;
53
+
54
+ &:hover {
55
+ color: var(--c-text-1);
56
+ }
57
+
58
+ &.disabled {
59
+ color: var(--c-text-3);
60
+ cursor: not-allowed;
61
+ }
62
+
63
+ .SInputSegmentsOption + &::before {
64
+ position: absolute;
65
+ left: -1px;
66
+ display: block;
67
+ width: 1px;
68
+ height: 16px;
69
+ border-radius: 4px;
70
+ background-color: var(--c-divider-2);
71
+ content: "";
72
+ transition: opacity 0.25s;
73
+ }
74
+
75
+ .SInputSegmentsOption.active + &::before,
76
+ &.active::before {
77
+ opacity: 0;
78
+ }
79
+ }
80
+
81
+ .SInputSegmentsOption.mini {
82
+ .SInputSegmentsOption + &::before {
83
+ top: 4px;
84
+ }
85
+
86
+ .label {
87
+ padding: 0 12px;
88
+ }
89
+ }
90
+
91
+ .SInputSegmentsOption.small {
92
+ .SInputSegmentsOption + &::before {
93
+ top: 7px;
94
+ }
95
+
96
+ .label {
97
+ padding: 0 12px;
98
+ }
99
+ }
100
+
101
+ .SInputSegmentsOption.medium {
102
+ .SInputSegmentsOption + &::before {
103
+ top: 10px;
104
+ }
105
+
106
+ .label {
107
+ padding: 0 16px;
108
+ }
109
+ }
110
+
111
+ .SInputSegmentsOption.neutral.active {
112
+ border-color: var(--button-fill-mute-border-color);
113
+ color: var(--button-fill-mute-text-color);
114
+ background-color: var(--button-fill-mute-bg-color);
115
+ }
116
+
117
+ .SInputSegmentsOption.mute.active {
118
+ border-color: var(--button-fill-mute-border-color);
119
+ color: var(--c-text-2);
120
+ background-color: var(--button-fill-mute-bg-color);
121
+ }
122
+
123
+ .SInputSegmentsOption.info.active {
124
+ border-color: var(--button-fill-info-border-color);
125
+ color: var(--button-fill-info-text-color);
126
+ background-color: var(--button-fill-info-bg-color);
127
+ }
128
+
129
+ .SInputSegmentsOption.success.active {
130
+ border-color: var(--button-fill-success-border-color);
131
+ color: var(--button-fill-success-text-color);
132
+ background-color: var(--button-fill-success-bg-color);
133
+ }
134
+
135
+ .SInputSegmentsOption.warning.active {
136
+ border-color: var(--button-fill-warning-border-color);
137
+ color: var(--button-fill-warning-text-color);
138
+ background-color: var(--button-fill-warning-bg-color);
139
+ }
140
+
141
+ .SInputSegmentsOption.danger.active {
142
+ border-color: var(--button-fill-danger-border-color);
143
+ color: var(--button-fill-danger-text-color);
144
+ background-color: var(--button-fill-danger-bg-color);
145
+ }
146
+
147
+ .label {
148
+ display: inline-block;
149
+ }
150
+ </style>
@@ -33,7 +33,7 @@ const names = computed(() => {
33
33
  return `${_avatars.value[0].name}, ${_avatars.value[1].name}`
34
34
  }
35
35
 
36
- return `${_avatars.value[0].name}, ${_avatars.value[1].name} +${_avatars.value.length - 1}`
36
+ return `${_avatars.value[0].name}, ${_avatars.value[1].name} +${_avatars.value.length - 2}`
37
37
  })
38
38
  </script>
39
39
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@globalbrain/sefirot",
3
- "version": "2.48.0",
3
+ "version": "2.49.0",
4
4
  "packageManager": "pnpm@8.8.0",
5
5
  "description": "Vue Components for Global Brain Design System.",
6
6
  "author": "Kia Ishii <ka.ishii@globalbrains.com>",