vira 28.19.4 → 28.19.6

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 (188) hide show
  1. package/package.json +13 -13
  2. package/src/elements/define-vira-element.ts +29 -0
  3. package/src/elements/form/vira-form-fields.ts +140 -0
  4. package/src/elements/form/vira-form.element.ts +204 -0
  5. package/src/elements/pop-up/pop-up-helpers.ts +85 -0
  6. package/{dist/elements/pop-up/pop-up-menu-item.d.ts → src/elements/pop-up/pop-up-menu-item.ts} +4 -3
  7. package/{dist/elements/pop-up/vira-menu-item.element.js → src/elements/pop-up/vira-menu-item.element.ts} +28 -11
  8. package/src/elements/pop-up/vira-menu-trigger.element.ts +158 -0
  9. package/{dist/elements/pop-up/vira-menu.element.js → src/elements/pop-up/vira-menu.element.ts} +76 -49
  10. package/{dist/elements/pop-up/vira-pop-up-menu.element.js → src/elements/pop-up/vira-pop-up-menu.element.ts} +34 -22
  11. package/{dist/elements/pop-up/vira-pop-up-trigger.element.js → src/elements/pop-up/vira-pop-up-trigger.element.ts} +200 -91
  12. package/src/elements/shared-text-input-logic.ts +173 -0
  13. package/{dist/elements/vira-bold-text.element.js → src/elements/vira-bold-text.element.ts} +8 -7
  14. package/{dist/elements/vira-button.element.js → src/elements/vira-button.element.ts} +64 -33
  15. package/{dist/elements/vira-card.element.js → src/elements/vira-card.element.ts} +16 -13
  16. package/{dist/elements/vira-checkbox.element.js → src/elements/vira-checkbox.element.ts} +71 -28
  17. package/{dist/elements/vira-collapsible-wrapper.element.js → src/elements/vira-collapsible-wrapper.element.ts} +18 -16
  18. package/{dist/elements/vira-dropdown.element.js → src/elements/vira-dropdown.element.ts} +94 -48
  19. package/{dist/elements/vira-error.element.js → src/elements/vira-error.element.ts} +6 -5
  20. package/{dist/elements/vira-icon.element.js → src/elements/vira-icon.element.ts} +13 -6
  21. package/{dist/elements/vira-image.element.js → src/elements/vira-image.element.ts} +63 -43
  22. package/{dist/elements/vira-input.element.js → src/elements/vira-input.element.ts} +151 -85
  23. package/{dist/elements/vira-link.element.js → src/elements/vira-link.element.ts} +62 -11
  24. package/{dist/elements/vira-modal.element.js → src/elements/vira-modal.element.ts} +89 -50
  25. package/src/elements/vira-overflow-switch.element.ts +137 -0
  26. package/{dist/elements/vira-progress.element.js → src/elements/vira-progress.element.ts} +26 -11
  27. package/{dist/elements/vira-select.element.js → src/elements/vira-select.element.ts} +96 -41
  28. package/src/icons/icon-color.test-helper.ts +9 -0
  29. package/{dist/icons/icon-css-vars.js → src/icons/icon-css-vars.ts} +2 -1
  30. package/src/icons/icon-svg.ts +71 -0
  31. package/{dist/icons/icon-svgs/bell-24.icon.js → src/icons/icon-svgs/bell-24.icon.ts} +5 -4
  32. package/{dist/icons/icon-svgs/chat-24.icon.js → src/icons/icon-svgs/chat-24.icon.ts} +5 -4
  33. package/{dist/icons/icon-svgs/check-24.icon.js → src/icons/icon-svgs/check-24.icon.ts} +5 -4
  34. package/{dist/icons/icon-svgs/chevron-down-24.icon.js → src/icons/icon-svgs/chevron-down-24.icon.ts} +5 -4
  35. package/{dist/icons/icon-svgs/chevron-up-24.icon.js → src/icons/icon-svgs/chevron-up-24.icon.ts} +5 -4
  36. package/{dist/icons/icon-svgs/close-x-24.icon.js → src/icons/icon-svgs/close-x-24.icon.ts} +5 -4
  37. package/{dist/icons/icon-svgs/commit-24.icon.js → src/icons/icon-svgs/commit-24.icon.ts} +5 -4
  38. package/{dist/icons/icon-svgs/copy-24.icon.js → src/icons/icon-svgs/copy-24.icon.ts} +5 -4
  39. package/{dist/icons/icon-svgs/document-24.icon.js → src/icons/icon-svgs/document-24.icon.ts} +5 -4
  40. package/{dist/icons/icon-svgs/document-search-24.icon.js → src/icons/icon-svgs/document-search-24.icon.ts} +5 -4
  41. package/{dist/icons/icon-svgs/double-chevron-24.icon.js → src/icons/icon-svgs/double-chevron-24.icon.ts} +5 -4
  42. package/{dist/icons/icon-svgs/element-16.icon.js → src/icons/icon-svgs/element-16.icon.ts} +5 -4
  43. package/{dist/icons/icon-svgs/element-24.icon.js → src/icons/icon-svgs/element-24.icon.ts} +5 -4
  44. package/{dist/icons/icon-svgs/external-link-24.icon.js → src/icons/icon-svgs/external-link-24.icon.ts} +5 -4
  45. package/{dist/icons/icon-svgs/eye-closed-24.icon.js → src/icons/icon-svgs/eye-closed-24.icon.ts} +5 -4
  46. package/{dist/icons/icon-svgs/eye-open-24.icon.js → src/icons/icon-svgs/eye-open-24.icon.ts} +5 -4
  47. package/{dist/icons/icon-svgs/filter-24.icon.js → src/icons/icon-svgs/filter-24.icon.ts} +5 -4
  48. package/{dist/icons/icon-svgs/link-24.icon.js → src/icons/icon-svgs/link-24.icon.ts} +5 -4
  49. package/{dist/icons/icon-svgs/loader-24.icon.js → src/icons/icon-svgs/loader-24.icon.ts} +5 -4
  50. package/{dist/icons/icon-svgs/loader-animated-24.icon.js → src/icons/icon-svgs/loader-animated-24.icon.ts} +8 -6
  51. package/{dist/icons/icon-svgs/lock-24.icon.js → src/icons/icon-svgs/lock-24.icon.ts} +5 -4
  52. package/{dist/icons/icon-svgs/options-24.icon.js → src/icons/icon-svgs/options-24.icon.ts} +5 -4
  53. package/{dist/icons/icon-svgs/pencil-24.icon.js → src/icons/icon-svgs/pencil-24.icon.ts} +5 -4
  54. package/{dist/icons/icon-svgs/shield-24.icon.js → src/icons/icon-svgs/shield-24.icon.ts} +5 -4
  55. package/{dist/icons/icon-svgs/sort-ascending-24.icon.js → src/icons/icon-svgs/sort-ascending-24.icon.ts} +5 -4
  56. package/{dist/icons/icon-svgs/sort-descending-24.icon.js → src/icons/icon-svgs/sort-descending-24.icon.ts} +5 -4
  57. package/{dist/icons/icon-svgs/speaker-loud-24.icon.js → src/icons/icon-svgs/speaker-loud-24.icon.ts} +5 -4
  58. package/{dist/icons/icon-svgs/speaker-medium-24.icon.js → src/icons/icon-svgs/speaker-medium-24.icon.ts} +5 -4
  59. package/{dist/icons/icon-svgs/speaker-muted-24.icon.js → src/icons/icon-svgs/speaker-muted-24.icon.ts} +5 -4
  60. package/{dist/icons/icon-svgs/speaker-quiet-24.icon.js → src/icons/icon-svgs/speaker-quiet-24.icon.ts} +5 -4
  61. package/{dist/icons/icon-svgs/star-24.icon.js → src/icons/icon-svgs/star-24.icon.ts} +5 -4
  62. package/{dist/icons/icon-svgs/status-failure-24.icon.js → src/icons/icon-svgs/status-failure-24.icon.ts} +5 -4
  63. package/{dist/icons/icon-svgs/status-in-progress-24.icon.js → src/icons/icon-svgs/status-in-progress-24.icon.ts} +5 -4
  64. package/{dist/icons/icon-svgs/status-success-24.icon.js → src/icons/icon-svgs/status-success-24.icon.ts} +5 -4
  65. package/{dist/icons/icon-svgs/status-unknown-24.icon.js → src/icons/icon-svgs/status-unknown-24.icon.ts} +5 -4
  66. package/{dist/icons/icon-svgs/status-warning-24.icon.js → src/icons/icon-svgs/status-warning-24.icon.ts} +5 -4
  67. package/{dist/icons/icon-svgs/upload-24.icon.js → src/icons/icon-svgs/upload-24.icon.ts} +5 -4
  68. package/{dist/icons/icon-svgs/x-24.icon.js → src/icons/icon-svgs/x-24.icon.ts} +5 -4
  69. package/{dist/icons/index.js → src/icons/index.ts} +43 -39
  70. package/{dist/styles/border.js → src/styles/border.ts} +2 -1
  71. package/{dist/styles/disabled.js → src/styles/disabled.ts} +3 -2
  72. package/{dist/styles/durations.js → src/styles/durations.ts} +2 -1
  73. package/{dist/styles/focus.js → src/styles/focus.ts} +32 -8
  74. package/{dist/styles/font.js → src/styles/font.ts} +2 -1
  75. package/{dist/styles/form-styles.js → src/styles/form-styles.ts} +6 -1
  76. package/{dist/styles/index.js → src/styles/index.ts} +1 -0
  77. package/{dist/styles/native-styles.js → src/styles/native-styles.ts} +5 -3
  78. package/{dist/styles/scrollbar.js → src/styles/scrollbar.ts} +4 -3
  79. package/{dist/styles/shadows.js → src/styles/shadows.ts} +8 -6
  80. package/{dist/styles/user-select.js → src/styles/user-select.ts} +3 -2
  81. package/{dist/styles/vira-color-palette.js → src/styles/vira-color-palette.ts} +11 -1
  82. package/src/styles/vira-color-theme.ts +1142 -0
  83. package/src/util/define-table.ts +279 -0
  84. package/src/util/dynamic-element.ts +129 -0
  85. package/src/util/pop-up-manager.ts +380 -0
  86. package/dist/elements/define-vira-element.d.ts +0 -18
  87. package/dist/elements/define-vira-element.js +0 -19
  88. package/dist/elements/form/vira-form-fields.d.ts +0 -100
  89. package/dist/elements/form/vira-form-fields.js +0 -60
  90. package/dist/elements/form/vira-form.element.d.ts +0 -35
  91. package/dist/elements/form/vira-form.element.js +0 -151
  92. package/dist/elements/index.js +0 -25
  93. package/dist/elements/pop-up/pop-up-helpers.d.ts +0 -33
  94. package/dist/elements/pop-up/pop-up-helpers.js +0 -58
  95. package/dist/elements/pop-up/pop-up-menu-item.js +0 -1
  96. package/dist/elements/pop-up/vira-menu-item.element.d.ts +0 -19
  97. package/dist/elements/pop-up/vira-menu-trigger.element.d.ts +0 -41
  98. package/dist/elements/pop-up/vira-menu-trigger.element.js +0 -121
  99. package/dist/elements/pop-up/vira-menu.element.d.ts +0 -38
  100. package/dist/elements/pop-up/vira-pop-up-menu.element.d.ts +0 -35
  101. package/dist/elements/pop-up/vira-pop-up-trigger.element.d.ts +0 -105
  102. package/dist/elements/shared-text-input-logic.d.ts +0 -63
  103. package/dist/elements/shared-text-input-logic.js +0 -101
  104. package/dist/elements/vira-bold-text.element.d.ts +0 -9
  105. package/dist/elements/vira-button.element.d.ts +0 -31
  106. package/dist/elements/vira-card.element.d.ts +0 -18
  107. package/dist/elements/vira-checkbox.element.d.ts +0 -34
  108. package/dist/elements/vira-collapsible-wrapper.element.d.ts +0 -14
  109. package/dist/elements/vira-dropdown.element.d.ts +0 -46
  110. package/dist/elements/vira-error.element.d.ts +0 -7
  111. package/dist/elements/vira-icon.element.d.ts +0 -13
  112. package/dist/elements/vira-image.element.d.ts +0 -45
  113. package/dist/elements/vira-input.element.d.ts +0 -62
  114. package/dist/elements/vira-link.element.d.ts +0 -73
  115. package/dist/elements/vira-modal.element.d.ts +0 -39
  116. package/dist/elements/vira-overflow-switch.element.d.ts +0 -21
  117. package/dist/elements/vira-overflow-switch.element.js +0 -110
  118. package/dist/elements/vira-progress.element.d.ts +0 -18
  119. package/dist/elements/vira-select.element.d.ts +0 -48
  120. package/dist/icons/icon-color.test-helper.d.ts +0 -6
  121. package/dist/icons/icon-color.test-helper.js +0 -9
  122. package/dist/icons/icon-css-vars.d.ts +0 -14
  123. package/dist/icons/icon-svg.d.ts +0 -27
  124. package/dist/icons/icon-svg.js +0 -48
  125. package/dist/icons/icon-svgs/bell-24.icon.d.ts +0 -8
  126. package/dist/icons/icon-svgs/chat-24.icon.d.ts +0 -8
  127. package/dist/icons/icon-svgs/check-24.icon.d.ts +0 -8
  128. package/dist/icons/icon-svgs/chevron-down-24.icon.d.ts +0 -8
  129. package/dist/icons/icon-svgs/chevron-up-24.icon.d.ts +0 -8
  130. package/dist/icons/icon-svgs/close-x-24.icon.d.ts +0 -8
  131. package/dist/icons/icon-svgs/commit-24.icon.d.ts +0 -8
  132. package/dist/icons/icon-svgs/copy-24.icon.d.ts +0 -8
  133. package/dist/icons/icon-svgs/document-24.icon.d.ts +0 -8
  134. package/dist/icons/icon-svgs/document-search-24.icon.d.ts +0 -8
  135. package/dist/icons/icon-svgs/double-chevron-24.icon.d.ts +0 -8
  136. package/dist/icons/icon-svgs/element-16.icon.d.ts +0 -8
  137. package/dist/icons/icon-svgs/element-24.icon.d.ts +0 -8
  138. package/dist/icons/icon-svgs/external-link-24.icon.d.ts +0 -8
  139. package/dist/icons/icon-svgs/eye-closed-24.icon.d.ts +0 -8
  140. package/dist/icons/icon-svgs/eye-open-24.icon.d.ts +0 -8
  141. package/dist/icons/icon-svgs/filter-24.icon.d.ts +0 -8
  142. package/dist/icons/icon-svgs/link-24.icon.d.ts +0 -8
  143. package/dist/icons/icon-svgs/loader-24.icon.d.ts +0 -8
  144. package/dist/icons/icon-svgs/loader-animated-24.icon.d.ts +0 -8
  145. package/dist/icons/icon-svgs/lock-24.icon.d.ts +0 -8
  146. package/dist/icons/icon-svgs/options-24.icon.d.ts +0 -8
  147. package/dist/icons/icon-svgs/pencil-24.icon.d.ts +0 -8
  148. package/dist/icons/icon-svgs/shield-24.icon.d.ts +0 -8
  149. package/dist/icons/icon-svgs/sort-ascending-24.icon.d.ts +0 -8
  150. package/dist/icons/icon-svgs/sort-descending-24.icon.d.ts +0 -8
  151. package/dist/icons/icon-svgs/speaker-loud-24.icon.d.ts +0 -8
  152. package/dist/icons/icon-svgs/speaker-medium-24.icon.d.ts +0 -8
  153. package/dist/icons/icon-svgs/speaker-muted-24.icon.d.ts +0 -8
  154. package/dist/icons/icon-svgs/speaker-quiet-24.icon.d.ts +0 -8
  155. package/dist/icons/icon-svgs/star-24.icon.d.ts +0 -8
  156. package/dist/icons/icon-svgs/status-failure-24.icon.d.ts +0 -8
  157. package/dist/icons/icon-svgs/status-in-progress-24.icon.d.ts +0 -8
  158. package/dist/icons/icon-svgs/status-success-24.icon.d.ts +0 -8
  159. package/dist/icons/icon-svgs/status-unknown-24.icon.d.ts +0 -8
  160. package/dist/icons/icon-svgs/status-warning-24.icon.d.ts +0 -8
  161. package/dist/icons/icon-svgs/upload-24.icon.d.ts +0 -8
  162. package/dist/icons/icon-svgs/x-24.icon.d.ts +0 -8
  163. package/dist/icons/index.d.ts +0 -86
  164. package/dist/index.js +0 -4
  165. package/dist/styles/border.d.ts +0 -9
  166. package/dist/styles/disabled.d.ts +0 -6
  167. package/dist/styles/durations.d.ts +0 -22
  168. package/dist/styles/focus.d.ts +0 -31
  169. package/dist/styles/font.d.ts +0 -9
  170. package/dist/styles/form-styles.d.ts +0 -20
  171. package/dist/styles/index.d.ts +0 -13
  172. package/dist/styles/native-styles.d.ts +0 -13
  173. package/dist/styles/scrollbar.d.ts +0 -6
  174. package/dist/styles/shadows.d.ts +0 -20
  175. package/dist/styles/user-select.d.ts +0 -6
  176. package/dist/styles/vira-color-palette.d.ts +0 -95
  177. package/dist/styles/vira-color-theme.d.ts +0 -1184
  178. package/dist/styles/vira-color-theme.js +0 -1137
  179. package/dist/util/define-table.d.ts +0 -110
  180. package/dist/util/define-table.js +0 -115
  181. package/dist/util/dynamic-element.d.ts +0 -63
  182. package/dist/util/dynamic-element.js +0 -61
  183. package/dist/util/index.js +0 -3
  184. package/dist/util/pop-up-manager.d.ts +0 -180
  185. package/dist/util/pop-up-manager.js +0 -203
  186. /package/{dist/elements/index.d.ts → src/elements/index.ts} +0 -0
  187. /package/{dist/index.d.ts → src/index.ts} +0 -0
  188. /package/{dist/util/index.d.ts → src/util/index.ts} +0 -0
