@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.
Files changed (192) hide show
  1. package/LICENSE +19 -6
  2. package/README.md +1 -0
  3. package/dist/components/cv-accordion-item.d.ts +1 -1
  4. package/dist/components/cv-accordion.d.ts +1 -1
  5. package/dist/components/cv-accordion.js +2 -1
  6. package/dist/components/cv-alert-dialog.d.ts +1 -1
  7. package/dist/components/cv-alert-dialog.js +17 -2
  8. package/dist/components/cv-alert.d.ts +1 -1
  9. package/dist/components/cv-alert.js +2 -1
  10. package/dist/components/cv-badge.d.ts +1 -1
  11. package/dist/components/cv-badge.js +2 -1
  12. package/dist/components/cv-bottom-sheet.d.ts +127 -0
  13. package/dist/components/cv-bottom-sheet.js +513 -0
  14. package/dist/components/cv-breadcrumb-item.d.ts +1 -1
  15. package/dist/components/cv-breadcrumb-item.js +1 -1
  16. package/dist/components/cv-breadcrumb.d.ts +1 -1
  17. package/dist/components/cv-breadcrumb.js +2 -1
  18. package/dist/components/cv-button.d.ts +23 -1
  19. package/dist/components/cv-button.js +194 -37
  20. package/dist/components/cv-callout.d.ts +8 -1
  21. package/dist/components/cv-callout.js +18 -1
  22. package/dist/components/cv-card.d.ts +1 -1
  23. package/dist/components/cv-card.js +2 -2
  24. package/dist/components/cv-carousel-slide.d.ts +1 -1
  25. package/dist/components/cv-carousel.d.ts +1 -1
  26. package/dist/components/cv-carousel.js +2 -1
  27. package/dist/components/cv-checkbox.d.ts +1 -1
  28. package/dist/components/cv-combobox-group.d.ts +1 -1
  29. package/dist/components/cv-combobox-option.d.ts +1 -1
  30. package/dist/components/cv-combobox-option.js +2 -2
  31. package/dist/components/cv-combobox.d.ts +3 -1
  32. package/dist/components/cv-combobox.js +49 -8
  33. package/dist/components/cv-command-item.d.ts +1 -1
  34. package/dist/components/cv-command-item.js +2 -2
  35. package/dist/components/cv-command-palette.d.ts +1 -1
  36. package/dist/components/cv-command-palette.js +21 -1
  37. package/dist/components/cv-context-menu.d.ts +1 -1
  38. package/dist/components/cv-context-menu.js +2 -1
  39. package/dist/components/cv-copy-button.d.ts +37 -9
  40. package/dist/components/cv-copy-button.js +129 -41
  41. package/dist/components/cv-date-picker.d.ts +1 -1
  42. package/dist/components/cv-date-picker.js +20 -1
  43. package/dist/components/cv-dialog.d.ts +44 -2
  44. package/dist/components/cv-dialog.js +686 -74
  45. package/dist/components/cv-disclosure.d.ts +1 -1
  46. package/dist/components/cv-disclosure.js +2 -1
  47. package/dist/components/cv-drawer.d.ts +29 -1
  48. package/dist/components/cv-drawer.js +229 -4
  49. package/dist/components/cv-feed-article.d.ts +1 -1
  50. package/dist/components/cv-feed-article.js +2 -1
  51. package/dist/components/cv-feed.d.ts +1 -1
  52. package/dist/components/cv-feed.js +2 -1
  53. package/dist/components/cv-grid-cell.d.ts +1 -1
  54. package/dist/components/cv-grid-cell.js +3 -3
  55. package/dist/components/cv-grid-column.d.ts +1 -1
  56. package/dist/components/cv-grid-column.js +1 -1
  57. package/dist/components/cv-grid-row.d.ts +1 -1
  58. package/dist/components/cv-grid.d.ts +1 -1
  59. package/dist/components/cv-grid.js +2 -1
  60. package/dist/components/cv-guidance-anchor.d.ts +47 -0
  61. package/dist/components/cv-guidance-anchor.js +113 -0
  62. package/dist/components/cv-guidance-panel.d.ts +29 -0
  63. package/dist/components/cv-guidance-panel.js +245 -0
  64. package/dist/components/cv-icon.d.ts +2 -1
  65. package/dist/components/cv-icon.js +28 -3
  66. package/dist/components/cv-input.d.ts +7 -1
  67. package/dist/components/cv-input.js +33 -1
  68. package/dist/components/cv-landmark.d.ts +1 -1
  69. package/dist/components/cv-landmark.js +2 -1
  70. package/dist/components/cv-link.d.ts +1 -1
  71. package/dist/components/cv-link.js +2 -1
  72. package/dist/components/cv-listbox-group.d.ts +1 -1
  73. package/dist/components/cv-listbox.d.ts +1 -1
  74. package/dist/components/cv-listbox.js +2 -1
  75. package/dist/components/cv-menu-button.d.ts +24 -1
  76. package/dist/components/cv-menu-button.js +226 -18
  77. package/dist/components/cv-menu-group.d.ts +1 -1
  78. package/dist/components/cv-menu-item.d.ts +1 -1
  79. package/dist/components/cv-menu-item.js +6 -2
  80. package/dist/components/cv-menu.d.ts +1 -1
  81. package/dist/components/cv-menu.js +21 -1
  82. package/dist/components/cv-meter.d.ts +1 -1
  83. package/dist/components/cv-meter.js +6 -22
  84. package/dist/components/cv-number.d.ts +1 -1
  85. package/dist/components/cv-option.d.ts +1 -1
  86. package/dist/components/cv-option.js +3 -9
  87. package/dist/components/cv-popover-positioning.d.ts +22 -0
  88. package/dist/components/cv-popover-positioning.js +112 -0
  89. package/dist/components/cv-popover.d.ts +45 -8
  90. package/dist/components/cv-popover.js +395 -113
  91. package/dist/components/cv-progress-ring.d.ts +1 -1
  92. package/dist/components/cv-progress-ring.js +2 -1
  93. package/dist/components/cv-progress.d.ts +8 -1
  94. package/dist/components/cv-progress.js +41 -10
  95. package/dist/components/cv-radio-group.d.ts +1 -1
  96. package/dist/components/cv-radio.d.ts +1 -1
  97. package/dist/components/cv-radio.js +1 -1
  98. package/dist/components/cv-select-group.d.ts +1 -1
  99. package/dist/components/cv-select-option.d.ts +1 -1
  100. package/dist/components/cv-select-option.js +2 -2
  101. package/dist/components/cv-select.d.ts +1 -1
  102. package/dist/components/cv-select.js +28 -1
  103. package/dist/components/cv-sidebar-item.d.ts +1 -1
  104. package/dist/components/cv-sidebar.d.ts +1 -1
  105. package/dist/components/cv-sidebar.js +3 -2
  106. package/dist/components/cv-slider-multi-thumb.d.ts +1 -1
  107. package/dist/components/cv-slider-multi-thumb.js +2 -1
  108. package/dist/components/cv-slider.d.ts +17 -4
  109. package/dist/components/cv-slider.js +63 -21
  110. package/dist/components/cv-spinbutton.d.ts +1 -1
  111. package/dist/components/cv-spinner.d.ts +1 -1
  112. package/dist/components/cv-spinner.js +2 -1
  113. package/dist/components/cv-switch.d.ts +1 -1
  114. package/dist/components/cv-tab-panel.d.ts +1 -1
  115. package/dist/components/cv-tab.d.ts +1 -1
  116. package/dist/components/cv-table-cell.d.ts +1 -1
  117. package/dist/components/cv-table-cell.js +1 -1
  118. package/dist/components/cv-table-column.d.ts +1 -1
  119. package/dist/components/cv-table-column.js +1 -1
  120. package/dist/components/cv-table-row.d.ts +1 -1
  121. package/dist/components/cv-table-row.js +1 -4
  122. package/dist/components/cv-table.d.ts +1 -3
  123. package/dist/components/cv-table.js +4 -11
  124. package/dist/components/cv-tabs.d.ts +1 -1
  125. package/dist/components/cv-tabs.js +3 -2
  126. package/dist/components/cv-textarea.d.ts +11 -1
  127. package/dist/components/cv-textarea.js +33 -0
  128. package/dist/components/cv-toast-region.d.ts +1 -1
  129. package/dist/components/cv-toast-region.js +2 -1
  130. package/dist/components/cv-toast.d.ts +1 -1
  131. package/dist/components/cv-toast.js +20 -27
  132. package/dist/components/cv-toolbar-item.d.ts +1 -1
  133. package/dist/components/cv-toolbar-separator.d.ts +1 -1
  134. package/dist/components/cv-toolbar.d.ts +1 -1
  135. package/dist/components/cv-toolbar.js +2 -1
  136. package/dist/components/cv-tooltip.d.ts +1 -1
  137. package/dist/components/cv-tooltip.js +2 -1
  138. package/dist/components/cv-treegrid-cell.d.ts +1 -1
  139. package/dist/components/cv-treegrid-cell.js +1 -1
  140. package/dist/components/cv-treegrid-column.d.ts +1 -1
  141. package/dist/components/cv-treegrid-column.js +1 -1
  142. package/dist/components/cv-treegrid-row.d.ts +1 -1
  143. package/dist/components/cv-treegrid-row.js +1 -1
  144. package/dist/components/cv-treegrid.d.ts +1 -1
  145. package/dist/components/cv-treegrid.js +4 -3
  146. package/dist/components/cv-treeitem.d.ts +1 -1
  147. package/dist/components/cv-treeitem.js +2 -2
  148. package/dist/components/cv-treeview.d.ts +1 -1
  149. package/dist/components/cv-treeview.js +2 -1
  150. package/dist/components/cv-window-splitter.d.ts +1 -1
  151. package/dist/components/cv-window-splitter.js +2 -1
  152. package/dist/components/index.d.ts +7 -0
  153. package/dist/components/index.js +3 -0
  154. package/dist/dialog/create-dialog-controller.d.ts +12 -4
  155. package/dist/dialog/create-dialog-controller.js +84 -22
  156. package/dist/dialog/index.d.ts +1 -1
  157. package/dist/index.d.ts +1 -1
  158. package/dist/reatom-lit/ReatomLitElement.d.ts +6 -3
  159. package/dist/reatom-lit/ReatomLitElement.js +18 -8
  160. package/dist/reatom-lit/createAfterRenderScheduler.d.ts +10 -0
  161. package/dist/reatom-lit/createAfterRenderScheduler.js +33 -0
  162. package/dist/reatom-lit/index.d.ts +2 -0
  163. package/dist/reatom-lit/index.js +1 -0
  164. package/dist/reatom-lit/watch.d.ts +1 -1
  165. package/dist/reatom-lit/withReatomElement.js +16 -2
  166. package/dist/register.js +4 -1
  167. package/dist/styles/component-styles.js +4 -0
  168. package/dist/styles/uno-generated.d.ts +2 -0
  169. package/dist/styles/uno-generated.js +1 -0
  170. package/dist/styles/uno-utilities.d.ts +5 -0
  171. package/dist/styles/uno-utilities.js +7 -0
  172. package/dist/theme/cv-theme-provider.d.ts +1 -1
  173. package/dist/theme/cv-theme-provider.js +2 -2
  174. package/dist/theme/tokens.css +619 -162
  175. package/package.json +9 -5
  176. package/specs/components/bottom-sheet.md +93 -0
  177. package/specs/components/button.md +8 -0
  178. package/specs/components/callout.md +8 -0
  179. package/specs/components/copy-button.md +54 -17
  180. package/specs/components/dialog.md +72 -43
  181. package/specs/components/drawer.md +18 -13
  182. package/specs/components/guidance-anchor.md +64 -0
  183. package/specs/components/guidance-panel.md +92 -0
  184. package/specs/components/input.md +7 -0
  185. package/specs/components/menu.md +8 -0
  186. package/specs/components/option.md +9 -9
  187. package/specs/components/progress.md +11 -0
  188. package/specs/components/sidebar.md +12 -12
  189. package/specs/components/table.md +13 -13
  190. package/specs/components/theme.md +13 -13
  191. package/specs/components/treegrid.md +15 -15
  192. package/specs/components/treeview.md +10 -10
