@pgcorp/ui-kit 0.4.0 → 0.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 +21 -0
- package/package.json +1 -1
- package/src/components/shared/_internal/SHeaderSurface.css +98 -0
- package/src/components/shared/_internal/SHeaderSurface.vue +80 -0
- package/src/components/shared/_internal/useRadioGroup.ts +106 -0
- package/src/components/shared/containers/SPageHeader.vue +13 -20
- package/src/components/shared/controls/SCheckbox.vue +14 -43
- package/src/components/shared/controls/SChoiceCards.vue +16 -39
- package/src/components/shared/controls/SField.css +0 -12
- package/src/components/shared/controls/SField.vue +14 -10
- package/src/components/shared/controls/SFieldGroup.css +1 -19
- package/src/components/shared/controls/SFieldGroup.vue +13 -10
- package/src/components/shared/controls/SFieldLabel.css +0 -1
- package/src/components/shared/controls/SFieldLabel.vue +2 -1
- package/src/components/shared/controls/SSegmentedControl.vue +15 -43
- package/src/components/shared/controls/SSwitch.vue +14 -32
- package/src/components/shared/data-display/SBadge.vue +41 -18
- package/src/components/shared/data-display/SChip.vue +22 -10
- package/src/components/shared/data-display/SSectionHeader.vue +17 -21
- package/src/components/shared/data-display/STable.vue +131 -18
- package/src/components/shared/data-display/table.ts +1 -0
- package/src/components/shared/database/SDataGrid.vue +13 -0
- package/src/internal/fieldPresentation.ts +28 -0
- package/src/internal/pillSurface.ts +92 -0
- package/src/internal/useBinaryInput.ts +76 -0
- package/src/styles/style.css +114 -0
- package/src/styles/tokens.css +31 -0
- package/src/components/shared/containers/SPageHeader.css +0 -82
- package/src/components/shared/data-display/SBadge.css +0 -73
- package/src/components/shared/data-display/SChip.css +0 -59
- package/src/components/shared/data-display/SSectionHeader.css +0 -84
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
>
|
|
15
15
|
<legend :id="labelId" class="s-field-group__legend">
|
|
16
16
|
<slot name="label">{{ validatedLabel }}</slot>
|
|
17
|
-
<span v-if="required" class="s-field-group__required" aria-hidden="true">*</span>
|
|
17
|
+
<span v-if="required" :class="['s-field-group__required', FIELD_REQUIRED_CLASS]" aria-hidden="true">*</span>
|
|
18
18
|
</legend>
|
|
19
19
|
|
|
20
20
|
<div class="s-field-group__controls">
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
/>
|
|
30
30
|
</div>
|
|
31
31
|
|
|
32
|
-
<p v-if="helpText || $slots.help" :id="helpId" class="s-field-group__help">
|
|
32
|
+
<p v-if="helpText || $slots.help" :id="helpId" :class="['s-field-group__help', FIELD_HELP_CLASS]">
|
|
33
33
|
<slot name="help">{{ helpText }}</slot>
|
|
34
34
|
</p>
|
|
35
|
-
<p v-if="invalid && (errorMessage || $slots.error)" :id="errorId" class="s-field-group__error">
|
|
35
|
+
<p v-if="invalid && (errorMessage || $slots.error)" :id="errorId" :class="['s-field-group__error', FIELD_ERROR_CLASS]">
|
|
36
36
|
<slot name="error">{{ errorMessage }}</slot>
|
|
37
37
|
</p>
|
|
38
38
|
</fieldset>
|
|
@@ -40,6 +40,12 @@
|
|
|
40
40
|
|
|
41
41
|
<script setup lang="ts">
|
|
42
42
|
import { computed, useId, useSlots } from 'vue'
|
|
43
|
+
import {
|
|
44
|
+
FIELD_ERROR_CLASS,
|
|
45
|
+
FIELD_HELP_CLASS,
|
|
46
|
+
FIELD_REQUIRED_CLASS,
|
|
47
|
+
useFieldSupportingText,
|
|
48
|
+
} from '../../../internal/fieldPresentation'
|
|
43
49
|
import { mergeIdReferences, useOwnedAttrs } from '../../../internal/ownedAttrs'
|
|
44
50
|
import {
|
|
45
51
|
validateBoundedInteger,
|
|
@@ -92,13 +98,10 @@ const groupId = computed(() => validateDomId(
|
|
|
92
98
|
))
|
|
93
99
|
const labelId = computed(() => `${groupId.value}-legend`)
|
|
94
100
|
const validatedLabel = computed(() => validateNonEmptyString('SFieldGroup', 'label', props.label))
|
|
95
|
-
const helpId =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (props.helpText || slots.help) ids.push(helpId.value)
|
|
100
|
-
if (props.invalid && (props.errorMessage || slots.error)) ids.push(errorId.value)
|
|
101
|
-
return ids.length > 0 ? ids.join(' ') : undefined
|
|
101
|
+
const { describedBy, errorId, helpId } = useFieldSupportingText({
|
|
102
|
+
baseId: groupId,
|
|
103
|
+
hasHelp: () => Boolean(props.helpText || slots.help),
|
|
104
|
+
hasError: () => Boolean(props.invalid && (props.errorMessage || slots.error)),
|
|
102
105
|
})
|
|
103
106
|
const validatedLayout = computed<SFieldGroupLayout>(() => validateExactString(
|
|
104
107
|
'SFieldGroup',
|
|
@@ -9,4 +9,3 @@
|
|
|
9
9
|
.s-field-label[data-size='md'] { @apply text-sm; }
|
|
10
10
|
.s-field-label[data-align='end'] { @apply text-right; }
|
|
11
11
|
.s-field-label[data-disabled='true'] { @apply text-surface-400 dark:text-surface-500; }
|
|
12
|
-
.s-field-label__required { @apply ml-0.5 text-danger-600 dark:text-danger-400; }
|
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
:data-disabled="disabled || undefined"
|
|
9
9
|
>
|
|
10
10
|
<slot />
|
|
11
|
-
<span v-if="required" class="s-field-label__required" aria-hidden="true">*</span>
|
|
11
|
+
<span v-if="required" :class="['s-field-label__required', FIELD_REQUIRED_CLASS]" aria-hidden="true">*</span>
|
|
12
12
|
</label>
|
|
13
13
|
</template>
|
|
14
14
|
|
|
15
15
|
<script setup lang="ts">
|
|
16
16
|
import type { VNodeChild } from 'vue'
|
|
17
|
+
import { FIELD_REQUIRED_CLASS } from '../../../internal/fieldPresentation'
|
|
17
18
|
import { useOwnedAttrs } from '../../../internal/ownedAttrs'
|
|
18
19
|
|
|
19
20
|
defineOptions({ inheritAttrs: false })
|
|
@@ -17,27 +17,21 @@
|
|
|
17
17
|
:data-option-wrap="optionWrap"
|
|
18
18
|
:data-invalid="group.invalid || undefined"
|
|
19
19
|
:data-readonly="group.readonly || undefined"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
v-bind="radioGroup.groupBindings({
|
|
21
|
+
labelledBy: group.labelId,
|
|
22
|
+
describedBy: group.describedBy,
|
|
23
|
+
required: group.required,
|
|
24
|
+
invalid: group.invalid,
|
|
25
|
+
})"
|
|
26
26
|
>
|
|
27
27
|
<button
|
|
28
28
|
v-for="option in options"
|
|
29
|
-
:key="optionToken(option)"
|
|
30
|
-
:ref="
|
|
29
|
+
:key="radioGroup.optionToken(option.value)"
|
|
30
|
+
:ref="radioGroup.optionRef(option.value)"
|
|
31
31
|
class="s-segmented-control__item"
|
|
32
32
|
:data-size="size"
|
|
33
|
-
type="button"
|
|
34
|
-
:aria-checked="option.value === modelValue"
|
|
35
|
-
:disabled="group.disabled || option.disabled"
|
|
36
|
-
role="radio"
|
|
37
|
-
:tabindex="option.value === focusableValue ? 0 : -1"
|
|
38
33
|
:title="option.title"
|
|
39
|
-
|
|
40
|
-
@keydown="roving.handleKeydown($event, option.value)"
|
|
34
|
+
v-bind="radioGroup.optionBindings(option)"
|
|
41
35
|
>{{ option.label }}</button>
|
|
42
36
|
</div>
|
|
43
37
|
</template>
|
|
@@ -74,10 +68,9 @@ export interface Props<T extends PublicSelectionKey = string> {
|
|
|
74
68
|
|
|
75
69
|
<script setup lang="ts" generic="T extends SelectionKey = string">
|
|
76
70
|
import { computed } from 'vue'
|
|
77
|
-
import type { ComponentPublicInstance } from 'vue'
|
|
78
71
|
import { useOwnedAttrs } from '../../../internal/ownedAttrs'
|
|
79
72
|
import { useInteractiveLeafRegistration } from '../../../internal/passiveContentContract'
|
|
80
|
-
import {
|
|
73
|
+
import { useRadioGroup } from '../_internal/useRadioGroup'
|
|
81
74
|
import type { SelectionKey } from '../_internal/useSelectionRoving'
|
|
82
75
|
import SFieldGroup from './SFieldGroup.vue'
|
|
83
76
|
|
|
@@ -100,35 +93,14 @@ const emit = defineEmits<{
|
|
|
100
93
|
}>()
|
|
101
94
|
const ownedAttrs = useOwnedAttrs({ component: 'SSegmentedControl', owner: 'field group root' })
|
|
102
95
|
useInteractiveLeafRegistration({ owner: 'SSegmentedControl' })
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (props.disabled || props.readonly || option.disabled) {
|
|
106
|
-
return
|
|
107
|
-
}
|
|
108
|
-
emit('update:modelValue', option.value)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const rovingOptions = computed(() => props.options.map((option) => ({
|
|
112
|
-
value: option.value,
|
|
113
|
-
disabled: props.disabled || option.disabled,
|
|
114
|
-
})))
|
|
115
|
-
const roving = useSelectionRoving({
|
|
116
|
-
options: rovingOptions,
|
|
96
|
+
const radioGroup = useRadioGroup({
|
|
97
|
+
options: computed(() => props.options),
|
|
117
98
|
selectedValue: computed(() => props.modelValue),
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
99
|
+
disabled: computed(() => props.disabled),
|
|
100
|
+
readonly: computed(() => props.readonly),
|
|
101
|
+
update: (value) => emit('update:modelValue', value),
|
|
121
102
|
component: 'SSegmentedControl',
|
|
122
103
|
})
|
|
123
|
-
const focusableValue = roving.focusableValue
|
|
124
|
-
const optionToken = (option: SegmentedControlOption<T>): string => selectionKeyToken(
|
|
125
|
-
'SSegmentedControl',
|
|
126
|
-
option.value,
|
|
127
|
-
'option.value',
|
|
128
|
-
)
|
|
129
|
-
const resolveNativeElement = (element: Element | ComponentPublicInstance | null): HTMLElement | null => (
|
|
130
|
-
element instanceof HTMLElement ? element : null
|
|
131
|
-
)
|
|
132
104
|
</script>
|
|
133
105
|
|
|
134
106
|
<style lang="postcss" src="./SSegmentedControl.css" scoped></style>
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
<template #default="field">
|
|
14
14
|
<span class="s-switch-control">
|
|
15
15
|
<input
|
|
16
|
+
ref="inputEl"
|
|
16
17
|
v-bind="ownedAttrs.bindings()"
|
|
17
18
|
:id="field.controlId"
|
|
18
19
|
type="checkbox"
|
|
@@ -37,10 +38,9 @@
|
|
|
37
38
|
</template>
|
|
38
39
|
|
|
39
40
|
<script setup lang="ts">
|
|
40
|
-
import { computed, useId } from 'vue'
|
|
41
41
|
import { mergeIdReferences, useOwnedAttrs } from '../../../internal/ownedAttrs'
|
|
42
42
|
import { useInteractiveLeafRegistration } from '../../../internal/passiveContentContract'
|
|
43
|
-
import {
|
|
43
|
+
import { useBinaryInput } from '../../../internal/useBinaryInput'
|
|
44
44
|
import SField from './SField.vue'
|
|
45
45
|
|
|
46
46
|
defineOptions({ inheritAttrs: false })
|
|
@@ -73,37 +73,19 @@ const emit = defineEmits<{
|
|
|
73
73
|
}>()
|
|
74
74
|
const ownedAttrs = useOwnedAttrs({ component: 'SSwitch', owner: 'native switch input' })
|
|
75
75
|
useInteractiveLeafRegistration({ owner: 'SSwitch' })
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return props.modelValue
|
|
76
|
+
const {
|
|
77
|
+
checkedValue,
|
|
78
|
+
inputEl,
|
|
79
|
+
inputId,
|
|
80
|
+
onChange,
|
|
81
|
+
onClick,
|
|
82
|
+
} = useBinaryInput({
|
|
83
|
+
owner: 'SSwitch',
|
|
84
|
+
inputName: 'switch',
|
|
85
|
+
props,
|
|
86
|
+
emitUpdate: (value) => emit('update:modelValue', value),
|
|
87
|
+
emitClick: (event) => emit('click', event),
|
|
89
88
|
})
|
|
90
|
-
|
|
91
|
-
function onChange(event: Event): void {
|
|
92
|
-
if (props.readonly) return
|
|
93
|
-
const target = event.currentTarget
|
|
94
|
-
if (!(target instanceof HTMLInputElement)) {
|
|
95
|
-
throw new TypeError('SSwitch: change event owner must be the native switch input')
|
|
96
|
-
}
|
|
97
|
-
emit('update:modelValue', target.checked)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function onClick(event: MouseEvent): void {
|
|
101
|
-
if (props.readonly) {
|
|
102
|
-
event.preventDefault()
|
|
103
|
-
return
|
|
104
|
-
}
|
|
105
|
-
emit('click', event)
|
|
106
|
-
}
|
|
107
89
|
</script>
|
|
108
90
|
|
|
109
91
|
<style lang="postcss" src="./SSwitch.css" scoped></style>
|
|
@@ -1,42 +1,56 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<span
|
|
3
|
-
v-bind="ownedAttrs.bindings()"
|
|
3
|
+
v-bind="{ ...ownedAttrs.bindings(), ...surfaceBindings }"
|
|
4
4
|
class="s-badge"
|
|
5
|
-
:class="{ 's-badge--dot': dot }"
|
|
6
|
-
:data-severity="severity"
|
|
7
|
-
:data-size="size"
|
|
8
|
-
:data-max-width="maxWidth"
|
|
9
|
-
:data-truncate="truncate || undefined"
|
|
10
|
-
:data-icon-motion="iconMotion"
|
|
11
5
|
>
|
|
12
6
|
<template v-if="!dot">
|
|
13
|
-
<span v-if="leadingIcon" class="
|
|
14
|
-
<component
|
|
7
|
+
<span v-if="leadingIcon" :class="PILL_ICON_CLASS" aria-hidden="true">
|
|
8
|
+
<component
|
|
9
|
+
:is="leadingIcon"
|
|
10
|
+
:class="[
|
|
11
|
+
PILL_ICON_GRAPHIC_CLASS,
|
|
12
|
+
{ [PILL_ICON_SPIN_CLASS]: iconMotion === 'spin' },
|
|
13
|
+
]"
|
|
14
|
+
/>
|
|
15
|
+
</span>
|
|
16
|
+
<span :class="[PILL_LABEL_CLASS, { [PILL_LABEL_TRUNCATE_CLASS]: truncate }]">
|
|
17
|
+
<slot />
|
|
15
18
|
</span>
|
|
16
|
-
<span class="s-badge__label"><slot /></span>
|
|
17
19
|
</template>
|
|
18
20
|
</span>
|
|
19
21
|
</template>
|
|
20
22
|
|
|
21
23
|
<script setup lang="ts">
|
|
22
|
-
import type
|
|
24
|
+
import { computed, type Component } from 'vue';
|
|
23
25
|
import { useOwnedAttrs } from '../../../internal/ownedAttrs';
|
|
26
|
+
import {
|
|
27
|
+
PILL_ICON_CLASS,
|
|
28
|
+
PILL_ICON_GRAPHIC_CLASS,
|
|
29
|
+
PILL_ICON_SPIN_CLASS,
|
|
30
|
+
PILL_LABEL_CLASS,
|
|
31
|
+
PILL_LABEL_TRUNCATE_CLASS,
|
|
32
|
+
resolvePillSurfaceBindings,
|
|
33
|
+
type PillSurfaceIconMotion,
|
|
34
|
+
type PillSurfaceMaxWidth,
|
|
35
|
+
type PillSurfaceSeverity,
|
|
36
|
+
type PillSurfaceSize,
|
|
37
|
+
} from '../../../internal/pillSurface';
|
|
24
38
|
|
|
25
39
|
defineOptions({ inheritAttrs: false });
|
|
26
40
|
|
|
27
|
-
export type BadgeSeverity =
|
|
41
|
+
export type BadgeSeverity = PillSurfaceSeverity;
|
|
28
42
|
|
|
29
43
|
export interface Props {
|
|
30
44
|
severity?: BadgeSeverity;
|
|
31
45
|
dot?: boolean;
|
|
32
|
-
size?:
|
|
46
|
+
size?: PillSurfaceSize;
|
|
33
47
|
leadingIcon?: Component;
|
|
34
|
-
iconMotion?:
|
|
48
|
+
iconMotion?: PillSurfaceIconMotion;
|
|
35
49
|
truncate?: boolean;
|
|
36
|
-
maxWidth?:
|
|
50
|
+
maxWidth?: PillSurfaceMaxWidth;
|
|
37
51
|
}
|
|
38
52
|
|
|
39
|
-
withDefaults(defineProps<Props>(), {
|
|
53
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
40
54
|
severity: 'secondary',
|
|
41
55
|
dot: false,
|
|
42
56
|
size: 'md',
|
|
@@ -47,6 +61,15 @@ withDefaults(defineProps<Props>(), {
|
|
|
47
61
|
});
|
|
48
62
|
|
|
49
63
|
const ownedAttrs = useOwnedAttrs({ component: 'SBadge', owner: 'badge root' });
|
|
64
|
+
const surfaceBindings = computed(() => resolvePillSurfaceBindings('SBadge', {
|
|
65
|
+
kind: 'badge',
|
|
66
|
+
severity: props.severity,
|
|
67
|
+
size: props.size,
|
|
68
|
+
dot: props.dot,
|
|
69
|
+
closable: false,
|
|
70
|
+
disabled: false,
|
|
71
|
+
truncate: props.truncate,
|
|
72
|
+
maxWidth: props.maxWidth,
|
|
73
|
+
iconMotion: props.iconMotion,
|
|
74
|
+
}));
|
|
50
75
|
</script>
|
|
51
|
-
|
|
52
|
-
<style lang="postcss" src="./SBadge.css" scoped></style>
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<span
|
|
3
|
-
v-bind="ownedAttrs.bindings()"
|
|
3
|
+
v-bind="{ ...ownedAttrs.bindings(), ...surfaceBindings }"
|
|
4
4
|
class="s-chip"
|
|
5
|
-
:data-severity="validatedSeverity"
|
|
6
|
-
:data-size="validatedSize"
|
|
7
|
-
:data-closable="closable || undefined"
|
|
8
|
-
:data-disabled="disabled || undefined"
|
|
9
5
|
>
|
|
10
|
-
<span v-if="leadingIcon" class="
|
|
11
|
-
<component :is="leadingIcon" class="
|
|
6
|
+
<span v-if="leadingIcon" :class="PILL_ICON_CLASS" aria-hidden="true">
|
|
7
|
+
<component :is="leadingIcon" :class="PILL_ICON_GRAPHIC_CLASS" />
|
|
12
8
|
</span>
|
|
13
|
-
<span class="
|
|
9
|
+
<span :class="[PILL_LABEL_CLASS, PILL_LABEL_TRUNCATE_CLASS]">{{ validatedLabel }}</span>
|
|
14
10
|
<SButton
|
|
15
11
|
v-if="closable"
|
|
16
12
|
label=""
|
|
@@ -34,6 +30,13 @@
|
|
|
34
30
|
import { computed, type Component } from 'vue'
|
|
35
31
|
import { X } from '../../icons/sputnigUiIcons'
|
|
36
32
|
import { useOwnedAttrs } from '../../../internal/ownedAttrs'
|
|
33
|
+
import {
|
|
34
|
+
PILL_ICON_CLASS,
|
|
35
|
+
PILL_ICON_GRAPHIC_CLASS,
|
|
36
|
+
PILL_LABEL_CLASS,
|
|
37
|
+
PILL_LABEL_TRUNCATE_CLASS,
|
|
38
|
+
resolvePillSurfaceBindings,
|
|
39
|
+
} from '../../../internal/pillSurface'
|
|
37
40
|
import {
|
|
38
41
|
validateBoolean,
|
|
39
42
|
validateExactString,
|
|
@@ -80,6 +83,17 @@ const validatedSeverity = computed(() => validateExactString(
|
|
|
80
83
|
const validatedSize = computed(() => validateExactString(
|
|
81
84
|
'SChip', 'size', props.size, ['sm', 'md'] as const,
|
|
82
85
|
))
|
|
86
|
+
const surfaceBindings = computed(() => resolvePillSurfaceBindings('SChip', {
|
|
87
|
+
kind: 'chip',
|
|
88
|
+
severity: validatedSeverity.value,
|
|
89
|
+
size: validatedSize.value,
|
|
90
|
+
dot: false,
|
|
91
|
+
closable: props.closable,
|
|
92
|
+
disabled: props.disabled,
|
|
93
|
+
truncate: true,
|
|
94
|
+
maxWidth: 'none',
|
|
95
|
+
iconMotion: 'static',
|
|
96
|
+
}))
|
|
83
97
|
const resolvedCloseLabel = computed(() => {
|
|
84
98
|
validateBoolean('SChip', 'closable', props.closable)
|
|
85
99
|
validateBoolean('SChip', 'disabled', props.disabled)
|
|
@@ -88,5 +102,3 @@ const resolvedCloseLabel = computed(() => {
|
|
|
88
102
|
: validateNonEmptyString('SChip', 'closeLabel', props.closeLabel)
|
|
89
103
|
})
|
|
90
104
|
</script>
|
|
91
|
-
|
|
92
|
-
<style lang="postcss" src="./SChip.css" scoped></style>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { useOwnedAttrs } from '../../../internal/ownedAttrs'
|
|
3
|
+
import SHeaderSurface from '../_internal/SHeaderSurface.vue'
|
|
3
4
|
|
|
4
5
|
defineOptions({ inheritAttrs: false })
|
|
5
6
|
|
|
@@ -32,27 +33,22 @@ const ownedAttrs = useOwnedAttrs({ component: 'SSectionHeader', owner: 'section
|
|
|
32
33
|
</script>
|
|
33
34
|
|
|
34
35
|
<template>
|
|
35
|
-
<
|
|
36
|
+
<SHeaderSurface
|
|
36
37
|
v-bind="ownedAttrs.bindings()"
|
|
37
|
-
|
|
38
|
-
:
|
|
39
|
-
:
|
|
40
|
-
:
|
|
41
|
-
:
|
|
42
|
-
:
|
|
43
|
-
:
|
|
38
|
+
kind="section"
|
|
39
|
+
:title="title"
|
|
40
|
+
:eyebrow="eyebrow"
|
|
41
|
+
:description="description"
|
|
42
|
+
:meta="meta"
|
|
43
|
+
:heading-level="headingLevel"
|
|
44
|
+
:size="size"
|
|
45
|
+
:variant="variant"
|
|
46
|
+
:divider="divider"
|
|
47
|
+
:padding="padding"
|
|
48
|
+
:spacing-after="spacingAfter"
|
|
49
|
+
:trailing-layout="trailingLayout"
|
|
44
50
|
>
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
<p v-if="description" class="s-section-header__description">{{ description }}</p>
|
|
49
|
-
<p v-if="meta" class="s-section-header__meta">{{ meta }}</p>
|
|
50
|
-
</div>
|
|
51
|
-
<div v-if="$slots.badges || $slots.actions" class="s-section-header__trailing">
|
|
52
|
-
<div v-if="$slots.badges" class="s-section-header__badges"><slot name="badges" /></div>
|
|
53
|
-
<div v-if="$slots.actions" class="s-section-header__actions"><slot name="actions" /></div>
|
|
54
|
-
</div>
|
|
55
|
-
</header>
|
|
51
|
+
<template v-if="$slots.badges" #badges><slot name="badges" /></template>
|
|
52
|
+
<template v-if="$slots.actions" #actions><slot name="actions" /></template>
|
|
53
|
+
</SHeaderSurface>
|
|
56
54
|
</template>
|
|
57
|
-
|
|
58
|
-
<style lang="postcss" src="./SSectionHeader.css" scoped></style>
|