@@ -1,6 +1,7 @@
1
- import { css, html } from 'element-vir';
2
- import { viraFormCssVars } from '../styles/form-styles.js';
3
- import { defineViraElement } from './define-vira-element.js';
1
+ import {css, html} from 'element-vir';
2
+ import {viraFormCssVars} from '../styles/form-styles.js';
3
+ import {defineViraElement} from './define-vira-element.js';
4
+
4
5
  /**
5
6
  * An error wrapper that applies error coloring (red, by default).
6
7
  *
@@ -12,14 +13,14 @@ export const ViraError = defineViraElement()({
12
13
  cssVars: {
13
14
  'vira-error-font-weight': 'bold',
14
15
  },
15
- styles: ({ cssVars }) => css `
16
+ styles: ({cssVars}) => css`
16
17
  :host {
17
18
  color: ${viraFormCssVars['vira-form-error-foreground-color'].value};
18
19
  font-weight: ${cssVars['vira-error-font-weight'].value};
19
20
  }
20
21
  `,
21
22
  render() {
22
- return html `
23
+ return html`
23
24
  <slot></slot>
24
25
  `;
25
26
  },
@@ -1,5 +1,7 @@
1
- import { css } from 'element-vir';
2
- import { defineViraElement } from './define-vira-element.js';
1
+ import {css} from 'element-vir';
2
+ import {type ViraIconSvg} from '../icons/icon-svg.js';
3
+ import {defineViraElement} from './define-vira-element.js';
4
+
3
5
  /**
4
6
  * An element that renders a single {@link ViraIconSvg}.
5
7
  *
@@ -7,13 +9,17 @@ import { defineViraElement } from './define-vira-element.js';
7
9
  * @category Elements
8
10
  * @see https://electrovir.github.io/vira/book/elements/vira-icon
9
11
  */
