@fluid-topics/ft-number-field 1.1.19
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 +19 -0
- package/build/ft-number-field.css.d.ts +13 -0
- package/build/ft-number-field.css.js +108 -0
- package/build/ft-number-field.d.ts +24 -0
- package/build/ft-number-field.js +131 -0
- package/build/ft-number-field.light.js +494 -0
- package/build/ft-number-field.min.js +612 -0
- package/build/ft-number-field.properties.d.ts +8 -0
- package/build/ft-number-field.properties.js +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.js +6 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
A number field input component.
|
|
2
|
+
|
|
3
|
+
## Install
|
|
4
|
+
|
|
5
|
+
```shell
|
|
6
|
+
npm install @fluid-topics/ft-number-field
|
|
7
|
+
yarn add @fluid-topics/ft-number-field
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { html } from "lit"
|
|
14
|
+
import "@fluid-topics/ft-number-field"
|
|
15
|
+
|
|
16
|
+
function render() {
|
|
17
|
+
return html` <ft-number-field foo="bar"></ft-number-field> `
|
|
18
|
+
}
|
|
19
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const FtNumberFieldCssVariables: {
|
|
2
|
+
fontSize: import("@fluid-topics/ft-wc-utils").FtCssVariable;
|
|
3
|
+
labelSize: import("@fluid-topics/ft-wc-utils").FtCssVariable;
|
|
4
|
+
verticalSpacing: import("@fluid-topics/ft-wc-utils").FtCssVariable;
|
|
5
|
+
horizontalSpacing: import("@fluid-topics/ft-wc-utils").FtCssVariable;
|
|
6
|
+
colorPrimary: import("@fluid-topics/ft-wc-utils").FtCssVariable;
|
|
7
|
+
colorOnSurface: import("@fluid-topics/ft-wc-utils").FtCssVariable;
|
|
8
|
+
colorOnSurfaceDisabled: import("@fluid-topics/ft-wc-utils").FtCssVariable;
|
|
9
|
+
borderRadiusS: import("@fluid-topics/ft-wc-utils").FtCssVariable;
|
|
10
|
+
colorSurface: import("@fluid-topics/ft-wc-utils").FtCssVariable;
|
|
11
|
+
colorOutline: import("@fluid-topics/ft-wc-utils").FtCssVariable;
|
|
12
|
+
};
|
|
13
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
import { designSystemVariables, FtCssVariableFactory, setVariable } from "@fluid-topics/ft-wc-utils";
|
|
3
|
+
import { FtTypographyBody1CssVariables } from "@fluid-topics/ft-typography/build/ft-typography.css";
|
|
4
|
+
import { FtInputLabelCssVariables } from "@fluid-topics/ft-input-label/build/ft-input-label.css";
|
|
5
|
+
import { FtRippleCssVariables } from "@fluid-topics/ft-ripple/build/ft-ripple.css";
|
|
6
|
+
export const FtNumberFieldCssVariables = {
|
|
7
|
+
fontSize: FtCssVariableFactory.create("--ft-number-field-font-size", "", "SIZE", "14px"),
|
|
8
|
+
labelSize: FtCssVariableFactory.create("--ft-number-field-label-size", "", "SIZE", "11px"),
|
|
9
|
+
verticalSpacing: FtCssVariableFactory.create("--ft-number-field-vertical-spacing", "", "SIZE", "4px"),
|
|
10
|
+
horizontalSpacing: FtCssVariableFactory.create("--ft-number-field-horizontal-spacing", "", "SIZE", "16px"),
|
|
11
|
+
colorPrimary: FtCssVariableFactory.external(designSystemVariables.colorPrimary, "Design system"),
|
|
12
|
+
colorOnSurface: FtCssVariableFactory.external(designSystemVariables.colorOnSurface, "Design system"),
|
|
13
|
+
colorOnSurfaceDisabled: FtCssVariableFactory.external(designSystemVariables.colorOnSurfaceDisabled, "Design system"),
|
|
14
|
+
borderRadiusS: FtCssVariableFactory.external(designSystemVariables.borderRadiusS, "Design system"),
|
|
15
|
+
colorSurface: FtCssVariableFactory.external(designSystemVariables.colorSurface, "Design system"),
|
|
16
|
+
colorOutline: FtCssVariableFactory.external(designSystemVariables.colorOutline, "Design system"),
|
|
17
|
+
};
|
|
18
|
+
// language=CSS
|
|
19
|
+
export const styles = css `
|
|
20
|
+
*:focus {
|
|
21
|
+
outline: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.ft-number-field {
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
align-items: stretch;
|
|
28
|
+
position: relative;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
ft-input-label {
|
|
32
|
+
${setVariable(FtInputLabelCssVariables.fontSize, FtNumberFieldCssVariables.fontSize)};
|
|
33
|
+
${setVariable(FtInputLabelCssVariables.raisedFontSize, FtNumberFieldCssVariables.labelSize)};
|
|
34
|
+
${setVariable(FtInputLabelCssVariables.verticalSpacing, FtNumberFieldCssVariables.verticalSpacing)};
|
|
35
|
+
${setVariable(FtInputLabelCssVariables.horizontalSpacing, FtNumberFieldCssVariables.horizontalSpacing)};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.ft-number-field--main-panel {
|
|
39
|
+
position: relative;
|
|
40
|
+
display: flex;
|
|
41
|
+
height: calc(4 * ${FtNumberFieldCssVariables.verticalSpacing} + ${FtNumberFieldCssVariables.labelSize} + ${FtNumberFieldCssVariables.fontSize});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.ft-number-field--input-panel {
|
|
45
|
+
flex-grow: 1;
|
|
46
|
+
position: relative;
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
overflow: hidden;
|
|
50
|
+
padding: 0 ${FtNumberFieldCssVariables.horizontalSpacing};
|
|
51
|
+
|
|
52
|
+
${setVariable(FtTypographyBody1CssVariables.fontSize, FtNumberFieldCssVariables.fontSize)};
|
|
53
|
+
${setVariable(FtTypographyBody1CssVariables.lineHeight, FtNumberFieldCssVariables.fontSize)};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.ft-number-field--input-panel ft-ripple {
|
|
57
|
+
${setVariable(FtRippleCssVariables.opacityContentOnSurfaceHover, "0.08")};
|
|
58
|
+
${setVariable(FtRippleCssVariables.opacityContentOnSurfacePressed, "0.04")};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.ft-number-field--filled.ft-number-field--with-label .ft-number-field--input-panel {
|
|
62
|
+
align-items: flex-end;
|
|
63
|
+
padding: 0 ${FtNumberFieldCssVariables.horizontalSpacing} ${FtNumberFieldCssVariables.verticalSpacing} ${FtNumberFieldCssVariables.horizontalSpacing};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.ft-number-field--input {
|
|
67
|
+
display: block;
|
|
68
|
+
position: relative;
|
|
69
|
+
flex-grow: 1;
|
|
70
|
+
flex-shrink: 1;
|
|
71
|
+
min-width: 0; /* flex sets this to auto an prevents input from shrinking properly */
|
|
72
|
+
|
|
73
|
+
color: ${FtNumberFieldCssVariables.colorOnSurface};
|
|
74
|
+
padding: calc(2 * ${FtNumberFieldCssVariables.verticalSpacing}) 0;
|
|
75
|
+
border: none;
|
|
76
|
+
background: none;
|
|
77
|
+
|
|
78
|
+
-moz-appearance: textfield;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.ft-number-field--filled.ft-number-field--with-label .ft-number-field--input {
|
|
82
|
+
padding-bottom: 0;
|
|
83
|
+
padding-top: calc(${FtNumberFieldCssVariables.labelSize} + 2 * ${FtNumberFieldCssVariables.verticalSpacing});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.ft-number-field--disabled .ft-number-field--input {
|
|
87
|
+
color: ${FtNumberFieldCssVariables.colorOnSurfaceDisabled};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.ft-number-field:not(.ft-number-field--disabled):focus-within ft-input-label {
|
|
91
|
+
${setVariable(FtInputLabelCssVariables.borderColor, FtNumberFieldCssVariables.colorPrimary)};
|
|
92
|
+
${setVariable(FtInputLabelCssVariables.textColor, FtNumberFieldCssVariables.colorPrimary)};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.ft-number-field--filled .ft-number-field--input-panel {
|
|
96
|
+
border-radius: ${FtNumberFieldCssVariables.borderRadiusS} ${FtNumberFieldCssVariables.borderRadiusS} 0 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.ft-number-field--outlined .ft-number-field--input-panel {
|
|
100
|
+
border-radius: ${FtNumberFieldCssVariables.borderRadiusS};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
input::-webkit-outer-spin-button,
|
|
104
|
+
input::-webkit-inner-spin-button {
|
|
105
|
+
-webkit-appearance: none;
|
|
106
|
+
margin: 0;
|
|
107
|
+
}
|
|
108
|
+
`;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { PropertyValues } from "lit";
|
|
2
|
+
import { ElementDefinitionsMap, FtLitElement } from "@fluid-topics/ft-wc-utils";
|
|
3
|
+
import { FtNumberFieldProperties } from "./ft-number-field.properties";
|
|
4
|
+
export declare class FtNumberField extends FtLitElement implements FtNumberFieldProperties {
|
|
5
|
+
static elementDefinitions: ElementDefinitionsMap;
|
|
6
|
+
static styles: import("lit").CSSResult;
|
|
7
|
+
label?: string;
|
|
8
|
+
value?: number;
|
|
9
|
+
outlined: boolean;
|
|
10
|
+
disabled: boolean;
|
|
11
|
+
min?: number;
|
|
12
|
+
max?: number;
|
|
13
|
+
focused: boolean;
|
|
14
|
+
input?: HTMLInputElement;
|
|
15
|
+
mainPanel?: HTMLElement;
|
|
16
|
+
protected render(): import("lit").TemplateResult<1>;
|
|
17
|
+
protected update(changedProperties: PropertyValues): void;
|
|
18
|
+
lowerBound(value: number): number;
|
|
19
|
+
upperBound(value: number): number;
|
|
20
|
+
private onChange;
|
|
21
|
+
private setValue;
|
|
22
|
+
private onFocus;
|
|
23
|
+
private onMainPanelBlur;
|
|
24
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, nothing } from "lit";
|
|
8
|
+
import { FtLitElement, optionalNumberProperty } from "@fluid-topics/ft-wc-utils";
|
|
9
|
+
import { styles } from "./ft-number-field.css";
|
|
10
|
+
import { property, query, state } from "lit/decorators.js";
|
|
11
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
12
|
+
import { FtInputLabel } from "@fluid-topics/ft-input-label";
|
|
13
|
+
import { FtRipple } from "@fluid-topics/ft-ripple";
|
|
14
|
+
import { FtTypography } from "@fluid-topics/ft-typography";
|
|
15
|
+
class FtNumberField extends FtLitElement {
|
|
16
|
+
constructor() {
|
|
17
|
+
super(...arguments);
|
|
18
|
+
this.outlined = false;
|
|
19
|
+
this.disabled = false;
|
|
20
|
+
this.focused = false;
|
|
21
|
+
}
|
|
22
|
+
render() {
|
|
23
|
+
const classes = {
|
|
24
|
+
"ft-number-field": true,
|
|
25
|
+
"ft-number-field--filled": !this.outlined,
|
|
26
|
+
"ft-number-field--outlined": this.outlined,
|
|
27
|
+
"ft-number-field--disabled": this.disabled,
|
|
28
|
+
"ft-number-field--has-value": this.value != null,
|
|
29
|
+
"ft-number-field--with-label": !!this.label,
|
|
30
|
+
};
|
|
31
|
+
return html `
|
|
32
|
+
<div class="${classMap(classes)}">
|
|
33
|
+
<div class="ft-number-field--main-panel"
|
|
34
|
+
@focusout=${this.onMainPanelBlur}>
|
|
35
|
+
<ft-input-label text="${this.label}"
|
|
36
|
+
?disabled=${this.disabled}
|
|
37
|
+
?outlined=${this.outlined}
|
|
38
|
+
?raised=${this.focused || this.value != null}>
|
|
39
|
+
</ft-input-label>
|
|
40
|
+
<div class="ft-number-field--input-panel">
|
|
41
|
+
${this.outlined ? nothing : html `
|
|
42
|
+
<ft-ripple ?disabled=${this.disabled} activated></ft-ripple>
|
|
43
|
+
`}
|
|
44
|
+
<input type="number"
|
|
45
|
+
.min=${this.min}
|
|
46
|
+
.max=${this.max}
|
|
47
|
+
aria-label="${this.label}"
|
|
48
|
+
class="ft-typography--body1 ft-number-field--input"
|
|
49
|
+
part="input"
|
|
50
|
+
?disabled=${this.disabled}
|
|
51
|
+
.value=${this.value}
|
|
52
|
+
@change=${this.onChange}
|
|
53
|
+
@focus=${this.onFocus}
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
update(changedProperties) {
|
|
61
|
+
super.update(changedProperties);
|
|
62
|
+
if (changedProperties.has("max") || changedProperties.has("min")) {
|
|
63
|
+
this.setValue(this.value);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
lowerBound(value) {
|
|
67
|
+
return this.min != undefined ? Math.max(this.min, value) : value;
|
|
68
|
+
}
|
|
69
|
+
upperBound(value) {
|
|
70
|
+
return this.max != undefined ? Math.min(this.max, value) : value;
|
|
71
|
+
}
|
|
72
|
+
onChange(event) {
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
event.stopPropagation();
|
|
75
|
+
this.setValue(+event.target.value);
|
|
76
|
+
}
|
|
77
|
+
setValue(value) {
|
|
78
|
+
let oldValue = this.value;
|
|
79
|
+
this.value = value;
|
|
80
|
+
let boundedValue = this.value == undefined ? undefined : this.lowerBound(this.upperBound(this.value));
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
this.value = boundedValue;
|
|
83
|
+
if (oldValue !== boundedValue) {
|
|
84
|
+
this.dispatchEvent(new CustomEvent("change", { detail: this.value }));
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
onFocus() {
|
|
89
|
+
this.focused = true;
|
|
90
|
+
}
|
|
91
|
+
onMainPanelBlur() {
|
|
92
|
+
var _a;
|
|
93
|
+
if (!((_a = this.mainPanel) === null || _a === void 0 ? void 0 : _a.matches(":focus-within"))) {
|
|
94
|
+
this.focused = false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
FtNumberField.elementDefinitions = {
|
|
99
|
+
"ft-input-label": FtInputLabel,
|
|
100
|
+
"ft-ripple": FtRipple,
|
|
101
|
+
"ft-typography": FtTypography,
|
|
102
|
+
};
|
|
103
|
+
FtNumberField.styles = styles;
|
|
104
|
+
__decorate([
|
|
105
|
+
property()
|
|
106
|
+
], FtNumberField.prototype, "label", void 0);
|
|
107
|
+
__decorate([
|
|
108
|
+
optionalNumberProperty()
|
|
109
|
+
], FtNumberField.prototype, "value", void 0);
|
|
110
|
+
__decorate([
|
|
111
|
+
property({ type: Boolean })
|
|
112
|
+
], FtNumberField.prototype, "outlined", void 0);
|
|
113
|
+
__decorate([
|
|
114
|
+
property({ type: Boolean })
|
|
115
|
+
], FtNumberField.prototype, "disabled", void 0);
|
|
116
|
+
__decorate([
|
|
117
|
+
optionalNumberProperty()
|
|
118
|
+
], FtNumberField.prototype, "min", void 0);
|
|
119
|
+
__decorate([
|
|
120
|
+
optionalNumberProperty()
|
|
121
|
+
], FtNumberField.prototype, "max", void 0);
|
|
122
|
+
__decorate([
|
|
123
|
+
state()
|
|
124
|
+
], FtNumberField.prototype, "focused", void 0);
|
|
125
|
+
__decorate([
|
|
126
|
+
query(".ft-number-field--input")
|
|
127
|
+
], FtNumberField.prototype, "input", void 0);
|
|
128
|
+
__decorate([
|
|
129
|
+
query(".ft-number-field--main-panel")
|
|
130
|
+
], FtNumberField.prototype, "mainPanel", void 0);
|
|
131
|
+
export { FtNumberField };
|