@neumorphism-ui/elements 1.0.0-next.1 → 1.0.0-next.3
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/README.md +12 -1
- package/cdn/neu.min.js +176 -51
- package/custom-elements.json +2555 -358
- package/dist/all.d.ts +8 -0
- package/dist/all.js +8 -0
- package/dist/checkbox.d.ts +3 -0
- package/dist/checkbox.js +4 -0
- package/dist/components/avatar/avatar.d.ts +0 -3
- package/dist/components/avatar/avatar.def.d.ts +0 -3
- package/dist/components/avatar/avatar.def.js +4 -18
- package/dist/components/avatar/avatar.docs.d.ts +2 -0
- package/dist/components/avatar/avatar.docs.js +22 -0
- package/dist/components/avatar/avatar.js +7 -1
- package/dist/components/badge/badge.d.ts +0 -2
- package/dist/components/badge/badge.def.d.ts +0 -2
- package/dist/components/badge/badge.def.js +1 -14
- package/dist/components/badge/badge.docs.d.ts +2 -0
- package/dist/components/badge/badge.docs.js +17 -0
- package/dist/components/button/button.d.ts +0 -2
- package/dist/components/button/button.def.d.ts +0 -5
- package/dist/components/button/button.def.js +3 -25
- package/dist/components/button/button.docs.d.ts +2 -0
- package/dist/components/button/button.docs.js +29 -0
- package/dist/components/button/button.js +3 -36
- package/dist/components/button-group/button-group.d.ts +0 -2
- package/dist/components/button-group/button-group.def.d.ts +0 -2
- package/dist/components/button-group/button-group.def.js +1 -10
- package/dist/components/button-group/button-group.docs.d.ts +2 -0
- package/dist/components/button-group/button-group.docs.js +13 -0
- package/dist/components/checkbox/checkbox.d.ts +40 -0
- package/dist/components/checkbox/checkbox.def.d.ts +27 -0
- package/dist/components/checkbox/checkbox.def.js +21 -0
- package/dist/components/checkbox/checkbox.docs.d.ts +2 -0
- package/dist/components/checkbox/checkbox.docs.js +27 -0
- package/dist/components/checkbox/checkbox.js +40 -0
- package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
- package/dist/components/checkbox/checkbox.styles.js +28 -0
- package/dist/components/divider/divider.d.ts +0 -1
- package/dist/components/divider/divider.def.d.ts +0 -1
- package/dist/components/divider/divider.def.js +0 -9
- package/dist/components/divider/divider.docs.d.ts +2 -0
- package/dist/components/divider/divider.docs.js +12 -0
- package/dist/components/icon/icon.d.ts +0 -3
- package/dist/components/icon/icon.def.d.ts +0 -3
- package/dist/components/icon/icon.def.js +3 -10
- package/dist/components/icon/icon.docs.d.ts +2 -0
- package/dist/components/icon/icon.docs.js +13 -0
- package/dist/components/icon/system-icons.d.ts +10 -0
- package/dist/components/icon/system-icons.js +22 -11
- package/dist/components/icon-button/icon-button.d.ts +0 -5
- package/dist/components/icon-button/icon-button.def.d.ts +0 -5
- package/dist/components/icon-button/icon-button.def.js +3 -17
- package/dist/components/icon-button/icon-button.docs.d.ts +2 -0
- package/dist/components/icon-button/icon-button.docs.js +26 -0
- package/dist/components/number-field/number-field.d.ts +79 -0
- package/dist/components/number-field/number-field.def.d.ts +115 -0
- package/dist/components/number-field/number-field.def.js +40 -0
- package/dist/components/number-field/number-field.docs.d.ts +2 -0
- package/dist/components/number-field/number-field.docs.js +45 -0
- package/dist/components/number-field/number-field.js +121 -0
- package/dist/components/number-field/number-field.styles.d.ts +1 -0
- package/dist/components/number-field/number-field.styles.js +15 -0
- package/dist/components/option/option-data.d.ts +8 -0
- package/dist/components/option/option-data.js +12 -0
- package/dist/components/option/option.d.ts +17 -0
- package/dist/components/option/option.def.d.ts +8 -0
- package/dist/components/option/option.def.js +12 -0
- package/dist/components/option/option.docs.d.ts +2 -0
- package/dist/components/option/option.docs.js +12 -0
- package/dist/components/option/option.js +17 -0
- package/dist/components/option/option.styles.d.ts +2 -0
- package/dist/components/option/option.styles.js +5 -0
- package/dist/components/radio/radio-link.d.ts +11 -0
- package/dist/components/radio/radio-link.js +5 -0
- package/dist/components/radio/radio.d.ts +27 -0
- package/dist/components/radio/radio.def.d.ts +9 -0
- package/dist/components/radio/radio.def.js +12 -0
- package/dist/components/radio/radio.docs.d.ts +2 -0
- package/dist/components/radio/radio.docs.js +18 -0
- package/dist/components/radio/radio.js +43 -0
- package/dist/components/radio/radio.styles.d.ts +1 -0
- package/dist/components/radio/radio.styles.js +21 -0
- package/dist/components/radio-group/radio-group.d.ts +76 -0
- package/dist/components/radio-group/radio-group.def.d.ts +36 -0
- package/dist/components/radio-group/radio-group.def.js +40 -0
- package/dist/components/radio-group/radio-group.docs.d.ts +2 -0
- package/dist/components/radio-group/radio-group.docs.js +37 -0
- package/dist/components/radio-group/radio-group.js +208 -0
- package/dist/components/radio-group/radio-group.styles.d.ts +1 -0
- package/dist/components/radio-group/radio-group.styles.js +13 -0
- package/dist/components/select/select.d.ts +115 -0
- package/dist/components/select/select.def.d.ts +34 -0
- package/dist/components/select/select.def.js +35 -0
- package/dist/components/select/select.docs.d.ts +2 -0
- package/dist/components/select/select.docs.js +65 -0
- package/dist/components/select/select.js +391 -0
- package/dist/components/select/select.styles.d.ts +1 -0
- package/dist/components/select/select.styles.js +35 -0
- package/dist/components/shared/checkable.d.ts +45 -0
- package/dist/components/shared/checkable.js +108 -0
- package/dist/components/shared/field.styles.d.ts +1 -0
- package/dist/components/shared/field.styles.js +34 -0
- package/dist/components/shared/press.d.ts +7 -0
- package/dist/components/shared/press.js +42 -0
- package/dist/components/shared/step.d.ts +2 -0
- package/dist/components/shared/step.js +2 -0
- package/dist/components/shared/text-control.d.ts +72 -0
- package/dist/components/shared/text-control.js +191 -0
- package/dist/components/slider/slider.d.ts +67 -0
- package/dist/components/slider/slider.def.d.ts +37 -0
- package/dist/components/slider/slider.def.js +54 -0
- package/dist/components/slider/slider.docs.d.ts +2 -0
- package/dist/components/slider/slider.docs.js +45 -0
- package/dist/components/slider/slider.js +170 -0
- package/dist/components/slider/slider.styles.d.ts +1 -0
- package/dist/components/slider/slider.styles.js +16 -0
- package/dist/components/spinner/spinner.d.ts +0 -1
- package/dist/components/spinner/spinner.def.d.ts +0 -1
- package/dist/components/spinner/spinner.def.js +1 -13
- package/dist/components/spinner/spinner.docs.d.ts +2 -0
- package/dist/components/spinner/spinner.docs.js +17 -0
- package/dist/components/surface/surface.d.ts +0 -4
- package/dist/components/surface/surface.def.d.ts +0 -4
- package/dist/components/surface/surface.def.js +3 -12
- package/dist/components/surface/surface.docs.d.ts +2 -0
- package/dist/components/surface/surface.docs.js +15 -0
- package/dist/components/switch/switch.d.ts +4 -35
- package/dist/components/switch/switch.def.d.ts +0 -5
- package/dist/components/switch/switch.def.js +5 -21
- package/dist/components/switch/switch.docs.d.ts +2 -0
- package/dist/components/switch/switch.docs.js +26 -0
- package/dist/components/switch/switch.js +5 -117
- package/dist/components/text-field/implicit-submit.d.ts +5 -0
- package/dist/components/text-field/implicit-submit.js +8 -3
- package/dist/components/text-field/text-field.d.ts +9 -42
- package/dist/components/text-field/text-field.def.d.ts +0 -12
- package/dist/components/text-field/text-field.def.js +5 -30
- package/dist/components/text-field/text-field.docs.d.ts +2 -0
- package/dist/components/text-field/text-field.docs.js +45 -0
- package/dist/components/text-field/text-field.js +21 -178
- package/dist/components/text-field/text-field.styles.d.ts +1 -1
- package/dist/components/text-field/text-field.styles.js +2 -35
- package/dist/components/textarea/textarea.d.ts +92 -0
- package/dist/components/textarea/textarea.def.d.ts +127 -0
- package/dist/components/textarea/textarea.def.js +44 -0
- package/dist/components/textarea/textarea.docs.d.ts +2 -0
- package/dist/components/textarea/textarea.docs.js +40 -0
- package/dist/components/textarea/textarea.js +101 -0
- package/dist/components/textarea/textarea.styles.d.ts +1 -0
- package/dist/components/textarea/textarea.styles.js +9 -0
- package/dist/components/theme-docs.d.ts +3 -0
- package/dist/components/theme-docs.js +8 -0
- package/dist/core/define.d.ts +20 -2
- package/dist/core/dom.d.ts +4 -0
- package/dist/core/dom.js +7 -0
- package/dist/core/form-control.js +6 -1
- package/dist/core/neu-element.d.ts +2 -2
- package/dist/core/neu-element.js +10 -7
- package/dist/core/props.d.ts +13 -1
- package/dist/core/props.js +13 -3
- package/dist/core/styles.d.ts +0 -2
- package/dist/core/styles.js +0 -7
- package/dist/core/validation.d.ts +6 -2
- package/dist/core/validation.js +15 -8
- package/dist/docs.d.ts +3 -0
- package/dist/docs.js +41 -0
- package/dist/number-field.d.ts +3 -0
- package/dist/number-field.js +4 -0
- package/dist/option.d.ts +3 -0
- package/dist/option.js +4 -0
- package/dist/radio-group.d.ts +4 -0
- package/dist/radio-group.js +6 -0
- package/dist/radio.d.ts +3 -0
- package/dist/radio.js +4 -0
- package/dist/select.d.ts +3 -0
- package/dist/select.js +4 -0
- package/dist/slider.d.ts +3 -0
- package/dist/slider.js +4 -0
- package/dist/ssr.d.ts +10 -6
- package/dist/ssr.js +26 -6
- package/dist/textarea.d.ts +3 -0
- package/dist/textarea.js +4 -0
- package/package.json +45 -1
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static brand of the custom elements that block implicit submission like a text input. A
|
|
3
|
+
* subclass inherits it, so it counts under any tag name.
|
|
4
|
+
*/
|
|
5
|
+
export declare const BLOCKS_IMPLICIT_SUBMIT: unique symbol;
|
|
1
6
|
/**
|
|
2
7
|
* Enter in a text control submits like a native input (HTML §4.10.21.2). With a default button
|
|
3
8
|
* (the form's first submit button, form="id" ones included) it clicks that button unless it is
|
|
@@ -14,6 +14,13 @@ const BLOCKING_TYPES = new Set([
|
|
|
14
14
|
'datetime-local',
|
|
15
15
|
'number',
|
|
16
16
|
]);
|
|
17
|
+
/**
|
|
18
|
+
* Static brand of the custom elements that block implicit submission like a text input. A
|
|
19
|
+
* subclass inherits it, so it counts under any tag name.
|
|
20
|
+
*/
|
|
21
|
+
export const BLOCKS_IMPLICIT_SUBMIT = Symbol.for('neu-ui.blocks-implicit-submit');
|
|
22
|
+
const blocks = (el) => (el instanceof HTMLInputElement && BLOCKING_TYPES.has(el.type)) ||
|
|
23
|
+
el.constructor[BLOCKS_IMPLICIT_SUBMIT] === true;
|
|
17
24
|
/**
|
|
18
25
|
* Enter in a text control submits like a native input (HTML §4.10.21.2). With a default button
|
|
19
26
|
* (the form's first submit button, form="id" ones included) it clicks that button unless it is
|
|
@@ -33,9 +40,7 @@ export function implicitSubmit(form) {
|
|
|
33
40
|
defaultButton.click();
|
|
34
41
|
return;
|
|
35
42
|
}
|
|
36
|
-
|
|
37
|
-
el.localName === 'neu-text-field');
|
|
38
|
-
if (blocking.length !== 1)
|
|
43
|
+
if (elements.filter(blocks).length !== 1)
|
|
39
44
|
return;
|
|
40
45
|
markSubmitAttempt(form);
|
|
41
46
|
form.requestSubmit();
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { TextControlElement } from '../shared/text-control.js';
|
|
2
|
+
import { BLOCKS_IMPLICIT_SUBMIT } from './implicit-submit.js';
|
|
3
|
+
export declare class NeuTextField extends TextControlElement {
|
|
3
4
|
static def: import("../../ssr.js").ComponentDef<{
|
|
4
5
|
readonly type: {
|
|
5
6
|
readonly type: "string";
|
|
6
7
|
readonly default: "text";
|
|
7
8
|
readonly values: readonly ["text", "email", "password", "search", "tel", "url"];
|
|
8
|
-
readonly reflect: true;
|
|
9
9
|
};
|
|
10
10
|
readonly value: {
|
|
11
11
|
readonly type: "string";
|
|
12
12
|
};
|
|
13
13
|
readonly name: {
|
|
14
14
|
readonly type: "string";
|
|
15
|
-
readonly reflect: true;
|
|
16
15
|
};
|
|
17
16
|
readonly label: {
|
|
18
17
|
readonly type: "string";
|
|
@@ -28,15 +27,12 @@ export declare class NeuTextField extends FormControlElement {
|
|
|
28
27
|
};
|
|
29
28
|
readonly required: {
|
|
30
29
|
readonly type: "boolean";
|
|
31
|
-
readonly reflect: true;
|
|
32
30
|
};
|
|
33
31
|
readonly disabled: {
|
|
34
32
|
readonly type: "boolean";
|
|
35
|
-
readonly reflect: true;
|
|
36
33
|
};
|
|
37
34
|
readonly readOnly: {
|
|
38
35
|
readonly type: "boolean";
|
|
39
|
-
readonly reflect: true;
|
|
40
36
|
readonly attribute: "readonly";
|
|
41
37
|
};
|
|
42
38
|
readonly minLength: {
|
|
@@ -67,50 +63,21 @@ export declare class NeuTextField extends FormControlElement {
|
|
|
67
63
|
readonly type: "string";
|
|
68
64
|
readonly default: "md";
|
|
69
65
|
readonly values: readonly ["sm", "md", "lg"];
|
|
70
|
-
readonly reflect: true;
|
|
71
66
|
};
|
|
72
67
|
}>;
|
|
68
|
+
static readonly [BLOCKS_IMPLICIT_SUBMIT] = true;
|
|
73
69
|
static extraProperties: string[];
|
|
74
70
|
type: 'text' | 'email' | 'password' | 'search' | 'tel' | 'url';
|
|
75
|
-
name: string;
|
|
76
|
-
label: string;
|
|
77
|
-
placeholder: string;
|
|
78
|
-
helpText: string;
|
|
79
|
-
errorText: string;
|
|
80
|
-
required: boolean;
|
|
81
|
-
disabled: boolean;
|
|
82
|
-
readOnly: boolean;
|
|
83
71
|
minLength: number;
|
|
84
72
|
maxLength: number;
|
|
85
73
|
pattern: string;
|
|
86
|
-
autocomplete: string;
|
|
87
74
|
size: 'sm' | 'md' | 'lg';
|
|
88
|
-
|
|
89
|
-
private
|
|
90
|
-
/** A value set before the shadow root exists. */
|
|
91
|
-
private pendingValue;
|
|
92
|
-
get value(): string;
|
|
93
|
-
set value(next: string);
|
|
94
|
-
get defaultValue(): string;
|
|
95
|
-
set defaultValue(next: string);
|
|
96
|
-
/** Focuses the inner input directly, so the caret stays where it was (no select-all). */
|
|
97
|
-
focus(options?: FocusOptions): void;
|
|
98
|
-
select(): void;
|
|
99
|
-
setSelectionRange(start: number, end: number, direction?: 'forward' | 'backward' | 'none'): void;
|
|
100
|
-
private get p();
|
|
101
|
-
private get input();
|
|
75
|
+
protected readonly commitProps: string[];
|
|
76
|
+
private get tp();
|
|
102
77
|
/** A detached input of this type holding `value`, sanitized the way the browser does it. */
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
private validityProbe;
|
|
106
|
-
protected rendered(): void;
|
|
78
|
+
protected probe(value: string): HTMLInputElement;
|
|
79
|
+
protected controlKeyDown(event: KeyboardEvent): void;
|
|
107
80
|
protected update(changed: ReadonlySet<string>): void;
|
|
108
|
-
/**
|
|
109
|
-
protected willUpdate(changed: ReadonlySet<string>): void;
|
|
110
|
-
protected formValue(): string;
|
|
111
|
-
/** Like a native input, a password or autocomplete=off field is never saved for restore. */
|
|
81
|
+
/** Like a native input, a password field is never saved for restore. */
|
|
112
82
|
protected formState(): string | null;
|
|
113
|
-
protected validate(): void;
|
|
114
|
-
protected resetToDefault(): void;
|
|
115
|
-
protected restoreState(state: string): void;
|
|
116
83
|
}
|
|
@@ -4,14 +4,12 @@ declare const props: {
|
|
|
4
4
|
readonly type: "string";
|
|
5
5
|
readonly default: "text";
|
|
6
6
|
readonly values: readonly ["text", "email", "password", "search", "tel", "url"];
|
|
7
|
-
readonly reflect: true;
|
|
8
7
|
};
|
|
9
8
|
readonly value: {
|
|
10
9
|
readonly type: "string";
|
|
11
10
|
};
|
|
12
11
|
readonly name: {
|
|
13
12
|
readonly type: "string";
|
|
14
|
-
readonly reflect: true;
|
|
15
13
|
};
|
|
16
14
|
readonly label: {
|
|
17
15
|
readonly type: "string";
|
|
@@ -27,15 +25,12 @@ declare const props: {
|
|
|
27
25
|
};
|
|
28
26
|
readonly required: {
|
|
29
27
|
readonly type: "boolean";
|
|
30
|
-
readonly reflect: true;
|
|
31
28
|
};
|
|
32
29
|
readonly disabled: {
|
|
33
30
|
readonly type: "boolean";
|
|
34
|
-
readonly reflect: true;
|
|
35
31
|
};
|
|
36
32
|
readonly readOnly: {
|
|
37
33
|
readonly type: "boolean";
|
|
38
|
-
readonly reflect: true;
|
|
39
34
|
readonly attribute: "readonly";
|
|
40
35
|
};
|
|
41
36
|
readonly minLength: {
|
|
@@ -66,7 +61,6 @@ declare const props: {
|
|
|
66
61
|
readonly type: "string";
|
|
67
62
|
readonly default: "md";
|
|
68
63
|
readonly values: readonly ["sm", "md", "lg"];
|
|
69
|
-
readonly reflect: true;
|
|
70
64
|
};
|
|
71
65
|
};
|
|
72
66
|
export type TextFieldProps = InferProps<typeof props>;
|
|
@@ -75,14 +69,12 @@ export declare const textFieldDef: import("../../core/define.js").ComponentDef<{
|
|
|
75
69
|
readonly type: "string";
|
|
76
70
|
readonly default: "text";
|
|
77
71
|
readonly values: readonly ["text", "email", "password", "search", "tel", "url"];
|
|
78
|
-
readonly reflect: true;
|
|
79
72
|
};
|
|
80
73
|
readonly value: {
|
|
81
74
|
readonly type: "string";
|
|
82
75
|
};
|
|
83
76
|
readonly name: {
|
|
84
77
|
readonly type: "string";
|
|
85
|
-
readonly reflect: true;
|
|
86
78
|
};
|
|
87
79
|
readonly label: {
|
|
88
80
|
readonly type: "string";
|
|
@@ -98,15 +90,12 @@ export declare const textFieldDef: import("../../core/define.js").ComponentDef<{
|
|
|
98
90
|
};
|
|
99
91
|
readonly required: {
|
|
100
92
|
readonly type: "boolean";
|
|
101
|
-
readonly reflect: true;
|
|
102
93
|
};
|
|
103
94
|
readonly disabled: {
|
|
104
95
|
readonly type: "boolean";
|
|
105
|
-
readonly reflect: true;
|
|
106
96
|
};
|
|
107
97
|
readonly readOnly: {
|
|
108
98
|
readonly type: "boolean";
|
|
109
|
-
readonly reflect: true;
|
|
110
99
|
readonly attribute: "readonly";
|
|
111
100
|
};
|
|
112
101
|
readonly minLength: {
|
|
@@ -137,7 +126,6 @@ export declare const textFieldDef: import("../../core/define.js").ComponentDef<{
|
|
|
137
126
|
readonly type: "string";
|
|
138
127
|
readonly default: "md";
|
|
139
128
|
readonly values: readonly ["sm", "md", "lg"];
|
|
140
|
-
readonly reflect: true;
|
|
141
129
|
};
|
|
142
130
|
}>;
|
|
143
131
|
export {};
|
|
@@ -1,30 +1,28 @@
|
|
|
1
1
|
import { defineComponent } from '../../core/define.js';
|
|
2
2
|
import { html } from '../../core/html.js';
|
|
3
|
-
import { themeCssProperties } from '../../core/styles.js';
|
|
4
3
|
import { textFieldStyles } from './text-field.styles.js';
|
|
5
4
|
const props = {
|
|
6
5
|
type: {
|
|
7
6
|
type: 'string',
|
|
8
7
|
default: 'text',
|
|
9
8
|
values: ['text', 'email', 'password', 'search', 'tel', 'url'],
|
|
10
|
-
reflect: true,
|
|
11
9
|
},
|
|
12
10
|
value: { type: 'string' },
|
|
13
|
-
name: { type: 'string'
|
|
11
|
+
name: { type: 'string' },
|
|
14
12
|
label: { type: 'string' },
|
|
15
13
|
placeholder: { type: 'string' },
|
|
16
14
|
helpText: { type: 'string' },
|
|
17
15
|
errorText: { type: 'string' },
|
|
18
|
-
required: { type: 'boolean'
|
|
19
|
-
disabled: { type: 'boolean'
|
|
20
|
-
readOnly: { type: 'boolean',
|
|
16
|
+
required: { type: 'boolean' },
|
|
17
|
+
disabled: { type: 'boolean' },
|
|
18
|
+
readOnly: { type: 'boolean', attribute: 'readonly' },
|
|
21
19
|
minLength: { type: 'number', default: -1, attribute: 'minlength' },
|
|
22
20
|
maxLength: { type: 'number', default: -1, attribute: 'maxlength' },
|
|
23
21
|
pattern: { type: 'string' },
|
|
24
22
|
autocomplete: { type: 'string' },
|
|
25
23
|
inputMode: { type: 'string', attribute: 'inputmode' },
|
|
26
24
|
enterKeyHint: { type: 'string', attribute: 'enterkeyhint' },
|
|
27
|
-
size: { type: 'string', default: 'md', values: ['sm', 'md', 'lg']
|
|
25
|
+
size: { type: 'string', default: 'md', values: ['sm', 'md', 'lg'] },
|
|
28
26
|
};
|
|
29
27
|
/** Attributes of the inner <input> that only appear when set. */
|
|
30
28
|
function inputAttributes(p) {
|
|
@@ -37,27 +35,4 @@ export const textFieldDef = defineComponent({
|
|
|
37
35
|
form: { valueProp: 'value' },
|
|
38
36
|
styles: textFieldStyles,
|
|
39
37
|
template: (p) => html `<div part="base" class="base"><label part="label" class="label" for="input"><slot name="label"><span class="label-text" data-ref="label-text">${p.label}</span></slot></label><div part="control" class="control"><span part="prefix" class="prefix"><slot name="prefix"></slot></span><input part="input" class="input" id="input" data-ref="input" type="${p.type}" value="${p.value}" aria-describedby="help"${inputAttributes(p)}><span part="suffix" class="suffix"><slot name="suffix"></slot></span></div><div part="help-text" class="help" id="help"><slot name="help-text"><span class="help-text" data-ref="help-text">${p.helpText}</span></slot><span class="error-text" data-ref="error-text">${p.errorText}</span></div></div>`,
|
|
40
|
-
docs: {
|
|
41
|
-
summary: 'A single-line text input with an inset field. The value attribute is the default value.',
|
|
42
|
-
events: [
|
|
43
|
-
{ name: 'input', description: 'Fired on every edit (the native input event, composed).' },
|
|
44
|
-
{ name: 'change', description: 'Fired when an edit is committed, usually on blur.' },
|
|
45
|
-
],
|
|
46
|
-
slots: [
|
|
47
|
-
{ name: 'label', description: 'Rich label; replaces the label attribute.' },
|
|
48
|
-
{ name: 'prefix', description: 'Content before the input, such as an icon.' },
|
|
49
|
-
{ name: 'suffix', description: 'Content after the input.' },
|
|
50
|
-
{ name: 'help-text', description: 'Rich help text; replaces the help-text attribute.' },
|
|
51
|
-
],
|
|
52
|
-
parts: [
|
|
53
|
-
{ name: 'base', description: 'Outer wrapper.' },
|
|
54
|
-
{ name: 'label', description: 'The <label> element.' },
|
|
55
|
-
{ name: 'control', description: 'The inset field around the input.' },
|
|
56
|
-
{ name: 'input', description: 'The native <input>.' },
|
|
57
|
-
{ name: 'prefix', description: 'Wrapper around the prefix slot.' },
|
|
58
|
-
{ name: 'suffix', description: 'Wrapper around the suffix slot.' },
|
|
59
|
-
{ name: 'help-text', description: 'Help or error text area.' },
|
|
60
|
-
],
|
|
61
|
-
cssProperties: themeCssProperties,
|
|
62
|
-
},
|
|
63
38
|
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { themeCssProperties } from '../theme-docs.js';
|
|
2
|
+
export const textFieldDocs = {
|
|
3
|
+
summary: 'A single-line text input with an inset field. The value attribute is the default value.',
|
|
4
|
+
descriptions: {
|
|
5
|
+
type: 'The kind of text the field accepts, which sets its keyboard and masking and drives email, url and tel validation.',
|
|
6
|
+
value: 'The current text as typed or set by script.',
|
|
7
|
+
name: 'The name under which the text is submitted with a form.',
|
|
8
|
+
label: 'Visible label text; the label slot replaces it.',
|
|
9
|
+
placeholder: 'Hint shown while the field is empty.',
|
|
10
|
+
helpText: 'Guidance shown below the field; the help-text slot replaces it.',
|
|
11
|
+
errorText: "Shown in place of the browser's validation message once the field is invalid after user interaction; does not itself make the field invalid.",
|
|
12
|
+
required: 'Makes the form invalid while the field is empty.',
|
|
13
|
+
disabled: 'Prevents interaction and leaves the field out of form submission.',
|
|
14
|
+
readOnly: 'Keeps the text visible and submitted but not editable.',
|
|
15
|
+
minLength: 'The fewest characters the text must have; checked after user edits, like native, not on script-set values.',
|
|
16
|
+
maxLength: 'The most characters the text may have; checked after user edits, like native, not a hard limit on script-set values.',
|
|
17
|
+
pattern: 'A regular expression the whole text must match.',
|
|
18
|
+
autocomplete: "Hint for the browser's autofill, as for the native attribute.",
|
|
19
|
+
inputMode: 'Hint for which virtual keyboard to show.',
|
|
20
|
+
enterKeyHint: "Hint for the label of the virtual keyboard's Enter key.",
|
|
21
|
+
size: 'The field size.',
|
|
22
|
+
defaultValue: 'The text the field starts with, which a form reset restores; set by the value attribute.',
|
|
23
|
+
},
|
|
24
|
+
events: [
|
|
25
|
+
{ name: 'input', description: 'Fired on every edit (the native input event, composed).' },
|
|
26
|
+
{ name: 'change', description: 'Fired when an edit is committed, usually on blur.' },
|
|
27
|
+
],
|
|
28
|
+
slots: [
|
|
29
|
+
{ name: 'label', description: 'Rich label; replaces the label attribute.' },
|
|
30
|
+
{ name: 'prefix', description: 'Content before the input, such as an icon.' },
|
|
31
|
+
{ name: 'suffix', description: 'Content after the input.' },
|
|
32
|
+
{ name: 'help-text', description: 'Rich help text; replaces the help-text attribute.' },
|
|
33
|
+
],
|
|
34
|
+
parts: [
|
|
35
|
+
{ name: 'base', description: 'Outer wrapper.' },
|
|
36
|
+
{ name: 'label', description: 'The <label> element.' },
|
|
37
|
+
{ name: 'control', description: 'The inset field around the input.' },
|
|
38
|
+
{ name: 'input', description: 'The native <input>.' },
|
|
39
|
+
{ name: 'prefix', description: 'Wrapper around the prefix slot.' },
|
|
40
|
+
{ name: 'suffix', description: 'Wrapper around the suffix slot.' },
|
|
41
|
+
{ name: 'help-text', description: 'Help or error text area.' },
|
|
42
|
+
],
|
|
43
|
+
cssProperties: themeCssProperties,
|
|
44
|
+
keyboard: [],
|
|
45
|
+
};
|
|
@@ -1,207 +1,50 @@
|
|
|
1
|
-
import { afterDispatch,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { implicitSubmit } from './implicit-submit.js';
|
|
1
|
+
import { afterDispatch, composing, setOptionalAttribute } from '../../core/dom.js';
|
|
2
|
+
import { baseCommitProps, TextControlElement } from '../shared/text-control.js';
|
|
3
|
+
import { BLOCKS_IMPLICIT_SUBMIT, implicitSubmit } from './implicit-submit.js';
|
|
5
4
|
import { textFieldDef } from './text-field.def.js';
|
|
6
|
-
|
|
7
|
-
const COMMIT_PROPS = [
|
|
8
|
-
'value',
|
|
9
|
-
'type',
|
|
10
|
-
'required',
|
|
11
|
-
'disabled',
|
|
12
|
-
'readOnly',
|
|
13
|
-
'minLength',
|
|
14
|
-
'maxLength',
|
|
15
|
-
'pattern',
|
|
16
|
-
'errorText',
|
|
17
|
-
'autocomplete',
|
|
18
|
-
];
|
|
19
|
-
function needsCommit(changed) {
|
|
20
|
-
return COMMIT_PROPS.some((key) => changed.has(key));
|
|
21
|
-
}
|
|
22
|
-
export class NeuTextField extends FormControlElement {
|
|
5
|
+
export class NeuTextField extends TextControlElement {
|
|
23
6
|
static def = textFieldDef;
|
|
7
|
+
static [BLOCKS_IMPLICIT_SUBMIT] = true;
|
|
24
8
|
static extraProperties = ['defaultValue'];
|
|
25
9
|
// inputMode and enterKeyHint are inherited from HTMLElement with the right type.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
/** A value set before the shadow root exists. */
|
|
29
|
-
pendingValue = null;
|
|
30
|
-
get value() {
|
|
31
|
-
return this.input?.value ?? this.pendingValue ?? this.p.value;
|
|
32
|
-
}
|
|
33
|
-
set value(next) {
|
|
34
|
-
const text = next === null || next === undefined ? '' : String(next);
|
|
35
|
-
this.dirty = true;
|
|
36
|
-
const input = this.input;
|
|
37
|
-
if (input)
|
|
38
|
-
input.value = text;
|
|
39
|
-
else
|
|
40
|
-
this.pendingValue = text;
|
|
41
|
-
this.commit();
|
|
42
|
-
}
|
|
43
|
-
get defaultValue() {
|
|
44
|
-
return this.p.value;
|
|
45
|
-
}
|
|
46
|
-
set defaultValue(next) {
|
|
47
|
-
this.setAttribute('value', String(next));
|
|
48
|
-
}
|
|
49
|
-
/** Focuses the inner input directly, so the caret stays where it was (no select-all). */
|
|
50
|
-
focus(options) {
|
|
51
|
-
const input = this.input;
|
|
52
|
-
if (input)
|
|
53
|
-
input.focus(options);
|
|
54
|
-
else
|
|
55
|
-
super.focus(options);
|
|
56
|
-
}
|
|
57
|
-
select() {
|
|
58
|
-
this.input?.select();
|
|
59
|
-
}
|
|
60
|
-
setSelectionRange(start, end, direction) {
|
|
61
|
-
this.input?.setSelectionRange(start, end, direction);
|
|
62
|
-
}
|
|
63
|
-
get p() {
|
|
10
|
+
commitProps = [...baseCommitProps, 'type', 'pattern'];
|
|
11
|
+
get tp() {
|
|
64
12
|
return this.props;
|
|
65
13
|
}
|
|
66
|
-
get input() {
|
|
67
|
-
return this.ref('input');
|
|
68
|
-
}
|
|
69
14
|
/** A detached input of this type holding `value`, sanitized the way the browser does it. */
|
|
70
15
|
probe(value) {
|
|
71
16
|
const probe = document.createElement('input');
|
|
72
|
-
probe.type = this.
|
|
17
|
+
probe.type = this.tp.type;
|
|
73
18
|
probe.value = value;
|
|
19
|
+
if (this.tp.pattern)
|
|
20
|
+
probe.setAttribute('pattern', this.tp.pattern);
|
|
74
21
|
return probe;
|
|
75
22
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const p = this.p;
|
|
79
|
-
const probe = this.probe(this.value);
|
|
80
|
-
probe.required = p.required;
|
|
81
|
-
probe.readOnly = p.readOnly;
|
|
82
|
-
probe.disabled = this.isDisabled;
|
|
83
|
-
if (p.pattern)
|
|
84
|
-
probe.setAttribute('pattern', p.pattern);
|
|
85
|
-
if (p.minLength >= 0)
|
|
86
|
-
probe.setAttribute('minlength', String(p.minLength));
|
|
87
|
-
if (p.maxLength >= 0)
|
|
88
|
-
probe.setAttribute('maxlength', String(p.maxLength));
|
|
89
|
-
return probe;
|
|
90
|
-
}
|
|
91
|
-
rendered() {
|
|
92
|
-
const input = this.input;
|
|
93
|
-
// A declarative root adopted without its input (cut short by the parser): nothing to wire up.
|
|
94
|
-
if (!input)
|
|
23
|
+
controlKeyDown(event) {
|
|
24
|
+
if (event.key !== 'Enter' || composing(event))
|
|
95
25
|
return;
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
input.value = this.pendingValue;
|
|
102
|
-
this.pendingValue = null;
|
|
103
|
-
}
|
|
104
|
-
input.addEventListener('input', () => {
|
|
105
|
-
this.dirty = true;
|
|
106
|
-
this.commit();
|
|
107
|
-
});
|
|
108
|
-
input.addEventListener('change', () => {
|
|
109
|
-
this.markInteracted();
|
|
110
|
-
dispatch(this, 'change');
|
|
111
|
-
});
|
|
112
|
-
input.addEventListener('keydown', (event) => {
|
|
113
|
-
if (event.key !== 'Enter' || event.isComposing)
|
|
114
|
-
return;
|
|
115
|
-
// Like a native input: submit once the keydown has finished dispatching, unless a listener
|
|
116
|
-
// (on the host or further up) cancelled it.
|
|
117
|
-
afterDispatch(event, () => {
|
|
118
|
-
if (!event.defaultPrevented)
|
|
119
|
-
implicitSubmit(this.internals.form);
|
|
120
|
-
});
|
|
26
|
+
// Like a native input: submit once the keydown has finished dispatching, unless a listener
|
|
27
|
+
// (on the host or further up) cancelled it.
|
|
28
|
+
afterDispatch(event, () => {
|
|
29
|
+
if (!event.defaultPrevented)
|
|
30
|
+
implicitSubmit(this.internals.form);
|
|
121
31
|
});
|
|
122
32
|
}
|
|
123
33
|
update(changed) {
|
|
124
|
-
const p = this.
|
|
34
|
+
const p = this.tp;
|
|
125
35
|
const input = this.input;
|
|
126
36
|
if (input) {
|
|
127
37
|
if (changed.has('type') && input.type !== p.type)
|
|
128
38
|
input.type = p.type;
|
|
129
|
-
if (changed.has('value')) {
|
|
130
|
-
if (input.defaultValue !== p.value)
|
|
131
|
-
input.defaultValue = p.value;
|
|
132
|
-
if (!this.dirty)
|
|
133
|
-
input.value = p.value;
|
|
134
|
-
}
|
|
135
|
-
if (changed.has('placeholder'))
|
|
136
|
-
setOptionalAttribute(input, 'placeholder', p.placeholder);
|
|
137
|
-
if (changed.has('required'))
|
|
138
|
-
input.required = p.required;
|
|
139
|
-
if (changed.has('disabled'))
|
|
140
|
-
input.disabled = this.isDisabled;
|
|
141
|
-
if (changed.has('readOnly'))
|
|
142
|
-
input.readOnly = p.readOnly;
|
|
143
|
-
if (changed.has('minLength')) {
|
|
144
|
-
setOptionalAttribute(input, 'minlength', p.minLength >= 0 ? String(p.minLength) : '');
|
|
145
|
-
}
|
|
146
|
-
if (changed.has('maxLength')) {
|
|
147
|
-
setOptionalAttribute(input, 'maxlength', p.maxLength >= 0 ? String(p.maxLength) : '');
|
|
148
|
-
}
|
|
149
39
|
if (changed.has('pattern'))
|
|
150
40
|
setOptionalAttribute(input, 'pattern', p.pattern);
|
|
151
|
-
if (changed.has('autocomplete'))
|
|
152
|
-
setOptionalAttribute(input, 'autocomplete', p.autocomplete);
|
|
153
41
|
if (changed.has('inputMode'))
|
|
154
42
|
setOptionalAttribute(input, 'inputmode', p.inputMode);
|
|
155
|
-
if (changed.has('enterKeyHint'))
|
|
156
|
-
setOptionalAttribute(input, 'enterkeyhint', p.enterKeyHint);
|
|
157
43
|
}
|
|
158
|
-
|
|
159
|
-
setText(this.ref('label-text'), p.label);
|
|
160
|
-
if (changed.has('helpText'))
|
|
161
|
-
setText(this.ref('help-text'), p.helpText);
|
|
162
|
-
if (needsCommit(changed))
|
|
163
|
-
this.commit();
|
|
44
|
+
super.update(changed);
|
|
164
45
|
}
|
|
165
|
-
/**
|
|
166
|
-
willUpdate(changed) {
|
|
167
|
-
if (!this.isConnected && !this.input && needsCommit(changed))
|
|
168
|
-
this.commit();
|
|
169
|
-
}
|
|
170
|
-
formValue() {
|
|
171
|
-
return this.value;
|
|
172
|
-
}
|
|
173
|
-
/** Like a native input, a password or autocomplete=off field is never saved for restore. */
|
|
46
|
+
/** Like a native input, a password field is never saved for restore. */
|
|
174
47
|
formState() {
|
|
175
|
-
|
|
176
|
-
if (p.type === 'password' || p.autocomplete.trim().toLowerCase() === 'off')
|
|
177
|
-
return null;
|
|
178
|
-
return this.value;
|
|
179
|
-
}
|
|
180
|
-
validate() {
|
|
181
|
-
const input = this.input;
|
|
182
|
-
const source = input ?? this.validityProbe();
|
|
183
|
-
// A disabled or readonly input still sets flags such as typeMismatch, but is barred from
|
|
184
|
-
// validation and has no message; setValidity() would throw on flags without a message.
|
|
185
|
-
if (!source.willValidate || source.validity.valid)
|
|
186
|
-
this.internals.setValidity({});
|
|
187
|
-
else {
|
|
188
|
-
this.internals.setValidity(copyValidity(source.validity), source.validationMessage, input ?? undefined);
|
|
189
|
-
}
|
|
190
|
-
setText(this.ref('error-text'), this.p.errorText || input?.validationMessage || '');
|
|
191
|
-
}
|
|
192
|
-
resetToDefault() {
|
|
193
|
-
this.dirty = false;
|
|
194
|
-
this.pendingValue = null;
|
|
195
|
-
const input = this.input;
|
|
196
|
-
if (input)
|
|
197
|
-
input.value = this.p.value;
|
|
198
|
-
}
|
|
199
|
-
restoreState(state) {
|
|
200
|
-
this.dirty = true;
|
|
201
|
-
const input = this.input;
|
|
202
|
-
if (input)
|
|
203
|
-
input.value = state;
|
|
204
|
-
else
|
|
205
|
-
this.pendingValue = state;
|
|
48
|
+
return this.tp.type === 'password' ? null : super.formState();
|
|
206
49
|
}
|
|
207
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const textFieldStyles = "\n:host {\n --_neu-bg: var(--neu-bg, #e0e5ec);\n --_neu-accent-c: var(--neu-accent, #6d5dfc);\n --_neu-d: var(--neu-distance, 6px);\n --_neu-k: var(--neu-intensity, 1);\n --_neu-r: var(--neu-radius, 12px);\n --_neu-danger: var(--neu-danger, #e5484d);\n --_neu-dur: var(--neu-duration, 150ms);\n --_neu-sd: var(--neu-shadow-dark, color-mix(in oklab, var(--_neu-bg), black min(100%, calc(var(--_neu-shade, 18%) * var(--_neu-k)))));\n --_neu-sl: var(--neu-shadow-light, color-mix(in oklab, var(--_neu-bg), white min(100%, calc(var(--_neu-light, 100%) * var(--_neu-k)))));\n --_neu-fg: var(--neu-fg, color-mix(in oklab, var(--_neu-bg), var(--_neu-ink, black) var(--_neu-fg-mix, 32%)));\n --_neu-fg-muted: var(--neu-fg-muted, color-mix(in oklab, var(--_neu-bg), var(--_neu-ink, black) var(--_neu-fg-muted-mix, 18%)));\n --_neu-accent-soft: color-mix(in oklab, var(--_neu-accent-c) 25%, var(--_neu-bg));\n --_neu-focus: 0 0 0 3px color-mix(in oklab, var(--_neu-accent-c) 45%, transparent);\n --_neu-raised: var(--_neu-d) var(--_neu-d) calc(var(--_neu-d) * 2) var(--_neu-sd), calc(var(--_neu-d) * -1) calc(var(--_neu-d) * -1) calc(var(--_neu-d) * 2) var(--_neu-sl);\n --_neu-raised-sm: calc(var(--_neu-d) * 0.5) calc(var(--_neu-d) * 0.5) var(--_neu-d) var(--_neu-sd), calc(var(--_neu-d) * -0.5) calc(var(--_neu-d) * -0.5) var(--_neu-d) var(--_neu-sl);\n --_neu-inset: inset var(--_neu-d) var(--_neu-d) calc(var(--_neu-d) * 2) var(--_neu-sd), inset calc(var(--_neu-d) * -1) calc(var(--_neu-d) * -1) calc(var(--_neu-d) * 2) var(--_neu-sl);\n --_neu-inset-sm: inset calc(var(--_neu-d) * 0.5) calc(var(--_neu-d) * 0.5) var(--_neu-d) var(--_neu-sd), inset calc(var(--_neu-d) * -0.5) calc(var(--_neu-d) * -0.5) var(--_neu-d) var(--_neu-sl);\n font-family: var(--neu-font);\n color: var(--_neu-fg);\n -webkit-tap-highlight-color: transparent;\n}\n:host(:not(:defined)) { visibility: inherit !important; min-block-size: auto !important; }\n:host([hidden]) { display: none !important; }\n:host(:focus) { outline: none; }\n*, *::before, *::after { box-sizing: border-box; }\n\n:host { display: block; }\n:host(:disabled), :host([disabled]) { cursor: not-allowed; }\n.base { display: flex; flex-direction: column; }\n.label-text, ::slotted([slot='label']) {
|
|
1
|
+
export declare const textFieldStyles = "\n:host {\n --_neu-bg: var(--neu-bg, #e0e5ec);\n --_neu-accent-c: var(--neu-accent, #6d5dfc);\n --_neu-d: var(--neu-distance, 6px);\n --_neu-k: var(--neu-intensity, 1);\n --_neu-r: var(--neu-radius, 12px);\n --_neu-danger: var(--neu-danger, #e5484d);\n --_neu-dur: var(--neu-duration, 150ms);\n --_neu-sd: var(--neu-shadow-dark, color-mix(in oklab, var(--_neu-bg), black min(100%, calc(var(--_neu-shade, 18%) * var(--_neu-k)))));\n --_neu-sl: var(--neu-shadow-light, color-mix(in oklab, var(--_neu-bg), white min(100%, calc(var(--_neu-light, 100%) * var(--_neu-k)))));\n --_neu-fg: var(--neu-fg, color-mix(in oklab, var(--_neu-bg), var(--_neu-ink, black) var(--_neu-fg-mix, 32%)));\n --_neu-fg-muted: var(--neu-fg-muted, color-mix(in oklab, var(--_neu-bg), var(--_neu-ink, black) var(--_neu-fg-muted-mix, 18%)));\n --_neu-accent-soft: color-mix(in oklab, var(--_neu-accent-c) 25%, var(--_neu-bg));\n --_neu-focus: 0 0 0 3px color-mix(in oklab, var(--_neu-accent-c) 45%, transparent);\n --_neu-raised: var(--_neu-d) var(--_neu-d) calc(var(--_neu-d) * 2) var(--_neu-sd), calc(var(--_neu-d) * -1) calc(var(--_neu-d) * -1) calc(var(--_neu-d) * 2) var(--_neu-sl);\n --_neu-raised-sm: calc(var(--_neu-d) * 0.5) calc(var(--_neu-d) * 0.5) var(--_neu-d) var(--_neu-sd), calc(var(--_neu-d) * -0.5) calc(var(--_neu-d) * -0.5) var(--_neu-d) var(--_neu-sl);\n --_neu-inset: inset var(--_neu-d) var(--_neu-d) calc(var(--_neu-d) * 2) var(--_neu-sd), inset calc(var(--_neu-d) * -1) calc(var(--_neu-d) * -1) calc(var(--_neu-d) * 2) var(--_neu-sl);\n --_neu-inset-sm: inset calc(var(--_neu-d) * 0.5) calc(var(--_neu-d) * 0.5) var(--_neu-d) var(--_neu-sd), inset calc(var(--_neu-d) * -0.5) calc(var(--_neu-d) * -0.5) var(--_neu-d) var(--_neu-sl);\n font-family: var(--neu-font);\n color: var(--_neu-fg);\n -webkit-tap-highlight-color: transparent;\n}\n:host(:not(:defined)) { visibility: inherit !important; min-block-size: auto !important; }\n:host([hidden]) { display: none !important; }\n:host(:focus) { outline: none; }\n*, *::before, *::after { box-sizing: border-box; }\n\n:host { display: block; }\n:host(:disabled), :host([disabled]) { cursor: not-allowed; }\n.base { display: flex; flex-direction: column; }\n.label { font-size: 0.8125rem; font-weight: 600; line-height: 1rem; color: var(--_neu-fg-muted); }\n.label-text, ::slotted([slot='label']) { display: block; margin-block-end: 0.375rem; }\n.label-text:empty { display: none; }\n.control {\n display: flex; align-items: center; min-block-size: 2.75rem; padding-inline: 0.875rem;\n border-radius: var(--_neu-r); background: var(--_neu-bg); box-shadow: var(--_neu-inset);\n transition: box-shadow var(--_neu-dur) ease;\n}\n:host([size='sm']) .control { min-block-size: 2.25rem; padding-inline: 0.75rem; box-shadow: var(--_neu-inset-sm); }\n:host([size='lg']) .control { min-block-size: 3.25rem; padding-inline: 1rem; }\n:host(:focus-within) .control { box-shadow: var(--_neu-inset), var(--_neu-focus); }\n:host(:state(user-invalid)) .control {\n box-shadow:\n inset var(--_neu-d) var(--_neu-d) calc(var(--_neu-d) * 2) color-mix(in oklab, var(--_neu-danger) 35%, var(--_neu-sd)),\n inset calc(var(--_neu-d) * -1) calc(var(--_neu-d) * -1) calc(var(--_neu-d) * 2) var(--_neu-sl);\n}\n:host(:disabled) .control, :host([disabled]) .control { box-shadow: var(--_neu-inset-sm); opacity: 0.6; }\n.input {\n flex: 1; min-inline-size: 0; align-self: stretch; padding: 0; border: none; outline: none;\n background: transparent; color: inherit; font: inherit; font-size: 0.9375rem;\n}\n.input::placeholder { color: var(--_neu-fg-muted); opacity: 1; }\n.help { font-size: 0.75rem; color: var(--_neu-fg-muted); }\n.help-text, ::slotted([slot='help-text']) { display: block; margin-block-start: 0.375rem; }\n.help-text:empty { display: none; }\n.error-text { display: none; margin-block-start: 0.375rem; color: var(--_neu-danger); }\n:host(:state(user-invalid)) slot[name='help-text'] { display: none; }\n:host(:state(user-invalid)) .error-text:not(:empty) { display: block; }\n\n.prefix, .suffix { display: inline-flex; }\n::slotted([slot='prefix']) { margin-inline-end: 0.5rem; }\n::slotted([slot='suffix']) { margin-inline-start: 0.5rem; }\n";
|
|
@@ -1,39 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export const textFieldStyles = `${
|
|
3
|
-
:host { display: block; }
|
|
4
|
-
:host(:disabled), :host([disabled]) { cursor: not-allowed; }
|
|
5
|
-
.base { display: flex; flex-direction: column; }
|
|
6
|
-
.label-text, ::slotted([slot='label']) {
|
|
7
|
-
display: block; margin-block-end: 0.375rem;
|
|
8
|
-
font-size: 0.8125rem; font-weight: 600; color: var(--_neu-fg-muted);
|
|
9
|
-
}
|
|
10
|
-
.label-text:empty { display: none; }
|
|
11
|
-
.control {
|
|
12
|
-
display: flex; align-items: center; min-block-size: 2.75rem; padding-inline: 0.875rem;
|
|
13
|
-
border-radius: var(--_neu-r); background: var(--_neu-bg); box-shadow: var(--_neu-inset);
|
|
14
|
-
transition: box-shadow var(--_neu-dur) ease;
|
|
15
|
-
}
|
|
16
|
-
:host([size='sm']) .control { min-block-size: 2.25rem; padding-inline: 0.75rem; box-shadow: var(--_neu-inset-sm); }
|
|
17
|
-
:host([size='lg']) .control { min-block-size: 3.25rem; padding-inline: 1rem; }
|
|
18
|
-
:host(:focus-within) .control { box-shadow: var(--_neu-inset), var(--_neu-focus); }
|
|
19
|
-
:host(:state(user-invalid)) .control {
|
|
20
|
-
box-shadow:
|
|
21
|
-
inset var(--_neu-d) var(--_neu-d) calc(var(--_neu-d) * 2) color-mix(in oklab, var(--_neu-danger) 35%, var(--_neu-sd)),
|
|
22
|
-
inset calc(var(--_neu-d) * -1) calc(var(--_neu-d) * -1) calc(var(--_neu-d) * 2) var(--_neu-sl);
|
|
23
|
-
}
|
|
24
|
-
:host(:disabled) .control, :host([disabled]) .control { box-shadow: var(--_neu-inset-sm); opacity: 0.6; }
|
|
25
|
-
.input {
|
|
26
|
-
flex: 1; min-inline-size: 0; align-self: stretch; padding: 0; border: none; outline: none;
|
|
27
|
-
background: transparent; color: inherit; font: inherit; font-size: 0.9375rem;
|
|
28
|
-
}
|
|
29
|
-
.input::placeholder { color: var(--_neu-fg-muted); opacity: 1; }
|
|
1
|
+
import { fieldStyles } from '../shared/field.styles.js';
|
|
2
|
+
export const textFieldStyles = `${fieldStyles}
|
|
30
3
|
.prefix, .suffix { display: inline-flex; }
|
|
31
4
|
::slotted([slot='prefix']) { margin-inline-end: 0.5rem; }
|
|
32
5
|
::slotted([slot='suffix']) { margin-inline-start: 0.5rem; }
|
|
33
|
-
.help { font-size: 0.75rem; color: var(--_neu-fg-muted); }
|
|
34
|
-
.help-text, ::slotted([slot='help-text']) { display: block; margin-block-start: 0.375rem; }
|
|
35
|
-
.help-text:empty { display: none; }
|
|
36
|
-
.error-text { display: none; margin-block-start: 0.375rem; color: var(--_neu-danger); }
|
|
37
|
-
:host(:state(user-invalid)) slot[name='help-text'] { display: none; }
|
|
38
|
-
:host(:state(user-invalid)) .error-text:not(:empty) { display: block; }
|
|
39
6
|
`;
|