vira 28.12.1 → 28.13.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.
@@ -20,5 +20,6 @@ export * from './vira-image.element.js';
20
20
  export * from './vira-input.element.js';
21
21
  export * from './vira-link.element.js';
22
22
  export * from './vira-modal.element.js';
23
+ export * from './vira-overflow-switch.element.js';
23
24
  export * from './vira-progress.element.js';
24
25
  export * from './vira-select.element.js';
@@ -20,5 +20,6 @@ export * from './vira-image.element.js';
20
20
  export * from './vira-input.element.js';
21
21
  export * from './vira-link.element.js';
22
22
  export * from './vira-modal.element.js';
23
+ export * from './vira-overflow-switch.element.js';
23
24
  export * from './vira-progress.element.js';
24
25
  export * from './vira-select.element.js';
@@ -13,8 +13,8 @@ export type ViraCheckboxInnerElements = 'label' | 'custom-checkbox' | 'text' | t
13
13
  * @category Internal
14
14
  */
15
15
  export type ViraCheckboxInputs = PartialWithUndefined<{
16
- stylePassthrough: Record<ViraCheckboxInnerElements, CSSResult>;
17
- attributePassthrough: Record<ViraCheckboxInnerElements, AttributeValues>;
16
+ stylePassthrough: Partial<Record<ViraCheckboxInnerElements, CSSResult>>;
17
+ attributePassthrough: Partial<Record<ViraCheckboxInnerElements, AttributeValues>>;
18
18
  disabled: boolean;
19
19
  label: string;
20
20
  hasError: boolean;
@@ -136,6 +136,7 @@ export const ViraCheckbox = defineViraElement()({
136
136
  error: !!inputs.hasError,
137
137
  })}"
138
138
  role="checkbox"
139
+ aria-label=${ifDefined(inputs.label || undefined)}
139
140
  aria-checked=${inputs.value ? 'true' : 'false'}
140
141
  aria-disabled=${inputs.disabled ? 'true' : 'false'}
141
142
  tabindex=${inputs.disabled ? '-1' : '0'}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * An element switches between two slots based on their overflow.
