vira 31.15.2 → 31.16.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/dist/elements/vira-button.element.d.ts +6 -4
- package/dist/elements/vira-button.element.js +113 -93
- package/dist/elements/vira-tabs.element.d.ts +14 -16
- package/dist/elements/vira-tabs.element.js +106 -78
- package/dist/elements/vira-tag.element.d.ts +9 -3
- package/dist/elements/vira-tag.element.js +139 -112
- package/dist/styles/form-variants.d.ts +29 -13
- package/dist/styles/form-variants.js +33 -24
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type PartialWithUndefined } from '@augment-vir/common';
|
|
2
2
|
import { type ViraIconSvg } from '../icons/index.js';
|
|
3
3
|
import { ViraColorVariant, ViraEmphasis, ViraSize } from '../styles/index.js';
|
|
4
|
+
import { ViraThemeColorName } from '../styles/vira-color-theme-object.js';
|
|
4
5
|
/**
|
|
5
6
|
* A custom button with default styling.
|
|
6
7
|
*
|
|
@@ -27,16 +28,17 @@ export declare const ViraButton: import("element-vir").DeclarativeElementDefinit
|
|
|
27
28
|
*/
|
|
28
29
|
buttonSize: ViraSize;
|
|
29
30
|
/**
|
|
30
|
-
* Set a predefined color variant
|
|
31
|
+
* Set a predefined color variant or a raw {@link ViraThemeColorName} (e.g.,
|
|
32
|
+
* `ViraThemeColorName.blue`). Set to `ViraColorVariant.Custom` for maximum customization.
|
|
31
33
|
* In that case, you will need to use this element's CSS vars to customize the colors.
|
|
32
34
|
*
|
|
33
|
-
* @default ViraColorVariant.
|
|
35
|
+
* @default ViraColorVariant.Plain
|
|
34
36
|
*/
|
|
35
|
-
|
|
37
|
+
color: ViraColorVariant | ViraThemeColorName;
|
|
36
38
|
/**
|
|
37
39
|
* Set to `true`
|
|
38
40
|
*
|
|
39
41
|
* @default false
|
|
40
42
|
*/
|
|
41
43
|
showMenuCaret: boolean;
|
|
42
|
-
}>, {}, {}, "vira-button-with-menu-caret" | "vira-button-size-large" | "vira-button-size-medium" | "vira-button-size-small" | "vira-button-emphasis-standard" | "vira-button-emphasis-subtle" | "vira-button-color-
|
|
44
|
+
}>, {}, {}, "vira-button-with-menu-caret" | "vira-button-size-large" | "vira-button-size-medium" | "vira-button-size-small" | "vira-button-emphasis-standard" | "vira-button-emphasis-subtle" | "vira-button-color-red" | "vira-button-color-yellow" | "vira-button-color-green" | "vira-button-color-blue" | "vira-button-color-brand" | "vira-button-color-purple" | "vira-button-color-plain" | "vira-button-color-neutral" | "vira-button-color-teal" | "vira-button-color-pink" | "vira-button-color-grey" | "vira-button-disabled" | "vira-button-icon-only", "vira-button-text-color" | "vira-button-background-color" | "vira-button-border-color" | "vira-button-hover-text-color" | "vira-button-hover-background-color" | "vira-button-hover-border-color" | "vira-button-active-text-color" | "vira-button-active-background-color" | "vira-button-active-border-color" | "vira-button-disabled-text-color" | "vira-button-disabled-background-color" | "vira-button-disabled-border-color" | "vira-button-border-width" | "vira-button-border-radius", readonly [], readonly []>;
|
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import { arrayToObject,
|
|
1
|
+
import { arrayToObject, getObjectTypedKeys } from '@augment-vir/common';
|
|
2
2
|
import { ContrastLevelName } from '@electrovir/color/dist/data/contrast/contrast.js';
|
|
3
3
|
import { css, html, nothing, unsafeCSS } from 'element-vir';
|
|
4
4
|
import { themeDefaultKey } from 'theme-vir/dist/color-theme/color-theme.js';
|
|
5
5
|
import { ChevronDown16Icon } from '../icons/index.js';
|
|
6
6
|
import { createFocusStyles } from '../styles/focus.js';
|
|
7
7
|
import { viraFormCssVars } from '../styles/form-styles.js';
|
|
8
|
-
import {
|
|
8
|
+
import { standaloneThemeColorNames, viraColorVariantToHostClassKey, viraEmphasisVariants, viraSizeHeights, viraSizeVariants, } from '../styles/form-variants.js';
|
|
9
9
|
import { noUserSelect, ViraColorVariant, ViraEmphasis, ViraSize, viraTheme, } from '../styles/index.js';
|
|
10
10
|
import { noNativeFormStyles } from '../styles/native-styles.js';
|
|
11
|
-
import { viraThemeByKeys } from '../styles/vira-color-theme-object.js';
|
|
11
|
+
import { viraThemeByKeys, ViraThemeColorName } from '../styles/vira-color-theme-object.js';
|
|
12
12
|
import { defineViraElement } from '../util/define-vira-element.js';
|
|
13
13
|
import { ViraIcon } from './vira-icon.element.js';
|
|
14
14
|
const transparentColor = {
|
|
15
15
|
value: css `transparent`,
|
|
16
16
|
};
|
|
17
|
-
function buildThemedButtonColors(
|
|
18
|
-
const colorName = viraColorVariantToColorName[colorVariant];
|
|
17
|
+
function buildThemedButtonColors(colorName) {
|
|
19
18
|
const behindBg = viraThemeByKeys[colorName]['behind-bg'];
|
|
20
19
|
const foreground = viraThemeByKeys[colorName].foreground;
|
|
21
20
|
const onSelf = viraThemeByKeys[colorName]['on-self'];
|
|
@@ -56,66 +55,61 @@ function buildThemedButtonColors(colorVariant) {
|
|
|
56
55
|
},
|
|
57
56
|
};
|
|
58
57
|
}
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
idle: {
|
|
66
|
-
backgroundColor: viraTheme.inverse[themeDefaultKey].background,
|
|
67
|
-
textColor: viraTheme.inverse[themeDefaultKey].foreground,
|
|
68
|
-
borderColor: viraTheme.inverse[themeDefaultKey].background,
|
|
69
|
-
},
|
|
70
|
-
hover: {
|
|
71
|
-
backgroundColor: viraTheme.colors['vira-grey-behind-bg-non-body'].background,
|
|
72
|
-
textColor: viraTheme.colors['vira-grey-behind-bg-non-body'].foreground,
|
|
73
|
-
borderColor: viraTheme.inverse[themeDefaultKey].background,
|
|
74
|
-
},
|
|
75
|
-
active: {
|
|
76
|
-
backgroundColor: viraTheme.colors['vira-grey-behind-bg-body'].background,
|
|
77
|
-
textColor: viraTheme.colors['vira-grey-behind-bg-body'].foreground,
|
|
78
|
-
borderColor: viraTheme.inverse[themeDefaultKey].background,
|
|
79
|
-
},
|
|
58
|
+
const plainButtonColors = {
|
|
59
|
+
[ViraEmphasis.Standard]: {
|
|
60
|
+
idle: {
|
|
61
|
+
backgroundColor: viraTheme.inverse[themeDefaultKey].background,
|
|
62
|
+
textColor: viraTheme.inverse[themeDefaultKey].foreground,
|
|
63
|
+
borderColor: viraTheme.inverse[themeDefaultKey].background,
|
|
80
64
|
},
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
borderColor: viraTheme.colors['vira-grey-on-self-body'].foreground,
|
|
91
|
-
},
|
|
92
|
-
active: {
|
|
93
|
-
backgroundColor: viraTheme.colors['vira-grey-on-self-non-body'].background,
|
|
94
|
-
textColor: viraTheme.colors['vira-grey-on-self-non-body'].foreground,
|
|
95
|
-
borderColor: viraTheme.colors['vira-grey-on-self-non-body'].foreground,
|
|
96
|
-
},
|
|
65
|
+
hover: {
|
|
66
|
+
backgroundColor: viraTheme.colors['vira-grey-behind-bg-non-body'].background,
|
|
67
|
+
textColor: viraTheme.colors['vira-grey-behind-bg-non-body'].foreground,
|
|
68
|
+
borderColor: viraTheme.inverse[themeDefaultKey].background,
|
|
69
|
+
},
|
|
70
|
+
active: {
|
|
71
|
+
backgroundColor: viraTheme.colors['vira-grey-behind-bg-body'].background,
|
|
72
|
+
textColor: viraTheme.colors['vira-grey-behind-bg-body'].foreground,
|
|
73
|
+
borderColor: viraTheme.inverse[themeDefaultKey].background,
|
|
97
74
|
},
|
|
98
75
|
},
|
|
99
|
-
[
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
76
|
+
[ViraEmphasis.Subtle]: {
|
|
77
|
+
idle: {
|
|
78
|
+
backgroundColor: transparentColor,
|
|
79
|
+
textColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
80
|
+
borderColor: transparentColor,
|
|
81
|
+
},
|
|
82
|
+
hover: {
|
|
83
|
+
backgroundColor: viraTheme.colors['vira-grey-on-self-body'].background,
|
|
84
|
+
textColor: viraTheme.colors['vira-grey-on-self-body'].foreground,
|
|
85
|
+
borderColor: viraTheme.colors['vira-grey-on-self-body'].foreground,
|
|
86
|
+
},
|
|
87
|
+
active: {
|
|
88
|
+
backgroundColor: viraTheme.colors['vira-grey-on-self-non-body'].background,
|
|
89
|
+
textColor: viraTheme.colors['vira-grey-on-self-non-body'].foreground,
|
|
90
|
+
borderColor: viraTheme.colors['vira-grey-on-self-non-body'].foreground,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
const neutralButtonColors = {
|
|
95
|
+
[ViraEmphasis.Standard]: {
|
|
96
|
+
idle: {
|
|
97
|
+
backgroundColor: viraTheme.colors[themeDefaultKey].background,
|
|
98
|
+
textColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
99
|
+
borderColor: viraFormCssVars['vira-form-border-color'],
|
|
100
|
+
},
|
|
101
|
+
hover: {
|
|
102
|
+
backgroundColor: viraTheme.colors['vira-grey-behind-fg-small-body'].background,
|
|
103
|
+
textColor: viraTheme.colors['vira-grey-behind-fg-small-body'].foreground,
|
|
104
|
+
borderColor: viraFormCssVars['vira-form-border-color'],
|
|
105
|
+
},
|
|
106
|
+
active: {
|
|
107
|
+
backgroundColor: viraTheme.colors['vira-grey-behind-fg-body'].background,
|
|
108
|
+
textColor: viraTheme.colors['vira-grey-behind-fg-body'].foreground,
|
|
109
|
+
borderColor: viraFormCssVars['vira-form-border-color'],
|
|
116
110
|
},
|
|
117
|
-
[ViraEmphasis.Subtle]: buildThemedButtonColors(ViraColorVariant.Neutral)[ViraEmphasis.Subtle],
|
|
118
111
|
},
|
|
112
|
+
[ViraEmphasis.Subtle]: buildThemedButtonColors(ViraThemeColorName.grey)[ViraEmphasis.Subtle],
|
|
119
113
|
};
|
|
120
114
|
/**
|
|
121
115
|
* A custom button with default styling.
|
|
@@ -133,13 +127,24 @@ export const ViraButton = defineViraElement()({
|
|
|
133
127
|
'vira-button-size-small': ({ inputs }) => inputs.buttonSize === ViraSize.Small,
|
|
134
128
|
'vira-button-emphasis-standard': ({ inputs }) => !inputs.buttonEmphasis || inputs.buttonEmphasis === ViraEmphasis.Standard,
|
|
135
129
|
'vira-button-emphasis-subtle': ({ inputs }) => inputs.buttonEmphasis === ViraEmphasis.Subtle,
|
|
136
|
-
...arrayToObject(
|
|
130
|
+
...arrayToObject(getObjectTypedKeys(viraColorVariantToHostClassKey), (colorVariant) => {
|
|
131
|
+
const colorKey = viraColorVariantToHostClassKey[colorVariant];
|
|
137
132
|
return {
|
|
138
|
-
key: `vira-button-color-${
|
|
133
|
+
key: `vira-button-color-${colorKey}`,
|
|
139
134
|
value: ({ inputs, }) => {
|
|
140
|
-
return colorVariant ===
|
|
141
|
-
|
|
142
|
-
|
|
135
|
+
return inputs.color === colorVariant || inputs.color === colorKey;
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}, {
|
|
139
|
+
useRequired: true,
|
|
140
|
+
}),
|
|
141
|
+
'vira-button-color-plain': ({ inputs, }) => !inputs.color || inputs.color === ViraColorVariant.Plain,
|
|
142
|
+
'vira-button-color-neutral': ({ inputs, }) => inputs.color === ViraColorVariant.Neutral,
|
|
143
|
+
...arrayToObject(standaloneThemeColorNames, (colorName) => {
|
|
144
|
+
return {
|
|
145
|
+
key: `vira-button-color-${colorName}`,
|
|
146
|
+
value: ({ inputs, }) => {
|
|
147
|
+
return inputs.color === colorName;
|
|
143
148
|
},
|
|
144
149
|
};
|
|
145
150
|
}, {
|
|
@@ -165,37 +170,52 @@ export const ViraButton = defineViraElement()({
|
|
|
165
170
|
'vira-button-border-radius': viraFormCssVars['vira-form-radius'].value,
|
|
166
171
|
},
|
|
167
172
|
styles: ({ hostClasses, cssVars }) => {
|
|
168
|
-
function
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
${variantSelector}${emphasisSelector} {
|
|
176
|
-
${cssVars['vira-button-background-color'].name}: ${colors.idle
|
|
177
|
-
.backgroundColor.value};
|
|
178
|
-
${cssVars['vira-button-text-color'].name}: ${colors.idle.textColor
|
|
179
|
-
.value};
|
|
180
|
-
${cssVars['vira-button-border-color'].name}: ${colors.idle.borderColor
|
|
181
|
-
.value};
|
|
173
|
+
function buildVariantCssRule(variantSelector, emphasisSelector, colors) {
|
|
174
|
+
return css `
|
|
175
|
+
${variantSelector}${emphasisSelector} {
|
|
176
|
+
${cssVars['vira-button-background-color'].name}: ${colors.idle.backgroundColor
|
|
177
|
+
.value};
|
|
178
|
+
${cssVars['vira-button-text-color'].name}: ${colors.idle.textColor.value};
|
|
179
|
+
${cssVars['vira-button-border-color'].name}: ${colors.idle.borderColor.value};
|
|
182
180
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
181
|
+
${cssVars['vira-button-hover-background-color'].name}: ${colors.hover
|
|
182
|
+
.backgroundColor.value};
|
|
183
|
+
${cssVars['vira-button-hover-text-color'].name}: ${colors.hover.textColor
|
|
184
|
+
.value};
|
|
185
|
+
${cssVars['vira-button-hover-border-color'].name}: ${colors.hover.borderColor
|
|
186
|
+
.value};
|
|
189
187
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
188
|
+
${cssVars['vira-button-active-background-color'].name}: ${colors.active
|
|
189
|
+
.backgroundColor.value};
|
|
190
|
+
${cssVars['vira-button-active-text-color'].name}: ${colors.active.textColor
|
|
191
|
+
.value};
|
|
192
|
+
${cssVars['vira-button-active-border-color'].name}: ${colors.active.borderColor
|
|
193
|
+
.value};
|
|
194
|
+
}
|
|
195
|
+
`;
|
|
196
|
+
}
|
|
197
|
+
function generateVariantCss() {
|
|
198
|
+
const allStyles = viraEmphasisVariants.flatMap((emphasis) => {
|
|
199
|
+
const emphasisSelector = hostClasses[`vira-button-emphasis-${emphasis}`].selector;
|
|
200
|
+
const themedStyles = getObjectTypedKeys(viraColorVariantToHostClassKey).map((colorVariant) => {
|
|
201
|
+
const colorKey = viraColorVariantToHostClassKey[colorVariant];
|
|
202
|
+
const colors = buildThemedButtonColors(colorKey)[emphasis];
|
|
203
|
+
const variantSelector = hostClasses[`vira-button-color-${colorKey}`].selector;
|
|
204
|
+
return buildVariantCssRule(variantSelector, emphasisSelector, colors);
|
|
205
|
+
});
|
|
206
|
+
const plainStyle = buildVariantCssRule(hostClasses['vira-button-color-plain'].selector, emphasisSelector, plainButtonColors[emphasis]);
|
|
207
|
+
const neutralStyle = buildVariantCssRule(hostClasses['vira-button-color-neutral'].selector, emphasisSelector, neutralButtonColors[emphasis]);
|
|
208
|
+
const standaloneStyles = standaloneThemeColorNames.map((colorName) => {
|
|
209
|
+
const colors = buildThemedButtonColors(colorName)[emphasis];
|
|
210
|
+
const variantSelector = hostClasses[`vira-button-color-${colorName}`].selector;
|
|
211
|
+
return buildVariantCssRule(variantSelector, emphasisSelector, colors);
|
|
198
212
|
});
|
|
213
|
+
return [
|
|
214
|
+
...themedStyles,
|
|
215
|
+
plainStyle,
|
|
216
|
+
neutralStyle,
|
|
217
|
+
...standaloneStyles,
|
|
218
|
+
];
|
|
199
219
|
});
|
|
200
220
|
return unsafeCSS(allStyles.join('\n'));
|
|
201
221
|
}
|
|
@@ -2,7 +2,7 @@ import { type PartialWithUndefined } from '@augment-vir/common';
|
|
|
2
2
|
import { type FullSpaRoute, type GenericTreePaths, type SpaRouter } from 'spa-router-vir';
|
|
3
3
|
import { type ViraIconSvg } from '../icons/icon-svg.js';
|
|
4
4
|
import { ViraColorVariant } from '../styles/form-variants.js';
|
|
5
|
-
import {
|
|
5
|
+
import { ViraThemeColorName } from '../styles/vira-color-theme-object.js';
|
|
6
6
|
/**
|
|
7
7
|
* Controls which edge of the tab the selection indicator bar appears on.
|
|
8
8
|
*
|
|
@@ -45,7 +45,7 @@ export type ViraTab = {
|
|
|
45
45
|
*/
|
|
46
46
|
export declare const ViraTabs: import("element-vir").DeclarativeElementDefinition<"vira-tabs", {
|
|
47
47
|
tabs: ReadonlyArray<Readonly<ViraTab>>;
|
|
48
|
-
router: Pick<SpaRouter<any, any, any>, "createRouteUrl" | "setRouteOnDirectNavigation">;
|
|
48
|
+
router: Pick<SpaRouter<any, any, any>, "createRouteUrl" | "setRouteOnDirectNavigation" | "setRoute">;
|
|
49
49
|
currentRoute: Readonly<FullSpaRoute>;
|
|
50
50
|
} & PartialWithUndefined<{
|
|
51
51
|
/**
|
|
@@ -55,34 +55,32 @@ export declare const ViraTabs: import("element-vir").DeclarativeElementDefinitio
|
|
|
55
55
|
*/
|
|
56
56
|
barDirection: ViraTabsBarDirection;
|
|
57
57
|
/**
|
|
58
|
-
* Color variant for the tab selection indicator and active tab text.
|
|
58
|
+
* Color variant for the tab selection indicator and active tab text. Accepts any
|
|
59
|
+
* {@link ViraColorVariant} or a {@link ViraThemeColorName} (e.g.,
|
|
60
|
+
* `ViraThemeColorName.blue`).
|
|
59
61
|
*
|
|
60
|
-
* @default ViraColorVariant.
|
|
62
|
+
* @default ViraColorVariant.Plain
|
|
61
63
|
*/
|
|
62
|
-
|
|
64
|
+
color: ViraColorVariant | ViraThemeColorName;
|
|
63
65
|
/**
|
|
64
66
|
* Layout direction for icons relative to their label text.
|
|
65
67
|
*
|
|
66
68
|
* @default ViraTabsIconLayout.Vertical
|
|
67
69
|
*/
|
|
68
70
|
iconLayout: ViraTabsIconLayout;
|
|
69
|
-
/**
|
|
70
|
-
* Horizontal anchor for the dropdown menu. Only used when tabs overflow into a dropdown.
|
|
71
|
-
*
|
|
72
|
-
* @default HorizontalAnchor.Left
|
|
73
|
-
*/
|
|
74
|
-
menuHorizontalAnchor: HorizontalAnchor;
|
|
75
|
-
/** Whether the dropdown trigger is disabled. Only used when tabs overflow into a dropdown. */
|
|
76
|
-
menuIsDisabled: boolean;
|
|
77
|
-
/** Offset for the dropdown pop-up. Only used when tabs overflow into a dropdown. */
|
|
78
|
-
menuPopUpOffset: Readonly<PopUpOffset>;
|
|
79
71
|
/** When true, tabs and their container expand to fill all available horizontal space. */
|
|
80
72
|
shouldFillWidth: boolean;
|
|
81
73
|
}>, {
|
|
82
74
|
isOverflowing: boolean;
|
|
83
75
|
/** A callback to remove all internal observers. */
|
|
84
76
|
cleanupObserver: undefined | (() => void);
|
|
77
|
+
/**
|
|
78
|
+
* Captured at the moment the overflow select is opened (mousedown or keydown on the
|
|
79
|
+
* select). Once the native picker opens, the OS owns keyboard input, so modifier state
|
|
80
|
+
* must be captured before that.
|
|
81
|
+
*/
|
|
82
|
+
modifierKeyHeld: boolean;
|
|
85
83
|
}, {
|
|
86
84
|
/** Fires when a tab is clicked with the corresponding tab entry. */
|
|
87
85
|
tabSelect: import("element-vir").DefineEvent<Readonly<ViraTab>>;
|
|
88
|
-
}, "vira-tabs-bar-top" | "vira-tabs-bar-bottom" | "vira-tabs-bar-left" | "vira-tabs-bar-right" | "vira-tabs-color-
|
|
86
|
+
}, "vira-tabs-bar-top" | "vira-tabs-bar-bottom" | "vira-tabs-bar-left" | "vira-tabs-bar-right" | "vira-tabs-color-red" | "vira-tabs-color-yellow" | "vira-tabs-color-green" | "vira-tabs-color-blue" | "vira-tabs-color-brand" | "vira-tabs-color-purple" | "vira-tabs-color-plain" | "vira-tabs-color-neutral" | "vira-tabs-color-teal" | "vira-tabs-color-pink" | "vira-tabs-color-grey" | "vira-tabs-icon-layout-vertical" | "vira-tabs-icon-layout-horizontal" | "vira-tabs-overflowing" | "vira-tabs-fill-width", "vira-tabs-active-color" | "vira-tabs-active-hover-color" | "vira-tabs-inactive-color" | "vira-tabs-inactive-hover-color" | "vira-tabs-bar-thickness", readonly [], readonly []>;
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import { check } from '@augment-vir/assert';
|
|
2
|
-
import { arrayToObject, filterMap } from '@augment-vir/common';
|
|
2
|
+
import { arrayToObject, filterMap, getObjectTypedKeys, } from '@augment-vir/common';
|
|
3
3
|
import { ContrastLevelName } from '@electrovir/color/dist/data/contrast/contrast.js';
|
|
4
4
|
import { classMap, css, defineElementEvent, html, listen, nothing, onDomCreated, unsafeCSS, } from 'element-vir';
|
|
5
5
|
import { routeHasPaths, } from 'spa-router-vir';
|
|
6
6
|
import { createFocusStyles } from '../styles/focus.js';
|
|
7
7
|
import { viraFormCssVars } from '../styles/form-styles.js';
|
|
8
|
-
import {
|
|
8
|
+
import { standaloneThemeColorNames, ViraColorVariant, viraColorVariantToHostClassKey, } from '../styles/form-variants.js';
|
|
9
9
|
import { noNativeFormStyles, noUserSelect, viraDisabledStyles, viraTheme } from '../styles/index.js';
|
|
10
|
-
import { viraThemeByKeys } from '../styles/vira-color-theme-object.js';
|
|
10
|
+
import { viraThemeByKeys, ViraThemeColorName } from '../styles/vira-color-theme-object.js';
|
|
11
11
|
import { defineViraElement } from '../util/define-vira-element.js';
|
|
12
12
|
import { createOverflowObserver } from '../util/overflow-observer.js';
|
|
13
|
-
import { renderMenuItemEntries } from '../util/pop-up-helpers.js';
|
|
14
|
-
import { ViraMenuTrigger } from './pop-up/vira-menu-trigger.element.js';
|
|
15
|
-
import { ViraMenuCornerStyle } from './pop-up/vira-menu.element.js';
|
|
16
|
-
import { ViraButton } from './vira-button.element.js';
|
|
17
13
|
import { ViraIcon } from './vira-icon.element.js';
|
|
18
14
|
import { ViraLink } from './vira-link.element.js';
|
|
15
|
+
import { ViraSelect } from './vira-select.element.js';
|
|
19
16
|
/**
|
|
20
17
|
* Controls which edge of the tab the selection indicator bar appears on.
|
|
21
18
|
*
|
|
@@ -56,6 +53,12 @@ export const ViraTabs = defineViraElement()({
|
|
|
56
53
|
isOverflowing: false,
|
|
57
54
|
/** A callback to remove all internal observers. */
|
|
58
55
|
cleanupObserver: undefined,
|
|
56
|
+
/**
|
|
57
|
+
* Captured at the moment the overflow select is opened (mousedown or keydown on the
|
|
58
|
+
* select). Once the native picker opens, the OS owns keyboard input, so modifier state
|
|
59
|
+
* must be captured before that.
|
|
60
|
+
*/
|
|
61
|
+
modifierKeyHeld: false,
|
|
59
62
|
};
|
|
60
63
|
},
|
|
61
64
|
hostClasses: {
|
|
@@ -63,13 +66,24 @@ export const ViraTabs = defineViraElement()({
|
|
|
63
66
|
'vira-tabs-bar-bottom': ({ inputs }) => !inputs.barDirection || inputs.barDirection === ViraTabsBarDirection.Bottom,
|
|
64
67
|
'vira-tabs-bar-left': ({ inputs }) => inputs.barDirection === ViraTabsBarDirection.Left,
|
|
65
68
|
'vira-tabs-bar-right': ({ inputs }) => inputs.barDirection === ViraTabsBarDirection.Right,
|
|
66
|
-
...arrayToObject(
|
|
69
|
+
...arrayToObject(getObjectTypedKeys(viraColorVariantToHostClassKey), (colorVariant) => {
|
|
70
|
+
const colorKey = viraColorVariantToHostClassKey[colorVariant];
|
|
67
71
|
return {
|
|
68
|
-
key: `vira-tabs-color-${
|
|
72
|
+
key: `vira-tabs-color-${colorKey}`,
|
|
69
73
|
value: ({ inputs, }) => {
|
|
70
|
-
return colorVariant ===
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
return inputs.color === colorVariant || inputs.color === colorKey;
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}, {
|
|
78
|
+
useRequired: true,
|
|
79
|
+
}),
|
|
80
|
+
'vira-tabs-color-plain': ({ inputs, }) => !inputs.color || inputs.color === ViraColorVariant.Plain,
|
|
81
|
+
'vira-tabs-color-neutral': ({ inputs, }) => inputs.color === ViraColorVariant.Neutral,
|
|
82
|
+
...arrayToObject(standaloneThemeColorNames, (colorName) => {
|
|
83
|
+
return {
|
|
84
|
+
key: `vira-tabs-color-${colorName}`,
|
|
85
|
+
value: ({ inputs, }) => {
|
|
86
|
+
return inputs.color === colorName;
|
|
73
87
|
},
|
|
74
88
|
};
|
|
75
89
|
}, {
|
|
@@ -81,40 +95,57 @@ export const ViraTabs = defineViraElement()({
|
|
|
81
95
|
'vira-tabs-fill-width': ({ inputs }) => !!inputs.shouldFillWidth,
|
|
82
96
|
},
|
|
83
97
|
cssVars: {
|
|
84
|
-
'vira-tabs-active-color': viraThemeByKeys[
|
|
85
|
-
'vira-tabs-active-hover-color': viraThemeByKeys[
|
|
98
|
+
'vira-tabs-active-color': viraThemeByKeys[viraColorVariantToHostClassKey[ViraColorVariant.Info]]['behind-bg'][ContrastLevelName.NonBodyText].background.value,
|
|
99
|
+
'vira-tabs-active-hover-color': viraThemeByKeys[viraColorVariantToHostClassKey[ViraColorVariant.Info]]['behind-bg'][ContrastLevelName.Header].background.value,
|
|
86
100
|
'vira-tabs-inactive-color': viraTheme.colors['vira-grey-foreground-header'].foreground.value,
|
|
87
101
|
'vira-tabs-inactive-hover-color': viraTheme.colors['vira-grey-foreground-non-body'].foreground.value,
|
|
88
102
|
'vira-tabs-bar-thickness': '3px',
|
|
89
103
|
},
|
|
90
104
|
styles: ({ hostClasses, cssVars }) => {
|
|
105
|
+
function buildThemedTabsColors(colorName) {
|
|
106
|
+
return {
|
|
107
|
+
active: viraThemeByKeys[colorName]['behind-bg'][ContrastLevelName.NonBodyText]
|
|
108
|
+
.background,
|
|
109
|
+
hover: viraThemeByKeys[colorName]['behind-bg'][ContrastLevelName.Header].background,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function buildVariantCssRule(variantSelector, colors) {
|
|
113
|
+
return css `
|
|
114
|
+
${variantSelector} {
|
|
115
|
+
${cssVars['vira-tabs-active-color'].name}: ${colors.active.value};
|
|
116
|
+
${cssVars['vira-tabs-active-hover-color'].name}: ${colors.hover.value};
|
|
117
|
+
}
|
|
118
|
+
`;
|
|
119
|
+
}
|
|
91
120
|
function generateVariantCss() {
|
|
92
121
|
const plainColors = {
|
|
93
122
|
active: viraTheme.colors['vira-grey-foreground-small-body'].foreground,
|
|
94
123
|
hover: viraTheme.colors['vira-grey-foreground-body'].foreground,
|
|
95
124
|
};
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
const variantSelector = hostClasses[`vira-tabs-color-${
|
|
99
|
-
const colors =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
125
|
+
const themedStyles = getObjectTypedKeys(viraColorVariantToHostClassKey).map((colorVariant) => {
|
|
126
|
+
const colorKey = viraColorVariantToHostClassKey[colorVariant];
|
|
127
|
+
const variantSelector = hostClasses[`vira-tabs-color-${colorKey}`].selector;
|
|
128
|
+
const colors = buildThemedTabsColors(colorKey);
|
|
129
|
+
return buildVariantCssRule(variantSelector, colors);
|
|
130
|
+
});
|
|
131
|
+
const plainStyle = buildVariantCssRule(hostClasses['vira-tabs-color-plain'].selector, plainColors);
|
|
132
|
+
const neutralStyle = buildVariantCssRule(hostClasses['vira-tabs-color-neutral'].selector, buildThemedTabsColors(ViraThemeColorName.grey));
|
|
133
|
+
const standaloneStyles = standaloneThemeColorNames.map((colorName) => {
|
|
134
|
+
const variantSelector = hostClasses[`vira-tabs-color-${colorName}`].selector;
|
|
135
|
+
const colors = buildThemedTabsColors(colorName);
|
|
136
|
+
return buildVariantCssRule(variantSelector, colors);
|
|
137
|
+
});
|
|
138
|
+
return unsafeCSS([
|
|
139
|
+
...themedStyles,
|
|
140
|
+
plainStyle,
|
|
141
|
+
neutralStyle,
|
|
142
|
+
...standaloneStyles,
|
|
143
|
+
].join('\n'));
|
|
114
144
|
}
|
|
115
145
|
return css `
|
|
116
146
|
:host {
|
|
117
147
|
display: flex;
|
|
148
|
+
position: relative;
|
|
118
149
|
box-sizing: border-box;
|
|
119
150
|
${noUserSelect};
|
|
120
151
|
width: 100%;
|
|
@@ -265,18 +296,19 @@ export const ViraTabs = defineViraElement()({
|
|
|
265
296
|
|
|
266
297
|
${hostClasses['vira-tabs-overflowing'].selector} .tabs-container {
|
|
267
298
|
visibility: hidden;
|
|
299
|
+
position: absolute;
|
|
268
300
|
height: 0;
|
|
269
301
|
}
|
|
270
302
|
|
|
271
|
-
|
|
303
|
+
${ViraSelect} {
|
|
272
304
|
display: none;
|
|
273
305
|
}
|
|
274
306
|
|
|
275
|
-
${hostClasses['vira-tabs-overflowing'].selector}
|
|
276
|
-
display: flex;
|
|
307
|
+
${hostClasses['vira-tabs-overflowing'].selector} ${ViraSelect} {
|
|
308
|
+
display: inline-flex;
|
|
277
309
|
align-items: center;
|
|
278
310
|
width: fit-content;
|
|
279
|
-
|
|
311
|
+
max-width: 100%;
|
|
280
312
|
}
|
|
281
313
|
|
|
282
314
|
${hostClasses['vira-tabs-fill-width'].selector} {
|
|
@@ -302,10 +334,6 @@ export const ViraTabs = defineViraElement()({
|
|
|
302
334
|
display: flex;
|
|
303
335
|
padding: 8px 16px;
|
|
304
336
|
}
|
|
305
|
-
|
|
306
|
-
${ViraMenuTrigger} {
|
|
307
|
-
margin: 3px 0;
|
|
308
|
-
}
|
|
309
337
|
`;
|
|
310
338
|
},
|
|
311
339
|
cleanup({ state }) {
|
|
@@ -365,53 +393,53 @@ export const ViraTabs = defineViraElement()({
|
|
|
365
393
|
`;
|
|
366
394
|
}, check.isTruthy);
|
|
367
395
|
const selectedTab = inputs.tabs.find((tab) => routeHasPaths(inputs.currentRoute, tab.paths));
|
|
368
|
-
const
|
|
396
|
+
const selectOptions = filterMap(inputs.tabs, (tab) => {
|
|
369
397
|
if (tab.isHidden) {
|
|
370
398
|
return undefined;
|
|
371
399
|
}
|
|
372
|
-
const isSelected = routeHasPaths(inputs.currentRoute, tab.paths);
|
|
373
400
|
return {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
route: {
|
|
377
|
-
router: inputs.router,
|
|
378
|
-
route: {
|
|
379
|
-
paths: tab.paths.fullPaths,
|
|
380
|
-
},
|
|
381
|
-
scrollToTop: true,
|
|
382
|
-
},
|
|
383
|
-
disableLinkStyles: true,
|
|
384
|
-
})}>
|
|
385
|
-
${tab.label}
|
|
386
|
-
</${ViraLink}>
|
|
387
|
-
`,
|
|
388
|
-
selected: isSelected,
|
|
401
|
+
value: tab.paths.fullPaths.join('/'),
|
|
402
|
+
label: tab.label,
|
|
389
403
|
disabled: tab.isDisabled,
|
|
390
|
-
onClick() {
|
|
391
|
-
if (!tab.isDisabled) {
|
|
392
|
-
dispatch(new events.tabSelect(tab));
|
|
393
|
-
}
|
|
394
|
-
},
|
|
395
404
|
};
|
|
396
|
-
}, check.isTruthy)
|
|
405
|
+
}, check.isTruthy);
|
|
406
|
+
function captureModifierState(event) {
|
|
407
|
+
updateState({
|
|
408
|
+
modifierKeyHeld: event.ctrlKey || event.metaKey || event.shiftKey,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
397
411
|
return html `
|
|
398
|
-
<${
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
popUpOffset: inputs.menuPopUpOffset,
|
|
402
|
-
menuCornerStyle: ViraMenuCornerStyle.AllRounded,
|
|
412
|
+
<${ViraSelect.assign({
|
|
413
|
+
options: selectOptions,
|
|
414
|
+
value: selectedTab?.paths.fullPaths.join('/'),
|
|
403
415
|
})}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
416
|
+
${listen('mousedown', captureModifierState)}
|
|
417
|
+
${listen('keydown', captureModifierState)}
|
|
418
|
+
${listen(ViraSelect.events.valueChange, (event) => {
|
|
419
|
+
try {
|
|
420
|
+
const selectedValue = event.detail;
|
|
421
|
+
const tab = inputs.tabs.find((tab) => tab.paths.fullPaths.join('/') === selectedValue);
|
|
422
|
+
if (!tab || tab.isDisabled) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
dispatch(new events.tabSelect(tab));
|
|
426
|
+
const route = {
|
|
427
|
+
paths: tab.paths.fullPaths,
|
|
428
|
+
};
|
|
429
|
+
if (state.modifierKeyHeld) {
|
|
430
|
+
globalThis.open(inputs.router.createRouteUrl(route), '_blank', 'noopener,noreferrer');
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
inputs.router.setRoute(route);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
finally {
|
|
437
|
+
updateState({
|
|
438
|
+
modifierKeyHeld: false,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
410
441
|
})}
|
|
411
|
-
|
|
412
|
-
></${ViraButton}>
|
|
413
|
-
${menuItems}
|
|
414
|
-
</${ViraMenuTrigger}>
|
|
442
|
+
></${ViraSelect}>
|
|
415
443
|
<ul
|
|
416
444
|
class="tabs-container"
|
|
417
445
|
role="tablist"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type PartialWithUndefined } from '@augment-vir/common';
|
|
2
2
|
import { type Primitive, type RequireExactlyOne } from 'type-fest';
|
|
3
3
|
import { ViraColorVariant, ViraEmphasis, ViraSize } from '../styles/form-variants.js';
|
|
4
|
+
import { ViraThemeColorName } from '../styles/vira-color-theme-object.js';
|
|
4
5
|
/**
|
|
5
6
|
* A "tag" or "label" or "pill" element. Supports many variations including non-clickable,
|
|
6
7
|
* selectable, and cancellable variations.
|
|
@@ -26,10 +27,15 @@ export declare const ViraTag: import("element-vir").DeclarativeElementDefinition
|
|
|
26
27
|
size: ViraSize;
|
|
27
28
|
/** @default ViraEmphasis.Standard */
|
|
28
29
|
emphasis: ViraEmphasis;
|
|
29
|
-
/**
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Color scheme. Accepts any {@link ViraColorVariant} or a {@link ViraThemeColorName} (e.g.,
|
|
32
|
+
* `ViraThemeColorName.blue`).
|
|
33
|
+
*
|
|
34
|
+
* @default ViraColorVariant.Plain
|
|
35
|
+
*/
|
|
36
|
+
color: ViraColorVariant | ViraThemeColorName;
|
|
31
37
|
disabled: boolean;
|
|
32
38
|
}>, {}, {
|
|
33
39
|
toggle: import("element-vir").DefineEvent<boolean>;
|
|
34
40
|
cancel: import("element-vir").DefineEvent<void>;
|
|
35
|
-
}, "vira-tag-selectable" | "vira-tag-checked" | "vira-tag-not-checked" | "vira-tag-cancellable" | "vira-tag-not-clickable" | "vira-tag-disabled" | "vira-tag-size-large" | "vira-tag-size-medium" | "vira-tag-size-small" | "vira-tag-emphasis-standard" | "vira-tag-emphasis-subtle" | "vira-tag-color-
|
|
41
|
+
}, "vira-tag-selectable" | "vira-tag-checked" | "vira-tag-not-checked" | "vira-tag-cancellable" | "vira-tag-not-clickable" | "vira-tag-disabled" | "vira-tag-size-large" | "vira-tag-size-medium" | "vira-tag-size-small" | "vira-tag-emphasis-standard" | "vira-tag-emphasis-subtle" | "vira-tag-color-red" | "vira-tag-color-yellow" | "vira-tag-color-green" | "vira-tag-color-blue" | "vira-tag-color-brand" | "vira-tag-color-purple" | "vira-tag-color-plain" | "vira-tag-color-neutral" | "vira-tag-color-teal" | "vira-tag-color-pink" | "vira-tag-color-grey", "vira-tag-text-color" | "vira-tag-background-color" | "vira-tag-border-color" | "vira-tag-hover-text-color" | "vira-tag-hover-background-color" | "vira-tag-hover-border-color" | "vira-tag-active-text-color" | "vira-tag-active-background-color" | "vira-tag-active-border-color" | "vira-tag-disabled-text-color" | "vira-tag-disabled-background-color" | "vira-tag-disabled-border-color" | "vira-tag-border-radius" | "vira-tag-gap" | "vira-tag-horizontal-padding" | "vira-tag-border-width", readonly [], readonly []>;
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import { check } from '@augment-vir/assert';
|
|
2
|
-
import { arrayToObject,
|
|
2
|
+
import { arrayToObject, getObjectTypedKeys } from '@augment-vir/common';
|
|
3
3
|
import { ContrastLevelName } from '@electrovir/color/dist/data/contrast/contrast.js';
|
|
4
4
|
import { css, defineElementEvent, html, listen, unsafeCSS } from 'element-vir';
|
|
5
5
|
import { themeDefaultKey } from 'theme-vir/dist/color-theme/color-theme.js';
|
|
6
6
|
import { Check16Icon } from '../icons/icon-svgs/16/check-16.icon.js';
|
|
7
7
|
import { X16Icon } from '../icons/icon-svgs/16/x-16.icon.js';
|
|
8
8
|
import { viraFormCssVars } from '../styles/form-styles.js';
|
|
9
|
-
import {
|
|
9
|
+
import { standaloneThemeColorNames, ViraColorVariant, viraColorVariantToHostClassKey, ViraEmphasis, viraEmphasisVariants, ViraSize, viraSizeHeights, viraSizeVariants, } from '../styles/form-variants.js';
|
|
10
10
|
import { noNativeFormStyles } from '../styles/native-styles.js';
|
|
11
11
|
import { noUserSelect } from '../styles/user-select.js';
|
|
12
|
-
import { viraThemeByKeys } from '../styles/vira-color-theme-object.js';
|
|
12
|
+
import { viraThemeByKeys, ViraThemeColorName } from '../styles/vira-color-theme-object.js';
|
|
13
13
|
import { viraTheme } from '../styles/vira-color-theme.js';
|
|
14
14
|
import { defineViraElement } from '../util/define-vira-element.js';
|
|
15
15
|
import { ViraIcon } from './vira-icon.element.js';
|
|
16
16
|
const transparentColor = {
|
|
17
17
|
value: css `transparent`,
|
|
18
18
|
};
|
|
19
|
-
function buildThemedTagColors(
|
|
20
|
-
const colorName = viraColorVariantToColorName[colorVariant];
|
|
19
|
+
function buildThemedTagColors(colorName) {
|
|
21
20
|
const behindBg = viraThemeByKeys[colorName]['behind-bg'];
|
|
22
21
|
const onSelf = viraThemeByKeys[colorName]['on-self'];
|
|
23
22
|
return {
|
|
@@ -57,8 +56,7 @@ function buildThemedTagColors(colorVariant) {
|
|
|
57
56
|
},
|
|
58
57
|
};
|
|
59
58
|
}
|
|
60
|
-
function buildThemedNotCheckedColors(
|
|
61
|
-
const colorName = viraColorVariantToColorName[colorVariant];
|
|
59
|
+
function buildThemedNotCheckedColors(colorName) {
|
|
62
60
|
const onSelfBodyText = viraThemeByKeys[colorName]['on-self'][ContrastLevelName.BodyText];
|
|
63
61
|
return {
|
|
64
62
|
idle: {
|
|
@@ -78,69 +76,59 @@ function buildThemedNotCheckedColors(colorVariant) {
|
|
|
78
76
|
},
|
|
79
77
|
};
|
|
80
78
|
}
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
idle: {
|
|
88
|
-
backgroundColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
89
|
-
textColor: viraTheme.colors[themeDefaultKey].background,
|
|
90
|
-
borderColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
91
|
-
},
|
|
92
|
-
hover: {
|
|
93
|
-
backgroundColor: viraTheme.colors['vira-grey-behind-bg-body'].background,
|
|
94
|
-
textColor: viraTheme.colors['vira-grey-behind-bg-body'].foreground,
|
|
95
|
-
borderColor: viraTheme.colors['vira-grey-behind-bg-body'].background,
|
|
96
|
-
},
|
|
97
|
-
active: {
|
|
98
|
-
backgroundColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
99
|
-
textColor: viraTheme.colors[themeDefaultKey].background,
|
|
100
|
-
borderColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
101
|
-
},
|
|
79
|
+
const plainTagColors = {
|
|
80
|
+
[ViraEmphasis.Standard]: {
|
|
81
|
+
idle: {
|
|
82
|
+
backgroundColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
83
|
+
textColor: viraTheme.colors[themeDefaultKey].background,
|
|
84
|
+
borderColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
102
85
|
},
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
borderColor: viraTheme.colors['vira-grey-behind-fg-small-body'].background,
|
|
113
|
-
},
|
|
114
|
-
active: {
|
|
115
|
-
backgroundColor: viraTheme.colors['vira-grey-behind-fg-body'].background,
|
|
116
|
-
textColor: viraTheme.colors['vira-grey-behind-fg-body'].foreground,
|
|
117
|
-
borderColor: viraTheme.colors['vira-grey-behind-fg-body'].background,
|
|
118
|
-
},
|
|
86
|
+
hover: {
|
|
87
|
+
backgroundColor: viraTheme.colors['vira-grey-behind-bg-body'].background,
|
|
88
|
+
textColor: viraTheme.colors['vira-grey-behind-bg-body'].foreground,
|
|
89
|
+
borderColor: viraTheme.colors['vira-grey-behind-bg-body'].background,
|
|
90
|
+
},
|
|
91
|
+
active: {
|
|
92
|
+
backgroundColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
93
|
+
textColor: viraTheme.colors[themeDefaultKey].background,
|
|
94
|
+
borderColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
119
95
|
},
|
|
120
96
|
},
|
|
121
|
-
|
|
122
|
-
const tagNotCheckedColors = {
|
|
123
|
-
...mapEnumToObject(ViraColorVariant, (colorVariant) => {
|
|
124
|
-
return buildThemedNotCheckedColors(colorVariant);
|
|
125
|
-
}),
|
|
126
|
-
[ViraColorVariant.Plain]: {
|
|
97
|
+
[ViraEmphasis.Subtle]: {
|
|
127
98
|
idle: {
|
|
128
|
-
textColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
129
99
|
backgroundColor: transparentColor,
|
|
130
|
-
|
|
100
|
+
textColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
101
|
+
borderColor: transparentColor,
|
|
131
102
|
},
|
|
132
103
|
hover: {
|
|
133
104
|
backgroundColor: viraTheme.colors['vira-grey-behind-fg-small-body'].background,
|
|
134
105
|
textColor: viraTheme.colors['vira-grey-behind-fg-small-body'].foreground,
|
|
135
|
-
borderColor: viraTheme.colors['vira-grey-
|
|
106
|
+
borderColor: viraTheme.colors['vira-grey-behind-fg-small-body'].background,
|
|
136
107
|
},
|
|
137
108
|
active: {
|
|
138
109
|
backgroundColor: viraTheme.colors['vira-grey-behind-fg-body'].background,
|
|
139
110
|
textColor: viraTheme.colors['vira-grey-behind-fg-body'].foreground,
|
|
140
|
-
borderColor: viraTheme.colors['vira-grey-
|
|
111
|
+
borderColor: viraTheme.colors['vira-grey-behind-fg-body'].background,
|
|
141
112
|
},
|
|
142
113
|
},
|
|
143
114
|
};
|
|
115
|
+
const plainNotCheckedColors = {
|
|
116
|
+
idle: {
|
|
117
|
+
textColor: viraTheme.colors[themeDefaultKey].foreground,
|
|
118
|
+
backgroundColor: transparentColor,
|
|
119
|
+
borderColor: viraTheme.colors['vira-grey-on-self-body'].background,
|
|
120
|
+
},
|
|
121
|
+
hover: {
|
|
122
|
+
backgroundColor: viraTheme.colors['vira-grey-behind-fg-small-body'].background,
|
|
123
|
+
textColor: viraTheme.colors['vira-grey-behind-fg-small-body'].foreground,
|
|
124
|
+
borderColor: viraTheme.colors['vira-grey-on-self-body'].background,
|
|
125
|
+
},
|
|
126
|
+
active: {
|
|
127
|
+
backgroundColor: viraTheme.colors['vira-grey-behind-fg-body'].background,
|
|
128
|
+
textColor: viraTheme.colors['vira-grey-behind-fg-body'].foreground,
|
|
129
|
+
borderColor: viraTheme.colors['vira-grey-on-self-body'].background,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
144
132
|
/**
|
|
145
133
|
* A "tag" or "label" or "pill" element. Supports many variations including non-clickable,
|
|
146
134
|
* selectable, and cancellable variations.
|
|
@@ -184,13 +172,24 @@ export const ViraTag = defineViraElement()({
|
|
|
184
172
|
'vira-tag-size-small': ({ inputs }) => inputs.size === ViraSize.Small,
|
|
185
173
|
'vira-tag-emphasis-standard': ({ inputs }) => !inputs.emphasis || inputs.emphasis === ViraEmphasis.Standard,
|
|
186
174
|
'vira-tag-emphasis-subtle': ({ inputs }) => inputs.emphasis === ViraEmphasis.Subtle,
|
|
187
|
-
...arrayToObject(
|
|
175
|
+
...arrayToObject(getObjectTypedKeys(viraColorVariantToHostClassKey), (colorVariant) => {
|
|
176
|
+
const colorKey = viraColorVariantToHostClassKey[colorVariant];
|
|
177
|
+
return {
|
|
178
|
+
key: `vira-tag-color-${colorKey}`,
|
|
179
|
+
value: ({ inputs, }) => {
|
|
180
|
+
return inputs.color === colorVariant || inputs.color === colorKey;
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
}, {
|
|
184
|
+
useRequired: true,
|
|
185
|
+
}),
|
|
186
|
+
'vira-tag-color-plain': ({ inputs, }) => !inputs.color || inputs.color === ViraColorVariant.Plain,
|
|
187
|
+
'vira-tag-color-neutral': ({ inputs, }) => inputs.color === ViraColorVariant.Neutral,
|
|
188
|
+
...arrayToObject(standaloneThemeColorNames, (colorName) => {
|
|
188
189
|
return {
|
|
189
|
-
key: `vira-tag-color-${
|
|
190
|
+
key: `vira-tag-color-${colorName}`,
|
|
190
191
|
value: ({ inputs, }) => {
|
|
191
|
-
return
|
|
192
|
-
? !inputs.colorVariant || inputs.colorVariant === colorVariant
|
|
193
|
-
: inputs.colorVariant === colorVariant;
|
|
192
|
+
return inputs.color === colorName;
|
|
194
193
|
},
|
|
195
194
|
};
|
|
196
195
|
}, {
|
|
@@ -198,68 +197,96 @@ export const ViraTag = defineViraElement()({
|
|
|
198
197
|
}),
|
|
199
198
|
},
|
|
200
199
|
styles: ({ cssVars, hostClasses }) => {
|
|
201
|
-
function
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
${variantSelector}${emphasisSelector} {
|
|
209
|
-
${cssVars['vira-tag-background-color'].name}: ${colors.idle
|
|
210
|
-
.backgroundColor.value};
|
|
211
|
-
${cssVars['vira-tag-text-color'].name}: ${colors.idle.textColor.value};
|
|
212
|
-
${cssVars['vira-tag-border-color'].name}: ${colors.idle.borderColor
|
|
213
|
-
.value};
|
|
200
|
+
function buildVariantCssRule(variantSelector, emphasisSelector, colors) {
|
|
201
|
+
return css `
|
|
202
|
+
${variantSelector}${emphasisSelector} {
|
|
203
|
+
${cssVars['vira-tag-background-color'].name}: ${colors.idle.backgroundColor
|
|
204
|
+
.value};
|
|
205
|
+
${cssVars['vira-tag-text-color'].name}: ${colors.idle.textColor.value};
|
|
206
|
+
${cssVars['vira-tag-border-color'].name}: ${colors.idle.borderColor.value};
|
|
214
207
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
.borderColor.value};
|
|
208
|
+
${cssVars['vira-tag-hover-background-color'].name}: ${colors.hover
|
|
209
|
+
.backgroundColor.value};
|
|
210
|
+
${cssVars['vira-tag-hover-text-color'].name}: ${colors.hover.textColor.value};
|
|
211
|
+
${cssVars['vira-tag-hover-border-color'].name}: ${colors.hover.borderColor
|
|
212
|
+
.value};
|
|
221
213
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
214
|
+
${cssVars['vira-tag-active-background-color'].name}: ${colors.active
|
|
215
|
+
.backgroundColor.value};
|
|
216
|
+
${cssVars['vira-tag-active-text-color'].name}: ${colors.active.textColor.value};
|
|
217
|
+
${cssVars['vira-tag-active-border-color'].name}: ${colors.active.borderColor
|
|
218
|
+
.value};
|
|
219
|
+
}
|
|
220
|
+
`;
|
|
221
|
+
}
|
|
222
|
+
function generateVariantCss() {
|
|
223
|
+
const allStyles = viraEmphasisVariants.flatMap((emphasis) => {
|
|
224
|
+
const emphasisSelector = hostClasses[`vira-tag-emphasis-${emphasis}`].selector;
|
|
225
|
+
const themedStyles = getObjectTypedKeys(viraColorVariantToHostClassKey).map((colorVariant) => {
|
|
226
|
+
const colorKey = viraColorVariantToHostClassKey[colorVariant];
|
|
227
|
+
const colors = buildThemedTagColors(colorKey)[emphasis];
|
|
228
|
+
const variantSelector = hostClasses[`vira-tag-color-${colorKey}`].selector;
|
|
229
|
+
return buildVariantCssRule(variantSelector, emphasisSelector, colors);
|
|
230
|
+
});
|
|
231
|
+
const plainStyle = buildVariantCssRule(hostClasses['vira-tag-color-plain'].selector, emphasisSelector, plainTagColors[emphasis]);
|
|
232
|
+
const neutralStyle = buildVariantCssRule(hostClasses['vira-tag-color-neutral'].selector, emphasisSelector, buildThemedTagColors(ViraThemeColorName.grey)[emphasis]);
|
|
233
|
+
const standaloneStyles = standaloneThemeColorNames.map((colorName) => {
|
|
234
|
+
const colors = buildThemedTagColors(colorName)[emphasis];
|
|
235
|
+
const variantSelector = hostClasses[`vira-tag-color-${colorName}`].selector;
|
|
236
|
+
return buildVariantCssRule(variantSelector, emphasisSelector, colors);
|
|
230
237
|
});
|
|
238
|
+
return [
|
|
239
|
+
...themedStyles,
|
|
240
|
+
plainStyle,
|
|
241
|
+
neutralStyle,
|
|
242
|
+
...standaloneStyles,
|
|
243
|
+
];
|
|
231
244
|
});
|
|
232
245
|
return unsafeCSS(allStyles.join('\n'));
|
|
233
246
|
}
|
|
234
|
-
function
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
${
|
|
241
|
-
|
|
242
|
-
.value};
|
|
243
|
-
${cssVars['vira-tag-text-color'].name}: ${colors.idle.textColor.value};
|
|
244
|
-
${cssVars['vira-tag-border-color'].name}: ${colors.idle.borderColor.value};
|
|
247
|
+
function buildNotCheckedCssRule(variantSelector, colors) {
|
|
248
|
+
const notCheckedSelector = hostClasses['vira-tag-not-checked'].selector;
|
|
249
|
+
return css `
|
|
250
|
+
${variantSelector}${notCheckedSelector}${notCheckedSelector}${notCheckedSelector} {
|
|
251
|
+
${cssVars['vira-tag-background-color'].name}: ${colors.idle.backgroundColor
|
|
252
|
+
.value};
|
|
253
|
+
${cssVars['vira-tag-text-color'].name}: ${colors.idle.textColor.value};
|
|
254
|
+
${cssVars['vira-tag-border-color'].name}: ${colors.idle.borderColor.value};
|
|
245
255
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
.
|
|
250
|
-
|
|
251
|
-
.value};
|
|
256
|
+
${cssVars['vira-tag-hover-background-color'].name}: ${colors.hover
|
|
257
|
+
.backgroundColor.value};
|
|
258
|
+
${cssVars['vira-tag-hover-text-color'].name}: ${colors.hover.textColor.value};
|
|
259
|
+
${cssVars['vira-tag-hover-border-color'].name}: ${colors.hover.borderColor
|
|
260
|
+
.value};
|
|
252
261
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
.
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
262
|
+
${cssVars['vira-tag-active-background-color'].name}: ${colors.active
|
|
263
|
+
.backgroundColor.value};
|
|
264
|
+
${cssVars['vira-tag-active-text-color'].name}: ${colors.active.textColor.value};
|
|
265
|
+
${cssVars['vira-tag-active-border-color'].name}: ${colors.active.borderColor
|
|
266
|
+
.value};
|
|
267
|
+
}
|
|
268
|
+
`;
|
|
269
|
+
}
|
|
270
|
+
function generateNotCheckedCss() {
|
|
271
|
+
const themedStyles = getObjectTypedKeys(viraColorVariantToHostClassKey).map((colorVariant) => {
|
|
272
|
+
const colorKey = viraColorVariantToHostClassKey[colorVariant];
|
|
273
|
+
const colors = buildThemedNotCheckedColors(colorKey);
|
|
274
|
+
const variantSelector = hostClasses[`vira-tag-color-${colorKey}`].selector;
|
|
275
|
+
return buildNotCheckedCssRule(variantSelector, colors);
|
|
261
276
|
});
|
|
262
|
-
|
|
277
|
+
const plainStyle = buildNotCheckedCssRule(hostClasses['vira-tag-color-plain'].selector, plainNotCheckedColors);
|
|
278
|
+
const neutralStyle = buildNotCheckedCssRule(hostClasses['vira-tag-color-neutral'].selector, buildThemedNotCheckedColors(ViraThemeColorName.grey));
|
|
279
|
+
const standaloneStyles = standaloneThemeColorNames.map((colorName) => {
|
|
280
|
+
const colors = buildThemedNotCheckedColors(colorName);
|
|
281
|
+
const variantSelector = hostClasses[`vira-tag-color-${colorName}`].selector;
|
|
282
|
+
return buildNotCheckedCssRule(variantSelector, colors);
|
|
283
|
+
});
|
|
284
|
+
return unsafeCSS([
|
|
285
|
+
...themedStyles,
|
|
286
|
+
plainStyle,
|
|
287
|
+
neutralStyle,
|
|
288
|
+
...standaloneStyles,
|
|
289
|
+
].join('\n'));
|
|
263
290
|
}
|
|
264
291
|
function generateSizeVariantCss() {
|
|
265
292
|
const styles = viraSizeVariants.map((sizeVariant) => {
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import { ViraThemeColorName } from './vira-color-theme-object.js';
|
|
2
1
|
/**
|
|
3
2
|
* All available variants for controlling vira form colors.
|
|
4
3
|
*
|
|
5
4
|
* @category Internal
|
|
6
5
|
*/
|
|
7
6
|
export declare enum ViraColorVariant {
|
|
7
|
+
/** @default blue colored */
|
|
8
|
+
Info = "info",
|
|
8
9
|
/**
|
|
9
|
-
*
|
|
10
|
+
* Applied when no `color` input is set on a color-aware element.
|
|
10
11
|
*
|
|
11
|
-
* @default
|
|
12
|
+
* @default black colored
|
|
12
13
|
*/
|
|
13
|
-
Info = "info",
|
|
14
|
-
/** @default black colored */
|
|
15
14
|
Plain = "plain",
|
|
16
15
|
/** @default grey colored */
|
|
17
16
|
Neutral = "neutral",
|
|
@@ -26,24 +25,41 @@ export declare enum ViraColorVariant {
|
|
|
26
25
|
/** @default purple colored */
|
|
27
26
|
Special = "special",
|
|
28
27
|
/**
|
|
29
|
-
* No color variant styles will be applied at all
|
|
30
|
-
*
|
|
28
|
+
* No color variant styles will be applied at all, allowing the element's colors to be fully
|
|
29
|
+
* customized via its CSS vars.
|
|
31
30
|
*/
|
|
32
|
-
|
|
31
|
+
Custom = "custom"
|
|
33
32
|
}
|
|
34
33
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
34
|
+
* All defined color variants starting with the default.
|
|
35
|
+
*
|
|
36
|
+
* @category Internal
|
|
37
|
+
*/
|
|
38
|
+
export declare const viraColorVariants: readonly [ViraColorVariant.Info, ViraColorVariant.Plain, ViraColorVariant.Neutral, ViraColorVariant.Danger, ViraColorVariant.Warning, ViraColorVariant.Positive, ViraColorVariant.Brand, ViraColorVariant.Special];
|
|
39
|
+
/**
|
|
40
|
+
* Maps themed {@link ViraColorVariant} members to the {@link ViraThemeColorName} used as their host
|
|
41
|
+
* class suffix on color-aware elements (`vira-*-color-${themeColor}`). `Plain` and `Neutral` are
|
|
42
|
+
* intentionally omitted: they are always special-cased by each element so their host classes stay
|
|
43
|
+
* distinct from any theme color class (including `grey`).
|
|
37
44
|
*
|
|
38
45
|
* @category Internal
|
|
39
46
|
*/
|
|
40
|
-
export declare const
|
|
47
|
+
export declare const viraColorVariantToHostClassKey: {
|
|
48
|
+
readonly info: "blue";
|
|
49
|
+
readonly danger: "red";
|
|
50
|
+
readonly warning: "yellow";
|
|
51
|
+
readonly positive: "green";
|
|
52
|
+
readonly brand: "brand";
|
|
53
|
+
readonly special: "purple";
|
|
54
|
+
};
|
|
41
55
|
/**
|
|
42
|
-
*
|
|
56
|
+
* {@link ViraThemeColorName} values that have no corresponding themed {@link ViraColorVariant} in
|
|
57
|
+
* {@link viraColorVariantToHostClassKey}. Color-aware elements generate a standalone host class for
|
|
58
|
+
* each so every {@link ViraThemeColorName} (including `grey`) can be passed as a `color` input.
|
|
43
59
|
*
|
|
44
60
|
* @category Internal
|
|
45
61
|
*/
|
|
46
|
-
export declare const
|
|
62
|
+
export declare const standaloneThemeColorNames: ("red" | "yellow" | "green" | "teal" | "blue" | "brand" | "purple" | "pink" | "grey")[];
|
|
47
63
|
/**
|
|
48
64
|
* All available variants for controlling vira form sizes.
|
|
49
65
|
*
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { check } from '@augment-vir/assert';
|
|
2
|
+
import { getObjectTypedValues } from '@augment-vir/common';
|
|
1
3
|
import { ViraThemeColorName } from './vira-color-theme-object.js';
|
|
2
4
|
/**
|
|
3
5
|
* All available variants for controlling vira form colors.
|
|
@@ -6,13 +8,13 @@ import { ViraThemeColorName } from './vira-color-theme-object.js';
|
|
|
6
8
|
*/
|
|
7
9
|
export var ViraColorVariant;
|
|
8
10
|
(function (ViraColorVariant) {
|
|
11
|
+
/** @default blue colored */
|
|
12
|
+
ViraColorVariant["Info"] = "info";
|
|
9
13
|
/**
|
|
10
|
-
*
|
|
14
|
+
* Applied when no `color` input is set on a color-aware element.
|
|
11
15
|
*
|
|
12
|
-
* @default
|
|
16
|
+
* @default black colored
|
|
13
17
|
*/
|
|
14
|
-
ViraColorVariant["Info"] = "info";
|
|
15
|
-
/** @default black colored */
|
|
16
18
|
ViraColorVariant["Plain"] = "plain";
|
|
17
19
|
/** @default grey colored */
|
|
18
20
|
ViraColorVariant["Neutral"] = "neutral";
|
|
@@ -27,28 +29,11 @@ export var ViraColorVariant;
|
|
|
27
29
|
/** @default purple colored */
|
|
28
30
|
ViraColorVariant["Special"] = "special";
|
|
29
31
|
/**
|
|
30
|
-
* No color variant styles will be applied at all
|
|
31
|
-
*
|
|
32
|
+
* No color variant styles will be applied at all, allowing the element's colors to be fully
|
|
33
|
+
* customized via its CSS vars.
|
|
32
34
|
*/
|
|
33
|
-
ViraColorVariant["
|
|
35
|
+
ViraColorVariant["Custom"] = "custom";
|
|
34
36
|
})(ViraColorVariant || (ViraColorVariant = {}));
|
|
35
|
-
/**
|
|
36
|
-
* Maps {@link ViraColorVariant} values that support colors to their respective vira theme color
|
|
37
|
-
* keys.
|
|
38
|
-
*
|
|
39
|
-
* @category Internal
|
|
40
|
-
*/
|
|
41
|
-
export const viraColorVariantToColorName = {
|
|
42
|
-
[ViraColorVariant.Info]: ViraThemeColorName.blue,
|
|
43
|
-
[ViraColorVariant.Neutral]: ViraThemeColorName.grey,
|
|
44
|
-
[ViraColorVariant.Danger]: ViraThemeColorName.red,
|
|
45
|
-
[ViraColorVariant.Warning]: ViraThemeColorName.yellow,
|
|
46
|
-
[ViraColorVariant.Positive]: ViraThemeColorName.green,
|
|
47
|
-
[ViraColorVariant.Brand]: ViraThemeColorName.brand,
|
|
48
|
-
[ViraColorVariant.Special]: ViraThemeColorName.purple,
|
|
49
|
-
[ViraColorVariant.Plain]: ViraThemeColorName.grey,
|
|
50
|
-
[ViraColorVariant.None]: ViraThemeColorName.grey,
|
|
51
|
-
};
|
|
52
37
|
/**
|
|
53
38
|
* All defined color variants starting with the default.
|
|
54
39
|
*
|
|
@@ -64,6 +49,30 @@ export const viraColorVariants = [
|
|
|
64
49
|
ViraColorVariant.Brand,
|
|
65
50
|
ViraColorVariant.Special,
|
|
66
51
|
];
|
|
52
|
+
/**
|
|
53
|
+
* Maps themed {@link ViraColorVariant} members to the {@link ViraThemeColorName} used as their host
|
|
54
|
+
* class suffix on color-aware elements (`vira-*-color-${themeColor}`). `Plain` and `Neutral` are
|
|
55
|
+
* intentionally omitted: they are always special-cased by each element so their host classes stay
|
|
56
|
+
* distinct from any theme color class (including `grey`).
|
|
57
|
+
*
|
|
58
|
+
* @category Internal
|
|
59
|
+
*/
|
|
60
|
+
export const viraColorVariantToHostClassKey = {
|
|
61
|
+
[ViraColorVariant.Info]: ViraThemeColorName.blue,
|
|
62
|
+
[ViraColorVariant.Danger]: ViraThemeColorName.red,
|
|
63
|
+
[ViraColorVariant.Warning]: ViraThemeColorName.yellow,
|
|
64
|
+
[ViraColorVariant.Positive]: ViraThemeColorName.green,
|
|
65
|
+
[ViraColorVariant.Brand]: ViraThemeColorName.brand,
|
|
66
|
+
[ViraColorVariant.Special]: ViraThemeColorName.purple,
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* {@link ViraThemeColorName} values that have no corresponding themed {@link ViraColorVariant} in
|
|
70
|
+
* {@link viraColorVariantToHostClassKey}. Color-aware elements generate a standalone host class for
|
|
71
|
+
* each so every {@link ViraThemeColorName} (including `grey`) can be passed as a `color` input.
|
|
72
|
+
*
|
|
73
|
+
* @category Internal
|
|
74
|
+
*/
|
|
75
|
+
export const standaloneThemeColorNames = getObjectTypedValues(ViraThemeColorName).filter((colorName) => !check.hasValue(getObjectTypedValues(viraColorVariantToHostClassKey), colorName));
|
|
67
76
|
/**
|
|
68
77
|
* All available variants for controlling vira form sizes.
|
|
69
78
|
*
|