10
- export const ViraIcon = defineViraElement()({
12
+ export const ViraIcon = defineViraElement<{
13
+ icon: Pick<ViraIconSvg, 'svgTemplate'> | undefined;
14
+ /** Ignores the given icon's embedded size and causes the <svg> element to fill its parent. */
15
+ fitContainer?: boolean | undefined;
16
+ }>()({
11
17
  tagName: 'vira-icon',
12
18
  hostClasses: {
13
19
  /** Ignores the given icon's embedded size and causes the <svg> element to fill its parent. */
14
- 'vira-icon-fit-container': ({ inputs }) => !!inputs.fitContainer,
20
+ 'vira-icon-fit-container': ({inputs}) => !!inputs.fitContainer,
15
21
  },
16
- styles: ({ hostClasses }) => css `
22
+ styles: ({hostClasses}) => css`
17
23
  :host {
18
24
  display: inline-block;
19
25
  }
@@ -31,10 +37,11 @@ export const ViraIcon = defineViraElement()({
31
37
  width: 100%;
32
38
  }
33
39
  `,
34
- render({ inputs }) {
40
+ render({inputs}) {
35
41
  if (!inputs.icon) {
36
42
  return '';
37
43
  }
44
+
38
45
  return inputs.icon.svgTemplate;
39
46
  },
40
47
  });
@@ -1,8 +1,10 @@
1
- import { wait } from '@augment-vir/common';
2
- import { classMap, css, defineElementEvent, html, listen, renderIf } from 'element-vir';
3
- import { LoaderAnimated24Icon, StatusFailure24Icon } from '../icons/index.js';
4
- import { defineViraElement } from './define-vira-element.js';
5
- import { ViraIcon } from './vira-icon.element.js';
1
+ import {type Dimensions, wait} from '@augment-vir/common';
2
+ import {type Duration, type DurationUnit} from 'date-vir';
3
+ import {classMap, css, defineElementEvent, html, listen, renderIf} from 'element-vir';
4
+ import {LoaderAnimated24Icon, StatusFailure24Icon} from '../icons/index.js';
5
+ import {defineViraElement} from './define-vira-element.js';
6
+ import {ViraIcon} from './vira-icon.element.js';
7
+
6
8
  /**
7
9
  * An `<img>` element wrapper that handles size constraints and includes slots for loading and error
8
10
  * indicators.
@@ -14,7 +16,20 @@ import { ViraIcon } from './vira-icon.element.js';
14
16
  * @category Elements
15
17
  * @see https://electrovir.github.io/vira/book/elements/vira-image
16
18
  */
17
- export const ViraImage = defineViraElement()({
19
+ export const ViraImage = defineViraElement<{
20
+ /** The URL of the image to load. This is passed directly to the `<img>` element. */
21
+ imageUrl: string;
22
+ /**
23
+ * The dimension which should dominantly constrain the image size. Whichever dimension this is
24
+ * set to is the dimension that the image will grow to match. This is only relevant if you apply
25
+ * size constraints on ViraImage via CSS in its parent.
26
+ *
27
+ * @default 'width'
28
+ */
29
+ dominantDimension?: keyof Dimensions | undefined;
30
+ /** For debugging only: artificially set a delay for the image loading so you can see the loader. */
31
+ _debugLoadDelay?: Duration<DurationUnit.Milliseconds> | undefined;
32
+ }>()({
18
33
  tagName: 'vira-image',
19
34
  state() {
20
35
  return {
@@ -22,26 +37,26 @@ export const ViraImage = defineViraElement()({
22
37
  * To avoid race conditions between `<img>` element events and potential input changing,
23
38
  * save the loaded state of an URL's image by the image's URL.
24
39
  */
25
- loadedUrls: {},
40
+ loadedUrls: {} as Readonly<{[url: string]: true}>,
26
41
  /**
27
42
  * To avoid race conditions between `<img>` element events and potential input changing,
28
43
  * save the errored state of an URL's image by the image's URL.
29
44
  */
30
- erroredUrls: {},
45
+ erroredUrls: {} as Readonly<{[url: string]: true}>,
31
46
  };
32
47
  },
33
48
  hostClasses: {
34
- 'vira-image-height-constrained': ({ inputs }) => inputs.dominantDimension === 'height',
49
+ 'vira-image-height-constrained': ({inputs}) => inputs.dominantDimension === 'height',
35
50
  },
36
51
  slotNames: [
37
52
  'loading',
38
53
  'error',
39
54
  ],
40
55
  events: {
41
- imageLoad: defineElementEvent(),
42
- imageError: defineElementEvent(),
56
+ imageLoad: defineElementEvent<void>(),
57
+ imageError: defineElementEvent<unknown>(),
43
58
  },
44
- styles: ({ hostClasses }) => css `
59
+ styles: ({hostClasses}) => css`
45
60
  :host {
46
61
  display: inline-flex;
47
62
  overflow: hidden;
@@ -88,55 +103,60 @@ export const ViraImage = defineViraElement()({
88
103
  display: none;
89
104
  }
90
105
  `,
91
- render({ inputs, state, updateState, dispatch, events, slotNames }) {
106
+ render({inputs, state, updateState, dispatch, events, slotNames}) {
92
107
  /**
93
108
  * Saved off for use in the image listeners. This is used to eliminate race conditions
94
109
  * between image events and the input URL changing.
95
110
  */
96
111
  const imageUrl = inputs.imageUrl;
112
+
97
113
  const statusTemplate = state.erroredUrls[imageUrl]
98
- ? html `
114
+ ? html`
99
115
  <slot class="status-wrapper" name=${slotNames.error}>
100
- <${ViraIcon.assign({ icon: StatusFailure24Icon })} class="error"></${ViraIcon}>
116
+ <${ViraIcon.assign({icon: StatusFailure24Icon})} class="error"></${ViraIcon}>
101
117
  </slot>
102
118
  `
103
119
  : state.loadedUrls[imageUrl]
104
- ? undefined
105
- : html `
120
+ ? undefined
121
+ : html`
106
122
  <slot class="status-wrapper" name=${slotNames.loading}>
107
- <${ViraIcon.assign({ icon: LoaderAnimated24Icon })}></${ViraIcon}>
123
+ <${ViraIcon.assign({icon: LoaderAnimated24Icon})}></${ViraIcon}>
108
124
  </slot>
109
125
  `;
110
- return html `
126
+
127
+ return html`
111
128
  ${renderIf(!!statusTemplate, statusTemplate)}
112
129
  <img
113
130
  class=${classMap({
114
- hidden: !!statusTemplate,
115
- })}
131
+ hidden: !!statusTemplate,
132
+ })}
116
133
  ${listen('load', async () => {
117
- if (inputs._debugLoadDelay) {
118
- await wait(inputs._debugLoadDelay);
119
- }
120
- updateState({
121
- loadedUrls: {
122
- ...state.loadedUrls,
123
- [imageUrl]: true,
124
- },
125
- });
126
- dispatch(new events.imageLoad());
127
- })}
134
+ if (inputs._debugLoadDelay) {
135
+ await wait(inputs._debugLoadDelay);
136
+ }
137
+
138
+ updateState({
139
+ loadedUrls: {
140
+ ...state.loadedUrls,
141
+ [imageUrl]: true,
142
+ },
143
+ });
144
+
145
+ dispatch(new events.imageLoad());
146
+ })}
128
147
  ${listen('error', async (event) => {
129
- if (inputs._debugLoadDelay) {
130
- await wait(inputs._debugLoadDelay);
131
- }
132
- updateState({
133
- erroredUrls: {
134
- ...state.erroredUrls,
135
- [imageUrl]: true,
136
- },
137
- });
138
- dispatch(new events.imageError(event.error));
139
- })}
148
+ if (inputs._debugLoadDelay) {
149
+ await wait(inputs._debugLoadDelay);
150
+ }
151
+ updateState({
152
+ erroredUrls: {
153
+ ...state.erroredUrls,
154
+ [imageUrl]: true,
155
+ },
156
+ });
157
+
158
+ dispatch(new events.imageError(event.error));
159
+ })}
140
160
  src=${imageUrl}
