vira 32.2.0 → 32.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,13 @@
1
1
  import { assertWrap } from '@augment-vir/assert';
2
2
  import { css, defineElementEvent, html } from 'element-vir';
3
3
  import { listenTo } from 'typed-event-target';
4
- import { Check24Icon } from '../../icons/icon-svgs/24/check-24.icon.js';
4
+ import { lucideIcons } from '../../icons/lucide-icons.js';
5
+ import { createSizedIcon } from '../../icons/sized-icon.js';
5
6
  import { viraFormCssVars } from '../../styles/form-styles.js';
6
7
  import { noUserSelect } from '../../styles/index.js';
7
8
  import { defineViraElement } from '../../util/define-vira-element.js';
8
9
  import { ViraIcon } from '../vira-icon.element.js';
10
+ const selectedCheckIcon = createSizedIcon(lucideIcons.Check, 16);
9
11
  /**
10
12
  * An element for an individual menu item.
11
13
  *
@@ -47,8 +49,8 @@ export const ViraMenuItem = defineViraElement()({
47
49
  },
48
50
  cssVars: {
49
51
  /** Horizontal gap between a menu item's icon and its label. */
50
- 'vira-menu-item-icon-gap': '0',
51
- 'vira-menu-item-padding': '4px 8px 4px 1px',
52
+ 'vira-menu-item-icon-gap': '3px',
53
+ 'vira-menu-item-padding': '8px 12px 8px 0',
52
54
  },
53
55
  styles({ hostClasses, cssVars }) {
54
56
  return css `
@@ -58,9 +60,9 @@ export const ViraMenuItem = defineViraElement()({
58
60
  ${noUserSelect};
59
61
  box-sizing: border-box;
60
62
  max-width: 100%;
63
+ padding-left: calc(${cssVars['vira-menu-item-icon-gap'].value} * 2);
61
64
  gap: ${cssVars['vira-menu-item-icon-gap'].value};
62
65
  overflow: hidden;
63
- padding: ${cssVars['vira-menu-item-padding'].value};
64
66
  align-items: center;
65
67
  text-align: left;
66
68
  }
@@ -93,7 +95,7 @@ export const ViraMenuItem = defineViraElement()({
93
95
  }
94
96
 
95
97
  ${ViraIcon} {
96
- width: 24px;
98
+ width: 16px;
97
99
  aspect-ratio: 1;
98
100
  align-items: center;
99
101
  justify-content: center;
@@ -110,12 +112,21 @@ export const ViraMenuItem = defineViraElement()({
110
112
  }
111
113
 
112
114
  .slot-wrapper {
115
+ padding: ${cssVars['vira-menu-item-padding'].value};
113
116
  display: flex;
114
117
  flex-grow: 1;
115
118
  overflow: hidden;
116
119
  text-overflow: ellipsis;
117
120
  white-space: nowrap;
118
121
  min-width: 0;
122
+
123
+ & > slot {
124
+ display: block;
125
+ flex-grow: 1;
126
+ overflow: hidden;
127
+ text-overflow: ellipsis;
128
+ min-width: 0;
129
+ }
119
130
  }
120
131
  `;
121
132
  },
