vira 0.1.2 → 0.3.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/dist/element-book/all-element-book-entries.js +4 -0
- package/dist/elements/index.d.ts +2 -0
- package/dist/elements/index.js +2 -0
- package/dist/elements/vira-button/vira-button.element.d.ts +2 -2
- package/dist/elements/vira-button/vira-button.element.js +7 -4
- package/dist/elements/vira-collapsible/vira-collapsible-wrapper.element.d.ts +10 -0
- package/dist/elements/vira-collapsible/vira-collapsible-wrapper.element.js +77 -0
- package/dist/elements/vira-icon/vira-icon.element.d.ts +1 -1
- package/dist/elements/vira-input/vira-input.element.d.ts +39 -0
- package/dist/elements/vira-input/vira-input.element.js +353 -0
- package/dist/icons/icon-svgs/element-16.icon.js +5 -3
- package/dist/icons/icon-svgs/element-24.icon.js +1 -3
- package/dist/styles/focus.d.ts +2 -0
- package/dist/styles/focus.js +3 -1
- package/dist/styles/native-styles.js +0 -1
- package/dist/styles/vira-css-vars.d.ts +3 -0
- package/dist/styles/vira-css-vars.js +7 -0
- package/package.json +1 -1
|
@@ -3,11 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.allElementBookEntries = void 0;
|
|
4
4
|
const elements_book_1 = require("../elements/elements.book");
|
|
5
5
|
const vira_button_element_book_1 = require("../elements/vira-button/vira-button.element.book");
|
|
6
|
+
const vira_collapsible_wrapper_element_book_1 = require("../elements/vira-collapsible/vira-collapsible-wrapper.element.book");
|
|
6
7
|
const vira_icon_element_book_1 = require("../elements/vira-icon/vira-icon.element.book");
|
|
8
|
+
const vira_input_element_book_1 = require("../elements/vira-input/vira-input.element.book");
|
|
7
9
|
const icons_book_1 = require("../icons/icons.book");
|
|
8
10
|
exports.allElementBookEntries = [
|
|
9
11
|
elements_book_1.elementsBookChapter,
|
|
10
12
|
...icons_book_1.iconBookEntries,
|
|
11
13
|
...vira_button_element_book_1.viraButtonBookEntries,
|
|
14
|
+
...vira_collapsible_wrapper_element_book_1.viraCollapsibleBookEntries,
|
|
12
15
|
...vira_icon_element_book_1.viraIconBookEntries,
|
|
16
|
+
...vira_input_element_book_1.viraInputBookEntries,
|
|
13
17
|
];
|
package/dist/elements/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/** This file is automatically updated by update-element-exports.ts */
|
|
2
2
|
export * from './define-vira-element';
|
|
3
3
|
export * from './vira-button/vira-button.element';
|
|
4
|
+
export * from './vira-collapsible/vira-collapsible-wrapper.element';
|
|
4
5
|
export * from './vira-icon/vira-icon.element';
|
|
6
|
+
export * from './vira-input/vira-input.element';
|
package/dist/elements/index.js
CHANGED
|
@@ -17,4 +17,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
__exportStar(require("./define-vira-element"), exports);
|
|
19
19
|
__exportStar(require("./vira-button/vira-button.element"), exports);
|
|
20
|
+
__exportStar(require("./vira-collapsible/vira-collapsible-wrapper.element"), exports);
|
|
20
21
|
__exportStar(require("./vira-icon/vira-icon.element"), exports);
|
|
22
|
+
__exportStar(require("./vira-input/vira-input.element"), exports);
|
|
@@ -5,7 +5,7 @@ export declare enum ViraButtonStyleEnum {
|
|
|
5
5
|
}
|
|
6
6
|
export declare const ViraButton: import("element-vir").DeclarativeElementDefinition<"vira-button", {
|
|
7
7
|
text?: string;
|
|
8
|
-
icon?: undefined | ViraIconSvg
|
|
8
|
+
icon?: undefined | Pick<ViraIconSvg, 'svgTemplate'>;
|
|
9
9
|
disabled?: boolean | undefined;
|
|
10
10
|
buttonStyle?: ViraButtonStyleEnum | undefined;
|
|
11
|
-
}, {}, {}, "vira-button-outline-style" | "vira-button-disabled", "vira-button-primary-color" | "vira-button-primary-hover-color" | "vira-button-primary-active-color" | "vira-button-secondary-color" | "vira-button-internal-foreground-color" | "vira-button-internal-background-color", import("lit-html").HTMLTemplateResult>;
|
|
11
|
+
}, {}, {}, "vira-button-outline-style" | "vira-button-disabled", "vira-button-primary-color" | "vira-button-primary-hover-color" | "vira-button-primary-active-color" | "vira-button-secondary-color" | "vira-button-internal-foreground-color" | "vira-button-internal-background-color" | "vira-button-padding", import("lit-html").HTMLTemplateResult>;
|
|
@@ -7,6 +7,7 @@ const disabled_1 = require("../../styles/disabled");
|
|
|
7
7
|
const durations_1 = require("../../styles/durations");
|
|
8
8
|
const focus_1 = require("../../styles/focus");
|
|
9
9
|
const native_styles_1 = require("../../styles/native-styles");
|
|
10
|
+
const vira_css_vars_1 = require("../../styles/vira-css-vars");
|
|
10
11
|
const define_vira_element_1 = require("../define-vira-element");
|
|
11
12
|
const vira_icon_element_1 = require("../vira-icon/vira-icon.element");
|
|
12
13
|
var ViraButtonStyleEnum;
|
|
@@ -29,6 +30,7 @@ exports.ViraButton = (0, define_vira_element_1.defineViraElement)()({
|
|
|
29
30
|
'vira-button-secondary-color': 'white',
|
|
30
31
|
'vira-button-internal-foreground-color': '',
|
|
31
32
|
'vira-button-internal-background-color': '',
|
|
33
|
+
'vira-button-padding': '5px 10px',
|
|
32
34
|
},
|
|
33
35
|
styles: ({ hostClasses, cssVars }) => (0, element_vir_1.css) `
|
|
34
36
|
:host {
|
|
@@ -65,6 +67,7 @@ exports.ViraButton = (0, define_vira_element_1.defineViraElement)()({
|
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
button {
|
|
70
|
+
cursor: pointer;
|
|
68
71
|
${native_styles_1.removeNativeFormStyles};
|
|
69
72
|
position: relative;
|
|
70
73
|
width: 100%;
|
|
@@ -75,10 +78,10 @@ exports.ViraButton = (0, define_vira_element_1.defineViraElement)()({
|
|
|
75
78
|
display: inline-flex;
|
|
76
79
|
justify-content: center;
|
|
77
80
|
align-items: center;
|
|
78
|
-
border-radius:
|
|
81
|
+
border-radius: ${vira_css_vars_1.viraCssVars['vira-form-input-border-radius'].value};
|
|
79
82
|
background-color: ${cssVars['vira-button-internal-background-color'].value};
|
|
80
83
|
color: ${cssVars['vira-button-internal-foreground-color'].value};
|
|
81
|
-
padding:
|
|
84
|
+
padding: ${cssVars['vira-button-padding'].value};
|
|
82
85
|
transition: color ${durations_1.viraAnimationDurations['vira-interaction-animation-duration'].value},
|
|
83
86
|
background-color
|
|
84
87
|
${durations_1.viraAnimationDurations['vira-interaction-animation-duration'].value},
|
|
@@ -86,7 +89,7 @@ exports.ViraButton = (0, define_vira_element_1.defineViraElement)()({
|
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
${(0, focus_1.createFocusStyles)({
|
|
89
|
-
mainSelector: 'button:focus:focus-visible:not(:active)',
|
|
92
|
+
mainSelector: 'button:focus:focus-visible:not(:active):not([disabled])',
|
|
90
93
|
elementBorderSize: 2,
|
|
91
94
|
})}
|
|
92
95
|
|
|
@@ -110,7 +113,7 @@ exports.ViraButton = (0, define_vira_element_1.defineViraElement)()({
|
|
|
110
113
|
`
|
|
111
114
|
: '';
|
|
112
115
|
return (0, element_vir_1.html) `
|
|
113
|
-
<button>${iconTemplate} ${textTemplate}</button>
|
|
116
|
+
<button ?disabled=${inputs.disabled}>${iconTemplate} ${textTemplate}</button>
|
|
114
117
|
`;
|
|
115
118
|
},
|
|
116
119
|
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare enum ViraCollapsibleSlotNameEnum {
|
|
2
|
+
Header = "header"
|
|
3
|
+
}
|
|
4
|
+
export declare const ViraCollapsibleWrapper: import("element-vir").DeclarativeElementDefinition<"vira-collapsible-wrapper", {
|
|
5
|
+
expanded: boolean;
|
|
6
|
+
}, {
|
|
7
|
+
contentHeight: number;
|
|
8
|
+
}, {
|
|
9
|
+
expandChange: import("element-vir").DefinedTypedEventNameDefinition<boolean>;
|
|
10
|
+
}, "vira-collapsible-wrapper-expanded", `vira-collapsible-wrapper-${string}`, import("lit-html").HTMLTemplateResult>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ViraCollapsibleWrapper = exports.ViraCollapsibleSlotNameEnum = void 0;
|
|
4
|
+
const element_vir_1 = require("element-vir");
|
|
5
|
+
const styles_1 = require("../../styles");
|
|
6
|
+
const define_vira_element_1 = require("../define-vira-element");
|
|
7
|
+
var ViraCollapsibleSlotNameEnum;
|
|
8
|
+
(function (ViraCollapsibleSlotNameEnum) {
|
|
9
|
+
ViraCollapsibleSlotNameEnum["Header"] = "header";
|
|
10
|
+
})(ViraCollapsibleSlotNameEnum = exports.ViraCollapsibleSlotNameEnum || (exports.ViraCollapsibleSlotNameEnum = {}));
|
|
11
|
+
exports.ViraCollapsibleWrapper = (0, define_vira_element_1.defineViraElement)()({
|
|
12
|
+
tagName: 'vira-collapsible-wrapper',
|
|
13
|
+
hostClasses: {
|
|
14
|
+
'vira-collapsible-wrapper-expanded': ({ inputs }) => inputs.expanded,
|
|
15
|
+
},
|
|
16
|
+
styles: ({ hostClasses }) => (0, element_vir_1.css) `
|
|
17
|
+
:host {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.header-wrapper {
|
|
23
|
+
${styles_1.removeNativeFormStyles};
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.content-wrapper,
|
|
28
|
+
.collapsing-element {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
box-sizing: border-box;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.collapsing-element {
|
|
35
|
+
transition: height ${styles_1.viraAnimationDurations['vira-pretty-animation-duration'].value};
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
}
|
|
38
|
+
${hostClasses['vira-collapsible-wrapper-expanded'].name} .collapsing-element {
|
|
39
|
+
pointer-events: none;
|
|
40
|
+
}
|
|
41
|
+
`,
|
|
42
|
+
events: {
|
|
43
|
+
expandChange: (0, element_vir_1.defineElementEvent)(),
|
|
44
|
+
},
|
|
45
|
+
stateInitStatic: {
|
|
46
|
+
contentHeight: 0,
|
|
47
|
+
},
|
|
48
|
+
renderCallback({ state, updateState, dispatch, events, inputs }) {
|
|
49
|
+
const collapsingStyles = inputs.expanded
|
|
50
|
+
? (0, element_vir_1.css) `
|
|
51
|
+
height: ${state.contentHeight}px;
|
|
52
|
+
`
|
|
53
|
+
: (0, element_vir_1.css) `
|
|
54
|
+
height: 0;
|
|
55
|
+
`;
|
|
56
|
+
return (0, element_vir_1.html) `
|
|
57
|
+
<button
|
|
58
|
+
class="header-wrapper"
|
|
59
|
+
${(0, element_vir_1.listen)('click', () => {
|
|
60
|
+
dispatch(new events.expandChange(!inputs.expanded));
|
|
61
|
+
})}
|
|
62
|
+
>
|
|
63
|
+
<slot name=${ViraCollapsibleSlotNameEnum.Header}>Header</slot>
|
|
64
|
+
</button>
|
|
65
|
+
<div class="collapsing-element" style=${collapsingStyles} disabled="disabled">
|
|
66
|
+
<div
|
|
67
|
+
${(0, element_vir_1.onResize)(({ contentRect }) => {
|
|
68
|
+
updateState({ contentHeight: contentRect.height });
|
|
69
|
+
})}
|
|
70
|
+
class="content-wrapper"
|
|
71
|
+
>
|
|
72
|
+
<slot></slot>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
`;
|
|
76
|
+
},
|
|
77
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ViraIconSvg } from '../../icons/icon-svg';
|
|
2
2
|
export declare const ViraIcon: import("element-vir").DeclarativeElementDefinition<"vira-icon", {
|
|
3
|
-
icon: ViraIconSvg | undefined;
|
|
3
|
+
icon: Pick<ViraIconSvg, 'svgTemplate'> | undefined;
|
|
4
4
|
/** Ignores the given icon's embedded size and causes the <svg> element to fill its parent. */
|
|
5
5
|
fitContainer?: boolean | undefined;
|
|
6
6
|
}, {}, {}, "vira-icon-fit-container", `vira-icon-${string}`, import("lit-html").TemplateResult | "">;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ViraIconSvg } from '../../icons';
|
|
2
|
+
export declare const ViraInput: import("element-vir").DeclarativeElementDefinition<"vira-input", {
|
|
3
|
+
icon?: undefined | Pick<ViraIconSvg, 'svgTemplate'>;
|
|
4
|
+
value: string;
|
|
5
|
+
/** Shown when no other text is present. Input restrictions do not apply to this property. */
|
|
6
|
+
placeholder?: string;
|
|
7
|
+
/** Set to true to trigger disabled styles and to block all user input. */
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Only letters in the given string or matches to the given RegExp will be allowed.
|
|
11
|
+
* blockedInputs takes precedence over this input.
|
|
12
|
+
*
|
|
13
|
+
* For example: if allowedInputs is set to "abcd" and blockedInputs is set to "d", only "a",
|
|
14
|
+
* "b", or "c" letters will be allowed.
|
|
15
|
+
*/
|
|
16
|
+
allowedInputs?: string | RegExp;
|
|
17
|
+
/** Any letters in the given string or matches to the given RegExp will be blocked. */
|
|
18
|
+
blockedInputs?: string | RegExp;
|
|
19
|
+
/** Disable all browser helps like spellchecking, autocomplete, etc. */
|
|
20
|
+
disableBrowserHelps?: boolean;
|
|
21
|
+
/** A suffix that, if provided, is shown following the user input field. */
|
|
22
|
+
suffix?: string;
|
|
23
|
+
/** Set this to true to make the whole element size to only fit the input text. */
|
|
24
|
+
fitText?: boolean;
|
|
25
|
+
}, {
|
|
26
|
+
forcedInputWidth: number;
|
|
27
|
+
}, {
|
|
28
|
+
/**
|
|
29
|
+
* Fires whenever a user input created a new value. Does not fire if all input letters are
|
|
30
|
+
* filtered out due to input restrictions.
|
|
31
|
+
*/
|
|
32
|
+
valueChange: import("element-vir").DefinedTypedEventNameDefinition<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Fires when inputs are blocked. Useful for showing warnings or error messages to inform
|
|
35
|
+
* the user why their input did not propagate if it was blocked. This does not fire for text
|
|
36
|
+
* that was blocked out of programmatic "value" property assignments.
|
|
37
|
+
*/
|
|
38
|
+
inputBlocked: import("element-vir").DefinedTypedEventNameDefinition<string>;
|
|
39
|
+
}, "vira-input-disabled" | "vira-input-has-value" | "vira-input-fit-text", "vira-input-placeholder-color" | "vira-input-text-color" | "vira-input-border-color" | "vira-input-focus-border-color" | "vira-input-text-selection-color" | "vira-input-padding-horizontal" | "vira-input-padding-vertical", import("lit-html").HTMLTemplateResult>;
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ViraInput = void 0;
|
|
4
|
+
const element_vir_1 = require("element-vir");
|
|
5
|
+
const styles_1 = require("../../styles");
|
|
6
|
+
const focus_1 = require("../../styles/focus");
|
|
7
|
+
const native_styles_1 = require("../../styles/native-styles");
|
|
8
|
+
const vira_css_vars_1 = require("../../styles/vira-css-vars");
|
|
9
|
+
const define_vira_element_1 = require("../define-vira-element");
|
|
10
|
+
const vira_icon_element_1 = require("../vira-icon/vira-icon.element");
|
|
11
|
+
function doesMatch({ input, matcher }) {
|
|
12
|
+
if (!input || !matcher) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
if (input.length > 1) {
|
|
16
|
+
return !!input.split('').every((singleInput) => doesMatch({ input: singleInput, matcher }));
|
|
17
|
+
}
|
|
18
|
+
if (matcher instanceof RegExp) {
|
|
19
|
+
return !!input.match(matcher);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
return matcher.includes(input);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function isAllowed({ value, allowed, blocked }) {
|
|
26
|
+
const isAllowedCharacter = allowed
|
|
27
|
+
? doesMatch({
|
|
28
|
+
input: value,
|
|
29
|
+
matcher: allowed,
|
|
30
|
+
})
|
|
31
|
+
: true;
|
|
32
|
+
const isBlockedCharacter = blocked
|
|
33
|
+
? doesMatch({
|
|
34
|
+
input: value,
|
|
35
|
+
matcher: blocked,
|
|
36
|
+
})
|
|
37
|
+
: false;
|
|
38
|
+
return isAllowedCharacter && !isBlockedCharacter;
|
|
39
|
+
}
|
|
40
|
+
function filterToAllowedCharactersOnly(inputs) {
|
|
41
|
+
if (!inputs.value) {
|
|
42
|
+
return { filtered: inputs.value, blocked: '' };
|
|
43
|
+
}
|
|
44
|
+
const { filtered, blocked } = inputs.value.split('').reduce((accum, letter) => {
|
|
45
|
+
const allowed = isAllowed({ ...inputs, value: letter });
|
|
46
|
+
if (allowed) {
|
|
47
|
+
accum.filtered.push(letter);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
accum.blocked.push(letter);
|
|
51
|
+
}
|
|
52
|
+
return accum;
|
|
53
|
+
}, {
|
|
54
|
+
filtered: [],
|
|
55
|
+
blocked: [],
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
filtered: filtered.join(''),
|
|
59
|
+
blocked: blocked.join(''),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
exports.ViraInput = (0, define_vira_element_1.defineViraElement)()({
|
|
63
|
+
tagName: 'vira-input',
|
|
64
|
+
hostClasses: {
|
|
65
|
+
'vira-input-disabled': ({ inputs }) => !!inputs.disabled,
|
|
66
|
+
'vira-input-has-value': ({ inputs }) => !!inputs.value,
|
|
67
|
+
'vira-input-fit-text': ({ inputs }) => !!inputs.fitText,
|
|
68
|
+
},
|
|
69
|
+
cssVars: {
|
|
70
|
+
'vira-input-placeholder-color': '#ccc',
|
|
71
|
+
'vira-input-text-color': 'black',
|
|
72
|
+
'vira-input-border-color': '#ccc',
|
|
73
|
+
'vira-input-focus-border-color': '#59B1FF',
|
|
74
|
+
'vira-input-text-selection-color': '#CFE9FF',
|
|
75
|
+
'vira-input-padding-horizontal': '10px',
|
|
76
|
+
'vira-input-padding-vertical': '6px',
|
|
77
|
+
},
|
|
78
|
+
events: {
|
|
79
|
+
/**
|
|
80
|
+
* Fires whenever a user input created a new value. Does not fire if all input letters are
|
|
81
|
+
* filtered out due to input restrictions.
|
|
82
|
+
*/
|
|
83
|
+
valueChange: (0, element_vir_1.defineElementEvent)(),
|
|
84
|
+
/**
|
|
85
|
+
* Fires when inputs are blocked. Useful for showing warnings or error messages to inform
|
|
86
|
+
* the user why their input did not propagate if it was blocked. This does not fire for text
|
|
87
|
+
* that was blocked out of programmatic "value" property assignments.
|
|
88
|
+
*/
|
|
89
|
+
inputBlocked: (0, element_vir_1.defineElementEvent)(),
|
|
90
|
+
},
|
|
91
|
+
styles: ({ hostClasses, cssVars }) => {
|
|
92
|
+
return (0, element_vir_1.css) `
|
|
93
|
+
:host {
|
|
94
|
+
position: relative;
|
|
95
|
+
display: inline-flex;
|
|
96
|
+
width: 224px;
|
|
97
|
+
box-sizing: border-box;
|
|
98
|
+
${focus_1.viraFocusCssVars['vira-focus-outline-color'].name}: ${cssVars['vira-input-focus-border-color'].value};
|
|
99
|
+
color: ${cssVars['vira-input-text-color'].value};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
${hostClasses['vira-input-disabled'].selector} {
|
|
103
|
+
${styles_1.viraDisabledStyles};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
${hostClasses['vira-input-fit-text'].selector} {
|
|
107
|
+
width: unset;
|
|
108
|
+
}
|
|
109
|
+
${hostClasses['vira-input-fit-text'].selector} input {
|
|
110
|
+
flex-grow: 0;
|
|
111
|
+
}
|
|
112
|
+
${hostClasses['vira-input-fit-text'].selector} input.has-value {
|
|
113
|
+
/*
|
|
114
|
+
Account for weird Safari <input> behavior with text alignment and size. so we
|
|
115
|
+
don't lose a pixel on the left side.
|
|
116
|
+
Only apply this when <input> has a value, otherwise externally-set width and a
|
|
117
|
+
placeholder input will cause the text selector bar to initially be in the center
|
|
118
|
+
of the element.
|
|
119
|
+
*/
|
|
120
|
+
text-align: center;
|
|
121
|
+
}
|
|
122
|
+
${hostClasses['vira-input-fit-text'].selector} .size-span {
|
|
123
|
+
${native_styles_1.removeNativeFormStyles};
|
|
124
|
+
font-family: inherit;
|
|
125
|
+
display: inline-block;
|
|
126
|
+
font-size: inherit;
|
|
127
|
+
line-height: inherit;
|
|
128
|
+
box-sizing: border-box;
|
|
129
|
+
position: absolute;
|
|
130
|
+
opacity: 0;
|
|
131
|
+
visibility: hidden;
|
|
132
|
+
pointer-events: none;
|
|
133
|
+
z-index: -1;
|
|
134
|
+
width: min-content;
|
|
135
|
+
${styles_1.noUserSelect};
|
|
136
|
+
vertical-align: middle;
|
|
137
|
+
max-height: 100%;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
pre {
|
|
141
|
+
${native_styles_1.removeNativeFormStyles};
|
|
142
|
+
font: inherit;
|
|
143
|
+
/*
|
|
144
|
+
Leave at least a few pixels for the cursor bar when there is no text at all.
|
|
145
|
+
This also accounts for a weird Safari <input> behavior where the text moves
|
|
146
|
+
around if it's not given a tiny bit of padding.
|
|
147
|
+
*/
|
|
148
|
+
padding-left: 2px;
|
|
149
|
+
display: block;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.border-style {
|
|
153
|
+
position: absolute;
|
|
154
|
+
top: 0;
|
|
155
|
+
left: 0;
|
|
156
|
+
width: 100%;
|
|
157
|
+
height: 100%;
|
|
158
|
+
border-radius: ${vira_css_vars_1.viraCssVars['vira-form-input-border-radius'].value};
|
|
159
|
+
z-index: 0;
|
|
160
|
+
pointer-events: none;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.label-border {
|
|
164
|
+
top: -1px;
|
|
165
|
+
left: -1px;
|
|
166
|
+
border: 1px solid ${cssVars['vira-input-border-color'].value};
|
|
167
|
+
transition: border
|
|
168
|
+
${styles_1.viraAnimationDurations['vira-interaction-animation-duration'].value};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
label {
|
|
172
|
+
${native_styles_1.removeNativeFormStyles};
|
|
173
|
+
max-width: 100%;
|
|
174
|
+
flex-grow: 1;
|
|
175
|
+
cursor: pointer;
|
|
176
|
+
display: inline-flex;
|
|
177
|
+
box-sizing: border-box;
|
|
178
|
+
align-items: center;
|
|
179
|
+
position: relative;
|
|
180
|
+
padding: 0 ${cssVars['vira-input-padding-horizontal'].value};
|
|
181
|
+
border-radius: ${vira_css_vars_1.viraCssVars['vira-form-input-border-radius'].value};
|
|
182
|
+
background-color: transparent;
|
|
183
|
+
/*
|
|
184
|
+
Border colors are actually applied via the .label-border class. However, we must
|
|
185
|
+
apply a border here still so that it takes up space.
|
|
186
|
+
*/
|
|
187
|
+
border: 1px solid transparent;
|
|
188
|
+
gap: 4px;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
${(0, focus_1.createFocusStyles)({
|
|
192
|
+
mainSelector: 'input:focus:focus-visible:not(:active):not([disabled]) ~ .focus-border',
|
|
193
|
+
elementBorderSize: 0,
|
|
194
|
+
})}
|
|
195
|
+
|
|
196
|
+
${vira_icon_element_1.ViraIcon} {
|
|
197
|
+
margin-right: calc(${cssVars['vira-input-padding-horizontal'].value} - 4px);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
input {
|
|
201
|
+
${native_styles_1.removeNativeFormStyles};
|
|
202
|
+
cursor: text;
|
|
203
|
+
margin: ${cssVars['vira-input-padding-vertical'].value} 0;
|
|
204
|
+
flex-grow: 1;
|
|
205
|
+
max-width: 100%;
|
|
206
|
+
/* fix input element not shrinking by default */
|
|
207
|
+
width: 0;
|
|
208
|
+
text-overflow: ellipsis;
|
|
209
|
+
box-sizing: border-box;
|
|
210
|
+
overflow: hidden;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
::selection {
|
|
214
|
+
background: ${cssVars['vira-input-text-selection-color']
|
|
215
|
+
.value}; /* WebKit/Blink Browsers */
|
|
216
|
+
}
|
|
217
|
+
::-moz-selection {
|
|
218
|
+
background: ${cssVars['vira-input-text-selection-color']
|
|
219
|
+
.value}; /* Gecko Browsers */
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
input:placeholder-shown {
|
|
223
|
+
text-overflow: ellipsis;
|
|
224
|
+
overflow: hidden;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
input:focus {
|
|
228
|
+
outline: none;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
input::placeholder {
|
|
232
|
+
color: ${cssVars['vira-input-placeholder-color'].value};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.suffix {
|
|
236
|
+
font-weight: bold;
|
|
237
|
+
}
|
|
238
|
+
`;
|
|
239
|
+
},
|
|
240
|
+
stateInitStatic: {
|
|
241
|
+
forcedInputWidth: 0,
|
|
242
|
+
},
|
|
243
|
+
renderCallback: ({ inputs, dispatch, state, updateState, events }) => {
|
|
244
|
+
const { filtered: filteredValue } = filterToAllowedCharactersOnly({
|
|
245
|
+
value: inputs.value ?? '',
|
|
246
|
+
allowed: inputs.allowedInputs,
|
|
247
|
+
blocked: inputs.blockedInputs,
|
|
248
|
+
});
|
|
249
|
+
const iconTemplate = inputs.icon
|
|
250
|
+
? (0, element_vir_1.html) `
|
|
251
|
+
<${vira_icon_element_1.ViraIcon} ${(0, element_vir_1.assign)(vira_icon_element_1.ViraIcon, { icon: inputs.icon })}></${vira_icon_element_1.ViraIcon}>
|
|
252
|
+
`
|
|
253
|
+
: '';
|
|
254
|
+
const forcedInputWidthStyles = inputs.fitText
|
|
255
|
+
? (0, element_vir_1.css) `
|
|
256
|
+
width: ${state.forcedInputWidth}px;
|
|
257
|
+
`
|
|
258
|
+
: '';
|
|
259
|
+
return (0, element_vir_1.html) `
|
|
260
|
+
<label>
|
|
261
|
+
${iconTemplate}
|
|
262
|
+
${(0, element_vir_1.renderIf)(!!inputs.fitText, (0, element_vir_1.html) `
|
|
263
|
+
<span
|
|
264
|
+
class="size-span"
|
|
265
|
+
${(0, element_vir_1.onResize)(({ contentRect }) => {
|
|
266
|
+
updateState({ forcedInputWidth: contentRect.width });
|
|
267
|
+
})}
|
|
268
|
+
>
|
|
269
|
+
<pre>${filteredValue || inputs.placeholder || ''}</pre>
|
|
270
|
+
</span>
|
|
271
|
+
`)}
|
|
272
|
+
<input
|
|
273
|
+
class=${(0, element_vir_1.classMap)({
|
|
274
|
+
'have-value': !!filteredValue,
|
|
275
|
+
})}
|
|
276
|
+
style=${forcedInputWidthStyles}
|
|
277
|
+
autocomplete=${inputs.disableBrowserHelps ? 'off' : ''}
|
|
278
|
+
autocorrect=${inputs.disableBrowserHelps ? 'off' : ''}
|
|
279
|
+
autocapitalize=${inputs.disableBrowserHelps ? 'off' : ''}
|
|
280
|
+
spellcheck=${inputs.disableBrowserHelps ? 'false' : ''}
|
|
281
|
+
?disabled=${inputs.disabled}
|
|
282
|
+
.value=${filteredValue}
|
|
283
|
+
${(0, element_vir_1.listen)('input', (event) => {
|
|
284
|
+
/**
|
|
285
|
+
* When attached to an input element (like here) this event type should
|
|
286
|
+
* always be InputEvent.
|
|
287
|
+
*/
|
|
288
|
+
if (!(event instanceof InputEvent)) {
|
|
289
|
+
throw new Error(`Input event type mismatch: "${event.constructor.name}"`);
|
|
290
|
+
}
|
|
291
|
+
const inputElement = event.target;
|
|
292
|
+
if (!(inputElement instanceof HTMLInputElement)) {
|
|
293
|
+
throw new Error(`Failed to find input element target from input event.`);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* This is usually a single character, but can be a bunch of characters in
|
|
297
|
+
* some circumstances. For example, when a bunch of characters are pasted,
|
|
298
|
+
* this will be the entire pasted contents.
|
|
299
|
+
*/
|
|
300
|
+
const changedText = event.data;
|
|
301
|
+
const beforeChangeText = filteredValue;
|
|
302
|
+
// this will be overwritten below if blocked characters are encountered
|
|
303
|
+
let finalText = inputElement.value ?? '';
|
|
304
|
+
/**
|
|
305
|
+
* When changedText is falsy, that means an operation other than inserting
|
|
306
|
+
* characters happened. Such as: deleting, cutting the text, etc.
|
|
307
|
+
*/
|
|
308
|
+
if (changedText) {
|
|
309
|
+
if (changedText.length === 1) {
|
|
310
|
+
if (!isAllowed({
|
|
311
|
+
value: changedText,
|
|
312
|
+
allowed: inputs.allowedInputs,
|
|
313
|
+
blocked: inputs.blockedInputs,
|
|
314
|
+
})) {
|
|
315
|
+
// prevent the change from happening
|
|
316
|
+
finalText = beforeChangeText;
|
|
317
|
+
dispatch(new events.inputBlocked(changedText));
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// filters out blocked pasted letters
|
|
321
|
+
else {
|
|
322
|
+
const { filtered, blocked } = filterToAllowedCharactersOnly({
|
|
323
|
+
value: changedText,
|
|
324
|
+
allowed: inputs.allowedInputs,
|
|
325
|
+
blocked: inputs.blockedInputs,
|
|
326
|
+
});
|
|
327
|
+
finalText = filtered;
|
|
328
|
+
dispatch(new events.inputBlocked(blocked));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (inputElement.value !== finalText) {
|
|
332
|
+
// this prevents blocked inputs by simply overwriting them
|
|
333
|
+
inputElement.value = finalText;
|
|
334
|
+
}
|
|
335
|
+
if (beforeChangeText !== finalText) {
|
|
336
|
+
dispatch(new events.valueChange(finalText));
|
|
337
|
+
}
|
|
338
|
+
})}
|
|
339
|
+
placeholder=${inputs.placeholder}
|
|
340
|
+
/>
|
|
341
|
+
${(0, element_vir_1.renderIf)(!!inputs.suffix, (0, element_vir_1.html) `
|
|
342
|
+
<div class="suffix">${inputs.suffix}</div>
|
|
343
|
+
`)}
|
|
344
|
+
<!--
|
|
345
|
+
These separate style elements are necessary so that we can select them as
|
|
346
|
+
siblings of the focused <input> element.
|
|
347
|
+
-->
|
|
348
|
+
<div class="border-style focus-border"></div>
|
|
349
|
+
<div class="border-style label-border"></div>
|
|
350
|
+
</label>
|
|
351
|
+
`;
|
|
352
|
+
},
|
|
353
|
+
});
|
|
@@ -8,14 +8,16 @@ exports.Element16Icon = (0, icon_svg_1.defineIcon)({
|
|
|
8
8
|
svgTemplate: (0, element_vir_1.html) `
|
|
9
9
|
<svg
|
|
10
10
|
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
-
xml:space="preserve"
|
|
12
11
|
fill="none"
|
|
13
12
|
width="16"
|
|
14
13
|
height="16"
|
|
15
14
|
viewBox="0 0 16 16"
|
|
16
|
-
stroke-width="1px"
|
|
17
15
|
>
|
|
18
|
-
<path
|
|
16
|
+
<path
|
|
17
|
+
stroke-width="1"
|
|
18
|
+
vector-effect="non-scaling-stroke"
|
|
19
|
+
d="M4 5 1 8l3 3m8-6 3 3-3 3m-5 0 2-6"
|
|
20
|
+
/>
|
|
19
21
|
</svg>
|
|
20
22
|
`,
|
|
21
23
|
});
|
|
@@ -8,14 +8,12 @@ exports.Element24Icon = (0, icon_svg_1.defineIcon)({
|
|
|
8
8
|
svgTemplate: (0, element_vir_1.html) `
|
|
9
9
|
<svg
|
|
10
10
|
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
-
xml:space="preserve"
|
|
12
11
|
viewBox="0 0 24 24"
|
|
13
12
|
fill="none"
|
|
14
13
|
width="24"
|
|
15
14
|
height="24"
|
|
16
|
-
stroke-width="1px"
|
|
17
15
|
>
|
|
18
|
-
<path d="m7 7-5 5 5 5M17 7l5 5-5 5m-6 0 2-10" />
|
|
16
|
+
<path stroke-width="1px" d="m7 7-5 5 5 5M17 7l5 5-5 5m-6 0 2-10" />
|
|
19
17
|
</svg>
|
|
20
18
|
`,
|
|
21
19
|
});
|
package/dist/styles/focus.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const viraFocusCssVars: import("lit-css-vars").CssVarDefinitions<{
|
|
2
2
|
'vira-focus-outline-color': string;
|
|
3
|
+
'vira-focus-outline-border-radius': import("element-vir").CSSResult;
|
|
3
4
|
}>;
|
|
4
5
|
/**
|
|
5
6
|
* Create styles that look like an outline for the given selector.
|
|
@@ -17,4 +18,5 @@ export declare function createFocusStyles({ mainSelector, elementBorderSize, out
|
|
|
17
18
|
elementBorderSize: number;
|
|
18
19
|
outlineGap?: number;
|
|
19
20
|
outlineWidth?: number;
|
|
21
|
+
borderRadius?: number;
|
|
20
22
|
}): import("element-vir").CSSResult;
|
package/dist/styles/focus.js
CHANGED
|
@@ -5,8 +5,10 @@ const element_vir_1 = require("element-vir");
|
|
|
5
5
|
const lit_1 = require("lit");
|
|
6
6
|
const lit_css_vars_1 = require("lit-css-vars");
|
|
7
7
|
const number_1 = require("../util/number");
|
|
8
|
+
const vira_css_vars_1 = require("./vira-css-vars");
|
|
8
9
|
exports.viraFocusCssVars = (0, lit_css_vars_1.defineCssVars)({
|
|
9
10
|
'vira-focus-outline-color': 'blue',
|
|
11
|
+
'vira-focus-outline-border-radius': (0, element_vir_1.css) `calc(${vira_css_vars_1.viraCssVars['vira-form-input-border-radius'].value} + 4px)`,
|
|
10
12
|
});
|
|
11
13
|
/**
|
|
12
14
|
* Create styles that look like an outline for the given selector.
|
|
@@ -27,7 +29,7 @@ function createFocusStyles({ mainSelector, elementBorderSize, outlineGap = 2, ou
|
|
|
27
29
|
box-sizing: border-box;
|
|
28
30
|
pointer-events: none;
|
|
29
31
|
border: ${outlineWidth}px solid ${exports.viraFocusCssVars['vira-focus-outline-color'].value};
|
|
30
|
-
border-radius:
|
|
32
|
+
border-radius: ${exports.viraFocusCssVars['vira-focus-outline-border-radius'].value};
|
|
31
33
|
z-index: 100;
|
|
32
34
|
}
|
|
33
35
|
`;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.viraCssVars = void 0;
|
|
4
|
+
const lit_css_vars_1 = require("lit-css-vars");
|
|
5
|
+
exports.viraCssVars = (0, lit_css_vars_1.defineCssVars)({
|
|
6
|
+
'vira-form-input-border-radius': '8px',
|
|
7
|
+
});
|