@threadlabs/looma 0.33.1 → 0.35.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 (215) hide show
  1. package/components/shared/overlay.js +8 -2
  2. package/components/shared/surface-material.js +21 -0
  3. package/components/ui-badge/ui-badge.html +11 -3
  4. package/components/ui-button/ui-button.html +92 -51
  5. package/components/ui-card/ui-card.html +50 -6
  6. package/components/ui-checkbox/ui-checkbox.html +4 -2
  7. package/components/ui-curve-editor/curve.js +10 -0
  8. package/components/ui-curve-editor/ui-curve-editor.html +181 -0
  9. package/components/ui-curve-editor/ui-curve-editor.js +51 -0
  10. package/components/ui-dialog/ui-dialog.html +64 -1
  11. package/components/ui-dialog/ui-dialog.js +9 -1
  12. package/components/ui-icon-button/ui-icon-button.html +97 -31
  13. package/components/ui-input/ui-input.html +2 -1
  14. package/components/ui-input-group/ui-input-group.html +4 -1
  15. package/components/ui-light-editor/ui-light-editor.html +45 -0
  16. package/components/ui-light-editor/ui-light-editor.js +53 -0
  17. package/components/ui-menu/ui-menu.html +62 -0
  18. package/components/ui-menu/ui-menu.js +1 -1
  19. package/components/ui-number-input/arithmetic.js +47 -0
  20. package/components/ui-number-input/ui-number-input.html +63 -0
  21. package/components/ui-number-input/ui-number-input.js +47 -0
  22. package/components/ui-popover/ui-popover.html +66 -1
  23. package/components/ui-popover/ui-popover.js +1 -1
  24. package/components/ui-select/ui-select.html +9 -7
  25. package/components/ui-slider/ui-slider.html +84 -0
  26. package/components/ui-slider/ui-slider.js +29 -0
  27. package/components/ui-switch/ui-switch.html +3 -0
  28. package/components/ui-tabs/ui-tabs.html +6 -1
  29. package/components/ui-text/ui-text.html +31 -6
  30. package/components/ui-textarea/ui-textarea.html +2 -1
  31. package/components/ui-tooltip/ui-tooltip.html +60 -0
  32. package/components/ui-tooltip/ui-tooltip.js +1 -1
  33. package/dist/index.js +47 -43
  34. package/docs/README.md +59 -5
  35. package/docs/card.html +16 -2
  36. package/docs/card.js +17 -2
  37. package/docs/catalog.json +1640 -108
  38. package/docs/customizer-render.mjs +50 -11
  39. package/docs/customizer.js +137 -24
  40. package/docs/documentation.css +9 -1
  41. package/docs/index.d.ts +8 -3
  42. package/docs/index.mjs +1 -1
  43. package/docs/preview.js +2 -0
  44. package/docs/render.mjs +16 -7
  45. package/docs/site.mjs +78 -27
  46. package/docs/theme-session.mjs +53 -0
  47. package/docs/theme.mjs +189 -18
  48. package/docs/value-editors.mjs +33 -0
  49. package/package.json +2 -2
  50. package/styles/ui-badge.css +11 -6
  51. package/styles/ui-button.css +74 -49
  52. package/styles/ui-card.css +51 -4
  53. package/styles/ui-checkbox.css +4 -2
  54. package/styles/ui-curve-editor.css +109 -0
  55. package/styles/ui-dialog.css +136 -0
  56. package/styles/ui-icon-button.css +85 -28
  57. package/styles/ui-input-group.css +4 -1
  58. package/styles/ui-input.css +2 -1
  59. package/styles/ui-light-editor.css +28 -0
  60. package/styles/ui-menu.css +74 -0
  61. package/styles/ui-number-input.css +34 -0
  62. package/styles/ui-popover.css +76 -0
  63. package/styles/ui-select.css +9 -7
  64. package/styles/ui-slider.css +53 -0
  65. package/styles/ui-switch.css +3 -0
  66. package/styles/ui-tabs.css +6 -1
  67. package/styles/ui-text.css +23 -1
  68. package/styles/ui-textarea.css +2 -1
  69. package/styles/ui-tooltip.css +72 -0
  70. package/theme-light.css +1 -0
  71. package/theme-system.css +69 -17
  72. package/tokens.css +12 -2
  73. package/vanilla/UiButton.d.ts +1 -0
  74. package/vanilla/UiButton.js +195 -130
  75. package/vanilla/UiCard.d.ts +1 -0
  76. package/vanilla/UiCard.js +12 -12
  77. package/vanilla/UiCurveEditor.d.ts +28 -0
  78. package/vanilla/UiCurveEditor.js +134 -0
  79. package/vanilla/UiIconButton.d.ts +2 -1
  80. package/vanilla/UiIconButton.js +58 -31
  81. package/vanilla/UiLightEditor.d.ts +29 -0
  82. package/vanilla/UiLightEditor.js +102 -0
  83. package/vanilla/UiNumberInput.d.ts +33 -0
  84. package/vanilla/UiNumberInput.js +86 -0
  85. package/vanilla/UiSlider.d.ts +33 -0
  86. package/vanilla/UiSlider.js +125 -0
  87. package/vanilla/UiText.d.ts +2 -2
  88. package/vanilla/UiText.js +45 -11
  89. package/vanilla/index.js +4 -0
  90. package/vue/UiBadge.vue +29 -4
  91. package/vue/UiButton.d.ts +6 -0
  92. package/vue/UiButton.vue +188 -60
  93. package/vue/UiCard.d.ts +6 -0
  94. package/vue/UiCard.vue +80 -6
  95. package/vue/UiCheckbox.vue +4 -2
  96. package/vue/UiCurveEditor.d.ts +53 -0
  97. package/vue/UiCurveEditor.js +2 -0
  98. package/vue/UiCurveEditor.vue +427 -0
  99. package/vue/UiDialog.vue +181 -1
  100. package/vue/UiIconButton.d.ts +8 -2
  101. package/vue/UiIconButton.vue +190 -45
  102. package/vue/UiInput.vue +2 -1
  103. package/vue/UiInputGroup.vue +4 -1
  104. package/vue/UiLightEditor.d.ts +75 -0
  105. package/vue/UiLightEditor.js +2 -0
  106. package/vue/UiLightEditor.vue +402 -0
  107. package/vue/UiMenu.vue +91 -0
  108. package/vue/UiNumberInput.d.ts +83 -0
  109. package/vue/UiNumberInput.js +2 -0
  110. package/vue/UiNumberInput.vue +399 -0
  111. package/vue/UiPopover.vue +94 -1
  112. package/vue/UiSelect.vue +16 -10
  113. package/vue/UiSlider.d.ts +83 -0
  114. package/vue/UiSlider.js +2 -0
  115. package/vue/UiSlider.vue +412 -0
  116. package/vue/UiSwitch.vue +3 -0
  117. package/vue/UiTabs.vue +6 -1
  118. package/vue/UiText.d.ts +7 -5
  119. package/vue/UiText.vue +104 -22
  120. package/vue/UiTextarea.vue +2 -1
  121. package/vue/UiTooltip.vue +89 -0
  122. package/vue/chunks/UiActionBar.js +1 -1
  123. package/vue/chunks/UiAffordanceScope.js +2 -2
  124. package/vue/chunks/UiAvatar.js +2 -2
  125. package/vue/chunks/UiAvatarGroup.js +2 -2
  126. package/vue/chunks/UiBadge.js +3 -3
  127. package/vue/chunks/UiBreadcrumbItem.js +2 -2
  128. package/vue/chunks/UiBreadcrumbs.js +2 -2
  129. package/vue/chunks/UiButton.js +94 -11
  130. package/vue/chunks/UiCallout.js +2 -2
  131. package/vue/chunks/UiCard.js +34 -5
  132. package/vue/chunks/UiCheckbox.js +3 -3
  133. package/vue/chunks/UiCluster.js +2 -2
  134. package/vue/chunks/UiColorPicker.js +2 -2
  135. package/vue/chunks/UiCombobox.js +2 -2
  136. package/vue/chunks/UiContainer.js +2 -2
  137. package/vue/chunks/UiContextMenu.js +2 -2
  138. package/vue/chunks/UiCover.js +2 -2
  139. package/vue/chunks/UiCurveEditor.js +413 -0
  140. package/vue/chunks/UiDescriptionItem.js +2 -2
  141. package/vue/chunks/UiDescriptionList.js +2 -2
  142. package/vue/chunks/UiDialog.js +4 -4
  143. package/vue/chunks/UiDisclosure.js +2 -2
  144. package/vue/chunks/UiEditable.js +2 -2
  145. package/vue/chunks/UiEditorBlockActions.js +2 -2
  146. package/vue/chunks/UiEditorChipEditor.js +2 -2
  147. package/vue/chunks/UiEditorCodeLanguage.js +2 -2
  148. package/vue/chunks/UiEditorFootnoteEditor.js +2 -2
  149. package/vue/chunks/UiEditorImageToolbar.js +3 -3
  150. package/vue/chunks/UiEditorInsertTableGrid.js +2 -2
  151. package/vue/chunks/UiEditorLinkCard.js +3 -3
  152. package/vue/chunks/UiEditorLinkForm.js +3 -3
  153. package/vue/chunks/UiEditorMentionMenu.js +2 -2
  154. package/vue/chunks/UiEditorMentionMenuItem.js +2 -2
  155. package/vue/chunks/UiEditorSlashMenu.js +2 -2
  156. package/vue/chunks/UiEditorSlashMenuGroup.js +2 -2
  157. package/vue/chunks/UiEditorSlashMenuItem.js +2 -2
  158. package/vue/chunks/UiEditorSurface.js +2 -2
  159. package/vue/chunks/UiEditorTableContextMenu.js +2 -2
  160. package/vue/chunks/UiEditorTableOverlay.js +2 -2
  161. package/vue/chunks/UiEditorTableToolbar.js +2 -2
  162. package/vue/chunks/UiEditorToolbar.js +2 -2
  163. package/vue/chunks/UiFloatingActionButton.js +2 -2
  164. package/vue/chunks/UiFormField.js +2 -2
  165. package/vue/chunks/UiGrid.js +2 -2
  166. package/vue/chunks/UiIcon.js +2 -2
  167. package/vue/chunks/UiIconButton.js +77 -11
  168. package/vue/chunks/UiImage.js +2 -2
  169. package/vue/chunks/UiInput.js +3 -3
  170. package/vue/chunks/UiInputGroup.js +3 -3
  171. package/vue/chunks/UiLightEditor.js +347 -0
  172. package/vue/chunks/UiList.js +2 -2
  173. package/vue/chunks/UiListItem.js +2 -2
  174. package/vue/chunks/UiListbox.js +2 -2
  175. package/vue/chunks/UiMenu.js +3 -3
  176. package/vue/chunks/UiMenuGroup.js +2 -2
  177. package/vue/chunks/UiMenuItem.js +2 -2
  178. package/vue/chunks/UiMeter.js +2 -2
  179. package/vue/chunks/UiNavItem.js +2 -2
  180. package/vue/chunks/UiNumberInput.js +403 -0
  181. package/vue/chunks/UiPageHeader.js +2 -2
  182. package/vue/chunks/UiPopover.js +4 -4
  183. package/vue/chunks/UiRadio.js +2 -2
  184. package/vue/chunks/UiRadioGroup.js +2 -2
  185. package/vue/chunks/UiReel.js +2 -2
  186. package/vue/chunks/UiScrollArea.js +2 -2
  187. package/vue/chunks/UiSearchResultRow.js +2 -2
  188. package/vue/chunks/UiSearchShell.js +2 -2
  189. package/vue/chunks/UiSection.js +2 -2
  190. package/vue/chunks/UiSelect.js +3 -3
  191. package/vue/chunks/UiSeparator.js +2 -2
  192. package/vue/chunks/UiSidebar.js +2 -2
  193. package/vue/chunks/UiSlider.js +396 -0
  194. package/vue/chunks/UiSpinner.js +2 -2
  195. package/vue/chunks/UiStack.js +2 -2
  196. package/vue/chunks/UiStatusMessage.js +2 -2
  197. package/vue/chunks/UiSwatch.js +2 -2
  198. package/vue/chunks/UiSwitch.js +3 -3
  199. package/vue/chunks/UiSwitcher.js +2 -2
  200. package/vue/chunks/UiTable.js +2 -2
  201. package/vue/chunks/UiTabs.js +3 -3
  202. package/vue/chunks/UiText.js +53 -12
  203. package/vue/chunks/UiTextarea.js +3 -3
  204. package/vue/chunks/UiToast.js +2 -2
  205. package/vue/chunks/UiToastRegion.js +2 -2
  206. package/vue/chunks/UiTooltip.js +3 -3
  207. package/vue/chunks/UiTopBar.js +1 -1
  208. package/vue/chunks/UiTree.js +2 -2
  209. package/vue/chunks/UiTreeItem.js +2 -2
  210. package/vue/chunks/_plugin-vue_export-helper.js +68 -2
  211. package/vue/chunks/props.js +24 -1
  212. package/vue/components.css +3391 -2139
  213. package/vue/editor/index.js +623 -211
  214. package/vue/index.d.ts +4 -0
  215. package/vue/index.js +6 -2
