@chromvoid/uikit 0.1.0 → 0.2.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/LICENSE +19 -6
- package/README.md +1 -0
- package/dist/components/cv-accordion-item.d.ts +1 -1
- package/dist/components/cv-accordion.d.ts +1 -1
- package/dist/components/cv-accordion.js +2 -1
- package/dist/components/cv-alert-dialog.d.ts +1 -1
- package/dist/components/cv-alert-dialog.js +17 -2
- package/dist/components/cv-alert.d.ts +1 -1
- package/dist/components/cv-alert.js +2 -1
- package/dist/components/cv-badge.d.ts +1 -1
- package/dist/components/cv-badge.js +2 -1
- package/dist/components/cv-bottom-sheet.d.ts +127 -0
- package/dist/components/cv-bottom-sheet.js +513 -0
- package/dist/components/cv-breadcrumb-item.d.ts +1 -1
- package/dist/components/cv-breadcrumb-item.js +1 -1
- package/dist/components/cv-breadcrumb.d.ts +1 -1
- package/dist/components/cv-breadcrumb.js +2 -1
- package/dist/components/cv-button.d.ts +23 -1
- package/dist/components/cv-button.js +194 -37
- package/dist/components/cv-callout.d.ts +8 -1
- package/dist/components/cv-callout.js +18 -1
- package/dist/components/cv-card.d.ts +1 -1
- package/dist/components/cv-card.js +2 -2
- package/dist/components/cv-carousel-slide.d.ts +1 -1
- package/dist/components/cv-carousel.d.ts +1 -1
- package/dist/components/cv-carousel.js +2 -1
- package/dist/components/cv-checkbox.d.ts +1 -1
- package/dist/components/cv-combobox-group.d.ts +1 -1
- package/dist/components/cv-combobox-option.d.ts +1 -1
- package/dist/components/cv-combobox-option.js +2 -2
- package/dist/components/cv-combobox.d.ts +3 -1
- package/dist/components/cv-combobox.js +49 -8
- package/dist/components/cv-command-item.d.ts +1 -1
- package/dist/components/cv-command-item.js +2 -2
- package/dist/components/cv-command-palette.d.ts +1 -1
- package/dist/components/cv-command-palette.js +21 -1
- package/dist/components/cv-context-menu.d.ts +1 -1
- package/dist/components/cv-context-menu.js +2 -1
- package/dist/components/cv-copy-button.d.ts +37 -9
- package/dist/components/cv-copy-button.js +129 -41
- package/dist/components/cv-date-picker.d.ts +1 -1
- package/dist/components/cv-date-picker.js +20 -1
- package/dist/components/cv-dialog.d.ts +44 -2
- package/dist/components/cv-dialog.js +686 -74
- package/dist/components/cv-disclosure.d.ts +1 -1
- package/dist/components/cv-disclosure.js +2 -1
- package/dist/components/cv-drawer.d.ts +29 -1
- package/dist/components/cv-drawer.js +229 -4
- package/dist/components/cv-feed-article.d.ts +1 -1
- package/dist/components/cv-feed-article.js +2 -1
- package/dist/components/cv-feed.d.ts +1 -1
- package/dist/components/cv-feed.js +2 -1
- package/dist/components/cv-grid-cell.d.ts +1 -1
- package/dist/components/cv-grid-cell.js +3 -3
- package/dist/components/cv-grid-column.d.ts +1 -1
- package/dist/components/cv-grid-column.js +1 -1
- package/dist/components/cv-grid-row.d.ts +1 -1
- package/dist/components/cv-grid.d.ts +1 -1
- package/dist/components/cv-grid.js +2 -1
- package/dist/components/cv-guidance-anchor.d.ts +47 -0
- package/dist/components/cv-guidance-anchor.js +113 -0
- package/dist/components/cv-guidance-panel.d.ts +29 -0
- package/dist/components/cv-guidance-panel.js +245 -0
- package/dist/components/cv-icon.d.ts +2 -1
- package/dist/components/cv-icon.js +28 -3
- package/dist/components/cv-input.d.ts +7 -1
- package/dist/components/cv-input.js +33 -1
- package/dist/components/cv-landmark.d.ts +1 -1
- package/dist/components/cv-landmark.js +2 -1
- package/dist/components/cv-link.d.ts +1 -1
- package/dist/components/cv-link.js +2 -1
- package/dist/components/cv-listbox-group.d.ts +1 -1
- package/dist/components/cv-listbox.d.ts +1 -1
- package/dist/components/cv-listbox.js +2 -1
- package/dist/components/cv-menu-button.d.ts +24 -1
- package/dist/components/cv-menu-button.js +226 -18
- package/dist/components/cv-menu-group.d.ts +1 -1
- package/dist/components/cv-menu-item.d.ts +1 -1
- package/dist/components/cv-menu-item.js +6 -2
- package/dist/components/cv-menu.d.ts +1 -1
- package/dist/components/cv-menu.js +21 -1
- package/dist/components/cv-meter.d.ts +1 -1
- package/dist/components/cv-meter.js +6 -22
- package/dist/components/cv-number.d.ts +1 -1
- package/dist/components/cv-option.d.ts +1 -1
- package/dist/components/cv-option.js +3 -9
- package/dist/components/cv-popover-positioning.d.ts +22 -0
- package/dist/components/cv-popover-positioning.js +112 -0
- package/dist/components/cv-popover.d.ts +45 -8
- package/dist/components/cv-popover.js +395 -113
- package/dist/components/cv-progress-ring.d.ts +1 -1
- package/dist/components/cv-progress-ring.js +2 -1
- package/dist/components/cv-progress.d.ts +8 -1
- package/dist/components/cv-progress.js +41 -10
- package/dist/components/cv-radio-group.d.ts +1 -1
- package/dist/components/cv-radio.d.ts +1 -1
- package/dist/components/cv-radio.js +1 -1
- package/dist/components/cv-select-group.d.ts +1 -1
- package/dist/components/cv-select-option.d.ts +1 -1
- package/dist/components/cv-select-option.js +2 -2
- package/dist/components/cv-select.d.ts +1 -1
- package/dist/components/cv-select.js +28 -1
- package/dist/components/cv-sidebar-item.d.ts +1 -1
- package/dist/components/cv-sidebar.d.ts +1 -1
- package/dist/components/cv-sidebar.js +3 -2
- package/dist/components/cv-slider-multi-thumb.d.ts +1 -1
- package/dist/components/cv-slider-multi-thumb.js +2 -1
- package/dist/components/cv-slider.d.ts +17 -4
- package/dist/components/cv-slider.js +63 -21
- package/dist/components/cv-spinbutton.d.ts +1 -1
- package/dist/components/cv-spinner.d.ts +1 -1
- package/dist/components/cv-spinner.js +2 -1
- package/dist/components/cv-switch.d.ts +1 -1
- package/dist/components/cv-tab-panel.d.ts +1 -1
- package/dist/components/cv-tab.d.ts +1 -1
- package/dist/components/cv-table-cell.d.ts +1 -1
- package/dist/components/cv-table-cell.js +1 -1
- package/dist/components/cv-table-column.d.ts +1 -1
- package/dist/components/cv-table-column.js +1 -1
- package/dist/components/cv-table-row.d.ts +1 -1
- package/dist/components/cv-table-row.js +1 -4
- package/dist/components/cv-table.d.ts +1 -3
- package/dist/components/cv-table.js +4 -11
- package/dist/components/cv-tabs.d.ts +1 -1
- package/dist/components/cv-tabs.js +3 -2
- package/dist/components/cv-textarea.d.ts +11 -1
- package/dist/components/cv-textarea.js +33 -0
- package/dist/components/cv-toast-region.d.ts +1 -1
- package/dist/components/cv-toast-region.js +2 -1
- package/dist/components/cv-toast.d.ts +1 -1
- package/dist/components/cv-toast.js +20 -27
- package/dist/components/cv-toolbar-item.d.ts +1 -1
- package/dist/components/cv-toolbar-separator.d.ts +1 -1
- package/dist/components/cv-toolbar.d.ts +1 -1
- package/dist/components/cv-toolbar.js +2 -1
- package/dist/components/cv-tooltip.d.ts +1 -1
- package/dist/components/cv-tooltip.js +2 -1
- package/dist/components/cv-treegrid-cell.d.ts +1 -1
- package/dist/components/cv-treegrid-cell.js +1 -1
- package/dist/components/cv-treegrid-column.d.ts +1 -1
- package/dist/components/cv-treegrid-column.js +1 -1
- package/dist/components/cv-treegrid-row.d.ts +1 -1
- package/dist/components/cv-treegrid-row.js +1 -1
- package/dist/components/cv-treegrid.d.ts +1 -1
- package/dist/components/cv-treegrid.js +4 -3
- package/dist/components/cv-treeitem.d.ts +1 -1
- package/dist/components/cv-treeitem.js +2 -2
- package/dist/components/cv-treeview.d.ts +1 -1
- package/dist/components/cv-treeview.js +2 -1
- package/dist/components/cv-window-splitter.d.ts +1 -1
- package/dist/components/cv-window-splitter.js +2 -1
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.js +3 -0
- package/dist/dialog/create-dialog-controller.d.ts +12 -4
- package/dist/dialog/create-dialog-controller.js +84 -22
- package/dist/dialog/index.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/reatom-lit/ReatomLitElement.d.ts +6 -3
- package/dist/reatom-lit/ReatomLitElement.js +18 -8
- package/dist/reatom-lit/createAfterRenderScheduler.d.ts +10 -0
- package/dist/reatom-lit/createAfterRenderScheduler.js +33 -0
- package/dist/reatom-lit/index.d.ts +2 -0
- package/dist/reatom-lit/index.js +1 -0
- package/dist/reatom-lit/watch.d.ts +1 -1
- package/dist/reatom-lit/withReatomElement.js +16 -2
- package/dist/register.js +4 -1
- package/dist/styles/component-styles.js +4 -0
- package/dist/styles/uno-generated.d.ts +2 -0
- package/dist/styles/uno-generated.js +1 -0
- package/dist/styles/uno-utilities.d.ts +5 -0
- package/dist/styles/uno-utilities.js +7 -0
- package/dist/theme/cv-theme-provider.d.ts +1 -1
- package/dist/theme/cv-theme-provider.js +2 -2
- package/dist/theme/tokens.css +619 -162
- package/package.json +9 -5
- package/specs/components/bottom-sheet.md +93 -0
- package/specs/components/button.md +8 -0
- package/specs/components/callout.md +8 -0
- package/specs/components/copy-button.md +54 -17
- package/specs/components/dialog.md +72 -43
- package/specs/components/drawer.md +18 -13
- package/specs/components/guidance-anchor.md +64 -0
- package/specs/components/guidance-panel.md +92 -0
- package/specs/components/input.md +7 -0
- package/specs/components/menu.md +8 -0
- package/specs/components/option.md +9 -9
- package/specs/components/progress.md +11 -0
- package/specs/components/sidebar.md +12 -12
- package/specs/components/table.md +13 -13
- package/specs/components/theme.md +13 -13
- package/specs/components/treegrid.md +15 -15
- package/specs/components/treeview.md +10 -10
|
@@ -13,6 +13,7 @@ export interface CVMenuButtonEventMap {
|
|
|
13
13
|
'cv-change': CVMenuButtonChangeEvent;
|
|
14
14
|
'cv-action': CVMenuButtonActionEvent;
|
|
15
15
|
}
|
|
16
|
+
type CVMenuButtonPreset = 'icon-overflow';
|
|
16
17
|
export declare class CVMenuButton extends ReatomLitElement {
|
|
17
18
|
static elementName: string;
|
|
18
19
|
static hostDisplay: "inline-block";
|
|
@@ -41,6 +42,10 @@ export declare class CVMenuButton extends ReatomLitElement {
|
|
|
41
42
|
type: StringConstructor;
|
|
42
43
|
reflect: boolean;
|
|
43
44
|
};
|
|
45
|
+
preset: {
|
|
46
|
+
type: StringConstructor;
|
|
47
|
+
reflect: boolean;
|
|
48
|
+
};
|
|
44
49
|
closeOnSelect: {
|
|
45
50
|
type: BooleanConstructor;
|
|
46
51
|
attribute: string;
|
|
@@ -57,10 +62,12 @@ export declare class CVMenuButton extends ReatomLitElement {
|
|
|
57
62
|
split: boolean;
|
|
58
63
|
size: 'small' | 'medium' | 'large';
|
|
59
64
|
variant: 'default' | 'primary' | 'danger' | 'ghost';
|
|
65
|
+
preset: CVMenuButtonPreset | undefined;
|
|
60
66
|
closeOnSelect: boolean;
|
|
61
67
|
ariaLabel: string;
|
|
62
68
|
private readonly idBase;
|
|
63
69
|
private itemRecords;
|
|
70
|
+
private portalItemRecords;
|
|
64
71
|
private itemListeners;
|
|
65
72
|
private hasPrefixContent;
|
|
66
73
|
private hasLabelContent;
|
|
@@ -68,6 +75,9 @@ export declare class CVMenuButton extends ReatomLitElement {
|
|
|
68
75
|
private model?;
|
|
69
76
|
private hasLayoutListeners;
|
|
70
77
|
private layoutFrame;
|
|
78
|
+
private portalRoot;
|
|
79
|
+
private readonly portalClickListener;
|
|
80
|
+
private readonly portalKeydownListener;
|
|
71
81
|
constructor();
|
|
72
82
|
static styles: import("lit").CSSResult[];
|
|
73
83
|
static define(): void;
|
|
@@ -77,10 +87,15 @@ export declare class CVMenuButton extends ReatomLitElement {
|
|
|
77
87
|
updated(changedProperties: PropertyValues): void;
|
|
78
88
|
private getMenuElement;
|
|
79
89
|
private getBaseElement;
|
|
90
|
+
private ensurePortalRoot;
|
|
91
|
+
private destroyPortal;
|
|
80
92
|
private clearInlineLayout;
|
|
81
93
|
private getMenuOffset;
|
|
82
94
|
private getMenuMinInlineSize;
|
|
95
|
+
private getMenuInlineStart;
|
|
96
|
+
private getMenuItemProperty;
|
|
83
97
|
private applyMenuLayout;
|
|
98
|
+
private applyPortalLayout;
|
|
84
99
|
private syncMenuLayout;
|
|
85
100
|
private cancelLayoutFrame;
|
|
86
101
|
private scheduleLayout;
|
|
@@ -96,6 +111,10 @@ export declare class CVMenuButton extends ReatomLitElement {
|
|
|
96
111
|
private detachItemListeners;
|
|
97
112
|
private attachItemListeners;
|
|
98
113
|
private syncItemElements;
|
|
114
|
+
private applyItemElementState;
|
|
115
|
+
private syncPortalElements;
|
|
116
|
+
private applyPortalBaseState;
|
|
117
|
+
private getMenuZIndex;
|
|
99
118
|
private captureState;
|
|
100
119
|
private dispatchInput;
|
|
101
120
|
private dispatchChange;
|
|
@@ -104,6 +123,9 @@ export declare class CVMenuButton extends ReatomLitElement {
|
|
|
104
123
|
private applyInteractionResult;
|
|
105
124
|
private syncOutsidePointerListener;
|
|
106
125
|
private handleDocumentPointerDown;
|
|
126
|
+
private getPortalItemIdFromEvent;
|
|
127
|
+
private handlePortalClick;
|
|
128
|
+
private handlePortalKeyDown;
|
|
107
129
|
private handleItemClick;
|
|
108
130
|
private handleTriggerClick;
|
|
109
131
|
private handleActionClick;
|
|
@@ -114,5 +136,6 @@ export declare class CVMenuButton extends ReatomLitElement {
|
|
|
114
136
|
private renderDropdownIcon;
|
|
115
137
|
private renderSplitMode;
|
|
116
138
|
private renderStandardMode;
|
|
117
|
-
protected render(): import("lit").TemplateResult
|
|
139
|
+
protected render(): import("lit-html").TemplateResult;
|
|
118
140
|
}
|
|
141
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createMenuButton } from '@chromvoid/headless-ui/menu-button';
|
|
2
|
-
import { css,
|
|
2
|
+
import { css, nothing } from 'lit';
|
|
3
|
+
import { html } from '../reatom-lit/index.js';
|
|
3
4
|
import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
|
|
4
5
|
import { CVIcon } from './cv-icon.js';
|
|
5
6
|
import { CVMenuItem } from './cv-menu-item.js';
|
|
@@ -26,12 +27,14 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
26
27
|
split: { type: Boolean, reflect: true },
|
|
27
28
|
size: { type: String, reflect: true },
|
|
28
29
|
variant: { type: String, reflect: true },
|
|
30
|
+
preset: { type: String, reflect: true },
|
|
29
31
|
closeOnSelect: { type: Boolean, attribute: 'close-on-select', reflect: true },
|
|
30
32
|
ariaLabel: { type: String, attribute: 'aria-label' },
|
|
31
33
|
};
|
|
32
34
|
}
|
|
33
35
|
idBase = `cv-menu-button-${++cvMenuButtonNonce}`;
|
|
34
36
|
itemRecords = [];
|
|
37
|
+
portalItemRecords = [];
|
|
35
38
|
itemListeners = new WeakMap();
|
|
36
39
|
hasPrefixContent = false;
|
|
37
40
|
hasLabelContent = false;
|
|
@@ -39,6 +42,9 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
39
42
|
model;
|
|
40
43
|
hasLayoutListeners = false;
|
|
41
44
|
layoutFrame = -1;
|
|
45
|
+
portalRoot = null;
|
|
46
|
+
portalClickListener = (event) => this.handlePortalClick(event);
|
|
47
|
+
portalKeydownListener = (event) => this.handlePortalKeyDown(event);
|
|
42
48
|
constructor() {
|
|
43
49
|
super();
|
|
44
50
|
this.value = '';
|
|
@@ -47,6 +53,7 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
47
53
|
this.split = false;
|
|
48
54
|
this.size = 'medium';
|
|
49
55
|
this.variant = 'default';
|
|
56
|
+
this.preset = undefined;
|
|
50
57
|
this.closeOnSelect = true;
|
|
51
58
|
this.ariaLabel = '';
|
|
52
59
|
}
|
|
@@ -57,9 +64,12 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
57
64
|
--cv-menu-button-padding-inline: var(--cv-space-3, 12px);
|
|
58
65
|
--cv-menu-button-padding-block: var(--cv-space-2, 8px);
|
|
59
66
|
--cv-menu-button-border-radius: var(--cv-radius-sm, 6px);
|
|
67
|
+
--cv-menu-button-border-color: var(--cv-color-border, #2a3245);
|
|
68
|
+
--cv-menu-button-background: var(--cv-color-surface, #141923);
|
|
60
69
|
--cv-menu-button-gap: var(--cv-space-2, 8px);
|
|
61
70
|
--cv-menu-button-font-size: inherit;
|
|
62
71
|
--cv-menu-button-menu-offset: var(--cv-space-1, 4px);
|
|
72
|
+
--cv-menu-button-menu-align: start;
|
|
63
73
|
--cv-menu-button-menu-min-inline-size: 180px;
|
|
64
74
|
--cv-menu-button-menu-z-index: 20;
|
|
65
75
|
}
|
|
@@ -78,6 +88,9 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
78
88
|
gap: var(--cv-menu-button-gap);
|
|
79
89
|
min-block-size: var(--cv-menu-button-min-height);
|
|
80
90
|
padding: var(--cv-menu-button-padding-block) var(--cv-menu-button-padding-inline);
|
|
91
|
+
border: 1px solid var(--cv-menu-button-border-color);
|
|
92
|
+
border-radius: var(--cv-menu-button-border-radius);
|
|
93
|
+
background: var(--cv-menu-button-background);
|
|
81
94
|
font-size: var(--cv-menu-button-font-size);
|
|
82
95
|
color: var(--cv-color-text, #e8ecf6);
|
|
83
96
|
cursor: pointer;
|
|
@@ -164,6 +177,21 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
164
177
|
--cv-menu-button-padding-block: var(--cv-space-2, 8px);
|
|
165
178
|
}
|
|
166
179
|
|
|
180
|
+
:host([preset='icon-overflow']) {
|
|
181
|
+
--cv-menu-button-gap: 0;
|
|
182
|
+
--cv-menu-button-padding-inline: 0;
|
|
183
|
+
--cv-menu-button-padding-block: 0;
|
|
184
|
+
--cv-menu-button-menu-offset: var(--cv-menu-button-icon-overflow-menu-offset, var(--cv-space-1, 4px));
|
|
185
|
+
--cv-menu-button-menu-min-inline-size: var(
|
|
186
|
+
--cv-menu-button-icon-overflow-menu-min-inline-size,
|
|
187
|
+
180px
|
|
188
|
+
);
|
|
189
|
+
--cv-menu-button-menu-max-inline-size: var(
|
|
190
|
+
--cv-menu-button-icon-overflow-menu-max-inline-size,
|
|
191
|
+
min(280px, calc(100vw - 16px))
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
167
195
|
/* --- variant: default --- */
|
|
168
196
|
:host([variant='default']) [part='trigger'],
|
|
169
197
|
:host([variant='default']) [part='action'],
|
|
@@ -229,6 +257,7 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
229
257
|
disconnectedCallback() {
|
|
230
258
|
super.disconnectedCallback();
|
|
231
259
|
this.detachItemListeners();
|
|
260
|
+
this.destroyPortal();
|
|
232
261
|
this.syncOutsidePointerListener(true);
|
|
233
262
|
this.toggleLayoutListeners(false);
|
|
234
263
|
this.cancelLayoutFrame();
|
|
@@ -282,6 +311,7 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
282
311
|
}
|
|
283
312
|
else {
|
|
284
313
|
this.cancelLayoutFrame();
|
|
314
|
+
this.destroyPortal();
|
|
285
315
|
const menu = this.getMenuElement();
|
|
286
316
|
if (menu) {
|
|
287
317
|
this.clearInlineLayout(menu);
|
|
@@ -297,6 +327,30 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
297
327
|
getBaseElement() {
|
|
298
328
|
return this.shadowRoot?.querySelector('[part="base"]');
|
|
299
329
|
}
|
|
330
|
+
ensurePortalRoot() {
|
|
331
|
+
const ownerDocument = this.ownerDocument;
|
|
332
|
+
if (!ownerDocument?.body)
|
|
333
|
+
return null;
|
|
334
|
+
if (this.portalRoot?.isConnected) {
|
|
335
|
+
return this.portalRoot;
|
|
336
|
+
}
|
|
337
|
+
const portal = ownerDocument.createElement('div');
|
|
338
|
+
portal.setAttribute('data-cv-menu-button-portal', this.idBase);
|
|
339
|
+
portal.addEventListener('click', this.portalClickListener);
|
|
340
|
+
portal.addEventListener('keydown', this.portalKeydownListener);
|
|
341
|
+
ownerDocument.body.append(portal);
|
|
342
|
+
this.portalRoot = portal;
|
|
343
|
+
return portal;
|
|
344
|
+
}
|
|
345
|
+
destroyPortal() {
|
|
346
|
+
if (!this.portalRoot)
|
|
347
|
+
return;
|
|
348
|
+
this.portalRoot.removeEventListener('click', this.portalClickListener);
|
|
349
|
+
this.portalRoot.removeEventListener('keydown', this.portalKeydownListener);
|
|
350
|
+
this.portalRoot.remove();
|
|
351
|
+
this.portalRoot = null;
|
|
352
|
+
this.portalItemRecords = [];
|
|
353
|
+
}
|
|
300
354
|
clearInlineLayout(menu) {
|
|
301
355
|
menu.style.position = '';
|
|
302
356
|
menu.style.top = '';
|
|
@@ -318,6 +372,23 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
318
372
|
const parsed = Number.parseFloat(raw);
|
|
319
373
|
return Number.isFinite(parsed) ? parsed : 180;
|
|
320
374
|
}
|
|
375
|
+
getMenuInlineStart(baseRect, menuWidth, viewportWidth) {
|
|
376
|
+
const rawAlign = getComputedStyle(this).getPropertyValue('--cv-menu-button-menu-align').trim();
|
|
377
|
+
const align = rawAlign === 'center' || rawAlign === 'end' ? rawAlign : 'start';
|
|
378
|
+
const viewportPadding = 8;
|
|
379
|
+
const maxLeft = Math.max(viewportPadding, viewportWidth - menuWidth - viewportPadding);
|
|
380
|
+
const preferredLeft = align === 'center'
|
|
381
|
+
? baseRect.left + baseRect.width / 2 - menuWidth / 2
|
|
382
|
+
: align === 'end'
|
|
383
|
+
? baseRect.right - menuWidth
|
|
384
|
+
: baseRect.left;
|
|
385
|
+
return Math.min(Math.max(preferredLeft, viewportPadding), maxLeft);
|
|
386
|
+
}
|
|
387
|
+
getMenuItemProperty(source, name, fallback) {
|
|
388
|
+
return (source?.getPropertyValue(name).trim() ||
|
|
389
|
+
getComputedStyle(this).getPropertyValue(name).trim() ||
|
|
390
|
+
fallback);
|
|
391
|
+
}
|
|
321
392
|
applyMenuLayout(menu, base) {
|
|
322
393
|
const baseRect = base.getBoundingClientRect();
|
|
323
394
|
const minWidth = Math.max(this.getMenuMinInlineSize(), Math.ceil(baseRect.width));
|
|
@@ -339,10 +410,8 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
339
410
|
const spaceBelow = Math.max(0, viewportHeight - baseRect.bottom - viewportPadding - gap);
|
|
340
411
|
const placeAbove = spaceBelow < menuRect.height + gap && spaceAbove > spaceBelow;
|
|
341
412
|
let top = placeAbove ? baseRect.top - menuRect.height - gap : baseRect.bottom + gap;
|
|
342
|
-
let left = baseRect.
|
|
343
|
-
const maxLeft = Math.max(viewportPadding, viewportWidth - menuRect.width - viewportPadding);
|
|
413
|
+
let left = this.getMenuInlineStart(baseRect, menuRect.width, viewportWidth);
|
|
344
414
|
const maxTop = Math.max(viewportPadding, viewportHeight - menuRect.height - viewportPadding);
|
|
345
|
-
left = Math.min(Math.max(left, viewportPadding), maxLeft);
|
|
346
415
|
top = Math.min(Math.max(top, viewportPadding), maxTop);
|
|
347
416
|
menu.style.position = 'absolute';
|
|
348
417
|
menu.style.top = `${top - baseRect.top}px`;
|
|
@@ -353,12 +422,48 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
353
422
|
menu.style.translate = 'none';
|
|
354
423
|
menu.style.visibility = 'visible';
|
|
355
424
|
}
|
|
425
|
+
applyPortalLayout(portal, base) {
|
|
426
|
+
const baseRect = base.getBoundingClientRect();
|
|
427
|
+
const minWidth = Math.max(this.getMenuMinInlineSize(), Math.ceil(baseRect.width));
|
|
428
|
+
portal.style.position = 'fixed';
|
|
429
|
+
portal.style.minWidth = `${minWidth}px`;
|
|
430
|
+
portal.style.top = '0px';
|
|
431
|
+
portal.style.left = '0px';
|
|
432
|
+
portal.style.bottom = 'auto';
|
|
433
|
+
portal.style.right = 'auto';
|
|
434
|
+
portal.style.transform = 'none';
|
|
435
|
+
portal.style.translate = 'none';
|
|
436
|
+
portal.style.visibility = 'hidden';
|
|
437
|
+
const menuRect = portal.getBoundingClientRect();
|
|
438
|
+
const viewportWidth = window.innerWidth;
|
|
439
|
+
const viewportHeight = window.innerHeight;
|
|
440
|
+
const gap = this.getMenuOffset();
|
|
441
|
+
const viewportPadding = 8;
|
|
442
|
+
const spaceAbove = Math.max(0, baseRect.top - viewportPadding - gap);
|
|
443
|
+
const spaceBelow = Math.max(0, viewportHeight - baseRect.bottom - viewportPadding - gap);
|
|
444
|
+
const placeAbove = spaceBelow < menuRect.height + gap && spaceAbove > spaceBelow;
|
|
445
|
+
let top = placeAbove ? baseRect.top - menuRect.height - gap : baseRect.bottom + gap;
|
|
446
|
+
let left = this.getMenuInlineStart(baseRect, menuRect.width, viewportWidth);
|
|
447
|
+
const maxTop = Math.max(viewportPadding, viewportHeight - menuRect.height - viewportPadding);
|
|
448
|
+
top = Math.min(Math.max(top, viewportPadding), maxTop);
|
|
449
|
+
portal.style.position = 'fixed';
|
|
450
|
+
portal.style.top = `${top}px`;
|
|
451
|
+
portal.style.left = `${left}px`;
|
|
452
|
+
portal.style.bottom = 'auto';
|
|
453
|
+
portal.style.right = 'auto';
|
|
454
|
+
portal.style.transform = 'none';
|
|
455
|
+
portal.style.translate = 'none';
|
|
456
|
+
portal.style.visibility = 'visible';
|
|
457
|
+
}
|
|
356
458
|
syncMenuLayout() {
|
|
357
459
|
const menu = this.getMenuElement();
|
|
358
460
|
const base = this.getBaseElement();
|
|
359
461
|
if (!menu || !base)
|
|
360
462
|
return;
|
|
361
463
|
this.applyMenuLayout(menu, base);
|
|
464
|
+
if (this.portalRoot) {
|
|
465
|
+
this.applyPortalLayout(this.portalRoot, base);
|
|
466
|
+
}
|
|
362
467
|
}
|
|
363
468
|
cancelLayoutFrame() {
|
|
364
469
|
if (this.layoutFrame === -1)
|
|
@@ -517,21 +622,92 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
517
622
|
return;
|
|
518
623
|
for (const record of this.itemRecords) {
|
|
519
624
|
const props = this.model.contracts.getItemProps(record.id);
|
|
520
|
-
record.element.
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
record.element.setAttribute('aria-disabled', props['aria-disabled']);
|
|
525
|
-
}
|
|
526
|
-
else {
|
|
527
|
-
record.element.removeAttribute('aria-disabled');
|
|
528
|
-
}
|
|
529
|
-
record.element.setAttribute('data-active', props['data-active']);
|
|
530
|
-
record.element.active = props['data-active'] === 'true';
|
|
531
|
-
record.element.selected = this.value === record.id;
|
|
532
|
-
record.element.disabled = props['aria-disabled'] === 'true';
|
|
533
|
-
record.element.hidden = !this.open;
|
|
625
|
+
this.applyItemElementState(record.element, props, this.value === record.id, !this.open);
|
|
626
|
+
}
|
|
627
|
+
if (this.open) {
|
|
628
|
+
this.syncPortalElements();
|
|
534
629
|
}
|
|
630
|
+
else {
|
|
631
|
+
this.destroyPortal();
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
applyItemElementState(element, props, selected, hidden) {
|
|
635
|
+
element.id = props.id;
|
|
636
|
+
element.setAttribute('role', props.role);
|
|
637
|
+
element.setAttribute('tabindex', props.tabindex);
|
|
638
|
+
if (props['aria-disabled']) {
|
|
639
|
+
element.setAttribute('aria-disabled', props['aria-disabled']);
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
element.removeAttribute('aria-disabled');
|
|
643
|
+
}
|
|
644
|
+
element.setAttribute('data-active', props['data-active']);
|
|
645
|
+
element.active = props['data-active'] === 'true';
|
|
646
|
+
element.selected = selected;
|
|
647
|
+
element.disabled = props['aria-disabled'] === 'true';
|
|
648
|
+
element.hidden = hidden;
|
|
649
|
+
}
|
|
650
|
+
syncPortalElements() {
|
|
651
|
+
if (!this.open || !this.model)
|
|
652
|
+
return;
|
|
653
|
+
const portal = this.ensurePortalRoot();
|
|
654
|
+
if (!portal)
|
|
655
|
+
return;
|
|
656
|
+
const menu = this.getMenuElement();
|
|
657
|
+
this.applyPortalBaseState(portal, menu);
|
|
658
|
+
const fragment = this.ownerDocument.createDocumentFragment();
|
|
659
|
+
const nextPortalRecords = [];
|
|
660
|
+
for (const record of this.itemRecords) {
|
|
661
|
+
const clone = record.element.cloneNode(true);
|
|
662
|
+
const props = this.model.contracts.getItemProps(record.id);
|
|
663
|
+
clone.removeAttribute('slot');
|
|
664
|
+
clone.setAttribute('data-cv-menu-value', record.id);
|
|
665
|
+
clone.value = record.id;
|
|
666
|
+
clone.className = record.element.className;
|
|
667
|
+
this.applyItemElementState(clone, props, this.value === record.id, false);
|
|
668
|
+
fragment.append(clone);
|
|
669
|
+
nextPortalRecords.push({ id: record.id, element: clone });
|
|
670
|
+
}
|
|
671
|
+
portal.replaceChildren(fragment);
|
|
672
|
+
this.portalItemRecords = nextPortalRecords;
|
|
673
|
+
const base = this.getBaseElement();
|
|
674
|
+
if (base) {
|
|
675
|
+
this.applyPortalLayout(portal, base);
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
portal.style.visibility = 'hidden';
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
applyPortalBaseState(portal, menu) {
|
|
682
|
+
const source = menu ? getComputedStyle(menu) : null;
|
|
683
|
+
portal.hidden = false;
|
|
684
|
+
portal.setAttribute('role', menu?.getAttribute('role') ?? 'menu');
|
|
685
|
+
portal.setAttribute('tabindex', menu?.getAttribute('tabindex') ?? '-1');
|
|
686
|
+
portal.setAttribute('aria-label', menu?.getAttribute('aria-label') ?? this.ariaLabel ?? '');
|
|
687
|
+
portal.style.boxSizing = 'border-box';
|
|
688
|
+
portal.style.display = 'inline-grid';
|
|
689
|
+
portal.style.gap = source?.gap || '4px';
|
|
690
|
+
portal.style.alignContent = source?.alignContent || 'start';
|
|
691
|
+
portal.style.padding = source?.padding || '4px';
|
|
692
|
+
portal.style.background = source?.background || 'var(--cv-color-surface-elevated, #1d2432)';
|
|
693
|
+
portal.style.border = source?.border || '0px solid transparent';
|
|
694
|
+
portal.style.borderRadius = source?.borderRadius || 'var(--cv-radius-sm, 6px)';
|
|
695
|
+
portal.style.boxShadow = source?.boxShadow || '';
|
|
696
|
+
portal.style.color = source?.color || 'var(--cv-color-text, #e8ecf6)';
|
|
697
|
+
portal.style.font = source?.font || 'inherit';
|
|
698
|
+
portal.style.maxWidth = source?.maxWidth || 'calc(100vw - 16px)';
|
|
699
|
+
portal.style.maxHeight = source?.maxHeight || 'calc(100dvh - 16px)';
|
|
700
|
+
portal.style.overflowY = source?.overflowY || 'auto';
|
|
701
|
+
portal.style.pointerEvents = 'auto';
|
|
702
|
+
portal.style.zIndex = source?.zIndex || this.getMenuZIndex();
|
|
703
|
+
portal.style.setProperty('--cv-menu-item-gap', this.getMenuItemProperty(source, '--cv-menu-item-gap', '10px'));
|
|
704
|
+
portal.style.setProperty('--cv-menu-item-padding-block', this.getMenuItemProperty(source, '--cv-menu-item-padding-block', '10px'));
|
|
705
|
+
portal.style.setProperty('--cv-menu-item-padding-inline', this.getMenuItemProperty(source, '--cv-menu-item-padding-inline', '12px'));
|
|
706
|
+
portal.style.setProperty('--cv-menu-item-border-radius', this.getMenuItemProperty(source, '--cv-menu-item-border-radius', 'var(--cv-radius-1, 6px)'));
|
|
707
|
+
}
|
|
708
|
+
getMenuZIndex() {
|
|
709
|
+
const raw = getComputedStyle(this).getPropertyValue('--cv-menu-button-menu-z-index').trim();
|
|
710
|
+
return raw || '20';
|
|
535
711
|
}
|
|
536
712
|
captureState() {
|
|
537
713
|
return {
|
|
@@ -568,6 +744,11 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
568
744
|
const activeId = this.model.state.activeId();
|
|
569
745
|
if (!activeId)
|
|
570
746
|
return;
|
|
747
|
+
const activePortalRecord = this.portalItemRecords.find((record) => record.id === activeId);
|
|
748
|
+
if (activePortalRecord) {
|
|
749
|
+
activePortalRecord.element.focus();
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
571
752
|
const activeRecord = this.itemRecords.find((record) => record.id === activeId);
|
|
572
753
|
activeRecord?.element.focus();
|
|
573
754
|
}
|
|
@@ -616,10 +797,37 @@ export class CVMenuButton extends ReatomLitElement {
|
|
|
616
797
|
const path = event.composedPath();
|
|
617
798
|
if (path.includes(this))
|
|
618
799
|
return;
|
|
800
|
+
if (this.portalRoot && path.includes(this.portalRoot))
|
|
801
|
+
return;
|
|
619
802
|
const previous = this.captureState();
|
|
620
803
|
this.model.actions.handleOutsidePointer();
|
|
621
804
|
this.applyInteractionResult(previous);
|
|
622
805
|
};
|
|
806
|
+
getPortalItemIdFromEvent(event) {
|
|
807
|
+
for (const target of event.composedPath()) {
|
|
808
|
+
if (!(target instanceof HTMLElement))
|
|
809
|
+
continue;
|
|
810
|
+
if (target === this.portalRoot)
|
|
811
|
+
break;
|
|
812
|
+
if (target.tagName.toLowerCase() !== CVMenuItem.elementName)
|
|
813
|
+
continue;
|
|
814
|
+
const id = target.dataset['cvMenuValue']?.trim();
|
|
815
|
+
if (id)
|
|
816
|
+
return id;
|
|
817
|
+
}
|
|
818
|
+
return null;
|
|
819
|
+
}
|
|
820
|
+
handlePortalClick(event) {
|
|
821
|
+
const id = this.getPortalItemIdFromEvent(event);
|
|
822
|
+
if (!id)
|
|
823
|
+
return;
|
|
824
|
+
event.preventDefault();
|
|
825
|
+
this.handleItemClick(id);
|
|
826
|
+
}
|
|
827
|
+
handlePortalKeyDown(event) {
|
|
828
|
+
event.stopPropagation();
|
|
829
|
+
this.handleKeyDown(event);
|
|
830
|
+
}
|
|
623
831
|
handleItemClick(id) {
|
|
624
832
|
if (!this.model)
|
|
625
833
|
return;
|
|
@@ -48,5 +48,5 @@ export declare class CVMenuItem extends LitElement {
|
|
|
48
48
|
static styles: import("lit").CSSResult[];
|
|
49
49
|
static define(): void;
|
|
50
50
|
private handleSubmenuSlotChange;
|
|
51
|
-
protected render(): import("lit").TemplateResult<1>;
|
|
51
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
52
52
|
}
|
|
@@ -44,12 +44,16 @@ export class CVMenuItem extends LitElement {
|
|
|
44
44
|
color var(--cv-duration-fast, 120ms) var(--cv-easing-standard, ease);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
:host(:hover) .item {
|
|
48
|
+
background: var(--cv-color-primary-ring);
|
|
49
|
+
}
|
|
50
|
+
|
|
47
51
|
:host([active]) .item {
|
|
48
|
-
background:
|
|
52
|
+
background: var(--cv-color-primary-ring);
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
:host([selected]) .item {
|
|
52
|
-
background:
|
|
56
|
+
background: var(--cv-color-primary-border);
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
:host([disabled]) .item {
|
|
@@ -58,5 +58,5 @@ export declare class CVMenu extends ReatomLitElement {
|
|
|
58
58
|
private syncOutsidePointerListener;
|
|
59
59
|
private handleDocumentPointerDown;
|
|
60
60
|
private handleSlotChange;
|
|
61
|
-
protected render(): import("lit").TemplateResult
|
|
61
|
+
protected render(): import("lit-html").TemplateResult;
|
|
62
62
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createMenu } from '@chromvoid/headless-ui/menu';
|
|
2
|
-
import { css,
|
|
2
|
+
import { css, nothing } from 'lit';
|
|
3
|
+
import { html } from '../reatom-lit/index.js';
|
|
3
4
|
import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
|
|
4
5
|
import { CVMenuItem } from './cv-menu-item.js';
|
|
5
6
|
const menuKeysToPrevent = new Set([
|
|
@@ -52,10 +53,28 @@ export class CVMenu extends ReatomLitElement {
|
|
|
52
53
|
max-height: var(--cv-menu-max-height, none);
|
|
53
54
|
min-inline-size: var(--cv-menu-min-inline-size, 180px);
|
|
54
55
|
overflow-y: auto;
|
|
56
|
+
opacity: 1;
|
|
57
|
+
transform: translate3d(0, 0, 0);
|
|
58
|
+
transition:
|
|
59
|
+
opacity var(--cv-menu-transition-duration, var(--cv-duration-fast, 120ms))
|
|
60
|
+
var(--cv-easing-standard, ease),
|
|
61
|
+
transform var(--cv-menu-transition-duration, var(--cv-duration-fast, 120ms))
|
|
62
|
+
var(--cv-easing-standard, ease),
|
|
63
|
+
display var(--cv-menu-transition-duration, var(--cv-duration-fast, 120ms)) allow-discrete;
|
|
64
|
+
transition-behavior: allow-discrete;
|
|
55
65
|
}
|
|
56
66
|
|
|
57
67
|
[part='base'][hidden] {
|
|
58
68
|
display: none;
|
|
69
|
+
opacity: 0;
|
|
70
|
+
transform: translate3d(0, -2px, 0);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@starting-style {
|
|
74
|
+
[part='base']:not([hidden]) {
|
|
75
|
+
opacity: 0;
|
|
76
|
+
transform: translate3d(0, -2px, 0);
|
|
77
|
+
}
|
|
59
78
|
}
|
|
60
79
|
`,
|
|
61
80
|
];
|
|
@@ -404,6 +423,7 @@ export class CVMenu extends ReatomLitElement {
|
|
|
404
423
|
tabindex=${menuProps.tabindex}
|
|
405
424
|
aria-label=${menuProps['aria-label'] ?? nothing}
|
|
406
425
|
?hidden=${!this.open}
|
|
426
|
+
class="cv-u-discrete-presence"
|
|
407
427
|
part="base"
|
|
408
428
|
@keydown=${this.handleMenuKeyDown}
|
|
409
429
|
>
|
|
@@ -62,5 +62,5 @@ export declare class CVMeter extends ReatomLitElement {
|
|
|
62
62
|
willUpdate(changedProperties: PropertyValues): void;
|
|
63
63
|
private createModel;
|
|
64
64
|
private toFiniteOrUndefined;
|
|
65
|
-
protected render(): import("lit").TemplateResult
|
|
65
|
+
protected render(): import("lit-html").TemplateResult;
|
|
66
66
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createMeter } from '@chromvoid/headless-ui/meter';
|
|
2
|
-
import { css,
|
|
2
|
+
import { css, nothing } from 'lit';
|
|
3
|
+
import { html } from '../reatom-lit/index.js';
|
|
3
4
|
import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
|
|
4
5
|
let cvMeterNonce = 0;
|
|
5
6
|
export class CVMeter extends ReatomLitElement {
|
|
@@ -54,38 +55,21 @@ export class CVMeter extends ReatomLitElement {
|
|
|
54
55
|
block-size: 100%;
|
|
55
56
|
inline-size: var(--cv-meter-width, 0%);
|
|
56
57
|
border-radius: inherit;
|
|
57
|
-
background:
|
|
58
|
-
90deg,
|
|
59
|
-
var(--cv-color-primary, #65d7ff) 0%,
|
|
60
|
-
color-mix(in oklab, var(--cv-color-primary, #65d7ff) 70%, white) 100%
|
|
61
|
-
);
|
|
58
|
+
background: var(--cv-gradient-progress-primary, var(--cv-gradient-primary));
|
|
62
59
|
transition: inline-size var(--cv-meter-transition-duration, var(--cv-duration-normal, 220ms))
|
|
63
60
|
var(--cv-easing-standard, ease);
|
|
64
61
|
}
|
|
65
62
|
|
|
66
63
|
[part='indicator'][data-status='low'] {
|
|
67
|
-
background:
|
|
68
|
-
90deg,
|
|
69
|
-
var(--cv-meter-suboptimum-color, var(--cv-color-warning, #ffbe65)) 0%,
|
|
70
|
-
color-mix(in oklab, var(--cv-meter-suboptimum-color, var(--cv-color-warning, #ffbe65)) 72%, white)
|
|
71
|
-
100%
|
|
72
|
-
);
|
|
64
|
+
background: var(--cv-gradient-progress-warning, var(--cv-gradient-primary));
|
|
73
65
|
}
|
|
74
66
|
|
|
75
67
|
[part='indicator'][data-status='high'] {
|
|
76
|
-
background:
|
|
77
|
-
90deg,
|
|
78
|
-
var(--cv-meter-danger-color, var(--cv-color-danger, #ff7a8a)) 0%,
|
|
79
|
-
color-mix(in oklab, var(--cv-meter-danger-color, var(--cv-color-danger, #ff7a8a)) 72%, white) 100%
|
|
80
|
-
);
|
|
68
|
+
background: var(--cv-gradient-progress-danger, var(--cv-gradient-primary));
|
|
81
69
|
}
|
|
82
70
|
|
|
83
71
|
[part='indicator'][data-status='optimum'] {
|
|
84
|
-
background:
|
|
85
|
-
90deg,
|
|
86
|
-
var(--cv-meter-optimum-color, var(--cv-color-success, #6ef7c8)) 0%,
|
|
87
|
-
color-mix(in oklab, var(--cv-meter-optimum-color, var(--cv-color-success, #6ef7c8)) 72%, white) 100%
|
|
88
|
-
);
|
|
72
|
+
background: var(--cv-gradient-progress-success, var(--cv-gradient-success));
|
|
89
73
|
}
|
|
90
74
|
`,
|
|
91
75
|
];
|
|
@@ -134,6 +134,6 @@ export declare class CVNumber extends FormAssociatedReatomElement {
|
|
|
134
134
|
private handleIncrementClick;
|
|
135
135
|
private handleDecrementClick;
|
|
136
136
|
private handleClearClick;
|
|
137
|
-
protected render(): import("lit").TemplateResult<1>;
|
|
137
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
138
138
|
}
|
|
139
139
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, css, html } from 'lit';
|
|
2
|
-
import { componentResetStyles
|
|
2
|
+
import { componentResetStyles } from '../styles/component-styles.js';
|
|
3
3
|
export class CVOption extends LitElement {
|
|
4
4
|
static elementName = 'cv-option';
|
|
5
5
|
static get properties() {
|
|
@@ -43,17 +43,11 @@ export class CVOption extends LitElement {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
:host([active]) [part='base'] {
|
|
46
|
-
background: var(
|
|
47
|
-
--cv-option-active-background,
|
|
48
|
-
color-mix(in oklab, var(--cv-color-primary, #65d7ff) 22%, transparent)
|
|
49
|
-
);
|
|
46
|
+
background: var(--cv-option-active-background, var(--cv-color-primary-ring));
|
|
50
47
|
}
|
|
51
48
|
|
|
52
49
|
:host([selected]) [part='base'] {
|
|
53
|
-
background: var(
|
|
54
|
-
--cv-option-selected-background,
|
|
55
|
-
color-mix(in oklab, var(--cv-color-primary, #65d7ff) 34%, transparent)
|
|
56
|
-
);
|
|
50
|
+
background: var(--cv-option-selected-background, var(--cv-color-primary-border));
|
|
57
51
|
color: var(--cv-color-text, #e8ecf6);
|
|
58
52
|
}
|
|
59
53
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type CVPopoverPlacement = 'top-start' | 'top' | 'top-end' | 'right-start' | 'right' | 'right-end' | 'bottom-start' | 'bottom' | 'bottom-end' | 'left-start' | 'left' | 'left-end';
|
|
2
|
+
export interface CVPopoverRect {
|
|
3
|
+
left: number;
|
|
4
|
+
top: number;
|
|
5
|
+
right: number;
|
|
6
|
+
bottom: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
}
|
|
10
|
+
export interface CVPopoverViewport {
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
padding: number;
|
|
14
|
+
}
|
|
15
|
+
export interface CVPopoverResolvedPosition {
|
|
16
|
+
left: number;
|
|
17
|
+
top: number;
|
|
18
|
+
placement: CVPopoverPlacement;
|
|
19
|
+
}
|
|
20
|
+
export declare function getPlacementFallbacks(placement: CVPopoverPlacement): CVPopoverPlacement[];
|
|
21
|
+
export declare function getPositionAreaForPlacement(placement: CVPopoverPlacement): string;
|
|
22
|
+
export declare function resolvePopoverPosition(anchorRect: CVPopoverRect, panelRect: CVPopoverRect, placement: CVPopoverPlacement, offset: number, viewport: CVPopoverViewport): CVPopoverResolvedPosition;
|