@globalbrain/sefirot 4.25.0 → 4.26.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,30 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { provideDataListState } from '../composables/DataList'
4
+
5
+ const props = withDefaults(defineProps<{
6
+ labelWidth?: string
7
+ }>(), {
8
+ labelWidth: '128px'
9
+ })
10
+
11
+ provideDataListState({
12
+ labelWidth: computed(() => props.labelWidth)
13
+ })
14
+ </script>
15
+
16
+ <template>
17
+ <div class="SDataList">
18
+ <slot />
19
+ </div>
20
+ </template>
21
+
22
+ <style scoped lang="postcss">
23
+ .SDataList :deep(.SDataListItem::after),
24
+ .SDataList :deep(.SDataListItem:first-child::before) {
25
+ display: block;
26
+ border-top: 1px dashed var(--c-divider);
27
+ width: 100%;
28
+ content: "";
29
+ }
30
+ </style>
@@ -0,0 +1,137 @@
1
+ <script setup lang="ts">
2
+ import { Comment, Text, computed, useSlots } from 'vue'
3
+ import { useDataListState } from '../composables/DataList'
4
+
5
+ const props = withDefaults(defineProps<{
6
+ dir?: 'row' | 'column'
7
+ maxWidth?: string
8
+ align?: 'left' | 'right'
9
+ preWrap?: boolean
10
+ lineClamp?: string | number
11
+ tnum?: boolean
12
+ }>(), {
13
+ dir: 'row',
14
+ maxWidth: '100%'
15
+ })
16
+
17
+ const {
18
+ labelWidth
19
+ } = useDataListState()
20
+
21
+ const slots = useSlots()
22
+
23
+ const classes = computed(() => [
24
+ props.dir,
25
+ props.align,
26
+ { 'pre-wrap': props.preWrap },
27
+ { 'line-clamp': !!props.lineClamp },
28
+ { tnum: props.tnum }
29
+ ])
30
+
31
+ const labelStyles = computed(() => ({
32
+ width: props.dir === 'row' ? labelWidth.value : '100%'
33
+ }))
34
+
35
+ const valueStyles = computed(() => ({
36
+ 'max-width': props.maxWidth,
37
+ '-webkit-line-clamp': props.lineClamp
38
+ }))
39
+
40
+ const hasValue = computed(() => hasSlotContent('value'))
41
+
42
+ function hasSlotContent(name = 'default'): boolean {
43
+ return !!slots[name]?.().some((s) => {
44
+ if (s.type === Comment) {
45
+ return false
46
+ }
47
+ if (s.type === Text && typeof s.children === 'string') {
48
+ return !!s.children.trim()
49
+ }
50
+ return true
51
+ })
52
+ }
53
+ </script>
54
+
55
+ <template>
56
+ <div class="SDataListItem" :class="classes">
57
+ <div class="content">
58
+ <div class="label" :style="labelStyles">
59
+ <slot name="label" />
60
+ </div>
61
+ <div v-if="!hasValue" class="empty">
62
+
63
+ </div>
64
+ <div v-else-if="hasValue" class="value" :style="valueStyles">
65
+ <slot name="value" />
66
+ </div>
67
+ </div>
68
+ </div>
69
+ </template>
70
+
71
+ <style scoped lang="postcss">
72
+ .SDataListItem {
73
+ width: 100%;
74
+ max-width: 100%;
75
+ }
76
+
77
+ .content {
78
+ display: flex;
79
+ padding: 10px 0;
80
+ min-height: 48px;
81
+ }
82
+
83
+ .label {
84
+ flex-shrink: 0;
85
+ padding: 2px 0;
86
+ line-height: 24px;
87
+ font-size: 14px;
88
+ color: var(--c-text-2);
89
+ }
90
+
91
+ .empty {
92
+ flex-grow: 1;
93
+ padding: 2px 0;
94
+ line-height: 24px;
95
+ font-size: 14px;
96
+ color: var(--c-text-3);
97
+ }
98
+
99
+ .value {
100
+ flex-grow: 1;
101
+ padding: 2px 0;
102
+ line-height: 24px;
103
+ font-size: 14px;
104
+ color: var(--c-text-1);
105
+ }
106
+
107
+ .SDataListItem.row .content {
108
+ flex-direction: row;
109
+ }
110
+
111
+ .SDataListItem.column .content {
112
+ flex-direction: column;
113
+ }
114
+
115
+ .SDataListItem.left .value {
116
+ text-align: left;
117
+ }
118
+
119
+ .SDataListItem.right .value {
120
+ text-align: right;
121
+ }
122
+
123
+ .SDataListItem.pre-wrap .value {
124
+ white-space: pre-wrap;
125
+ }
126
+
127
+ .SDataListItem.line-clamp .value {
128
+ display: -webkit-box;
129
+ -webkit-box-orient: vertical;
130
+ text-overflow: ellipsis;
131
+ overflow: hidden;
132
+ }
133
+
134
+ .SDataListItem.tnum .value {
135
+ font-feature-settings: "tnum";
136
+ }
137
+ </style>
@@ -141,6 +141,7 @@ function handleArray(value: OptionValue) {
141
141
  :check-text
142
142
  :check-color
143
143
  :validation
144
+ :hide-error
144
145
  >
145
146
  <div class="container" ref="container">
146
147
  <div
@@ -61,6 +61,7 @@ function onSelect(value: T) {
61
61
  <SInputBase
62
62
  class="SInputSegments"
63
63
  :class="[size ?? 'small', { block }]"
64
+ :size
64
65
  :label
65
66
  :note
66
67
  :info
@@ -61,6 +61,13 @@ const cellOfColToGrow = computed(() => {
61
61
  const colWidths = reactive<Record<string, string>>({})
62
62
  const blockWidth = ref<number | undefined>()
63
63
 
64
+ watch(() => unref(props.options.columns), (columns) => {
65
+ Object.keys(columns).forEach((key) => {
66
+ const width = columns[key]?.width
67
+ if (width) { colWidths[key] = width }
68
+ })
69
+ }, { immediate: true, deep: true, flush: 'pre' })
70
+
64
71
  const showHeader = computed(() => {
65
72
  const header = unref(props.options.header)
66
73
 
@@ -355,7 +362,7 @@ function removeSelected(item: any) {
355
362
 
356
363
  function getColWidth(key: string) {
357
364
  if (key === '__select') {
358
- return '48px + var(--table-padding-left, 0)'
365
+ return '48px + var(--table-padding-left)'
359
366
  }
360
367
  const adjustedWidth = colWidths[key]
361
368
  if (adjustedWidth && adjustedWidth !== 'auto') {
@@ -631,7 +638,7 @@ function getStyles(key: string) {
631
638
  }
632
639
 
633
640
  .STable .col-__select {
634
- --table-col-width: calc(48px + var(--table-padding-left, 0));
641
+ --table-col-width: calc(48px + var(--table-padding-left));
635
642
 
636
643
  :deep(.input) {
637
644
  align-items: center;
@@ -25,14 +25,14 @@ const classes = computed(() => [
25
25
  <style scoped lang="postcss">
26
26
  .STableItem {
27
27
  position: var(--table-col-position, relative);
28
- left: var(--table-col-left, 0);
28
+ left: var(--table-col-left, 0px);
29
29
  right: var(--table-col-right, auto);
30
30
  z-index: var(--table-col-z-index, auto);
31
31
  flex-shrink: 0;
32
32
  flex-grow: 1;
33
- border-left: var(--table-col-border-left, 0) solid var(--c-gutter);
33
+ border-left: var(--table-col-border-left, 0px) solid var(--c-gutter);
34
34
  border-right: 1px solid var(--c-gutter);
35
- margin-left: calc(var(--table-col-border-left, 0) * -1);
35
+ margin-left: calc(var(--table-col-border-left, 0px) * -1);
36
36
  min-width: var(--table-col-width);
37
37
  max-width: var(--table-col-width);
38
38
 
@@ -0,0 +1,23 @@
1
+ import { type ComputedRef, inject, provide } from 'vue'
2
+
3
+ export interface DataListState {
4
+ labelWidth: ComputedRef<string>
5
+ }
6
+
7
+ export const DataListStateKey = 'sefirot-data-list-state-key'
8
+
9
+ export function provideDataListState(state: DataListState): void {
10
+ provide(DataListStateKey, state)
11
+ }
12
+
13
+ export function useDataListState(): DataListState {
14
+ const state = inject<DataListState | null>(DataListStateKey, null) || null
15
+ if (!state) {
16
+ throw new Error(
17
+ 'Unexpected call to `useDataListState`. This probably means you are using'
18
+ + '`<DDataList>` child component outside of `<DDataList>`. Make sure'
19
+ + ' to wrap the component within `<DDataList>` component.'
20
+ )
21
+ }
22
+ return state
23
+ }
@@ -45,6 +45,7 @@ export interface TableColumn<V, R, SV, SR> {
45
45
  className?: string
46
46
  dropdown?: DropdownSection[]
47
47
  freeze?: boolean
48
+ width?: string
48
49
  grow?: boolean
49
50
  resizable?: boolean
50
51
  cell?: TableCell<V, R> | TableColumnCellFn<V, R>
@@ -0,0 +1,15 @@
1
+ import { type App } from 'vue'
2
+ import SDataList from '../components/SDataList.vue'
3
+ import SDataListItem from '../components/SDataListItem.vue'
4
+
5
+ export function mixin(app: App): void {
6
+ app.component('SDataList', SDataList)
7
+ app.component('SDataListItem', SDataListItem)
8
+ }
9
+
10
+ declare module 'vue' {
11
+ export interface GlobalComponents {
12
+ SDataList: typeof SDataList
13
+ SDataListItem: typeof SDataListItem
14
+ }
15
+ }
@@ -6,6 +6,7 @@ import SModal from '../components/SModal.vue'
6
6
  import STrans from '../components/STrans.vue'
7
7
  import { mixin as mixinCard } from './Card'
8
8
  import { mixin as mixinControl } from './Control'
9
+ import { mixin as mixinDataList } from './DataList'
9
10
  import { mixin as mixinDesc } from './Desc'
10
11
  import { mixin as mixinDoc } from './Doc'
11
12
  import { mixin as mixinGrid } from './Grid'
@@ -14,6 +15,7 @@ import { mixin as mixinHead } from './Head'
14
15
  export function mixin(app: App): void {
15
16
  mixinCard(app)
16
17
  mixinControl(app)
18
+ mixinDataList(app)
17
19
  mixinDesc(app)
18
20
  mixinDoc(app)
19
21
  mixinGrid(app)
@@ -871,8 +871,8 @@
871
871
  --table-border-left: var(--table-border);
872
872
  --table-border-radius: 6px;
873
873
 
874
- --table-padding-right: 0;
875
- --table-padding-left: 0;
874
+ --table-padding-right: 0px;
875
+ --table-padding-left: 0px;
876
876
 
877
877
  --table-cell-font-size: 14px;
878
878
  --table-cell-font-weight: 400;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@globalbrain/sefirot",
3
3
  "type": "module",
4
- "version": "4.25.0",
4
+ "version": "4.26.0",
5
5
  "packageManager": "pnpm@9.15.4",
6
6
  "description": "Vue Components for Global Brain Design System.",
7
7
  "author": "Kia Ishii <ka.ishii@globalbrains.com>",