@pgcorp/ui-kit 0.7.3 → 0.8.1
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 +161 -8
- package/docs/accessibility.md +12 -0
- package/docs/getting-started.md +32 -2
- package/docs/public-api.md +27 -2
- package/package.json +18 -3
- package/src/components/shared/codeLanguages.ts +2 -107
- package/src/components/shared/containers/SPanel.css +32 -1
- package/src/components/shared/containers/SPanel.vue +4 -0
- package/src/components/shared/controls/SCheckbox.vue +2 -2
- package/src/components/shared/controls/SInteractiveSurface.css +54 -4
- package/src/components/shared/controls/SInteractiveSurface.vue +45 -31
- package/src/components/shared/controls/SListbox.vue +4 -4
- package/src/components/shared/controls/SSwitch.vue +2 -2
- package/src/components/shared/data-display/SActionCard.css +6 -2
- package/src/components/shared/data-display/SActionCard.vue +13 -3
- package/src/components/shared/data-display/SActionListItem.css +7 -8
- package/src/components/shared/data-display/SActionListItem.vue +21 -18
- package/src/components/shared/data-display/SChart.css +149 -0
- package/src/components/shared/data-display/SChart.vue +493 -0
- package/src/components/shared/data-display/SChip.css +24 -0
- package/src/components/shared/data-display/SChip.vue +30 -6
- package/src/components/shared/data-display/SCodeBlock.css +68 -0
- package/src/components/shared/data-display/SCodeBlock.vue +102 -16
- package/src/components/shared/data-display/SMetricCard.css +1 -0
- package/src/components/shared/data-display/SMetricCard.vue +1 -0
- package/src/components/shared/data-display/STable.vue +120 -145
- package/src/components/shared/data-display/chart.ts +54 -0
- package/src/components/shared/navigation/STabList.vue +0 -3
- package/src/internal/chartGeometry.ts +852 -0
- package/src/internal/codeLanguageIdentity.ts +89 -0
- package/src/internal/lazyCodeEditor.ts +1 -0
- package/src/internal/linkTarget.ts +1 -3
- package/src/internal/ownedAttrs.ts +1 -0
- package/src/internal/useBinaryInput.ts +9 -2
- package/src/styles/tailwind.css +3 -0
- package/src/styles/tokens.css +33 -0
|
@@ -14,10 +14,36 @@
|
|
|
14
14
|
color var(--s-motion-standard) ease;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
.s-interactive-surface:has(.s-interactive-surface__actions > *) {
|
|
18
|
+
container-type: inline-size;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.s-interactive-surface__layout {
|
|
22
|
+
@apply grid min-h-0 min-w-0 w-full items-center;
|
|
23
|
+
grid-template-columns: minmax(0, 1fr);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.s-interactive-surface:has(.s-interactive-surface__actions > *) .s-interactive-surface__layout {
|
|
27
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.s-interactive-surface__primary {
|
|
31
|
+
@apply relative flex min-h-0 min-w-0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.s-interactive-surface__actions {
|
|
35
|
+
@apply flex min-w-0 shrink-0 items-center;
|
|
36
|
+
gap: var(--s-space-control-gap);
|
|
37
|
+
}
|
|
38
|
+
|
|
17
39
|
.s-interactive-surface[data-appearance='plain'] {
|
|
18
40
|
@apply border-transparent bg-transparent dark:border-transparent dark:bg-transparent;
|
|
19
41
|
}
|
|
20
42
|
|
|
43
|
+
.s-interactive-surface[data-appearance='bare'] {
|
|
44
|
+
@apply overflow-visible border-0 bg-transparent dark:bg-transparent;
|
|
45
|
+
}
|
|
46
|
+
|
|
21
47
|
.s-interactive-surface__activation {
|
|
22
48
|
@apply absolute inset-0 z-10 block h-full w-full cursor-pointer border-0 bg-transparent p-0;
|
|
23
49
|
border-radius: inherit;
|
|
@@ -42,7 +68,9 @@
|
|
|
42
68
|
pointer-events: none;
|
|
43
69
|
}
|
|
44
70
|
|
|
45
|
-
.s-interactive-surface[data-fill='container']
|
|
71
|
+
.s-interactive-surface[data-fill='container'],
|
|
72
|
+
.s-interactive-surface[data-fill='container'] .s-interactive-surface__layout,
|
|
73
|
+
.s-interactive-surface[data-fill='container'] .s-interactive-surface__primary { @apply h-full w-full; }
|
|
46
74
|
.s-interactive-surface[data-density='compact'] { @apply text-sm; }
|
|
47
75
|
.s-interactive-surface[data-density='comfortable'] { @apply text-base; }
|
|
48
76
|
.s-interactive-surface[data-padding='none'] { @apply p-0; }
|
|
@@ -56,9 +84,31 @@
|
|
|
56
84
|
.s-interactive-surface[data-s-tone='danger'] { @apply border-danger-200 bg-danger-50 dark:border-danger-800 dark:bg-danger-950; }
|
|
57
85
|
.s-interactive-surface[data-selected='true'] { @apply border-primary-400 bg-primary-50 dark:border-primary-600 dark:bg-primary-950; }
|
|
58
86
|
.s-interactive-surface[data-pressed='true'] { @apply border-primary-500 bg-primary-100 dark:border-primary-500 dark:bg-primary-950/70; }
|
|
59
|
-
.s-interactive-surface[data-disabled='true'] { @apply cursor-not-allowed
|
|
60
|
-
.s-interactive-surface[data-
|
|
61
|
-
.s-interactive-surface[data-
|
|
87
|
+
.s-interactive-surface[data-disabled='true'] { @apply cursor-not-allowed; }
|
|
88
|
+
.s-interactive-surface[data-disabled='true']:not(:has(.s-interactive-surface__actions > *)),
|
|
89
|
+
.s-interactive-surface[data-disabled='true']:has(.s-interactive-surface__actions > *) .s-interactive-surface__primary {
|
|
90
|
+
@apply opacity-60;
|
|
91
|
+
}
|
|
92
|
+
.s-interactive-surface[data-content-align='start'] .s-interactive-surface__content { @apply justify-start text-left; }
|
|
93
|
+
.s-interactive-surface[data-content-align='center'] .s-interactive-surface__content { @apply justify-center text-center; }
|
|
94
|
+
|
|
95
|
+
.s-interactive-surface[data-actions-layout='stacked']:has(.s-interactive-surface__actions > *) .s-interactive-surface__layout {
|
|
96
|
+
grid-template-columns: minmax(0, 1fr);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.s-interactive-surface[data-actions-layout='stacked'] .s-interactive-surface__actions {
|
|
100
|
+
@apply w-full;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@container (max-width: 32rem) {
|
|
104
|
+
.s-interactive-surface[data-actions-layout='responsive'] .s-interactive-surface__layout {
|
|
105
|
+
grid-template-columns: minmax(0, 1fr);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.s-interactive-surface[data-actions-layout='responsive'] .s-interactive-surface__actions {
|
|
109
|
+
@apply w-full;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
62
112
|
|
|
63
113
|
.s-interactive-surface[data-mode='action']:not([data-disabled='true']),
|
|
64
114
|
.s-interactive-surface[data-mode='link']:not([data-disabled='true']) {
|
|
@@ -20,7 +20,8 @@ export type InteractiveSurfaceDensity = 'compact' | 'comfortable'
|
|
|
20
20
|
export type InteractiveSurfacePadding = 'none' | 'sm' | 'md'
|
|
21
21
|
export type InteractiveSurfaceRadius = 'md' | 'lg' | 'xl'
|
|
22
22
|
export type InteractiveSurfaceFill = 'content' | 'container'
|
|
23
|
-
export type InteractiveSurfaceAppearance = 'card' | 'plain'
|
|
23
|
+
export type InteractiveSurfaceAppearance = 'card' | 'plain' | 'bare'
|
|
24
|
+
export type InteractiveSurfaceActionsLayout = 'responsive' | 'inline' | 'stacked'
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* Единственный semantic-контракт поверхности: passive, action или ровно одна link-target.
|
|
@@ -60,6 +61,7 @@ export interface Props {
|
|
|
60
61
|
radius?: InteractiveSurfaceRadius
|
|
61
62
|
fill?: InteractiveSurfaceFill
|
|
62
63
|
appearance?: InteractiveSurfaceAppearance
|
|
64
|
+
actionsLayout?: InteractiveSurfaceActionsLayout
|
|
63
65
|
contentAlign?: 'start' | 'center'
|
|
64
66
|
/** Полный binding явного STooltip trigger, направляемый на activation owner. / Complete explicit STooltip trigger binding routed to the activation owner. */
|
|
65
67
|
tooltipTrigger?: STooltipTriggerBinding
|
|
@@ -73,6 +75,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
73
75
|
radius: 'lg',
|
|
74
76
|
fill: 'content',
|
|
75
77
|
appearance: 'card',
|
|
78
|
+
actionsLayout: 'inline',
|
|
76
79
|
contentAlign: 'start',
|
|
77
80
|
tooltipTrigger: undefined,
|
|
78
81
|
})
|
|
@@ -80,9 +83,11 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
80
83
|
const emit = defineEmits<{
|
|
81
84
|
activate: [event: MouseEvent]
|
|
82
85
|
}>()
|
|
83
|
-
defineSlots<{
|
|
86
|
+
const slots = defineSlots<{
|
|
84
87
|
/** Пассивное flow-содержимое поверхности. / Passive flow content of the surface. */
|
|
85
88
|
default?: () => VNodeChild
|
|
89
|
+
/** Sibling controls inside the same visual chrome and outside the primary activation owner. */
|
|
90
|
+
actions?: () => VNodeChild
|
|
86
91
|
}>()
|
|
87
92
|
|
|
88
93
|
const ownedAttrs = useOwnedAttrs({ component: 'SInteractiveSurface', owner: 'interactive surface owner' })
|
|
@@ -297,40 +302,49 @@ function activateAction(event: MouseEvent): void {
|
|
|
297
302
|
:data-radius="radius"
|
|
298
303
|
:data-fill="fill"
|
|
299
304
|
:data-appearance="appearance"
|
|
305
|
+
:data-actions-layout="actionsLayout"
|
|
306
|
+
:data-has-actions="Boolean(slots.actions) || undefined"
|
|
300
307
|
:data-selected="selected || undefined"
|
|
301
308
|
:data-pressed="surfacePressed"
|
|
302
309
|
:data-disabled="surfaceDisabled || undefined"
|
|
303
310
|
:data-content-align="contentAlign"
|
|
304
311
|
>
|
|
305
|
-
<
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
<
|
|
333
|
-
|
|
312
|
+
<div class="s-interactive-surface__layout">
|
|
313
|
+
<div class="s-interactive-surface__primary">
|
|
314
|
+
<button
|
|
315
|
+
v-if="surfaceMode === 'action'"
|
|
316
|
+
v-bind="activationBindings()"
|
|
317
|
+
class="s-interactive-surface__activation"
|
|
318
|
+
type="button"
|
|
319
|
+
:disabled="surfaceDisabled"
|
|
320
|
+
:aria-label="resolvedAccessibleLabel"
|
|
321
|
+
:aria-pressed="surfacePressed"
|
|
322
|
+
@click="activateAction"
|
|
323
|
+
>
|
|
324
|
+
<span class="s-interactive-surface__accessible-label">{{ resolvedAccessibleLabel }}</span>
|
|
325
|
+
</button>
|
|
326
|
+
<component
|
|
327
|
+
v-else-if="surfaceMode === 'link'"
|
|
328
|
+
:is="linkComponent"
|
|
329
|
+
v-bind="linkBindings()"
|
|
330
|
+
class="s-interactive-surface__activation"
|
|
331
|
+
:aria-label="resolvedAccessibleLabel"
|
|
332
|
+
:aria-current="selected ? 'page' : undefined"
|
|
333
|
+
:aria-disabled="surfaceDisabled || undefined"
|
|
334
|
+
:tabindex="surfaceDisabled ? -1 : undefined"
|
|
335
|
+
@click="activateLink"
|
|
336
|
+
>
|
|
337
|
+
<span class="s-interactive-surface__accessible-label">{{ resolvedAccessibleLabel }}</span>
|
|
338
|
+
</component>
|
|
339
|
+
<div class="s-interactive-surface__content" data-passive-content="">
|
|
340
|
+
<PassiveContentBoundary :contract="passiveContentContract">
|
|
341
|
+
<slot />
|
|
342
|
+
</PassiveContentBoundary>
|
|
343
|
+
</div>
|
|
344
|
+
</div>
|
|
345
|
+
<div v-if="$slots.actions" class="s-interactive-surface__actions">
|
|
346
|
+
<slot name="actions" />
|
|
347
|
+
</div>
|
|
334
348
|
</div>
|
|
335
349
|
</div>
|
|
336
350
|
</template>
|
|
@@ -338,7 +338,7 @@ provide(listboxContextKey, {
|
|
|
338
338
|
},
|
|
339
339
|
})
|
|
340
340
|
|
|
341
|
-
function focusOption(target: ListboxOptionRegistration
|
|
341
|
+
function focusOption(target: ListboxOptionRegistration): void {
|
|
342
342
|
for (const option of registrations) option.element.tabIndex = -1
|
|
343
343
|
target.element.tabIndex = 0
|
|
344
344
|
target.element.focus()
|
|
@@ -451,7 +451,7 @@ function handleKeydown(event: KeyboardEvent): void {
|
|
|
451
451
|
const match = searchOrder.find((option) => option.label().toLocaleLowerCase().startsWith(query))
|
|
452
452
|
if (match) {
|
|
453
453
|
event.preventDefault()
|
|
454
|
-
focusOption(match
|
|
454
|
+
focusOption(match)
|
|
455
455
|
}
|
|
456
456
|
return
|
|
457
457
|
}
|
|
@@ -467,7 +467,7 @@ function handleKeydown(event: KeyboardEvent): void {
|
|
|
467
467
|
const target = options[nextIndex]
|
|
468
468
|
if (!target) return
|
|
469
469
|
event.preventDefault()
|
|
470
|
-
focusOption(target
|
|
470
|
+
focusOption(target)
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
function focusSelectedOrFirst(): void {
|
|
@@ -476,7 +476,7 @@ function focusSelectedOrFirst(): void {
|
|
|
476
476
|
}
|
|
477
477
|
const options = enabledRegistrations()
|
|
478
478
|
const target = options.find((option) => option.selected()) ?? options[0]
|
|
479
|
-
if (target) focusOption(target
|
|
479
|
+
if (target) focusOption(target)
|
|
480
480
|
}
|
|
481
481
|
|
|
482
482
|
onBeforeUnmount(() => { if (typeaheadTimer) clearTimeout(typeaheadTimer) })
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<template #default="field">
|
|
14
14
|
<span class="s-switch-control">
|
|
15
15
|
<input
|
|
16
|
-
ref="
|
|
16
|
+
:ref="setInputElement"
|
|
17
17
|
v-bind="ownedAttrs.bindings()"
|
|
18
18
|
:id="field.controlId"
|
|
19
19
|
type="checkbox"
|
|
@@ -75,10 +75,10 @@ const ownedAttrs = useOwnedAttrs({ component: 'SSwitch', owner: 'native switch i
|
|
|
75
75
|
useInteractiveLeafRegistration({ owner: 'SSwitch' })
|
|
76
76
|
const {
|
|
77
77
|
checkedValue,
|
|
78
|
-
inputEl,
|
|
79
78
|
inputId,
|
|
80
79
|
onChange,
|
|
81
80
|
onClick,
|
|
81
|
+
setInputElement,
|
|
82
82
|
} = useBinaryInput({
|
|
83
83
|
owner: 'SSwitch',
|
|
84
84
|
inputName: 'switch',
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
@reference "../../../styles/reference.css";
|
|
2
2
|
|
|
3
|
-
.s-action-card { @apply
|
|
3
|
+
.s-action-card { @apply min-h-0 min-w-0; }
|
|
4
4
|
.s-action-card[data-fill='container'] { @apply h-full w-full; }
|
|
5
5
|
.s-action-card__content { @apply flex min-h-0 min-w-0 w-full flex-1 flex-col; }
|
|
6
|
-
.s-action-card__actions { @apply flex shrink-0 items-center gap-1; }
|
|
6
|
+
.s-action-card__actions { @apply flex min-w-0 max-w-full shrink-0 items-center gap-1; }
|
|
7
|
+
.s-action-card[data-actions-layout='responsive'] .s-action-card__actions,
|
|
8
|
+
.s-action-card[data-actions-layout='stacked'] .s-action-card__actions {
|
|
9
|
+
@apply w-full;
|
|
10
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type {
|
|
2
|
+
import type { VNodeChild } from 'vue'
|
|
3
|
+
import type { InteractiveSurfaceActionsLayout, InteractiveSurfaceContract, InteractiveSurfaceDensity, InteractiveSurfaceFill, InteractiveSurfacePadding, InteractiveSurfaceRadius, InteractiveSurfaceTone } from '../controls/SInteractiveSurface.vue'
|
|
3
4
|
import { useOwnedAttrs } from '../../../internal/ownedAttrs'
|
|
4
5
|
import SInteractiveSurface from '../controls/SInteractiveSurface.vue'
|
|
5
6
|
|
|
@@ -13,6 +14,7 @@ export interface Props {
|
|
|
13
14
|
padding?: InteractiveSurfacePadding
|
|
14
15
|
radius?: InteractiveSurfaceRadius
|
|
15
16
|
fill?: InteractiveSurfaceFill
|
|
17
|
+
actionsLayout?: InteractiveSurfaceActionsLayout
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
withDefaults(defineProps<Props>(), {
|
|
@@ -22,14 +24,19 @@ withDefaults(defineProps<Props>(), {
|
|
|
22
24
|
padding: 'md',
|
|
23
25
|
radius: 'lg',
|
|
24
26
|
fill: 'content',
|
|
27
|
+
actionsLayout: 'inline',
|
|
25
28
|
})
|
|
26
29
|
|
|
27
30
|
const emit = defineEmits<{ activate: [event: MouseEvent] }>()
|
|
31
|
+
defineSlots<{
|
|
32
|
+
default?: () => VNodeChild
|
|
33
|
+
actions?: () => VNodeChild
|
|
34
|
+
}>()
|
|
28
35
|
const ownedAttrs = useOwnedAttrs({ component: 'SActionCard', owner: 'action card root' })
|
|
29
36
|
</script>
|
|
30
37
|
|
|
31
38
|
<template>
|
|
32
|
-
<div v-bind="ownedAttrs.bindings()" class="s-action-card" :data-has-actions="Boolean($slots.actions) || undefined" :data-fill="fill" :data-mode="surface.mode">
|
|
39
|
+
<div v-bind="ownedAttrs.bindings()" class="s-action-card" :data-has-actions="Boolean($slots.actions) || undefined" :data-fill="fill" :data-mode="surface.mode" :data-actions-layout="actionsLayout">
|
|
33
40
|
<SInteractiveSurface
|
|
34
41
|
:surface="surface"
|
|
35
42
|
:selected="selected"
|
|
@@ -38,11 +45,14 @@ const ownedAttrs = useOwnedAttrs({ component: 'SActionCard', owner: 'action card
|
|
|
38
45
|
:padding="padding"
|
|
39
46
|
:radius="radius"
|
|
40
47
|
:fill="fill"
|
|
48
|
+
:actions-layout="actionsLayout"
|
|
41
49
|
@activate="emit('activate', $event)"
|
|
42
50
|
>
|
|
43
51
|
<div class="s-action-card__content"><slot /></div>
|
|
52
|
+
<template v-if="$slots.actions" #actions>
|
|
53
|
+
<div class="s-action-card__actions"><slot name="actions" /></div>
|
|
54
|
+
</template>
|
|
44
55
|
</SInteractiveSurface>
|
|
45
|
-
<div v-if="$slots.actions" class="s-action-card__actions"><slot name="actions" /></div>
|
|
46
56
|
</div>
|
|
47
57
|
</template>
|
|
48
58
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
@reference "../../../styles/reference.css";
|
|
2
2
|
|
|
3
3
|
.s-action-list-item {
|
|
4
|
-
@apply
|
|
4
|
+
@apply min-h-12 min-w-0;
|
|
5
5
|
height: max-content;
|
|
6
|
-
grid-template-columns: minmax(0, 1fr) auto;
|
|
7
6
|
}
|
|
8
7
|
|
|
9
8
|
.s-action-list-item[data-height-mode='fill'] {
|
|
@@ -94,7 +93,7 @@
|
|
|
94
93
|
.s-action-list-item[data-density='compact'] .s-action-list-item__icon { @apply h-7 w-7; }
|
|
95
94
|
|
|
96
95
|
.s-action-list-item[data-trailing-layout='stacked'] {
|
|
97
|
-
|
|
96
|
+
@apply w-full;
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
.s-action-list-item[data-trailing-layout='stacked'] .s-action-list-item__trailing {
|
|
@@ -103,12 +102,12 @@
|
|
|
103
102
|
}
|
|
104
103
|
|
|
105
104
|
@container (max-width: 32rem) {
|
|
106
|
-
.s-action-list-item[data-trailing-layout='responsive'] {
|
|
107
|
-
grid-template-columns: minmax(0, 1fr);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
105
|
.s-action-list-item[data-trailing-layout='responsive'] .s-action-list-item__trailing {
|
|
111
|
-
@apply w-full justify-end pb-2 pr-2;
|
|
106
|
+
@apply w-full flex-wrap justify-end gap-y-1 pb-2 pr-2;
|
|
112
107
|
padding-left: calc(3.5rem + var(--s-action-list-item-indent));
|
|
113
108
|
}
|
|
109
|
+
|
|
110
|
+
.s-action-list-item[data-trailing-layout='responsive'] .s-action-list-item__trailing > * {
|
|
111
|
+
max-width: 100%;
|
|
112
|
+
}
|
|
114
113
|
}
|
|
@@ -194,6 +194,7 @@ function emitAction(event: MouseEvent): void {
|
|
|
194
194
|
:padding="surfacePadding"
|
|
195
195
|
:radius="surfaceRadius"
|
|
196
196
|
:fill="heightMode === 'fill' ? 'container' : 'content'"
|
|
197
|
+
:actions-layout="trailingLayout"
|
|
197
198
|
@activate="emit('activate', $event)"
|
|
198
199
|
>
|
|
199
200
|
<div class="s-action-list-item__main" :class="{ 's-action-list-item__main--static': resolvedMode === 'static' }">
|
|
@@ -212,25 +213,27 @@ function emitAction(event: MouseEvent): void {
|
|
|
212
213
|
</span>
|
|
213
214
|
</span>
|
|
214
215
|
</div>
|
|
216
|
+
<template v-if="hasTrailing" #actions>
|
|
217
|
+
<div class="s-action-list-item__trailing">
|
|
218
|
+
<slot name="status" />
|
|
219
|
+
<SBadge v-if="statusLabel" :severity="statusSeverity">{{ statusLabel }}</SBadge>
|
|
220
|
+
<SBadge v-for="badge in validatedBadges" :key="badge.id" :severity="badge.severity">
|
|
221
|
+
{{ badge.label }}
|
|
222
|
+
</SBadge>
|
|
223
|
+
<SButton
|
|
224
|
+
v-if="actionLabel"
|
|
225
|
+
size="sm"
|
|
226
|
+
:label="actionLabel"
|
|
227
|
+
:leading-icon="actionIcon"
|
|
228
|
+
:severity="actionSeverity"
|
|
229
|
+
:disabled="surfaceDisabled || actionDisabled"
|
|
230
|
+
@click="emitAction"
|
|
231
|
+
/>
|
|
232
|
+
<slot name="actions" :disabled="surfaceDisabled || actionDisabled" :emit-action="emitAction" />
|
|
233
|
+
<component :is="trailingIcon" v-if="trailingIcon" class="s-action-list-item__trailing-icon" aria-hidden="true" />
|
|
234
|
+
</div>
|
|
235
|
+
</template>
|
|
215
236
|
</SActionCard>
|
|
216
|
-
<div v-if="hasTrailing" class="s-action-list-item__trailing">
|
|
217
|
-
<slot name="status" />
|
|
218
|
-
<SBadge v-if="statusLabel" :severity="statusSeverity">{{ statusLabel }}</SBadge>
|
|
219
|
-
<SBadge v-for="badge in validatedBadges" :key="badge.id" :severity="badge.severity">
|
|
220
|
-
{{ badge.label }}
|
|
221
|
-
</SBadge>
|
|
222
|
-
<SButton
|
|
223
|
-
v-if="actionLabel"
|
|
224
|
-
size="sm"
|
|
225
|
-
:label="actionLabel"
|
|
226
|
-
:leading-icon="actionIcon"
|
|
227
|
-
:severity="actionSeverity"
|
|
228
|
-
:disabled="surfaceDisabled || actionDisabled"
|
|
229
|
-
@click="emitAction"
|
|
230
|
-
/>
|
|
231
|
-
<slot name="actions" :disabled="surfaceDisabled || actionDisabled" :emit-action="emitAction" />
|
|
232
|
-
<component :is="trailingIcon" v-if="trailingIcon" class="s-action-list-item__trailing-icon" aria-hidden="true" />
|
|
233
|
-
</div>
|
|
234
237
|
</div>
|
|
235
238
|
</template>
|
|
236
239
|
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
@reference "../../../styles/reference.css";
|
|
2
|
+
|
|
3
|
+
.s-chart {
|
|
4
|
+
@apply m-0 grid min-w-0 w-full text-surface-700 dark:text-surface-200;
|
|
5
|
+
gap: var(--s-space-content-gap);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.s-chart__viewport {
|
|
9
|
+
@apply relative min-w-0 w-full overflow-hidden rounded-md;
|
|
10
|
+
background: var(--s-chart-surface);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.s-chart[data-size='compact'] .s-chart__viewport { aspect-ratio: 15 / 4; }
|
|
14
|
+
.s-chart[data-size='sm'] .s-chart__viewport { aspect-ratio: 8 / 3; }
|
|
15
|
+
.s-chart[data-size='md'] .s-chart__viewport { aspect-ratio: 20 / 9; }
|
|
16
|
+
.s-chart[data-size='lg'] .s-chart__viewport { aspect-ratio: 25 / 12; }
|
|
17
|
+
|
|
18
|
+
.s-chart[data-empty='true'] .s-chart__viewport { aspect-ratio: auto; }
|
|
19
|
+
.s-chart[data-size='compact'][data-empty='true'] .s-chart__viewport { min-height: 6rem; }
|
|
20
|
+
.s-chart[data-size='sm'][data-empty='true'] .s-chart__viewport { min-height: 10rem; }
|
|
21
|
+
.s-chart[data-size='md'][data-empty='true'] .s-chart__viewport { min-height: 14rem; }
|
|
22
|
+
.s-chart[data-size='lg'][data-empty='true'] .s-chart__viewport { min-height: 18rem; }
|
|
23
|
+
|
|
24
|
+
.s-chart__svg { @apply block h-full w-full overflow-visible; }
|
|
25
|
+
|
|
26
|
+
.s-chart__grid line {
|
|
27
|
+
stroke: var(--s-chart-grid);
|
|
28
|
+
stroke-width: 1;
|
|
29
|
+
vector-effect: non-scaling-stroke;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.s-chart__axis line {
|
|
33
|
+
stroke: var(--s-chart-axis);
|
|
34
|
+
stroke-width: 1;
|
|
35
|
+
vector-effect: non-scaling-stroke;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.s-chart__axis text,
|
|
39
|
+
.s-chart__data-label {
|
|
40
|
+
fill: var(--s-chart-label);
|
|
41
|
+
font-family: var(--font-sans);
|
|
42
|
+
font-size: 11px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.s-chart[data-size='compact'] .s-chart__axis text,
|
|
46
|
+
.s-chart[data-size='compact'] .s-chart__data-label { font-size: 9px; }
|
|
47
|
+
|
|
48
|
+
.s-chart__axis .s-chart__axis-title {
|
|
49
|
+
fill: var(--s-chart-axis-title);
|
|
50
|
+
font-weight: 600;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.s-chart__line {
|
|
54
|
+
fill: none;
|
|
55
|
+
stroke: var(--s-chart-tone);
|
|
56
|
+
stroke-linecap: round;
|
|
57
|
+
stroke-linejoin: round;
|
|
58
|
+
stroke-width: 2.5;
|
|
59
|
+
vector-effect: non-scaling-stroke;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.s-chart[data-size='compact'] .s-chart__line { stroke-width: 2; }
|
|
63
|
+
|
|
64
|
+
.s-chart__area {
|
|
65
|
+
fill: color-mix(in srgb, var(--s-chart-tone) 20%, transparent);
|
|
66
|
+
stroke: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.s-chart__marker {
|
|
70
|
+
fill: var(--s-chart-surface);
|
|
71
|
+
stroke: var(--s-chart-tone);
|
|
72
|
+
stroke-width: 2.5;
|
|
73
|
+
vector-effect: non-scaling-stroke;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.s-chart__bar,
|
|
77
|
+
.s-chart__slice {
|
|
78
|
+
fill: var(--s-chart-tone);
|
|
79
|
+
stroke: var(--s-chart-surface);
|
|
80
|
+
stroke-width: 1;
|
|
81
|
+
vector-effect: non-scaling-stroke;
|
|
82
|
+
transition: opacity var(--s-motion-fast) ease;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.s-chart__bar:hover,
|
|
86
|
+
.s-chart__slice:hover { opacity: 0.82; }
|
|
87
|
+
|
|
88
|
+
.s-chart__radial-label {
|
|
89
|
+
fill: var(--s-chart-label-on-series);
|
|
90
|
+
font-family: var(--font-sans);
|
|
91
|
+
font-size: 11px;
|
|
92
|
+
font-weight: 700;
|
|
93
|
+
paint-order: stroke;
|
|
94
|
+
stroke: color-mix(in srgb, var(--color-surface-950) 28%, transparent);
|
|
95
|
+
stroke-width: 2px;
|
|
96
|
+
stroke-linejoin: round;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.s-chart__center {
|
|
100
|
+
fill: var(--s-chart-center-label);
|
|
101
|
+
font-family: var(--font-sans);
|
|
102
|
+
font-size: 20px;
|
|
103
|
+
font-weight: 700;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.s-chart__center-label {
|
|
107
|
+
fill: var(--s-chart-label);
|
|
108
|
+
font-size: 10px;
|
|
109
|
+
font-weight: 500;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.s-chart__legend {
|
|
113
|
+
@apply flex min-w-0 flex-wrap items-center text-xs text-surface-600 dark:text-surface-300;
|
|
114
|
+
gap: var(--s-space-content-gap);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.s-chart__legend[data-position='top'] { @apply justify-start; }
|
|
118
|
+
.s-chart__legend[data-position='bottom'] { @apply justify-center; }
|
|
119
|
+
.s-chart__legend-item { @apply inline-flex min-w-0 items-center gap-1.5; }
|
|
120
|
+
|
|
121
|
+
.s-chart__legend-swatch {
|
|
122
|
+
@apply block h-2.5 w-2.5 shrink-0 rounded-full;
|
|
123
|
+
background: var(--s-chart-tone);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.s-chart__data-table { @apply w-full border-collapse overflow-hidden rounded-md text-left text-sm; }
|
|
127
|
+
|
|
128
|
+
.s-chart__data-table th,
|
|
129
|
+
.s-chart__data-table td { @apply border-b border-surface-200 px-3 py-2 dark:border-surface-700; }
|
|
130
|
+
|
|
131
|
+
.s-chart__data-table thead th {
|
|
132
|
+
@apply bg-surface-100 font-semibold text-surface-700 dark:bg-surface-800 dark:text-surface-200;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.s-chart__data-table tbody th { @apply font-medium; }
|
|
136
|
+
.s-chart__data-table tbody td { @apply tabular-nums; }
|
|
137
|
+
.s-chart__data-table--assistive { @apply sr-only; }
|
|
138
|
+
|
|
139
|
+
[data-s-chart-tone='series-1'] { --s-chart-tone: var(--s-chart-series-1); }
|
|
140
|
+
[data-s-chart-tone='series-2'] { --s-chart-tone: var(--s-chart-series-2); }
|
|
141
|
+
[data-s-chart-tone='series-3'] { --s-chart-tone: var(--s-chart-series-3); }
|
|
142
|
+
[data-s-chart-tone='series-4'] { --s-chart-tone: var(--s-chart-series-4); }
|
|
143
|
+
[data-s-chart-tone='series-5'] { --s-chart-tone: var(--s-chart-series-5); }
|
|
144
|
+
[data-s-chart-tone='series-6'] { --s-chart-tone: var(--s-chart-series-6); }
|
|
145
|
+
[data-s-chart-tone='series-7'] { --s-chart-tone: var(--s-chart-series-7); }
|
|
146
|
+
[data-s-chart-tone='series-8'] { --s-chart-tone: var(--s-chart-series-8); }
|
|
147
|
+
[data-s-chart-tone='success'] { --s-chart-tone: var(--color-success-500); }
|
|
148
|
+
[data-s-chart-tone='warn'] { --s-chart-tone: var(--color-warn-500); }
|
|
149
|
+
[data-s-chart-tone='danger'] { --s-chart-tone: var(--color-danger-500); }
|