@globalbrain/sefirot 2.43.0 → 2.45.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,14 +1,28 @@
1
1
  <script setup lang="ts">
2
+ import { provide } from 'vue'
2
3
  import SGrid from './SGrid.vue'
3
4
 
4
- defineProps<{
5
+ const props = withDefaults(defineProps<{
5
6
  cols?: string | number
6
7
  gap?: string | number
7
- }>()
8
+ dir?: 'column' | 'row'
9
+ labelWidth?: string | number
10
+ divider?: boolean
11
+ }>(), {
12
+ dir: 'column',
13
+ divider: true
14
+ })
15
+
16
+ provide('sefirot-desc-label-wdith', () => props.labelWidth)
8
17
  </script>
9
18
 
10
19
  <template>
11
- <SGrid class="SDesc" :cols="cols" :gap="gap">
20
+ <SGrid
21
+ class="SDesc"
22
+ :class="[dir, { divider }]"
23
+ :cols="cols"
24
+ :gap="gap"
25
+ >
12
26
  <slot />
13
27
  </SGrid>
14
28
  </template>
@@ -34,11 +34,6 @@ const _value = computed(() => {
34
34
  </template>
35
35
 
36
36
  <style scoped lang="postcss">
37
- .SDescDay {
38
- border-bottom: 1px dashed var(--c-divider-1);
39
- padding-bottom: 7px;
40
- }
41
-
42
37
  .value {
43
38
  line-height: 24px;
44
39
  font-size: 14px;
@@ -5,11 +5,6 @@
5
5
  </template>
6
6
 
7
7
  <style scoped lang="postcss">
8
- .SDescEmpty {
9
- border-bottom: 1px dashed var(--c-divider-1);
10
- padding-bottom: 7px;
11
- }
12
-
13
8
  .value {
14
9
  line-height: 24px;
15
10
  font-size: 14px;
@@ -1,9 +1,17 @@
1
1
  <script setup lang="ts">
2
+ import { computed, inject } from 'vue'
2
3
  import SGridItem from './SGridItem.vue'
3
4
 
4
5
  defineProps<{
5
6
  span?: string | number
6
7
  }>()
8
+
9
+ const labelWidthProp = inject<() => string | number | undefined>('sefirot-desc-label-wdith')
10
+
11
+ const labelWidth = computed(() => {
12
+ const w = labelWidthProp?.()
13
+ return w ? `${w}px` : '1fr'
14
+ })
7
15
  </script>
8
16
 
9
17
  <template>
@@ -11,3 +19,18 @@ defineProps<{
11
19
  <slot />
12
20
  </SGridItem>
13
21
  </template>
22
+
23
+ <style scoped lang="postcss">
24
+ .SDescItem {
25
+ display: grid;
26
+ }
27
+
28
+ .SDesc.row > .SDescItem {
29
+ grid-template-columns: var(--desc-label-width, v-bind(labelWidth)) 1fr;
30
+ }
31
+
32
+ .SDesc.divider > .SDescItem {
33
+ border-bottom: 1px dashed var(--c-divider-1);
34
+ padding-bottom: 7px;
35
+ }
36
+ </style>
@@ -33,11 +33,6 @@ const link = computed(() => {
33
33
  </template>
34
34
 
35
35
  <style scoped lang="postcss">
36
- .SDescLink {
37
- border-bottom: 1px dashed var(--c-divider-1);
38
- padding-bottom: 7px;
39
- }
40
-
41
36
  .value {
42
37
  display: block;
43
38
  line-height: 24px;
@@ -34,11 +34,6 @@ const _value = computed(() => {
34
34
  </template>
35
35
 
36
36
  <style scoped lang="postcss">
37
- .SDescNumber {
38
- border-bottom: 1px dashed var(--c-divider-1);
39
- padding-bottom: 7px;
40
- }
41
-
42
37
  .value {
43
38
  line-height: 24px;
44
39
  font-size: 14px;
@@ -32,11 +32,6 @@ const pills = computed(() => {
32
32
  </template>
33
33
 
34
34
  <style scoped lang="postcss">
35
- .SDescPill {
36
- border-bottom: 1px dashed var(--c-divider-1);
37
- padding-bottom: 7px;
38
- }
39
-
40
35
  .value {
41
36
  display: flex;
42
37
  gap: 4px 6px;
@@ -22,11 +22,6 @@ defineProps<{
22
22
  </template>
23
23
 
24
24
  <style scoped lang="postcss">
25
- .SDescState {
26
- border-bottom: 1px dashed var(--c-divider-1);
27
- padding-bottom: 7px;
28
- }
29
-
30
25
  .value {
31
26
  display: flex;
32
27
  align-items: center;
@@ -30,11 +30,6 @@ const lineClamp = computed(() => props.lineClamp ?? 'none')
30
30
  </template>
31
31
 
32
32
  <style scoped lang="postcss">
33
- .SDescText {
34
- border-bottom: 1px dashed var(--c-divider-1);
35
- padding-bottom: 7px;
36
- }
37
-
38
33
  .value {
39
34
  line-height: 24px;
40
35
  font-size: 14px;
@@ -1,6 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import { type IconifyIcon } from '@iconify/vue/dist/offline'
3
3
  import IconCheck from '@iconify-icons/ph/check-bold'
4
+ import IconMinus from '@iconify-icons/ph/minus-bold'
4
5
  import { computed } from 'vue'
5
6
  import { type Validatable } from '../composables/Validation'
6
7
  import SIcon from './SIcon.vue'
@@ -19,8 +20,9 @@ const props = withDefaults(defineProps<{
19
20
  checkText?: string
20
21
  checkColor?: Color
21
22
  text?: string
22
- value?: boolean
23
- modelValue?: boolean
23
+ disabled?: boolean
24
+ value?: boolean | 'indeterminate'
25
+ modelValue?: boolean | 'indeterminate'
24
26
  validation?: Validatable
25
27
  hideError?: boolean
26
28
  }>(), {
@@ -33,22 +35,33 @@ const emit = defineEmits<{
33
35
  (e: 'change', value: boolean): void
34
36
  }>()
35
37
 
38
+ const classes = computed(() => [
39
+ props.size ?? 'small',
40
+ { disabled: props.disabled }
41
+ ])
42
+
43
+ const isIndeterminate = computed(() => {
44
+ return props.modelValue === 'indeterminate' || props.value === 'indeterminate'
45
+ })
46
+
36
47
  const _value = computed(() => {
37
48
  return props.modelValue !== undefined
38
- ? props.modelValue
39
- : props.value !== undefined ? props.value : false
49
+ ? props.modelValue === true
50
+ : props.value !== undefined ? props.value === true : false
40
51
  })
41
52
 
42
53
  function onClick() {
43
- emit('update:model-value', !_value.value)
44
- emit('change', !_value.value)
54
+ if (!props.disabled) {
55
+ emit('update:model-value', !_value.value)
56
+ emit('change', !_value.value)
57
+ }
45
58
  }
46
59
  </script>
47
60
 
48
61
  <template>
49
62
  <SInputBase
50
63
  class="SInputCheckbox"
51
- :class="[size ?? 'small']"
64
+ :class="classes"
52
65
  :label="label"
53
66
  :note="note"
54
67
  :info="info"
@@ -59,10 +72,19 @@ function onClick() {
59
72
  :validation="validation"
60
73
  >
61
74
  <div class="container">
62
- <div class="input" :class="{ on: _value }" role="button" @click="onClick">
75
+ <div
76
+ class="input"
77
+ :class="{ on: _value || isIndeterminate }"
78
+ role="button"
79
+ @click="onClick"
80
+ :aria-disabled="disabled"
81
+ >
63
82
  <div class="box">
64
83
  <div class="check">
65
- <SIcon :icon="IconCheck" class="check-icon" />
84
+ <SIcon
85
+ :icon="isIndeterminate ? IconMinus : IconCheck"
86
+ class="check-icon"
87
+ />
66
88
  </div>
67
89
  </div>
68
90
 
@@ -139,4 +161,16 @@ function onClick() {
139
161
  font-size: 14px;
140
162
  font-weight: 400;
141
163
  }
164
+
165
+ .SInputCheckbox.disabled {
166
+ .box {
167
+ border-color: var(--input-disabled-border-color);
168
+ background-color: var(--input-disabled-bg-color);
169
+
170
+ &:hover { border-color: var(--input-disabled-border-color); }
171
+ &:focus:not(:focus-visible) { border-color: var(--input-disabled-border-color); }
172
+ }
173
+
174
+ .input { cursor: not-allowed; }
175
+ }
142
176
  </style>
@@ -13,6 +13,7 @@ export type Value = string | number | boolean
13
13
  export interface Option {
14
14
  label: string
15
15
  value: Value
16
+ disabled?: boolean
16
17
  }
17
18
 
18
19
  const props = withDefaults(defineProps<{
@@ -27,6 +28,7 @@ const props = withDefaults(defineProps<{
27
28
  checkColor?: Color
28
29
  options: Option[]
29
30
  nullable?: boolean
31
+ disabled?: boolean
30
32
  value?: Value[]
31
33
  modelValue?: Value[]
32
34
  validation?: Validatable
@@ -82,6 +84,7 @@ function handleChange(value: Value): void {
82
84
  <div v-for="option in options" :key="String(option.value)" class="col">
83
85
  <SInputCheckbox
84
86
  :text="option.label"
87
+ :disabled="option.disabled ?? disabled"
85
88
  :model-value="isChecked(option.value)"
86
89
  @update:model-value="handleChange(option.value)"
87
90
  />
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { type IconifyIcon } from '@iconify/vue/dist/offline'
3
- import { type DefineComponent } from 'vue'
3
+ import { type DefineComponent, computed } from 'vue'
4
4
  import { type Validatable } from '../composables/Validation'
5
5
  import SInputBase from './SInputBase.vue'
6
6
 
@@ -18,6 +18,7 @@ const props = defineProps<{
18
18
  checkText?: string
19
19
  checkColor?: Color
20
20
  text: string
21
+ disabled?: boolean
21
22
  modelValue: boolean
22
23
  validation?: Validatable
23
24
  hideError?: boolean
@@ -28,16 +29,23 @@ const emit = defineEmits<{
28
29
  (e: 'change', value: boolean): void
29
30
  }>()
30
31
 
32
+ const classes = computed(() => [
33
+ props.size ?? 'small',
34
+ { disabled: props.disabled }
35
+ ])
36
+
31
37
  function onClick() {
32
- emit('update:model-value', !props.modelValue)
33
- emit('change', !props.modelValue)
38
+ if (!props.disabled) {
39
+ emit('update:model-value', !props.modelValue)
40
+ emit('change', !props.modelValue)
41
+ }
34
42
  }
35
43
  </script>
36
44
 
37
45
  <template>
38
46
  <SInputBase
39
47
  class="SInputRadio"
40
- :class="[size ?? 'small']"
48
+ :class="classes"
41
49
  :label="label"
42
50
  :note="note"
43
51
  :info="info"
@@ -49,7 +57,13 @@ function onClick() {
49
57
  :hide-error="hideError"
50
58
  >
51
59
  <div class="container">
52
- <div class="input" :class="{ on: props.modelValue }" role="button" @click="onClick">
60
+ <div
61
+ class="input"
62
+ :class="{ on: props.modelValue }"
63
+ role="button"
64
+ @click="onClick"
65
+ :aria-disabled="disabled"
66
+ >
53
67
  <div class="box">
54
68
  <div class="check" />
55
69
  </div>
@@ -125,4 +139,16 @@ function onClick() {
125
139
  font-size: 14px;
126
140
  font-weight: 400;
127
141
  }
142
+
143
+ .SInputRadio.disabled {
144
+ .box {
145
+ border-color: var(--input-disabled-border-color);
146
+ background-color: var(--input-disabled-bg-color);
147
+
148
+ &:hover { border-color: var(--input-disabled-border-color); }
149
+ &:focus:not(:focus-visible) { border-color: var(--input-disabled-border-color); }
150
+ }
151
+
152
+ .input { cursor: not-allowed; }
153
+ }
128
154
  </style>
@@ -12,6 +12,7 @@ export type Color = 'neutral' | 'mute' | 'info' | 'success' | 'warning' | 'dange
12
12
  export interface Option {
13
13
  label: string
14
14
  value: string | number | boolean
15
+ disabled?: boolean
15
16
  }
16
17
 
17
18
  const props = withDefaults(defineProps<{
@@ -26,6 +27,7 @@ const props = withDefaults(defineProps<{
26
27
  checkColor?: Color
27
28
  options: Option[]
28
29
  nullable?: boolean
30
+ disabled?: boolean
29
31
  value?: string | number | boolean | null
30
32
  modelValue?: string | number | boolean | null
31
33
  validation?: Validatable
@@ -92,6 +94,7 @@ function onChange(value: string | number | boolean) {
92
94
  <div v-for="(option, index) in options" :key="index" class="col">
93
95
  <SInputRadio
94
96
  :text="option.label"
97
+ :disabled="option.disabled ?? disabled"
95
98
  :model-value="isChecked(option.value)"
96
99
  @update:model-value="onUpdate(option.value)"
97
100
  @change="onChange(option.value)"
@@ -277,6 +277,9 @@ function createRequiredTouched(): boolean[] {
277
277
  .container {
278
278
  background-color: var(--input-disabled-bg-color);
279
279
  }
280
+
281
+ .container:hover { border-color: var(--input-border-color); }
282
+ .container.focus { border-color: var(--input-border-color); }
280
283
  }
281
284
 
282
285
  .SInputYMD.has-error {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@globalbrain/sefirot",
3
- "version": "2.43.0",
3
+ "version": "2.45.0",
4
4
  "packageManager": "pnpm@8.6.2",
5
5
  "description": "Vue Components for Global Brain Design System.",
6
6
  "author": "Kia Ishii <ka.ishii@globalbrains.com>",