vira 20.0.9 → 21.0.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.
package/LICENSE-MIT CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 electrovir
3
+ Copyright (c) 2024 electrovir
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,13 +1,20 @@
1
1
  import { ViraIconSvg } from '../icons';
2
2
  import { SharedTextInputElementInputs } from './shared-text-input-logic';
3
3
  export * from './shared-text-input-logic';
4
+ export declare enum ViraInputType {
5
+ Default = "text",
6
+ Password = "password",
7
+ Email = "email"
8
+ }
4
9
  export declare const ViraInput: import("element-vir").DeclarativeElementDefinition<"vira-input", {
5
10
  icon?: undefined | Pick<ViraIconSvg, 'svgTemplate'>;
6
11
  /** A suffix that, if provided, is shown following the user input field. */
7
12
  suffix?: string | undefined;
8
13
  showClearButton?: boolean | undefined;
14
+ type?: ViraInputType;
9
15
  } & SharedTextInputElementInputs, {
10
16
  forcedInputWidth: number;
17
+ showPassword: boolean;
11
18
  }, {
12
19
  /**
13
20
  * Fires whenever a user input created a new value. Does not fire if all input letters are
@@ -20,4 +27,4 @@ export declare const ViraInput: import("element-vir").DeclarativeElementDefiniti
20
27
  * that was blocked out of programmatic "value" property assignments.
21
28
  */
22
29
  inputBlocked: import("element-vir").DefinedTypedEventNameDefinition<string>;
23
- }, "vira-input-disabled" | "vira-input-fit-text" | "vira-input-clear-button-shown", "vira-input-placeholder-color" | "vira-input-text-color" | "vira-input-border-color" | "vira-input-focus-border-color" | "vira-input-text-selection-color" | "vira-input-clear-button-color" | "vira-input-clear-button-hover-color" | "vira-input-clear-button-active-color" | "vira-input-padding-horizontal" | "vira-input-padding-vertical", readonly string[]>;
30
+ }, "vira-input-disabled" | "vira-input-fit-text" | "vira-input-clear-button-shown", "vira-input-placeholder-color" | "vira-input-text-color" | "vira-input-border-color" | "vira-input-focus-border-color" | "vira-input-text-selection-color" | "vira-input-action-button-color" | "vira-input-clear-button-hover-color" | "vira-input-clear-button-active-color" | "vira-input-show-password-button-hover-color" | "vira-input-show-password-button-active-color" | "vira-input-padding-horizontal" | "vira-input-padding-vertical", readonly string[]>;
@@ -1,4 +1,5 @@
1
1
  import { css, defineElementEvent, html, listen, onResize, renderIf, } from 'element-vir';
2
+ import { EyeClosed24Icon, EyeOpen24Icon } from '../icons';
2
3
  import { CloseX24Icon } from '../icons/icon-svgs/close-x-24.icon';
3
4
  import { noUserSelect, viraAnimationDurations, viraDisabledStyles } from '../styles';
4
5
  import { createFocusStyles, viraFocusCssVars } from '../styles/focus';
@@ -8,6 +9,12 @@ import { defineViraElement } from './define-vira-element';
8
9
  import { filterTextInputValue, textInputListener, } from './shared-text-input-logic';
9
10
  import { ViraIcon } from './vira-icon.element';
10
11
  export * from './shared-text-input-logic';
