vira 26.4.0 → 26.5.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.
@@ -26,6 +26,7 @@ export const ViraMenuItem = defineViraElement()({
26
26
  display: flex;
27
27
  align-items: center;
28
28
  padding: 8px;
29
+ padding-right: 24px;
29
30
  padding-left: 0;
30
31
  text-align: left;
31
32
  }
@@ -47,6 +48,7 @@ export const ViraMenuItem = defineViraElement()({
47
48
 
48
49
  .include-left-spacing {
49
50
  padding-left: 12px;
51
+ padding-right: 12px;
50
52
  }
51
53
  `,
52
54
  render({ inputs }) {
@@ -3,7 +3,7 @@ import { type NavController } from 'device-navigation';
3
3
  import { type PopUpManager, type ShowPopUpResult } from '../../util/pop-up-manager.js';
4
4
  import { type MenuItem } from './pop-up-menu-item.js';
5
5
  import { type PopUpMenuCornerStyle } from './vira-pop-up-menu.element.js';
6
- import { type PopUpOffset } from './vira-pop-up-trigger.element.js';
6
+ import { HorizontalAnchor, type PopUpOffset } from './vira-pop-up-trigger.element.js';
7
7
  /**
8
8
  * Test ids for {@link ViraMenuTrigger}.
9
9
  *
@@ -30,6 +30,20 @@ export declare const ViraMenuTrigger: import("element-vir").DeclarativeElementDe
30
30
  /** Hide menu item check mark icons. */
31
31
  hideCheckIcons: boolean;
32
32
  menuCornerStyle: PopUpMenuCornerStyle;
33
+ /**
34
+ * - `HorizontalAnchor.Left`: pop-up is anchored to the left side of the trigger and the
35
+ * pop-up can grow to the right.
36
+ * - `HorizontalAnchor.Right`: pop-up is anchored to the right side of the trigger and the
37
+ * pop-up can grow to the left.
38
+ * - `HorizontalAnchor.Both`: pop-up is anchored on both sides of the trigger and cannot grow
39
+ * beyond it.
40
+ *
41
+ * Note that when `HorizontalAnchor.Both` is _not_ used, this anchor will cancel out any
42
+ * `popUpOffset` for the direction _opposite_ of the chosen anchor.
43
+ *
44
+ * @default HorizontalAnchor.Left
45
+ */
46
+ horizontalAnchor: HorizontalAnchor;
33
47
  }>, {
34
48
  navController: undefined | NavController;
35
49
  popUpManager: undefined | PopUpManager;
@@ -3,7 +3,7 @@ import { defineViraElement } from '../define-vira-element.js';
3
3
  import { updateSelectedItems } from './pop-up-helpers.js';
4
4
  import { ViraMenu } from './vira-menu.element.js';
5
5
  import { PopUpMenuDirection, ViraPopUpMenu, } from './vira-pop-up-menu.element.js';
6
- import { ViraPopUpTrigger } from './vira-pop-up-trigger.element.js';
6
+ import { HorizontalAnchor, ViraPopUpTrigger, } from './vira-pop-up-trigger.element.js';
7
7
  /**
8
8
  * Test ids for {@link ViraMenuTrigger}.
9
9
  *
@@ -51,6 +51,7 @@ export const ViraMenuTrigger = defineViraElement()({
51
51
  keepOpenAfterInteraction: true,
52
52
  z_debug_forceOpenState: inputs.z_debug_forceOpenState,
53
53
  popUpOffset: inputs.popUpOffset,
54
+ horizontalAnchor: inputs.horizontalAnchor || HorizontalAnchor.Left,
54
55
  })}
55
56
  class=${classMap({
56
57
  open: !!state.showPopUpResult,
@@ -11,6 +11,29 @@ export type PopUpOffset = PartialWithUndefined<{
11
11
  right: number;
12
12
  left: number;
13
13
  }>;
14
+ /**
15
+ * Anchor options for pop-ups.
16
+ *
17
+ * @category Internal
18
+ */
19
+ export declare enum HorizontalAnchor {
20
+ /**
21
+ * The left side of the pop-up will be anchored to the left side of the trigger, allowing the
22
+ * pop-up to grow on the right side of the trigger.
23
+ */
24
+ Left = "left",
25
+ /**
26
+ * The Right side of the pop-up will be anchored to the right side of the trigger, allowing the
27
+ * pop-up to grow on the left side of the trigger.
28
+ */
29
+ Right = "right",
30
+ /**
31
+ * Restrict the pop-up on both sides.
32
+ *
33
+ * This is the default anchor for {@link ViraPopUpTrigger}.
34
+ */
35
+ Both = "both"
36
+ }
14
37
  /**
15
38
  * An element with slots for a pop-up trigger and pop-up contents.
16
39
  *
@@ -26,6 +49,20 @@ export declare const ViraPopUpTrigger: import("element-vir").DeclarativeElementD
26
49
  keepOpenAfterInteraction: boolean;
27
50
  /** All values in px. */
28
51
  popUpOffset?: PopUpOffset;
52
+ /**
53
+ * - `HorizontalAnchor.Left`: pop-up is anchored to the left side of the trigger and the
54
+ * pop-up can grow to the right.
55
+ * - `HorizontalAnchor.Right`: pop-up is anchored to the right side of the trigger and the
56
+ * pop-up can grow to the left.
57
+ * - `HorizontalAnchor.Both`: pop-up is anchored on both sides of the trigger and cannot grow
58
+ * beyond it. (This is the default experience.)
59
+ *
60
+ * Note that when `HorizontalAnchor.Both` is _not_ used, this anchor will cancel out any
61
+ * `popUpOffset` for the direction _opposite_ of the chosen anchor.
62
+ *
63
+ * @default HorizontalAnchor.Both
64
+ */
65
+ horizontalAnchor?: HorizontalAnchor;
29
66
  }>, {
30
67
  /** `undefined` means the pop up is not currently showing. */
31
68
  showPopUpResult: ShowPopUpResult | undefined;
@@ -6,6 +6,30 @@ import { noNativeFormStyles, noUserSelect, viraDisabledStyles } from '../../styl
6
6
  import { HidePopUpEvent, NavSelectEvent, PopUpManager, } from '../../util/pop-up-manager.js';
7
7
  import { defineViraElement } from '../define-vira-element.js';
8
8
  import { triggerPopUpState } from './pop-up-helpers.js';
9
+ /**
10
+ * Anchor options for pop-ups.
11
+ *
12
+ * @category Internal
13
+ */
14
+ export var HorizontalAnchor;
15
+ (function (HorizontalAnchor) {
16
+ /**
17
+ * The left side of the pop-up will be anchored to the left side of the trigger, allowing the
18
+ * pop-up to grow on the right side of the trigger.
19
+ */
20
+ HorizontalAnchor["Left"] = "left";
21
+ /**
22
+ * The Right side of the pop-up will be anchored to the right side of the trigger, allowing the
23
+ * pop-up to grow on the left side of the trigger.
24
+ */
25
+ HorizontalAnchor["Right"] = "right";
26
+ /**
27
+ * Restrict the pop-up on both sides.
28
+ *
29
+ * This is the default anchor for {@link ViraPopUpTrigger}.
30
+ */
31
+ HorizontalAnchor["Both"] = "both";
32
+ })(HorizontalAnchor || (HorizontalAnchor = {}));
9
33
  /**
10
34
  * An element with slots for a pop-up trigger and pop-up contents.
11
35
  *
@@ -75,8 +99,6 @@ export const ViraPopUpTrigger = defineViraElement()({
75
99
 
76
100
  /* highest possible z-index */
77
101
  z-index: 2147483647;
78
- left: 0;
79
- right: 0;
80
102
 
81
103
  & > * {
82
104
  pointer-events: auto;
@@ -166,6 +188,24 @@ export const ViraPopUpTrigger = defineViraElement()({
166
188
  triggerPopUp({ emitEvent: false, open: true }, undefined);
167
189
  }
168
190
  }
191
+ const horizontalPositionStyle = state.showPopUpResult
192
+ ? css `
193
+ ${inputs.horizontalAnchor === HorizontalAnchor.Right
194
+ ? css `
195
+ left: -${state.showPopUpResult.positions.diff.left}px;
196
+ `
197
+ : css `
198
+ left: ${inputs.popUpOffset?.left || 0}px;
199
+ `}
200
+ ${inputs.horizontalAnchor === HorizontalAnchor.Left
201
+ ? css `
202
+ right: -${state.showPopUpResult.positions.diff.right}px;
203
+ `
204
+ : css `
205
+ right: ${inputs.popUpOffset?.right || 0}px;
206
+ `}
207
+ `
208
+ : css ``;
169
209
  /**
170
210
  * These styles do _not_ account for window resizing while the menu is open. I decided this
171
211
  * was not a major enough problem to tackle. If it becomes major enough in the future,
@@ -178,15 +218,13 @@ export const ViraPopUpTrigger = defineViraElement()({
178
218
  css `
179
219
  bottom: -${state.showPopUpResult.positions.diff.bottom}px;
180
220
  top: calc(100% + ${inputs.popUpOffset?.vertical || 0}px);
181
- left: ${inputs.popUpOffset?.left || 0}px;
182
- right: ${inputs.popUpOffset?.right || 0}px;
221
+ ${horizontalPositionStyle}
183
222
  `
184
223
  : /** Dropdown going up position. */
185
224
  css `
186
225
  top: -${state.showPopUpResult.positions.diff.top}px;
187
226
  bottom: calc(100% + ${inputs.popUpOffset?.vertical || 0}px);
188
- left: ${inputs.popUpOffset?.left || 0}px;
189
- right: ${inputs.popUpOffset?.right || 0}px;
227
+ ${horizontalPositionStyle}
190
228
  `
191
229
  : undefined;
192
230
  function respondToClick(event) {
@@ -2,6 +2,7 @@ import { type PartialWithUndefined } from '@augment-vir/common';
2
2
  import { type ViraIconSvg } from '../icons/icon-svg.js';
3
3
  import { type ShowPopUpResult } from '../util/pop-up-manager.js';
4
4
  import { type MenuItem } from './pop-up/pop-up-menu-item.js';
5
+ import { HorizontalAnchor } from './pop-up/vira-pop-up-trigger.element.js';
5
6
  /**
6
7
  * Test ids for {@link ViraDropdown}.
7
8
  *
@@ -36,6 +37,17 @@ export declare const ViraDropdown: import("element-vir").DeclarativeElementDefin
36
37
  isDisabled: boolean;
37
38
  /** For debugging purposes only. Very bad for actual production code use. */
38
39
  z_debug_forceOpenState: boolean;
40
+ /**
41
+ * - `HorizontalAnchor.Left`: dropdown is anchored to the left side of the trigger and the
42
+ * dropdown can grow to the right.
43
+ * - `HorizontalAnchor.Right`: dropdown is anchored to the right side of the trigger and the
44
+ * dropdown can grow to the left.
45
+ * - `HorizontalAnchor.Both`: dropdown is anchored on both sides of the trigger and cannot
46
+ * grow beyond it. (This is the default experience.)
47
+ *
48
+ * @default HorizontalAnchor.Both
49
+ */
50
+ horizontalAnchor: HorizontalAnchor;
39
51
  }>, {
40
52
  /** `undefined` means the pop up is not currently showing. */
41
53
  showPopUpResult: ShowPopUpResult | undefined;
@@ -7,6 +7,7 @@ import { viraFormCssVars } from '../styles/form-themes.js';
7
7
  import { noUserSelect, viraAnimationDurations } from '../styles/index.js';
8
8
  import { defineViraElement } from './define-vira-element.js';
9
9
  import { ViraMenuTrigger } from './pop-up/vira-menu-trigger.element.js';
10
+ import { HorizontalAnchor } from './pop-up/vira-pop-up-trigger.element.js';
10
11
  import { ViraIcon } from './vira-icon.element.js';
11
12
  /**
12
13
  * Test ids for {@link ViraDropdown}.
@@ -140,6 +141,7 @@ export const ViraDropdown = defineViraElement()({
140
141
  vertical: -1,
141
142
  right: 24,
142
143
  },
144
+ horizontalAnchor: inputs.horizontalAnchor || HorizontalAnchor.Both,
143
145
  })}
144
146
  ${listen(ViraMenuTrigger.events.openChange, (event) => {
145
147
  updateState({ showPopUpResult: event.detail });
@@ -1,8 +1,8 @@
1
1
  import { type PartialWithUndefined } from '@augment-vir/common';
2
2
  /**
3
3
  * A [`<progress>`](https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/progress)
4
- * alternative that supports custom styling in _all_ browsers via host styles or CSS variables _and_
5
- * prevents background bleed-through on curved corners.
4
+ * alternative that supports custom styling in _all_ browsers via CSS vars _and_ prevents background
5
+ * bleed.
6
6
  *
7
7
  * @category Progress
8
8
  * @category Elements
@@ -1,9 +1,11 @@
1
+ import { clamp } from '@augment-vir/common';
2
+ import { applyAttributes } from 'device-navigation';
1
3
  import { css, html } from 'element-vir';
2
4
  import { defineViraElement } from './define-vira-element.js';
3
5
  /**
4
6
  * A [`<progress>`](https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/progress)
5
- * alternative that supports custom styling in _all_ browsers via host styles or CSS variables _and_
6
- * prevents background bleed-through on curved corners.
7
+ * alternative that supports custom styling in _all_ browsers via CSS vars _and_ prevents background
8
+ * bleed.
7
9
  *
8
10
  * @category Progress
9
11
  * @category Elements
@@ -28,33 +30,46 @@ export const ViraProgress = defineViraElement()({
28
30
  height: 10px;
29
31
  display: inline-flex;
30
32
  align-items: center;
31
- background-color: ${cssVars['vira-progress-background-color'].value};
32
33
  border-radius: ${cssVars['vira-progress-border-radius'].value};
33
34
  color: ${cssVars['vira-progress-foreground-color'].value};
35
+ overflow: hidden;
34
36
  }
35
37
 
36
38
  .progress-bar {
37
39
  background-color: currentColor;
38
- border-radius: calc(${cssVars['vira-progress-border-radius'].value} - 1px);
39
- /* Add some extra pixels to prevent the background from bleeding through on the curved corners. */
40
- height: calc(100% + 2px);
41
- /* Overlap a bin on the left to prevent the background from bleeding through on the curved corners. */
42
- margin-left: -1px;
40
+ height: 100%;
41
+ }
42
+
43
+ .background-bar {
44
+ background-color: ${cssVars['vira-progress-background-color'].value};
45
+ height: 100%;
46
+ flex-grow: 1;
43
47
  }
44
48
  `,
45
- render({ inputs }) {
49
+ render({ inputs, host }) {
46
50
  const min = inputs.min || 0;
47
51
  const max = inputs.max || 100;
48
52
  const totalRange = max - min;
49
53
  const value = inputs.value - min;
50
- const percentFull = Math.round((value / totalRange) * 100);
54
+ const percentFull = clamp(Math.round((value / totalRange) * 100), { min: 0, max: 100 });
55
+ applyAttributes(host, {
56
+ 'aria-valuemin': inputs.min,
57
+ 'aria-valuemax': inputs.max,
58
+ 'aria-valuenow': inputs.value,
59
+ 'aria-role': 'progressbar',
60
+ });
51
61
  return html `
52
62
  <div
53
63
  class="progress-bar"
54
- style=${css `
55
- width: calc(${percentFull}% + 1px);
56
- `}
64
+ style=${percentFull
65
+ ? css `
66
+ width: ${percentFull}%;
67
+ `
68
+ : css `
69
+ display: none;
70
+ `}
57
71
  ></div>
72
+ <div class="background-bar"></div>
58
73
  `;
59
74
  },
60
75
  });
@@ -59,7 +59,7 @@ export type PopUpManagerOptions = {
59
59
  supportNavigation: boolean;
60
60
  };
61
61
  /**
62
- * Output type from {@link PopUpManager.showPopUp}
62
+ * Output type from `PopUpManager.showPopUp`
63
63
  *
64
64
  * @category PopUp
65
65
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vira",
3
- "version": "26.4.0",
3
+ "version": "26.5.0",
4
4
  "description": "A simple and highly versatile design system using element-vir.",
5
5
  "keywords": [
6
6
  "design",
@@ -38,21 +38,21 @@
38
38
  "test:docs": "virmator docs check"
39
39
  },
40
40
  "dependencies": {
41
- "@augment-vir/assert": "^31.23.3",
42
- "@augment-vir/common": "^31.23.3",
43
- "@augment-vir/web": "^31.23.3",
41
+ "@augment-vir/assert": "^31.26.0",
42
+ "@augment-vir/common": "^31.26.0",
43
+ "@augment-vir/web": "^31.26.0",
44
44
  "colorjs.io": "^0.5.2",
45
45
  "date-vir": "^7.3.1",
46
46
  "device-navigation": "^4.5.5",
47
47
  "lit-css-vars": "^3.0.11",
48
- "observavir": "^2.0.5",
48
+ "observavir": "^2.1.0",
49
49
  "page-active": "^1.0.1",
50
- "spa-router-vir": "^6.1.1",
50
+ "spa-router-vir": "^6.1.3",
51
51
  "type-fest": "^4.41.0",
52
52
  "typed-event-target": "^4.1.0"
53
53
  },
54
54
  "devDependencies": {
55
- "@augment-vir/test": "^31.23.3",
55
+ "@augment-vir/test": "^31.26.0",
56
56
  "@web/dev-server-esbuild": "^1.0.4",
57
57
  "@web/test-runner": "^0.20.2",
58
58
  "@web/test-runner-commands": "^0.9.0",
@@ -63,11 +63,11 @@
63
63
  "markdown-code-example-inserter": "^3.0.3",
64
64
  "typedoc": "^0.28.5",
65
65
  "typescript": "5.8.3",
66
- "vite": "^6.3.5",
66
+ "vite": "^7.0.0",
67
67
  "vite-tsconfig-paths": "^5.1.4"
68
68
  },
69
69
  "peerDependencies": {
70
- "element-vir": "^26.4.0"
70
+ "element-vir": "^26.5.0"
71
71
  },
72
72
  "engines": {
73
73
  "node": ">=22"