141
161
  />
142
162
  `;
@@ -1,28 +1,49 @@
1
- import { assertWrap } from '@augment-vir/assert';
2
- import { randomString } from '@augment-vir/common';
3
- import { extractEventTarget } from '@augment-vir/web';
4
- import { attributes, css, defineElementEvent, html, ifDefined, listen, nothing, onResize, renderIf, } from 'element-vir';
5
- import { CloseX24Icon } from '../icons/icon-svgs/close-x-24.icon.js';
6
- import { EyeClosed24Icon, EyeOpen24Icon } from '../icons/index.js';
7
- import { createFocusStyles } from '../styles/focus.js';
8
- import { viraFormCssVars } from '../styles/form-styles.js';
9
- import { noUserSelect, viraAnimationDurations, viraBorders, viraDisabledStyles, } from '../styles/index.js';
10
- import { noNativeFormStyles } from '../styles/native-styles.js';
11
- import { defineViraElement } from './define-vira-element.js';
12
- import { filterTextInputValue, textInputListener, } from './shared-text-input-logic.js';
13
- import { ViraIcon } from './vira-icon.element.js';
1
+ import {assertWrap} from '@augment-vir/assert';
2
+ import {type PartialWithUndefined, randomString} from '@augment-vir/common';
3
+ import {extractEventTarget} from '@augment-vir/web';
4
+ import {
5
+ attributes,
6
+ css,
7
+ defineElementEvent,
8
+ html,
9
+ ifDefined,
10
+ listen,
11
+ nothing,
12
+ onResize,
13
+ renderIf,
14
+ } from 'element-vir';
15
+ import {CloseX24Icon} from '../icons/icon-svgs/close-x-24.icon.js';
16
+ import {EyeClosed24Icon, EyeOpen24Icon, type ViraIconSvg} from '../icons/index.js';
17
+ import {createFocusStyles} from '../styles/focus.js';
18
+ import {viraFormCssVars} from '../styles/form-styles.js';
19
+ import {
20
+ noUserSelect,
21
+ viraAnimationDurations,
22
+ viraBorders,
23
+ viraDisabledStyles,
24
+ } from '../styles/index.js';
25
+ import {noNativeFormStyles} from '../styles/native-styles.js';
26
+ import {defineViraElement} from './define-vira-element.js';
27
+ import {
28
+ type SharedTextInputElementInputs,
29
+ filterTextInputValue,
30
+ textInputListener,
31
+ } from './shared-text-input-logic.js';
32
+ import {ViraIcon} from './vira-icon.element.js';
33
+
14
34
  export * from './shared-text-input-logic.js';
35
+
15
36
  /**
16
37
  * Input types for {@link ViraInput}.
17
38
  *
18
39
  * @category Internal
19
40
  */
20
- export var ViraInputType;
21
- (function (ViraInputType) {
22
- ViraInputType["Default"] = "text";
23
- ViraInputType["Password"] = "password";
24
- ViraInputType["Email"] = "email";
25
- })(ViraInputType || (ViraInputType = {}));
41
+ export enum ViraInputType {
42
+ Default = 'text',
43
+ Password = 'password',
44
+ Email = 'email',
45
+ }
46
+
26
47
  /**
27
48
  * A single line input element with all listeners properly attached. Multiple types are allowed with
28
49
  * {@link ViraInputType}.
@@ -31,21 +52,39 @@ export var ViraInputType;
31
52
  * @category Elements
32
53
  * @see https://electrovir.github.io/vira/book/elements/vira-input
33
54
  */
34
- export const ViraInput = defineViraElement()({
55
+ export const ViraInput = defineViraElement<
56
+ Readonly<
57
+ PartialWithUndefined<{
58
+ icon: Pick<ViraIconSvg, 'svgTemplate'>;
59
+ /** A suffix that, if provided, is shown following the input field. */
60
+ suffix: string;
61
+ /** A label that is shown above the input, if provided. */
62
+ label: string;
63
+ /** If true, applies error styling. */
64
+ hasError: boolean;
65
+ showClearButton: boolean;
66
+ type: ViraInputType;
67
+ }> &
68
+ SharedTextInputElementInputs
69
+ >
70
+ >()({
35
71
  tagName: 'vira-input',
36
72
  cssVars: {
37
73
  'vira-input-action-button-color': '#aaaaaa',
74
+
38
75
  'vira-input-clear-button-hover-color': '#ff0000',
39
76
  'vira-input-clear-button-active-color': '#b30000',
77
+
40
78
  // eslint-disable-next-line sonarjs/no-hardcoded-passwords
41
79
  'vira-input-show-password-button-hover-color': '#0a89ff',
42
80
  // eslint-disable-next-line sonarjs/no-hardcoded-passwords
43
81
  'vira-input-show-password-button-active-color': '#0261ba',
82
+
44
83
  'vira-input-padding-horizontal': '10px',
45
84
  'vira-input-padding-vertical': '6px',
46
85
  },
47
- styles: ({ hostClasses, cssVars }) => {
48
- return css `
86
+ styles: ({hostClasses, cssVars}) => {
87
+ return css`
49
88
  :host {
50
89
  position: relative;
51
90
  display: inline-flex;
@@ -178,19 +217,19 @@ export const ViraInput = defineViraElement()({
178
217
 
179
218
  &:focus:focus-visible:not([disabled]) ~ .focus-border {
180
219
  ${createFocusStyles({
181
- elementBorderSize: 0,
182
- noNesting: true,
183
- })}
220
+ elementBorderSize: 0,
221
+ noNesting: true,
222
+ })}
184
223
  }
185
224
  }
186
225
 
187
226
  ::selection {
188
227
  background: ${viraFormCssVars['vira-form-text-selection-color']
189
- .value}; /* WebKit/Blink Browsers */
228
+ .value}; /* WebKit/Blink Browsers */
190
229
  }
191
230
  ::-moz-selection {
192
231
  background: ${viraFormCssVars['vira-form-text-selection-color']
193
- .value}; /* Gecko Browsers */
232
+ .value}; /* Gecko Browsers */
194
233
  }
195
234
 
196
235
  input:placeholder-shown {
@@ -268,13 +307,13 @@ export const ViraInput = defineViraElement()({
268
307
  * Fires whenever a user input created a new value. Does not fire if all input letters are
269
308
  * filtered out due to input restrictions.
270
309
  */
271
- valueChange: defineElementEvent(),
310
+ valueChange: defineElementEvent<string>(),
272
311
  /**
273
312
  * Fires when inputs are blocked. Useful for showing warnings or error messages to inform
274
313
  * the user why their input did not propagate if it was blocked. This does not fire for text
275
314
  * that was blocked out of programmatic "value" property assignments.
276
315
  */
277
- inputBlocked: defineElementEvent(),
316
+ inputBlocked: defineElementEvent<string>(),
278
317
  },
279
318
  state() {
280
319
  return {
@@ -288,56 +327,69 @@ export const ViraInput = defineViraElement()({
288
327
  };
289
328
  },
290
329
  hostClasses: {
291
- 'vira-input-disabled': ({ inputs }) => !!inputs.disabled,
292
- 'vira-input-fit-text': ({ inputs }) => !!inputs.fitText,
293
- 'vira-input-clear-button-shown': ({ inputs }) => !!inputs.showClearButton,
294
- 'vira-input-error': ({ inputs }) => !!inputs.hasError,
330
+ 'vira-input-disabled': ({inputs}) => !!inputs.disabled,
331
+ 'vira-input-fit-text': ({inputs}) => !!inputs.fitText,
332
+ 'vira-input-clear-button-shown': ({inputs}) => !!inputs.showClearButton,
333
+ 'vira-input-error': ({inputs}) => !!inputs.hasError,
295
334
  },
296
- render: ({ inputs, dispatch, state, updateState, events, host }) => {
297
- const { filtered: filteredValue } = filterTextInputValue({
335
+ render: ({inputs, dispatch, state, updateState, events, host}) => {
336
+ const {filtered: filteredValue} = filterTextInputValue({
298
337
  value: inputs.value,
299
338
  allowed: inputs.allowedInputs,
300
339
  blocked: inputs.blockedInputs,
301
340
  });
341
+
302
342
  const iconTemplate = inputs.icon
303
- ? html `
304
- <${ViraIcon.assign({ icon: inputs.icon })} class="left-side-icon"></${ViraIcon}>
343
+ ? html`
344
+ <${ViraIcon.assign({icon: inputs.icon})} class="left-side-icon"></${ViraIcon}>
305
345
  `
306
346
  : nothing;
347
+
307
348
  const forcedInputWidthStyles = inputs.fitText
308
- ? css `
349
+ ? css`
309
350
  width: ${state.forcedInputWidth}px;
310
351
  `
311
352
  : nothing;
353
+
312
354
  const mousedownListener = listen('mousedown', (event) => {
313
355
  const eventTarget = extractEventTarget(event, HTMLElement, {
314
356
  useOriginalTarget: true,
315
357
  });
316
- const inputElement = assertWrap.instanceOf(host.shadowRoot.querySelector('input'), HTMLInputElement);
358
+ const inputElement = assertWrap.instanceOf(
359
+ host.shadowRoot.querySelector('input'),
360
+ HTMLInputElement,
361
+ );
362
+
317
363
  if (eventTarget !== inputElement) {
318
364
  event.preventDefault();
319
365
  inputElement.focus();
320
366
  }
321
367
  });
322
- const shouldBlockBrowserHelps = inputs.disableBrowserHelps ||
368
+
369
+ const shouldBlockBrowserHelps =
370
+ inputs.disableBrowserHelps ||
323
371
  /**
324
372
  * Some browsers leaks passwords with their browser helps (like Chrome with
325
373
  * spellchecking).
326
374
  */
327
375
  inputs.type === ViraInputType.Password;
328
- const inputTemplate = html `
376
+
377
+ const inputTemplate = html`
329
378
  <span class="input-wrapper" ${inputs.label ? nothing : mousedownListener}>
330
379
  ${iconTemplate}
331
- ${renderIf(!!inputs.fitText, html `
380
+ ${renderIf(
381
+ !!inputs.fitText,
382
+ html`
332
383
  <span
333
384
  class="size-span"
334
- ${onResize(({ contentRect }) => {
335
- updateState({ forcedInputWidth: contentRect.width });
336
- })}
385
+ ${onResize(({contentRect}) => {
386
+ updateState({forcedInputWidth: contentRect.width});
387
+ })}
337
388
  >
338
389
  <pre>${filteredValue || inputs.placeholder || nothing}</pre>
339
390
  </span>
340
- `)}
391
+ `,
392
+ )}
341
393
 
342
394
  <input
343
395
  id=${ifDefined(inputs.label ? state.randomId : undefined)}
@@ -352,61 +404,70 @@ export const ViraInput = defineViraElement()({
352
404
  ?disabled=${inputs.disabled}
353
405
  .value=${filteredValue}
354
406
  ${listen('input', (event) => {
355
- textInputListener({
356
- inputs,
357
- previousValue: filteredValue,
358
- event,
359
- inputBlockedCallback(blockedInput) {
360
- dispatch(new events.inputBlocked(blockedInput));
361
- },
362
- newValueCallback(newValue) {
363
- dispatch(new events.valueChange(newValue));
364
- },
365
- });
366
- })}
407
+ textInputListener({
408
+ inputs,
409
+ previousValue: filteredValue,
410
+ event,
411
+ inputBlockedCallback(blockedInput) {
412
+ dispatch(new events.inputBlocked(blockedInput));
413
+ },
414
+ newValueCallback(newValue) {
415
+ dispatch(new events.valueChange(newValue));
416
+ },
417
+ });
418
+ })}
367
419
  placeholder=${ifDefined(inputs.placeholder || undefined)}
368
420
  ${attributes(inputs.attributePassthrough)}
369
421
  />
370
422
 
371
- ${renderIf(!!(inputs.showClearButton && inputs.value), html `
423
+ ${renderIf(
424
+ !!(inputs.showClearButton && inputs.value),
425
+ html`
372
426
  <button
373
427
  class="clear-x-button"
374
428
  title="clear"
375
429
  ${listen('mousedown', (event) => {
376
- event.stopImmediatePropagation();
377
- event.preventDefault();
378
- })}
430
+ event.stopImmediatePropagation();
431
+ event.preventDefault();
432
+ })}
379
433
  ${listen('click', () => {
380
- if (inputs.disabled) {
381
- return;
382
- }
383
- dispatch(new events.valueChange(''));
384
- })}
434
+ if (inputs.disabled) {
435
+ return;
436
+ }
437
+ dispatch(new events.valueChange(''));
438
+ })}
385
439
  >
386
- <${ViraIcon.assign({ icon: CloseX24Icon })}></${ViraIcon}>
440
+ <${ViraIcon.assign({icon: CloseX24Icon})}></${ViraIcon}>
387
441
  </button>
388
- `)}
389
- ${renderIf(inputs.type === ViraInputType.Password, html `
442
+ `,
443
+ )}
444
+ ${renderIf(
445
+ inputs.type === ViraInputType.Password,
446
+ html`
390
447
  <button
391
448
  class="show-password-button"
392
449
  title="show password"
393
450
  ${listen('mousedown', (event) => {
394
- /** Prevent focus of the input. */
395
- event.stopImmediatePropagation();
396
- event.preventDefault();
397
- })}
451
+ /** Prevent focus of the input. */
452
+ event.stopImmediatePropagation();
453
+ event.preventDefault();
454
+ })}
398
455
  ${listen('click', () => {
399
- updateState({ showPassword: !state.showPassword });
400
- })}
456
+ updateState({showPassword: !state.showPassword});
457
+ })}
401
458
  >
402
459
  <${ViraIcon.assign({
403
- icon: state.showPassword ? EyeOpen24Icon : EyeClosed24Icon,
404
- })}></${ViraIcon}>
460
+ icon: state.showPassword ? EyeOpen24Icon : EyeClosed24Icon,
461
+ })}></${ViraIcon}>
405
462
  </button>
406
- `)}
407
- ${renderIf(!!inputs.suffix, html `
463
+ `,
464
+ )}
465
+ ${renderIf(
466
+ !!inputs.suffix,
467
+ html`
408
468
  <div class="suffix">${inputs.suffix}</div>
409
- `)}
469
+ `,
470
+ )}
410
471
 
411
472
  <!--
412
473
  These separate style elements are necessary so that we can select them as
@@ -418,22 +479,27 @@ export const ViraInput = defineViraElement()({
418
479
  <div class="border-style wrapper-border"></div>
419
480
  </span>
420
481
  `;
482
+
421
483
  if (inputs.label) {
422
- return html `
484
+ return html`
423
485
  <label for=${state.randomId} ${mousedownListener}>
424
486
  <span class="input-label">${inputs.label}</span>
425
487
  ${inputTemplate}
426
488
  </label>
427
489
  `;
428
- }
429
- else {
490
+ } else {
430
491
  return inputTemplate;
431
492
  }
432
493
  },
433
494
  });
434
- function calculateEffectiveInputType(type, showPassword) {
495
+
496
+ function calculateEffectiveInputType(
497
+ type: ViraInputType | undefined,
498
+ showPassword: boolean,
499
+ ): ViraInputType {
435
500
  if (type === ViraInputType.Password && showPassword) {
436
501
  return ViraInputType.Default;
437
502
  }
503
+
438
504
  return type || ViraInputType.Default;
439
505
  }