3
+ *
4
+ * @category Elements
5
+ * @see https://electrovir.github.io/vira/book/elements/vira-overflow-switch
6
+ */
7
+ export declare const ViraOverflowSwitch: import("element-vir").DeclarativeElementDefinition<"vira-overflow-switch", Readonly<((Required<Pick<{
8
+ automaticallySwitch: boolean;
9
+ useSmall: boolean;
10
+ }, "automaticallySwitch">> & Partial<Record<"useSmall", never>>) | (Required<Pick<{
11
+ automaticallySwitch: boolean;
12
+ useSmall: boolean;
13
+ }, "useSmall">> & Partial<Record<"automaticallySwitch", never>>)) & Omit<{
14
+ automaticallySwitch: boolean;
15
+ useSmall: boolean;
16
+ }, "automaticallySwitch" | "useSmall">>, {
17
+ isOverflowing: boolean;
18
+ resizeObserver: undefined | ResizeObserver;
19
+ /** Called on cleanup to clear all listeners. */
20
+ cleanup: undefined | (() => void);
21
+ }, {}, "vira-overflow-switch-show-small", "vira-overflow-switch-", readonly ["large", "small"], readonly []>;
@@ -0,0 +1,110 @@
1
+ import { css, html, onDomCreated } from 'element-vir';
2
+ import { listenTo } from 'typed-event-target';
3
+ import { defineViraElement } from './define-vira-element.js';
4
+ /**
5
+ * An element switches between two slots based on their overflow.
6
+ *
7
+ * @category Elements
8
+ * @see https://electrovir.github.io/vira/book/elements/vira-overflow-switch
9
+ */
10
+ export const ViraOverflowSwitch = defineViraElement()({
11
+ tagName: 'vira-overflow-switch',
12
+ slotNames: [
13
+ /** The child to render, if it fits. */
14
+ 'large',
15
+ /** The child to render if the large one does not fit. */
16
+ 'small',
17
+ ],
18
+ state() {
19
+ return {
20
+ isOverflowing: false,
21
+ resizeObserver: undefined,
22
+ /** Called on cleanup to clear all listeners. */
23
+ cleanup: undefined,
24
+ };
25
+ },
26
+ hostClasses: {
27
+ 'vira-overflow-switch-show-small': ({ state, inputs }) => state.isOverflowing || !!inputs.useSmall,
28
+ },
29
+ styles: ({ hostClasses }) => css `
30
+ :host {
31
+ display: inline-block;
32
+ max-width: 100%;
33
+ }
34
+
35
+ .large,
36
+ .small {
37
+ display: inline-block;
38
+ }
39
+
40
+ .small {
41
+ display: none;
42
+ }
43
+
44
+ /**
45
+ * When the large content overflows, hide it but keep it in layout so we can measure it.
46
+ * The small content is then shown instead.
47
+ */
48
+ ${hostClasses['vira-overflow-switch-show-small'].selector} .large {
49
+ visibility: hidden;
50
+ position: absolute;
51
+ top: 0;
52
+ left: 0;
53
+ }
54
+
55
+ ${hostClasses['vira-overflow-switch-show-small'].selector} .small {
56
+ display: inline-block;
57
+ }
58
+ `,
59
+ cleanup({ state, updateState }) {
60
+ state.cleanup?.();
61
+ updateState({
62
+ cleanup: undefined,
63
+ });
64
+ },
65
+ render({ slotNames, updateState, inputs, host, state }) {
66
+ return html `
67
+ <div
68
+ class="large"
69
+ ${onDomCreated((largeElement) => {
70
+ if (!inputs.automaticallySwitch) {
71
+ return;
72
+ }
73
+ const overflowParams = {
74
+ elementToTest: largeElement,
75
+ host,
76
+ updateState,
77
+ };
78
+ const resizeObserver = new ResizeObserver(() => {
79
+ updateOverflowing(overflowParams);
80
+ });
81
+ resizeObserver.observe(host);
82
+ /**
83
+ * Also observe the large slot wrapper itself in case its own layout changes
84
+ * without host resizing.
85
+ */
86
+ resizeObserver.observe(largeElement);
87
+ const removeSlotChangeListener = listenTo(largeElement, 'slotchange', () => {
88
+ updateOverflowing(overflowParams);
89
+ });
90
+ /** Initial measurement: defer until after first layout. */
91
+ updateOverflowing(overflowParams);
92
+ state.cleanup?.();
93
+ updateState({
94
+ cleanup() {
95
+ resizeObserver.disconnect();
96
+ removeSlotChangeListener();
97
+ },
98
+ });
99
+ })}
100
+ >
101
+ <slot name=${slotNames.large}></slot>
102
+ </div>
103
+ <div class="small"><slot name=${slotNames.small}></slot></div>
104
+ `;
105
+ },
106
+ });
107
+ function updateOverflowing({ elementToTest, host, updateState, }) {
108
+ const isOverflowing = elementToTest.scrollWidth > host.clientWidth;
109
+ updateState({ isOverflowing });
110
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vira",
3
- "version": "28.12.1",
3
+ "version": "28.13.0",
4
4
  "description": "A simple and highly versatile design system using element-vir.",
5
5
  "keywords": [
6
6
  "design",
@@ -38,33 +38,33 @@
38
38
  "test:docs": "virmator docs check"
39
39
  },
40
40
  "dependencies": {
41
- "@augment-vir/assert": "^31.54.3",
42
- "@augment-vir/common": "^31.54.3",
43
- "@augment-vir/web": "^31.54.3",
41
+ "@augment-vir/assert": "^31.54.4",
42
+ "@augment-vir/common": "^31.54.4",
43
+ "@augment-vir/web": "^31.54.4",
44
44
  "colorjs.io": "^0.5.2",
45
- "date-vir": "^8.0.0",
45
+ "date-vir": "^8.1.0",
46
46
  "device-navigation": "^4.5.5",
47
47
  "lit-css-vars": "^3.0.11",
48
- "observavir": "^2.2.0",
48
+ "observavir": "^2.3.0",
49
49
  "page-active": "^1.0.3",
50
- "spa-router-vir": "^6.3.1",
51
- "type-fest": "^5.2.0",
50
+ "spa-router-vir": "^6.4.1",
51
+ "type-fest": "^5.3.1",
52
52
  "typed-event-target": "^4.1.0"
53
53
  },
54
54
  "devDependencies": {
55
- "@augment-vir/test": "^31.54.3",
55
+ "@augment-vir/test": "^31.54.4",
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",
59
59
  "@web/test-runner-playwright": "^0.11.1",
60
60
  "@web/test-runner-visual-regression": "^0.10.0",
61
- "esbuild": "^0.27.0",
61
+ "esbuild": "^0.27.2",
62
62
  "istanbul-smart-text-reporter": "^1.1.5",
63
63
  "markdown-code-example-inserter": "^3.0.3",
64
64
  "typedoc": "^0.28.15",
65
65
  "typescript": "5.9.3",
66
- "vite": "^7.1.12",
67
- "vite-tsconfig-paths": "^5.1.4"
66
+ "vite": "^7.3.0",
67
+ "vite-tsconfig-paths": "^6.0.3"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "element-vir": "^26.9.1"