@@ -59,6 +59,10 @@
59
59
  syntax: "*";
60
60
  inherits: false;
61
61
  }
62
+ @property --ui-tabs-panel-padding {
63
+ syntax: "*";
64
+ inherits: false;
65
+ }
62
66
 
63
67
  /* Density resolves into the tab row's own values; the public tokens still override them. */
64
68
  :host {
@@ -66,6 +70,7 @@
66
70
  --_ui-tabs-tab-min-block-size: var(--ui-tabs-tab-min-block-size);
67
71
  --_ui-tabs-tab-padding-block: var(--ui-tabs-tab-padding-block);
68
72
  --_ui-tabs-tab-padding-inline: var(--ui-tabs-tab-padding-inline);
73
+ --_ui-tabs-panel-padding: var(--ui-tabs-panel-padding);
69
74
 
70
75
  --_tab-min-block-size: var(--ui-control-size);
71
76
  --_tab-padding-block: var(--ui-space-2);
@@ -165,7 +170,7 @@
165
170
  min-inline-size: 0;
166
171
  }
167
172
  .panels > :slotted(*) {
168
- padding: var(--ui-space-4) !important;
173
+ padding: var(--_ui-tabs-panel-padding, var(--ui-space-4)) !important;
169
174
  }
170
175
 