@@ -222,7 +233,7 @@ export const ViraMenuItem = defineViraElement()({
222
233
  render({ inputs }) {
223
234
  return html `
224
235
  <${ViraIcon.assign({
225
- icon: inputs.iconOverride || Check24Icon,
236
+ icon: inputs.iconOverride || selectedCheckIcon,
226
237
  })}></${ViraIcon}>
227
238
  <div class="slot-wrapper">
228
239
  <slot>&nbsp;</slot>
@@ -31,6 +31,7 @@ export declare const ViraDropdown: import("element-vir").DeclarativeElementDefin
31
31
  } & PopUpTriggerPosition>, {
32
32
  /** `undefined` means the pop up is not currently showing. */
33
33
  showPopUpResult: ShowPopUpResult | undefined;
34
+ shouldSelectOnMouseUp: boolean;
34
35
  /**
35
36
  * Used to couple the label and trigger together. This is not applied if no label is
36
37
  * provided.
@@ -1,11 +1,13 @@
1
1
  import { check } from '@augment-vir/assert';
2
2
  import { filterMap, randomString } from '@augment-vir/common';
3
+ import { extractEventTarget } from '@augment-vir/web';
3
4
  import { classMap, css, defineElementEvent, html, ifDefined, listen, nothing, testId, } from 'element-vir';
4
5
  import { ChevronUp16Icon } from '../icons/index.js';
5
6
  import { viraFormCssVars } from '../styles/form-styles.js';
6
7
  import { noUserSelect, viraAnimationDurations } from '../styles/index.js';
7
8
  import { defineViraElement } from '../util/define-vira-element.js';
8
9
  import { renderMenuItemEntries } from '../util/pop-up-helpers.js';
10
+ import { ViraMenuItem } from './pop-up/vira-menu-item.element.js';
9
11
  import { ViraMenu, ViraMenuPopUpDirection } from './pop-up/vira-menu.element.js';
10
12
  import { HorizontalAnchor, ViraPopUpTrigger, } from './pop-up/vira-pop-up-trigger.element.js';
11
13
  import { ViraIcon } from './vira-icon.element.js';
@@ -118,6 +120,7 @@ export const ViraDropdown = defineViraElement()({
118
120
  return {
119
121
  /** `undefined` means the pop up is not currently showing. */
120
122
  showPopUpResult: undefined,
123
+ shouldSelectOnMouseUp: false,
121
124
  /**
122
125
  * Used to couple the label and trigger together. This is not applied if no label is
123
126
  * provided.
@@ -149,6 +152,19 @@ export const ViraDropdown = defineViraElement()({
149
152
  : inputs.isMultiSelect && selectedOptions.length > 1
150
153
  ? `${selectedOptions.length} Selected`
151
154
  : selectedOptions[0]?.label || '';
155
+ function selectOption(option) {
156
+ const newSelectedValues = inputs.isMultiSelect
157
+ ? selectedOptions.includes(option)
158
+ ? filterMap(selectedOptions, (selectedOption) => selectedOption.value, (value, selectedOption) => selectedOption !== option)
159
+ : [
160
+ ...selectedOptions.map((selectedOption) => selectedOption.value),
161
+ option.value,
162
+ ]
163
+ : [option.value];
164
+ dispatch(new events.selectedValuesChange({
165
+ detail: newSelectedValues,
166
+ }));
167
+ }
152
168
  const menuTemplate = html `
153
169
  <${ViraMenu.assign({
154
170
  direction: state.showPopUpResult?.popDown
@@ -156,22 +172,27 @@ export const ViraDropdown = defineViraElement()({
156
172
  : ViraMenuPopUpDirection.Upwards,
157
173
  })}
158
174
  slot=${ViraPopUpTrigger.slotNames['vira-pop-up-trigger-pop-up']}
175
+ ${listen('mouseup', (event) => {
176
+ if (state.shouldSelectOnMouseUp) {
177
+ const menuItem = event
178
+ .composedPath()
179
+ .find((eventTarget) => {
180
+ return eventTarget instanceof ViraMenuItem;
181
+ });
182
+ const option = menuItem
183
+ ? inputs.options[Array.from(extractEventTarget(event, ViraMenu).querySelectorAll(ViraMenuItem.tagName)).indexOf(menuItem)]
184
+ : undefined;
185
+ if (check.isDefined(option) && !option.disabled) {
186
+ selectOption(option);
187
+ }
188
+ }
189
+ })}
159
190
  >
160
191
  ${renderMenuItemEntries(inputs.options.map((option) => {
161
192
  return {
162
193
  content: option.label,
163
194
  onClick() {
164
- const newSelectedValues = inputs.isMultiSelect
165
- ? selectedOptions.includes(option)
166
- ? filterMap(selectedOptions, (selectedOption) => selectedOption.value, (value, selectedOption) => selectedOption !== option)
167
- : [
168
- ...selectedOptions.map((selectedOption) => selectedOption.value),
169
- option.value,
170
- ]
171
- : [option.value];
172
- dispatch(new events.selectedValuesChange({
173
- detail: newSelectedValues,
174
- }));
195
+ selectOption(option);
175
196
  },
176
197
  disabled: option.disabled,
177
198
  selected: selectedOptions.includes(option),
@@ -199,6 +220,13 @@ export const ViraDropdown = defineViraElement()({
199
220
  updateState({
200
221
  showPopUpResult: event.detail,
201
222
  });
223
+ })}
224
+ ${listen('mouseup', () => {
225
+ if (state.shouldSelectOnMouseUp) {
226
+ updateState({
227
+ shouldSelectOnMouseUp: false,
228
+ });
229
+ }
202
230
  })}
203
231
  >
204
232
  <div
@@ -210,6 +238,13 @@ export const ViraDropdown = defineViraElement()({
210
238
  id=${ifDefined(inputs.label ? state.randomId : undefined)}
211
239
  aria-label=${ifDefined(inputs.label || undefined)}
212
240
  ${testId(testIds.trigger)}
241
+ ${listen('mousedown', () => {
242
+ if (!state.showPopUpResult) {
243
+ updateState({
244
+ shouldSelectOnMouseUp: true,
245
+ });
246
+ }
247
+ })}
213
248
  >
214
249
  ${leadingIconTemplate}
215
250
  <span
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vira",
3
- "version": "32.2.0",
3
+ "version": "32.2.1",
4
4
  "description": "A simple and highly versatile design system using element-vir.",
5
5
  "keywords": [
6
6
  "design",
@@ -38,9 +38,9 @@
38
38
  "test:docs": "virmator docs check"
39
39
  },
40
40
  "dependencies": {
41
- "@augment-vir/assert": "^32.3.0",
42
- "@augment-vir/common": "^32.3.0",
43
- "@augment-vir/web": "^32.3.0",
41
+ "@augment-vir/assert": "^32.3.1",
42
+ "@augment-vir/common": "^32.3.1",
43
+ "@augment-vir/web": "^32.3.1",
44
44
  "@electrovir/color": "^2.0.0",
45
45
  "@electrovir/local-storage-client": "^0.1.1",
46
46
  "date-vir": "^9.1.1",
@@ -51,10 +51,10 @@
51
51
  "observavir": "^2.3.3",
52
52
  "page-active": "^1.0.4",
53
53
  "spa-router-vir": "^6.8.0",
54
- "typed-event-target": "^4.3.3"
54
+ "typed-event-target": "^4.3.4"
55
55
  },
56
56
  "devDependencies": {
57
- "@augment-vir/test": "^32.3.0",
57
+ "@augment-vir/test": "^32.3.1",
58
58
  "@web/dev-server-esbuild": "^2.0.0",
59
59
  "@web/test-runner": "^1.0.0",
60
60
  "@web/test-runner-commands": "^1.0.1",
@@ -62,12 +62,12 @@
62
62
  "@web/test-runner-visual-regression": "^1.0.1",
63
63
  "esbuild": "^0.28.2",
64
64
  "istanbul-smart-text-reporter": "^1.1.5",
65
- "lucide-static": "^1.42.0",
65
+ "lucide-static": "^1.46.0",
66
66
  "markdown-code-example-inserter": "^3.0.6",
67
67
  "theme-vir": "^29.0.0",
68
68
  "typedoc": "^0.28.20",
69
69
  "typescript": "^6.0.3",
70
- "vite": "^8.2.2",
70
+ "vite": "^8.3.0",
71
71
  "vite-tsconfig-paths": "^6.1.1"
72
72
  },
73
73
  "peerDependencies": {