@@ -53,5 +53,5 @@ export declare class CVDisclosure extends ReatomLitElement {
53
53
  hide(): void;
54
54
  private handleTriggerClick;
55
55
  private handleTriggerKeyDown;
56
- protected render(): import("lit").TemplateResult<1>;
56
+ protected render(): import("lit-html").TemplateResult;
57
57
  }
@@ -1,5 +1,6 @@
1
1
  import { createDisclosure } from '@chromvoid/headless-ui/disclosure';
2
- import { css, html, nothing } from 'lit';
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 cvDisclosureNonce = 0;
5
6
  export class CVDisclosure extends ReatomLitElement {
@@ -46,6 +46,11 @@ export declare class CVDrawer extends ReatomLitElement {
46
46
  attribute: string;
47
47
  reflect: boolean;
48
48
  };
49
+ dragToClose: {
50
+ type: BooleanConstructor;
51
+ attribute: string;
52
+ reflect: boolean;
53
+ };
49
54
  };
50
55
  open: boolean;
51
56
  modal: boolean;
@@ -56,6 +61,7 @@ export declare class CVDrawer extends ReatomLitElement {
56
61
  closeOnOutsideFocus: boolean;
57
62
  initialFocusId: string;
58
63
  noHeader: boolean;
64
+ dragToClose: boolean;
59
65
  private readonly idBase;
60
66
  private model;
61
67
  private lockScrollApplied;
@@ -67,6 +73,11 @@ export declare class CVDrawer extends ReatomLitElement {
67
73
  private openAnimationFrame;
68
74
  private closeAnimationTimeout;
69
75
  private shouldAnimatePresence;
76
+ private dragPointerId;
77
+ private dragStartX;
78
+ private dragStartY;
79
+ private dragStartedAt;
80
+ private dragMoved;
70
81
  constructor();
71
82
  static styles: import("lit").CSSResult[];
72
83
  static define(): void;
@@ -91,12 +102,29 @@ export declare class CVDrawer extends ReatomLitElement {
91
102
  private syncOutsideFocusListener;
92
103
  private syncScrollLock;
93
104
  private releaseScrollLock;
105
+ private getDragElements;
106
+ private resetDragState;
107
+ private finishDragInteraction;
108
+ private isHorizontalPlacement;
109
+ private getClosingDistance;
110
+ private getVisualDragOffset;
111
+ private getPanelDragSize;
112
+ private shouldCancelDragForScroll;
113
+ private setDragOffset;
114
+ private commitDragClose;
115
+ private trySetPointerCapture;
116
+ private tryReleasePointerCapture;
94
117
  private focusInitialTarget;
95
118
  private handleDocumentFocusIn;
96
119
  private handleTriggerClick;
97
120
  private handleTriggerKeyDown;
98
121
  private handleOverlayPointerDown;
122
+ private handleOverlayClick;
99
123
  private handlePanelKeyDown;
100
124
  private handleHeaderCloseClick;
101
- protected render(): import("lit").TemplateResult<1>;
125
+ private handlePanelPointerDown;
126
+ private handlePanelPointerMove;
127
+ private handlePanelPointerUp;
128
+ private handlePanelPointerCancel;
129
+ protected render(): import("lit-html").TemplateResult;
102
130
  }
@@ -1,7 +1,12 @@
1
1
  import { createDrawer } from '@chromvoid/headless-ui/drawer';
2
- import { css, html, nothing } from 'lit';
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 cvDrawerNonce = 0;
6
+ const DRAG_CLOSE_DISTANCE_PX = 96;
7
+ const DRAG_CLOSE_VELOCITY_PX_PER_MS = 0.75;
8
+ const DRAG_SCROLL_DOMINANCE_PX = 18;
9
+ const DRAG_MOVE_EPSILON_PX = 4;
5
10
  export class CVDrawer extends ReatomLitElement {
6
11
  static elementName = 'cv-drawer';
7
12
  static get properties() {
@@ -15,6 +20,7 @@ export class CVDrawer extends ReatomLitElement {
15
20
  closeOnOutsideFocus: { type: Boolean, attribute: 'close-on-outside-focus', reflect: true },
16
21
  initialFocusId: { type: String, attribute: 'initial-focus-id' },
17
22
  noHeader: { type: Boolean, attribute: 'no-header', reflect: true },
23
+ dragToClose: { type: Boolean, attribute: 'drag-to-close', reflect: true },
18
24
  };
19
25
  }
20
26
  idBase = `cv-drawer-${++cvDrawerNonce}`;
@@ -28,6 +34,11 @@ export class CVDrawer extends ReatomLitElement {
28
34
  openAnimationFrame = 0;
29
35
  closeAnimationTimeout = 0;
30
36
  shouldAnimatePresence = false;
37
+ dragPointerId = null;
38
+ dragStartX = 0;
39
+ dragStartY = 0;
40
+ dragStartedAt = 0;
41
+ dragMoved = false;
31
42
  constructor() {
32
43
  super();
33
44
  this.open = false;
@@ -39,6 +50,7 @@ export class CVDrawer extends ReatomLitElement {
39
50
  this.closeOnOutsideFocus = true;
40
51
  this.initialFocusId = '';
41
52
  this.noHeader = false;
53
+ this.dragToClose = false;
42
54
  this.model = this.createModel();
43
55
  this.overlayVisible = this.open;
44
56
  this.renderState = this.open ? 'open' : 'closed';
@@ -74,9 +86,12 @@ export class CVDrawer extends ReatomLitElement {
74
86
  display: flex;
75
87
  overflow: clip;
76
88
  contain: paint;
77
- background: var(--cv-drawer-overlay-color, color-mix(in oklab, black 56%, transparent));
89
+ background: var(--cv-drawer-overlay-color, var(--cv-color-overlay));
78
90
  opacity: var(--cv-drawer-overlay-closed-opacity, 1);
79
- transition: opacity var(--cv-drawer-overlay-transition-duration, 0ms) ease;
91
+ transition:
92
+ opacity var(--cv-drawer-overlay-transition-duration, 0ms) ease,
93
+ display var(--cv-drawer-overlay-transition-duration, 0ms) allow-discrete;
94
+ transition-behavior: allow-discrete;
80
95
  }
81
96
 
82
97
  [part='overlay'][hidden] {
@@ -87,7 +102,14 @@ export class CVDrawer extends ReatomLitElement {
87
102
  opacity: 1;
88
103
  }
89
104
 
105
+ [part='overlay'][data-dragging='true'] {
106
+ opacity: var(--cv-drawer-drag-overlay-opacity, 1);
107
+ transition: none;
108
+ }
109
+
90
110
  [part='panel'] {
111
+ --cv-drawer-drag-offset-x: 0px;
112
+ --cv-drawer-drag-offset-y: 0px;
91
113
  position: fixed;
92
114
  overflow: auto;
93
115
  display: grid;
@@ -100,6 +122,7 @@ export class CVDrawer extends ReatomLitElement {
100
122
  transition:
101
123
  transform var(--cv-drawer-transition-duration, 250ms) ease,
102
124
  opacity var(--cv-drawer-transition-duration, 250ms) ease;
125
+ transition-behavior: allow-discrete;
103
126
  }
104
127
 
105
128
  [part='panel']:focus-visible {
@@ -116,6 +139,7 @@ export class CVDrawer extends ReatomLitElement {
116
139
  border-radius: 0 var(--cv-drawer-border-radius, var(--cv-radius-lg, 14px))
117
140
  var(--cv-drawer-border-radius, var(--cv-radius-lg, 14px)) 0;
118
141
  transform: translate3d(-100%, 0, 0);
142
+ touch-action: pan-y;
119
143
  }
120
144
 
121
145
  /* Placement: end (inline-end edge) */
@@ -127,6 +151,7 @@ export class CVDrawer extends ReatomLitElement {
127
151
  border-radius: var(--cv-drawer-border-radius, var(--cv-radius-lg, 14px)) 0 0
128
152
  var(--cv-drawer-border-radius, var(--cv-radius-lg, 14px));
129
153
  transform: translate3d(100%, 0, 0);
154
+ touch-action: pan-y;
130
155
  }
131
156
 
132
157
  /* Placement: top */
@@ -138,6 +163,7 @@ export class CVDrawer extends ReatomLitElement {
138
163
  border-radius: 0 0 var(--cv-drawer-border-radius, var(--cv-radius-lg, 14px))
139
164
  var(--cv-drawer-border-radius, var(--cv-radius-lg, 14px));
140
165
  transform: translate3d(0, -100%, 0);
166
+ touch-action: pan-x;
141
167
  }
142
168
 
143
169
  /* Placement: bottom */
@@ -149,11 +175,25 @@ export class CVDrawer extends ReatomLitElement {
149
175
  border-radius: var(--cv-drawer-border-radius, var(--cv-radius-lg, 14px))
150
176
  var(--cv-drawer-border-radius, var(--cv-radius-lg, 14px)) 0 0;
151
177
  transform: translate3d(0, 100%, 0);
178
+ touch-action: pan-x;
152
179
  }
153
180
 
154
181
  [part='panel'][data-state='open'] {
155
182
  opacity: 1;
156
- transform: translate3d(0, 0, 0);
183
+ }
184
+
185
+ [part='panel'][data-placement='start'][data-state='open'],
186
+ [part='panel'][data-placement='end'][data-state='open'] {
187
+ transform: translate3d(var(--cv-drawer-drag-offset-x, 0px), 0, 0);
188
+ }
189
+
190
+ [part='panel'][data-placement='top'][data-state='open'],
191
+ [part='panel'][data-placement='bottom'][data-state='open'] {
192
+ transform: translate3d(0, var(--cv-drawer-drag-offset-y, 0px), 0);
193
+ }
194
+
195
+ [part='panel'][data-dragging='true'] {
196
+ transition: none;
157
197
  }
158
198
 
159
199
  @media (prefers-reduced-motion: reduce) {
@@ -226,6 +266,7 @@ export class CVDrawer extends ReatomLitElement {
226
266
  this.syncOutsideFocusListener(true);
227
267
  this.releaseScrollLock();
228
268
  this.clearAnimationQueue();
269
+ this.resetDragState();
229
270
  }
230
271
  willUpdate(changedProperties) {
231
272
  super.willUpdate(changedProperties);
@@ -300,6 +341,7 @@ export class CVDrawer extends ReatomLitElement {
300
341
  }
301
342
  }
302
343
  startOpenAnimation() {
344
+ this.resetDragState();
303
345
  this.openAnimationFrame = requestAnimationFrame(() => {
304
346
  this.openAnimationFrame = 0;
305
347
  if (!this.open)
@@ -312,6 +354,7 @@ export class CVDrawer extends ReatomLitElement {
312
354
  const duration = this.getTransitionDuration();
313
355
  if (duration === 0) {
314
356
  this.overlayVisible = false;
357
+ this.resetDragState();
315
358
  this.syncRenderedState();
316
359
  return;
317
360
  }
@@ -320,6 +363,7 @@ export class CVDrawer extends ReatomLitElement {
320
363
  if (this.open)
321
364
  return;
322
365
  this.overlayVisible = false;
366
+ this.resetDragState();
323
367
  this.syncRenderedState();
324
368
  }, duration);
325
369
  }
@@ -460,6 +504,111 @@ export class CVDrawer extends ReatomLitElement {
460
504
  document.body.style.overflow = this.previousBodyOverflow;
461
505
  this.lockScrollApplied = false;
462
506
  }
507
+ getDragElements() {
508
+ return {
509
+ panel: this.shadowRoot?.querySelector('[part="panel"]'),
510
+ overlay: this.shadowRoot?.querySelector('[part="overlay"]'),
511
+ };
512
+ }
513
+ resetDragState() {
514
+ this.dragPointerId = null;
515
+ this.dragStartX = 0;
516
+ this.dragStartY = 0;
517
+ this.dragStartedAt = 0;
518
+ this.dragMoved = false;
519
+ const { panel, overlay } = this.getDragElements();
520
+ panel?.removeAttribute('data-dragging');
521
+ panel?.style.removeProperty('--cv-drawer-drag-offset-x');
522
+ panel?.style.removeProperty('--cv-drawer-drag-offset-y');
523
+ overlay?.removeAttribute('data-dragging');
524
+ overlay?.style.removeProperty('--cv-drawer-drag-overlay-opacity');
525
+ }
526
+ finishDragInteraction() {
527
+ this.dragPointerId = null;
528
+ this.dragStartedAt = 0;
529
+ this.dragMoved = false;
530
+ const { panel, overlay } = this.getDragElements();
531
+ panel?.removeAttribute('data-dragging');
532
+ overlay?.removeAttribute('data-dragging');
533
+ }
534
+ isHorizontalPlacement() {
535
+ return this.placement === 'start' || this.placement === 'end';
536
+ }
537
+ getClosingDistance(event) {
538
+ switch (this.placement) {
539
+ case 'start':
540
+ return this.dragStartX - event.clientX;
541
+ case 'end':
542
+ return event.clientX - this.dragStartX;
543
+ case 'top':
544
+ return this.dragStartY - event.clientY;
545
+ case 'bottom':
546
+ return event.clientY - this.dragStartY;
547
+ default:
548
+ return 0;
549
+ }
550
+ }
551
+ getVisualDragOffset(closingDistance) {
552
+ const offset = Math.max(0, closingDistance);
553
+ return this.placement === 'start' || this.placement === 'top' ? -offset : offset;
554
+ }
555
+ getPanelDragSize(panel) {
556
+ if (!panel)
557
+ return DRAG_CLOSE_DISTANCE_PX;
558
+ const rect = panel.getBoundingClientRect();
559
+ const size = this.isHorizontalPlacement() ? rect.width : rect.height;
560
+ return Math.max(size, DRAG_CLOSE_DISTANCE_PX);
561
+ }
562
+ shouldCancelDragForScroll(event) {
563
+ if (this.dragMoved)
564
+ return false;
565
+ const mainDelta = this.isHorizontalPlacement()
566
+ ? Math.abs(event.clientX - this.dragStartX)
567
+ : Math.abs(event.clientY - this.dragStartY);
568
+ const crossDelta = this.isHorizontalPlacement()
569
+ ? Math.abs(event.clientY - this.dragStartY)
570
+ : Math.abs(event.clientX - this.dragStartX);
571
+ return crossDelta > DRAG_SCROLL_DOMINANCE_PX && crossDelta > mainDelta;
572
+ }
573
+ setDragOffset(closingDistance) {
574
+ const { panel, overlay } = this.getDragElements();
575
+ const visualOffset = this.getVisualDragOffset(closingDistance);
576
+ const panelSize = this.getPanelDragSize(panel);
577
+ const progress = Math.min(Math.max(Math.max(0, closingDistance) / panelSize, 0), 1);
578
+ const overlayOpacity = Math.max(0.55, 1 - progress * 0.45);
579
+ if (this.isHorizontalPlacement()) {
580
+ panel?.style.setProperty('--cv-drawer-drag-offset-x', `${Math.round(visualOffset)}px`);
581
+ panel?.style.setProperty('--cv-drawer-drag-offset-y', '0px');
582
+ }
583
+ else {
584
+ panel?.style.setProperty('--cv-drawer-drag-offset-x', '0px');
585
+ panel?.style.setProperty('--cv-drawer-drag-offset-y', `${Math.round(visualOffset)}px`);
586
+ }
587
+ overlay?.style.setProperty('--cv-drawer-drag-overlay-opacity', String(overlayOpacity));
588
+ }
589
+ commitDragClose() {
590
+ if (!this.open)
591
+ return;
592
+ const previous = this.captureState();
593
+ this.model.actions.close();
594
+ this.applyInteractionResult(previous);
595
+ }
596
+ trySetPointerCapture(target, pointerId) {
597
+ try {
598
+ target?.setPointerCapture?.(pointerId);
599
+ }
600
+ catch {
601
+ // Synthetic PointerEvents used by browser tests do not always register an active pointer.
602
+ }
603
+ }
604
+ tryReleasePointerCapture(target, pointerId) {
605
+ try {
606
+ target?.releasePointerCapture?.(pointerId);
607
+ }
608
+ catch {
609
+ // Release is best-effort because the pointer may already be cancelled or synthetic.
610
+ }
611
+ }
463
612
  focusInitialTarget() {
464
613
  const panelProps = this.model.contracts.getPanelProps();
465
614
  const requestedId = panelProps['data-initial-focus'];
@@ -504,6 +653,15 @@ export class CVDrawer extends ReatomLitElement {
504
653
  this.model.contracts.getOverlayProps().onPointerDownOutside();
505
654
  this.applyInteractionResult(previous);
506
655
  }
656
+ handleOverlayClick(event) {
657
+ if (event.target !== event.currentTarget)
658
+ return;
659
+ if (!this.open)
660
+ return;
661
+ const previous = this.captureState();
662
+ this.model.contracts.getOverlayProps().onPointerDownOutside();
663
+ this.applyInteractionResult(previous);
664
+ }
507
665
  handlePanelKeyDown(event) {
508
666
  if (event.key === 'Escape') {
509
667
  event.preventDefault();
@@ -517,6 +675,66 @@ export class CVDrawer extends ReatomLitElement {
517
675
  this.model.contracts.getHeaderCloseButtonProps().onClick();
518
676
  this.applyInteractionResult(previous);
519
677
  }
678
+ handlePanelPointerDown(event) {
679
+ if (!this.open || !this.dragToClose)
680
+ return;
681
+ if (event.pointerType !== 'touch')
682
+ return;
683
+ if (event.isPrimary === false)
684
+ return;
685
+ if (typeof event.button === 'number' && event.button !== 0)
686
+ return;
687
+ this.dragPointerId = event.pointerId;
688
+ this.dragStartX = event.clientX;
689
+ this.dragStartY = event.clientY;
690
+ this.dragStartedAt = performance.now();
691
+ this.dragMoved = false;
692
+ this.setDragOffset(0);
693
+ const { panel, overlay } = this.getDragElements();
694
+ panel?.setAttribute('data-dragging', 'true');
695
+ overlay?.setAttribute('data-dragging', 'true');
696
+ const target = event.currentTarget;
697
+ this.trySetPointerCapture(target, event.pointerId);
698
+ }
699
+ handlePanelPointerMove(event) {
700
+ if (this.dragPointerId !== event.pointerId)
701
+ return;
702
+ if (this.shouldCancelDragForScroll(event)) {
703
+ const target = event.currentTarget;
704
+ this.tryReleasePointerCapture(target, event.pointerId);
705
+ this.resetDragState();
706
+ return;
707
+ }
708
+ const closingDistance = Math.max(0, this.getClosingDistance(event));
709
+ this.dragMoved ||= closingDistance > DRAG_MOVE_EPSILON_PX;
710
+ this.setDragOffset(closingDistance);
711
+ if (closingDistance > 0) {
712
+ event.preventDefault();
713
+ }
714
+ }
715
+ handlePanelPointerUp(event) {
716
+ if (this.dragPointerId !== event.pointerId)
717
+ return;
718
+ const target = event.currentTarget;
719
+ this.tryReleasePointerCapture(target, event.pointerId);
720
+ const elapsed = Math.max(1, performance.now() - this.dragStartedAt);
721
+ const closingDistance = Math.max(0, this.getClosingDistance(event));
722
+ const velocity = closingDistance / elapsed;
723
+ const shouldClose = closingDistance >= DRAG_CLOSE_DISTANCE_PX || velocity >= DRAG_CLOSE_VELOCITY_PX_PER_MS;
724
+ if (shouldClose) {
725
+ this.finishDragInteraction();
726
+ this.commitDragClose();
727
+ return;
728
+ }
729
+ this.resetDragState();
730
+ }
731
+ handlePanelPointerCancel(event) {
732
+ if (this.dragPointerId !== event.pointerId)
733
+ return;
734
+ const target = event.currentTarget;
735
+ this.tryReleasePointerCapture(target, event.pointerId);
736
+ this.resetDragState();
737
+ }
520
738
  render() {
521
739
  const triggerProps = this.model.contracts.getTriggerProps();
522
740
  const overlayProps = this.model.contracts.getOverlayProps();
@@ -545,8 +763,10 @@ export class CVDrawer extends ReatomLitElement {
545
763
  data-open=${overlayProps['data-open']}
546
764
  data-state=${this.renderState}
547
765
  ?hidden=${!this.overlayVisible}
766
+ class="cv-u-discrete-presence"
548
767
  part="overlay"
549
768
  @mousedown=${this.handleOverlayPointerDown}
769
+ @click=${this.handleOverlayClick}
550
770
  >
551
771
  <section
552
772
  id=${panelProps.id}
@@ -558,8 +778,13 @@ export class CVDrawer extends ReatomLitElement {
558
778
  data-placement=${panelProps['data-placement']}
559
779
  data-state=${this.renderState}
560
780
  data-initial-focus=${panelProps['data-initial-focus'] ?? nothing}
781
+ class="cv-u-discrete-presence"
561
782
  part="panel"
562
783
  @keydown=${this.handlePanelKeyDown}
784
+ @pointerdown=${this.handlePanelPointerDown}
785
+ @pointermove=${this.handlePanelPointerMove}
786
+ @pointerup=${this.handlePanelPointerUp}
787
+ @pointercancel=${this.handlePanelPointerCancel}
563
788
  >
564
789
  <header part="header" ?hidden=${this.noHeader}>
565
790
  <h2 id=${titleProps.id} part="title">
@@ -22,5 +22,5 @@ export declare class CVFeedArticle extends ReatomLitElement {
22
22
  constructor();
23
23
  static styles: import("lit").CSSResult[];
24
24
  static define(): void;
25
- protected render(): import("lit").TemplateResult<1>;
25
+ protected render(): import("lit-html").TemplateResult;
26
26
  }
@@ -1,4 +1,5 @@
1
- import { css, html } from 'lit';
1
+ import { css } from 'lit';
2
+ import { html } from '../reatom-lit/index.js';
2
3
  import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
3
4
  export class CVFeedArticle extends ReatomLitElement {
4
5
  static elementName = 'cv-feed-article';
@@ -58,5 +58,5 @@ export declare class CVFeed extends ReatomLitElement {
58
58
  private destroyObserver;
59
59
  private handleKeyDown;
60
60
  private handleSlotChange;
61
- protected render(): import("lit").TemplateResult<1>;
61
+ protected render(): import("lit-html").TemplateResult;
62
62
  }
@@ -1,5 +1,6 @@
1
1
  import { createFeed, } from '@chromvoid/headless-ui/feed';
2
- import { css, html, nothing } from 'lit';
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 cvFeedNonce = 0;
5
6
  export class CVFeed extends ReatomLitElement {
@@ -26,5 +26,5 @@ export declare class CVGridCell extends LitElement {
26
26
  constructor();
27
27
  static styles: import("lit").CSSResult[];
28
28
  static define(): void;
29
- protected render(): import("lit").TemplateResult<1>;
29
+ protected render(): import("lit-html").TemplateResult<1>;
30
30
  }
@@ -21,17 +21,17 @@ export class CVGridCell extends LitElement {
21
21
  :host {
22
22
  display: table-cell;
23
23
  padding: var(--cv-space-2, 8px) var(--cv-space-3, 12px);
24
- border-bottom: 1px solid color-mix(in oklab, var(--cv-color-border, #2a3245) 70%, transparent);
24
+ border-bottom: 1px solid var(--cv-color-border-soft);
25
25
  color: var(--cv-color-text, #e8ecf6);
26
26
  outline: none;
27
27
  }
28
28
 
29
29
  :host([active]) {
30
- background: color-mix(in oklab, var(--cv-color-primary, #65d7ff) 14%, transparent);
30
+ background: var(--cv-color-active);
31
31
  }
32
32
 
33
33
  :host([selected]) {
34
- background: color-mix(in oklab, var(--cv-color-primary, #65d7ff) 24%, transparent);
34
+ background: var(--cv-color-primary-ring);
35
35
  }
36
36
 
37
37
  :host([disabled]) {
@@ -26,5 +26,5 @@ export declare class CVGridColumn extends LitElement {
26
26
  constructor();
27
27
  static styles: import("lit").CSSResult[];
28
28
  static define(): void;
29
- protected render(): import("lit").TemplateResult<1>;
29
+ protected render(): import("lit-html").TemplateResult<1>;
30
30
  }
@@ -24,7 +24,7 @@ export class CVGridColumn extends LitElement {
24
24
  border-bottom: 1px solid var(--cv-color-border, #2a3245);
25
25
  color: var(--cv-color-text, #e8ecf6);
26
26
  font-weight: 600;
27
- background: color-mix(in oklab, var(--cv-color-surface, #141923) 82%, transparent);
27
+ background: var(--cv-color-surface-glass-strong);
28
28
  }
29
29
 
30
30
  :host([disabled]) {
@@ -26,5 +26,5 @@ export declare class CVGridRow extends LitElement {
26
26
  static styles: import("lit").CSSResult[];
27
27
  static define(): void;
28
28
  private handleSlotChange;
29
- protected render(): import("lit").TemplateResult<1>;
29
+ protected render(): import("lit-html").TemplateResult<1>;
30
30
  }
@@ -115,5 +115,5 @@ export declare class CVGrid extends ReatomLitElement {
115
115
  private handleColumnsSlotChange;
116
116
  private handleRowsSlotChange;
117
117
  private handleRowSlotChange;
118
- protected render(): import("lit").TemplateResult<1>;
118
+ protected render(): import("lit-html").TemplateResult;
119
119
  }
@@ -1,5 +1,6 @@
1
1
  import { createGrid, } from '@chromvoid/headless-ui/grid';
2
- import { css, html, nothing } from 'lit';
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 { CVGridCell } from './cv-grid-cell.js';
5
6
  import { CVGridColumn } from './cv-grid-column.js';
@@ -0,0 +1,47 @@
1
+ import type { PropertyValues } from 'lit';
2
+ import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
3
+ export declare const GUIDANCE_ANCHOR_REGISTER_EVENT = "guidance-anchor-register";
4
+ export declare const GUIDANCE_ANCHOR_UNREGISTER_EVENT = "guidance-anchor-unregister";
5
+ export type CVGuidanceAnchorEventDetail = {
6
+ anchorId: string;
7
+ surface: string;
8
+ owner: string;
9
+ element: CVGuidanceAnchor;
10
+ };
11
+ export type CVGuidanceAnchorRegisterEvent = CustomEvent<CVGuidanceAnchorEventDetail>;
12
+ export type CVGuidanceAnchorUnregisterEvent = CustomEvent<CVGuidanceAnchorEventDetail>;
13
+ export declare class CVGuidanceAnchor extends ReatomLitElement {
14
+ static elementName: string;
15
+ static get properties(): {
16
+ anchorId: {
17
+ type: StringConstructor;
18
+ attribute: string;
19
+ reflect: boolean;
20
+ };
21
+ surface: {
22
+ type: StringConstructor;
23
+ reflect: boolean;
24
+ };
25
+ owner: {
26
+ type: StringConstructor;
27
+ reflect: boolean;
28
+ };
29
+ };
30
+ anchorId: string;
31
+ surface: string;
32
+ owner: string;
33
+ private registeredDetail;
34
+ private unregisterEventTarget;
35
+ constructor();
36
+ static styles: import("lit").CSSResult[];
37
+ static define(): void;
38
+ connectedCallback(): void;
39
+ disconnectedCallback(): void;
40
+ updated(changedProperties: PropertyValues): void;
41
+ private createDetail;
42
+ private createDetailKey;
43
+ private hasRequiredMetadata;
44
+ private dispatchRegister;
45
+ private dispatchUnregister;
46
+ protected render(): import("lit-html").TemplateResult;
47
+ }