12
+ export var ViraInputType;
13
+ (function (ViraInputType) {
14
+ ViraInputType["Default"] = "text";
15
+ ViraInputType["Password"] = "password";
16
+ ViraInputType["Email"] = "email";
17
+ })(ViraInputType || (ViraInputType = {}));
11
18
  export const ViraInput = defineViraElement()({
12
19
  tagName: 'vira-input',
13
20
  hostClasses: {
@@ -21,9 +28,11 @@ export const ViraInput = defineViraElement()({
21
28
  'vira-input-border-color': '#cccccc',
22
29
  'vira-input-focus-border-color': '#59b1ff',
23
30
  'vira-input-text-selection-color': '#cfe9ff',
24
- 'vira-input-clear-button-color': '#aaaaaa',
31
+ 'vira-input-action-button-color': '#aaaaaa',
25
32
  'vira-input-clear-button-hover-color': '#ff0000',
26
33
  'vira-input-clear-button-active-color': '#b30000',
34
+ 'vira-input-show-password-button-hover-color': '#0a89ff',
35
+ 'vira-input-show-password-button-active-color': '#0261ba',
27
36
  'vira-input-padding-horizontal': '10px',
28
37
  'vira-input-padding-vertical': '6px',
29
38
  },
@@ -193,25 +202,39 @@ export const ViraInput = defineViraElement()({
193
202
  ${noUserSelect};
194
203
  }
195
204
 
196
- .close-x-button {
205
+ button {
197
206
  ${noNativeFormStyles};
198
- color: ${cssVars['vira-input-clear-button-color'].value};
199
207
  cursor: pointer;
200
208
  display: flex;
201
- transition: ${viraAnimationDurations['vira-interaction-animation-duration'].value};
209
+ transition: color
210
+ ${viraAnimationDurations['vira-interaction-animation-duration'].value};
211
+ }
212
+
213
+ .clear-x-button,
214
+ .show-password-button {
215
+ color: ${cssVars['vira-input-action-button-color'].value};
202
216
  }
203
217
 
204
- .close-x-button:hover {
218
+ .clear-x-button:hover {
205
219
  color: ${cssVars['vira-input-clear-button-hover-color'].value};
206
220
  }
207
221
 
208
- .close-x-button:active {
222
+ .clear-x-button:active {
209
223
  color: ${cssVars['vira-input-clear-button-active-color'].value};
210
224
  }
225
+
226
+ .show-password-button:hover {
227
+ color: ${cssVars['vira-input-show-password-button-hover-color'].value};
228
+ }
229
+
230
+ .show-password-button:active {
231
+ color: ${cssVars['vira-input-show-password-button-active-color'].value};
232
+ }
211
233
  `;
212
234
  },
213
235
  stateInitStatic: {
214
236
  forcedInputWidth: 0,
237
+ showPassword: false,
215
238
  },
216
239
  renderCallback: ({ inputs, dispatch, state, updateState, events }) => {
217
240
  const { filtered: filteredValue } = filterTextInputValue({
@@ -243,6 +266,7 @@ export const ViraInput = defineViraElement()({
243
266
  </span>
244
267
  `)}
245
268
  <input
269
+ type=${calculateEffectiveInputType(inputs.type, state.showPassword)}
246
270
  style=${forcedInputWidthStyles}
247
271
  autocomplete=${inputs.disableBrowserHelps ? 'off' : ''}
248
272
  autocorrect=${inputs.disableBrowserHelps ? 'off' : ''}
@@ -267,8 +291,8 @@ export const ViraInput = defineViraElement()({
267
291
  />
268
292
  ${renderIf(!!(inputs.showClearButton && inputs.value), html `
269
293
  <button
270
- class="close-x-button"
271
- title="clear input"
294
+ class="clear-x-button"
295
+ title="clear"
272
296
  ${listen('click', (event) => {
273
297
  /** Prevent focus of the input. */
274
298
  event.stopImmediatePropagation();
@@ -279,6 +303,22 @@ export const ViraInput = defineViraElement()({
279
303
  <${ViraIcon.assign({ icon: CloseX24Icon })}></${ViraIcon}>
280
304
  </button>
281
305
  `)}
306
+ ${renderIf(!!(inputs.type === ViraInputType.Password), html `
307
+ <button
308
+ class="show-password-button"
309
+ title="show password"
310
+ ${listen('click', (event) => {
311
+ /** Prevent focus of the input. */
312
+ event.stopImmediatePropagation();
313
+ event.preventDefault();
314
+ updateState({ showPassword: !state.showPassword });
315
+ })}
316
+ >
317
+ <${ViraIcon.assign({
318
+ icon: state.showPassword ? EyeOpen24Icon : EyeClosed24Icon,
319
+ })}></${ViraIcon}>
320
+ </button>
321
+ `)}
282
322
  ${renderIf(!!inputs.suffix, html `
283
323
  <div class="suffix">${inputs.suffix}</div>
284
324
  `)}
@@ -292,3 +332,9 @@ export const ViraInput = defineViraElement()({
292
332
  `;
293
333
  },
294
334
  });
335
+ function calculateEffectiveInputType(type, showPassword) {
336
+ if (type === ViraInputType.Password && showPassword) {
337
+ return ViraInputType.Default;
338
+ }
339
+ return type || ViraInputType.Default;
340
+ }
@@ -0,0 +1 @@
1
+ export declare const EyeClosed24Icon: import("../icon-svg").ViraIconSvg;
@@ -0,0 +1,21 @@
1
+ import { html } from 'element-vir';
2
+ import { viraIconCssVars } from '../icon-css-vars';
3
+ import { defineIcon } from '../icon-svg';
4
+ export const EyeClosed24Icon = defineIcon({
5
+ name: 'EyeClosed24Icon',
6
+ svgTemplate: html `
7
+ <svg
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ fill=${viraIconCssVars['vira-icon-fill-color'].value}
10
+ stroke=${viraIconCssVars['vira-icon-stroke-color'].value}
11
+ width="24"
12
+ height="24"
13
+ viewBox="0 0 24 24"
14
+ >
15
+ <path
16
+ stroke-width=${viraIconCssVars['vira-icon-stroke-width'].value}
17
+ d="M4 20 20 4M18.4 8.54C20 10.28 21 12 21 12s-4.03 7-9 7a6.53 6.53 0 0 1-3.16-.9M5.6 15.46C4 13.72 3 12 3 12s4.03-7 9-7c1.11 0 2.18.35 3.16.9"
18
+ />
19
+ </svg>
20
+ `,
21
+ });
@@ -0,0 +1 @@
1
+ export declare const EyeOpen24Icon: import("../icon-svg").ViraIconSvg;
@@ -0,0 +1,22 @@
1
+ import { html } from 'element-vir';
2
+ import { viraIconCssVars } from '../icon-css-vars';
3
+ import { defineIcon } from '../icon-svg';
4
+ export const EyeOpen24Icon = defineIcon({
5
+ name: 'EyeOpen24Icon',
6
+ svgTemplate: html `
7
+ <svg
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ fill=${viraIconCssVars['vira-icon-fill-color'].value}
10
+ stroke=${viraIconCssVars['vira-icon-stroke-color'].value}
11
+ width="24"
12
+ height="24"
13
+ viewBox="0 0 24 24"
14
+ >
15
+ <path
16
+ stroke-width=${viraIconCssVars['vira-icon-stroke-width'].value}
17
+ d="M12 5c5 0 9 7 9 7s-4 7-9 7-9-7-9-7 4-7 9-7Zm0 4a3 3 0 1 1 0 6 3 3 0 0 1 0-6Z"
18
+ />
19
+ </svg>
20
+ `,
21
+ });
22
+ // xml:space="preserve"
@@ -4,6 +4,8 @@ export * from './icon-svg';
4
4
  export * from './icon-svgs/close-x-24.icon';
5
5
  export * from './icon-svgs/element-16.icon';
6
6
  export * from './icon-svgs/element-24.icon';
7
+ export * from './icon-svgs/eye-closed-24.icon';
8
+ export * from './icon-svgs/eye-open-24.icon';
7
9
  export * from './icon-svgs/loader-24.icon';
8
10
  export * from './icon-svgs/loader-animated-24.icon';
9
11
  export * from './icon-svgs/options-24.icon';
@@ -14,6 +16,8 @@ export declare const allIconsByName: {
14
16
  readonly CloseX24Icon: import("./icon-svg").ViraIconSvg;
15
17
  readonly Element16Icon: import("./icon-svg").ViraIconSvg;
16
18
  readonly Element24Icon: import("./icon-svg").ViraIconSvg;
19
+ readonly EyeClosed24Icon: import("./icon-svg").ViraIconSvg;
20
+ readonly EyeOpen24Icon: import("./icon-svg").ViraIconSvg;
17
21
  readonly Loader24Icon: import("./icon-svg").ViraIconSvg;
18
22
  readonly LoaderAnimated24Icon: import("./icon-svg").ViraIconSvg;
19
23
  readonly Options24Icon: import("./icon-svg").ViraIconSvg;
@@ -2,6 +2,8 @@
2
2
  import { CloseX24Icon } from './icon-svgs/close-x-24.icon';
3
3
  import { Element16Icon } from './icon-svgs/element-16.icon';
4
4
  import { Element24Icon } from './icon-svgs/element-24.icon';
5
+ import { EyeClosed24Icon } from './icon-svgs/eye-closed-24.icon';
6
+ import { EyeOpen24Icon } from './icon-svgs/eye-open-24.icon';
5
7
  import { Loader24Icon } from './icon-svgs/loader-24.icon';
6
8
  import { LoaderAnimated24Icon } from './icon-svgs/loader-animated-24.icon';
7
9
  import { Options24Icon } from './icon-svgs/options-24.icon';
@@ -13,6 +15,8 @@ export * from './icon-svg';
13
15
  export * from './icon-svgs/close-x-24.icon';
14
16
  export * from './icon-svgs/element-16.icon';
15
17
  export * from './icon-svgs/element-24.icon';
18
+ export * from './icon-svgs/eye-closed-24.icon';
19
+ export * from './icon-svgs/eye-open-24.icon';
16
20
  export * from './icon-svgs/loader-24.icon';
17
21
  export * from './icon-svgs/loader-animated-24.icon';
18
22
  export * from './icon-svgs/options-24.icon';
@@ -23,6 +27,8 @@ export const allIconsByName = {
23
27
  CloseX24Icon,
24
28
  Element16Icon,
25
29
  Element24Icon,
30
+ EyeClosed24Icon,
31
+ EyeOpen24Icon,
26
32
  Loader24Icon,
27
33
  LoaderAnimated24Icon,
28
34
  Options24Icon,
@@ -10,7 +10,7 @@ export function getAssertedValidColor(input) {
10
10
  catch (caught) {
11
11
  const stringInput = String(input);
12
12
  const inputForMessage = stringInput.toLowerCase().match(/\[\s*object\s+object\s*\]/)
13
- ? wrapInTry({ callback: () => JSON.stringify(input), fallbackValue: stringInput })
13
+ ? wrapInTry(() => JSON.stringify(input), { fallbackValue: stringInput })
14
14
  : stringInput;
15
15
  throw new Error(`Invalid color: ${inputForMessage}`);
16
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vira",
3
- "version": "20.0.9",
3
+ "version": "21.0.0",
4
4
  "description": "A simple and highly versatile design system using element-vir.",
5
5
  "keywords": [
6
6
  "design",
@@ -32,33 +32,33 @@
32
32
  "test": "virmator test-web"
33
33
  },
34
34
  "dependencies": {
35
- "@augment-vir/browser": "^23.3.4",
36
- "@augment-vir/common": "^23.3.4",
37
- "colorjs.io": "^0.4.5",
38
- "date-vir": "^5.1.2",
39
- "lit-css-vars": "^3.0.8",
40
- "spa-router-vir": "^3.0.3",
41
- "type-fest": "^4.10.2"
35
+ "@augment-vir/browser": "^26.2.1",
36
+ "@augment-vir/common": "^26.2.1",
37
+ "colorjs.io": "^0.5.0",
38
+ "date-vir": "^5.1.3",
39
+ "lit-css-vars": "^3.0.9",
40
+ "spa-router-vir": "^3.0.4",
41
+ "type-fest": "^4.14.0"
42
42
  },
43
43
  "devDependencies": {
44
- "@augment-vir/browser-testing": "^23.3.4",
45
- "@augment-vir/node-js": "^23.3.4",
44
+ "@augment-vir/browser-testing": "^26.2.1",
45
+ "@augment-vir/node-js": "^26.2.1",
46
46
  "@open-wc/testing": "^4.0.0",
47
- "@types/chai": "^4.3.11",
47
+ "@types/chai": "^4.3.14",
48
48
  "@types/mocha": "^10.0.6",
49
49
  "@web/dev-server-esbuild": "^1.0.2",
50
- "@web/test-runner": "^0.18.0",
50
+ "@web/test-runner": "^0.18.1",
51
51
  "@web/test-runner-commands": "^0.9.0",
52
52
  "@web/test-runner-playwright": "^0.11.0",
53
53
  "@web/test-runner-visual-regression": "^0.9.0",
54
- "esbuild": "^0.20.1",
54
+ "esbuild": "^0.20.2",
55
55
  "istanbul-smart-text-reporter": "^1.1.4",
56
56
  "markdown-code-example-inserter": "^1.0.0",
57
- "run-time-assertions": "^1.0.0",
58
- "typedoc": "^0.25.8",
59
- "typescript": "^5.3.3",
57
+ "run-time-assertions": "^1.2.0",
58
+ "typedoc": "^0.25.12",
59
+ "typescript": "5.3.3",
60
60
  "vite": "^4.5.0",
61
- "vite-tsconfig-paths": "^4.3.1"
61
+ "vite-tsconfig-paths": "^4.3.2"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "element-vir": ">=17"