171
176
  :host([orientation="vertical"]) {
@@ -17,14 +17,16 @@
17
17
  does not carry the meaning, so the words must say it too.</prop>
18
18
  <prop name="weight" type="keyword" values="inherit, normal, medium, semibold" default="inherit"
19
19
  >The weight. inherit keeps the surrounding weight; medium and semibold emphasise a name or a figure.</prop>
20
- <prop name="variant" type="keyword" values="body, eyebrow, code" default="body"
21
- >body is running text. eyebrow is a short, uppercase, tracked label that names what follows, such as a group of links; code sets a value to copy or read
22
- exactly, such as an address, in the monospace face.</prop>
20
+ <prop name="variant" type="keyword" values="body, display, heading, label, caption, eyebrow, code" default="body"
21
+ >body is running text. display is a page title, heading names a section, label identifies a control, and caption is supporting text. These roles set their
22
+ shared type scale, weight and leading; pair heading or display with an appropriate as heading element. eyebrow is a short, uppercase, tracked label that
23
+ names what follows, such as a group of links; code sets a value to copy or read exactly, such as an address, in the monospace face.</prop>
23
24
  <prop name="truncate" type="boolean" default="false">Keeps the text on one line, ending in an ellipsis when it does not fit.</prop>
24
25
  <prop name="align" type="keyword" values="start, center" default="start">Aligns the text within its line.</prop>
25
- <prop name="as" type="keyword" values="p, span, div, small, strong, label, h2, h3, h4, h5, h6" default="p"
26
+ <prop name="as" type="keyword" values="p, span, div, small, strong, label, h1, h2, h3, h4, h5, h6" default="p"
26
27
  >The native element the text renders: a paragraph by default, inline span, small, or strong within a line, a div for a block, a label for a control, or a
27
- heading, h2 to h6, below a Page Header's h1 and a Section's h2. A heading takes its size and weight from size and weight, like any other text.</prop>
28
+ heading, h1 to h6. Choose its document level independently from its visual variant. The default body variant keeps the existing size and weight
29
+ behavior.</prop>
28
30
  </defs>
29
31
  <template $match>
30
32
  <span $when="$as = 'span'"><slot></slot></span>
@@ -32,6 +34,7 @@
32
34
  <small $when="$as = 'small'"><slot></slot></small>
33
35
  <strong $when="$as = 'strong'"><slot></slot></strong>
34
36
  <label $when="$as = 'label'"><slot></slot></label>
37
+ <h1 $when="$as = 'h1'"><slot></slot></h1>
35
38
  <h2 $when="$as = 'h2'"><slot></slot></h2>
36
39
  <h3 $when="$as = 'h3'"><slot></slot></h3>
37
40
  <h4 $when="$as = 'h4'"><slot></slot></h4>
@@ -56,7 +59,7 @@
56
59
 
57
60
  /* A heading drops the browser's heading size and weight, so size and weight set it as they set
58
61
  any text, and inherit keeps the text around it. */
59
- :host:is(h2, h3, h4, h5, h6) {
62
+ :host:is(h1, h2, h3, h4, h5, h6) {
60
63
  font-family: var(--ui-font-display, inherit);
61
64
  font-size: inherit;
62
65
  font-weight: inherit;
@@ -119,10 +122,32 @@
119
122
  font-weight: var(--ui-font-semibold);
120
123
  }
121
124
 
125
+ :host([variant="display"]), :host([variant="heading"]) {
126
+ font-family: var(--ui-font-display, var(--ui-font-family-sans));
127
+ font-weight: var(--ui-font-semibold);
128
+ line-height: var(--ui-line-height-tight);
129
+ }
130
+ :host([variant="display"]) {
131
+ font-size: var(--ui-font-size-2xl);
132
+ }
133
+ :host([variant="heading"]) {
134
+ font-size: var(--ui-font-size-xl);
135
+ }
136
+ :host([variant="label"]) {
137
+ font-size: var(--ui-font-size-sm);
138
+ font-weight: var(--ui-font-medium);
139
+ line-height: var(--ui-line-height);
140
+ }
141
+ :host([variant="caption"]) {
142
+ font-size: var(--ui-font-size-sm);
143
+ line-height: var(--ui-line-height);
144
+ }
145
+
122
146
  :host([variant="eyebrow"]) {
123
147
  font-size: var(--ui-font-size-xs);
124
148
  font-weight: var(--ui-font-semibold);
125
149
  letter-spacing: 0.06em;
150
+ line-height: var(--ui-line-height);
126
151
  text-transform: uppercase;
127
152
  }
128
153
  :host([variant="code"]) {
@@ -93,7 +93,8 @@
93
93
  border: var(--ui-textarea-border-width, var(--_ui-default-textarea-border-width, var(--ui-border-width))) solid
94
94
  var(--ui-textarea-border, var(--_ui-default-textarea-border, var(--ui-control-border, var(--ui-border-strong))));
95
95
  border-radius: var(--ui-textarea-radius, var(--_ui-default-textarea-radius, var(--ui-field-radius, var(--ui-radius-md))));
96
- background: var(--ui-textarea-surface, var(--_ui-default-textarea-surface, var(--ui-control-surface, var(--ui-surface-elevated))));
96
+ background-color: var(--ui-textarea-surface, var(--_ui-default-textarea-surface, var(--ui-control-surface, var(--ui-surface-elevated))));
97
+ background-image: var(--_ui-default-textarea-highlight, var(--ui-surface-highlight, none));
97
98
  color: var(--ui-text-primary);
98
99
  font: inherit;
99
100
  line-height: var(--ui-line-height-md);
@@ -81,6 +81,7 @@
81
81
  }
82
82
 
83
83
  :host {
84
+ --_ui-material-scale: 0.08;
84
85
  /* Hooks do not inherit, so the parts below read them from the root. */
85
86
  --_ui-tooltip-border: var(--ui-tooltip-border);
86
87
  --_ui-tooltip-max-inline-size: var(--ui-tooltip-max-inline-size);
@@ -133,6 +134,65 @@
133
134
  box-shadow: var(--_ui-tooltip-shadow, var(--ui-overlay-shadow, var(--ui-elevation-tooltip, var(--ui-shadow-md))));
134
135
  }
135
136
 
137
+ /* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
138
+ transparency, saturation and edge light belong to the surrounding decorative material. */
139
+ .surface {
140
+ --_ui-material-glassiness: clamp(0, var(--ui-glassiness, 0), 1);
141
+ --_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
142
+ --_ui-material-active: clamp(0, calc((var(--_ui-material-glassiness) + var(--_ui-material-separation)) * 100000), 1);
143
+ --_ui-material-rim: calc((var(--_ui-material-separation) + var(--_ui-material-glassiness) * 0.25) * var(--_ui-material-scale, 0.08) * 8px);
144
+ --_ui-material-content-color: var(--_ui-tooltip-surface, var(--ui-material-content, var(--ui-overlay-surface, var(--ui-surface-elevated))));
145
+ --_ui-material-rim-color: color-mix(in srgb, var(--ui-material-glass, var(--ui-surface-elevated)) calc(var(--_ui-material-active) * 100%), transparent);
146
+ background:
147
+ linear-gradient(var(--_ui-material-content-color), var(--_ui-material-content-color)) padding-box,
148
+ linear-gradient(var(--_ui-material-rim-color), var(--_ui-material-rim-color)) border-box,
149
+ var(--_ui-material-content-color) padding-box;
150
+ border-width: calc(var(--ui-border-width) + var(--_ui-material-rim));
151
+ border-color: var(
152
+ --_ui-tooltip-border,
153
+ color-mix(in oklab, var(--ui-overlay-border, var(--ui-border-strong)) calc((1 - var(--_ui-material-active)) * 100%), transparent)
154
+ );
155
+ box-shadow: var(
156
+ --_ui-tooltip-shadow,
157
+ var(
158
+ --ui-overlay-shadow,
159
+ 0 calc(var(--_ui-material-separation) * var(--_ui-material-scale, 0.08) * 8px) calc(
160
+ var(--_ui-material-separation) * var(--_ui-material-scale, 0.08) * 24px
161
+ ) color-mix(in oklab, var(--ui-text-primary) 15%, transparent),
162
+ inset 0 0 0 calc(var(--_ui-material-active) * var(--ui-border-width)) var(--ui-material-edge, var(--ui-border-strong)),
163
+ var(--ui-elevation-tooltip, var(--ui-shadow-md))
164
+ )
165
+ );
166
+ backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.08) * 18px))
167
+ saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.08) * 0.18));
168
+ -webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.08) * 18px))
169
+ saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.08) * 0.18));
170
+ }
171
+
172
+ @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
173
+ .surface {
174
+ background: var(--_ui-material-content-color);
175
+ }
176
+ }
177
+
178
+ @media (prefers-reduced-transparency: reduce) {
179
+ .surface {
180
+ background: var(--_ui-material-content-color);
181
+ backdrop-filter: none;
182
+ -webkit-backdrop-filter: none;
183
+ }
184
+ }
185
+
186
+ @media (forced-colors: active) {
187
+ .surface {
188
+ background: Canvas;
189
+ border-color: CanvasText;
190
+ box-shadow: none;
191
+ backdrop-filter: none;
192
+ -webkit-backdrop-filter: none;
193
+ }
194
+ }
195
+
136
196
  /* A keyboard shortcut follows the label after a thin divider, smaller and quieter, as menus show
137
197
  it. The label stays first in the description, so a screen reader hears the name, then the keys. */
138
198
  .shortcut {
@@ -160,7 +160,7 @@ export function connect(host) {
160
160
  attach();
161
161
  }
162
162
  surface?.destroy();
163
- surface = createAnchoredSurface(element, { anchor: trigger, placement: nextPlacement, gap: offset });
163
+ surface = createAnchoredSurface(element, { anchor: trigger, placement: nextPlacement, gap: offset, materialRole: "tooltip" });
164
164
  };
165
165
  const close = (reason, input) => {
166
166
  if (reason !== "escape" && reason !== "light-dismiss" && reason !== "programmatic") return;