@inglorious/ui 6.0.0 → 7.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/package.json +32 -12
- package/src/controls/controls.css +3 -1
- package/src/controls/file-upload/file-upload.stories.js +93 -0
- package/src/controls/file-upload/index.js +3 -0
- package/src/controls/file-upload/style.css +99 -0
- package/src/controls/file-upload/template.js +100 -0
- package/src/controls/input/input.stories.js +110 -3
- package/src/controls/textarea/index.js +3 -0
- package/src/controls/textarea/style.css +98 -0
- package/src/controls/textarea/template.js +94 -0
- package/src/controls/textarea/textarea.stories.js +158 -0
- package/src/data-display/before-after/before-after.stories.js +74 -0
- package/src/data-display/before-after/handlers.js +44 -0
- package/src/data-display/before-after/helpers.js +4 -0
- package/src/data-display/before-after/index.js +17 -0
- package/src/data-display/before-after/style.css +128 -0
- package/src/data-display/before-after/template.js +225 -0
- package/src/data-display/carousel/carousel.stories.js +166 -0
- package/src/data-display/carousel/handlers.js +78 -0
- package/src/data-display/carousel/helpers.js +54 -0
- package/src/data-display/carousel/index.js +17 -0
- package/src/data-display/carousel/style.css +233 -0
- package/src/data-display/carousel/template.js +655 -0
- package/src/data-display/data-display.css +2 -0
- package/src/examples/dashboard/app-drawer.js +12 -0
- package/src/examples/dashboard/before-after-data.js +29 -0
- package/src/examples/dashboard/primitive-content.js +220 -33
- package/src/index.js +4 -0
- package/src/layout/flex/flex.stories.js +49 -0
- package/src/layout/flex/style.css +59 -0
- package/src/layout/flex/template.js +2 -0
- package/types/controls/file-upload.d.ts +27 -0
- package/types/controls/input.d.ts +6 -0
- package/types/controls/textarea.d.ts +29 -0
- package/types/controls/upload-field.d.ts +27 -0
- package/types/data-display/before-after.d.ts +39 -0
- package/types/data-display/carousel.d.ts +72 -0
- package/types/index.d.ts +2 -0
- package/types/layout/flex.d.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "A design system for Inglorious Web with render-function components and customizable themes",
|
|
5
5
|
"author": "Matteo Antony Mistretta <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"./themes/inglorious.css": "./src/styles/themes/inglorious.css",
|
|
39
39
|
"./themes/material.css": "./src/styles/themes/material.css",
|
|
40
40
|
"./themes/bootstrap.css": "./src/styles/themes/bootstrap.css",
|
|
41
|
+
"./before-after": {
|
|
42
|
+
"types": "./types/data-display/before-after.d.ts",
|
|
43
|
+
"import": "./src/data-display/before-after/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./before-after.css": "./src/data-display/before-after/style.css",
|
|
41
46
|
"./button": {
|
|
42
47
|
"types": "./types/controls/button.d.ts",
|
|
43
48
|
"import": "./src/controls/button/index.js"
|
|
@@ -48,6 +53,11 @@
|
|
|
48
53
|
"import": "./src/controls/button-group/index.js"
|
|
49
54
|
},
|
|
50
55
|
"./button-group.css": "./src/controls/button-group/style.css",
|
|
56
|
+
"./carousel": {
|
|
57
|
+
"types": "./types/data-display/carousel.d.ts",
|
|
58
|
+
"import": "./src/data-display/carousel/index.js"
|
|
59
|
+
},
|
|
60
|
+
"./carousel.css": "./src/data-display/carousel/style.css",
|
|
51
61
|
"./checkbox": {
|
|
52
62
|
"types": "./types/controls/checkbox.d.ts",
|
|
53
63
|
"import": "./src/controls/checkbox/index.js"
|
|
@@ -103,6 +113,16 @@
|
|
|
103
113
|
"import": "./src/controls/switch/index.js"
|
|
104
114
|
},
|
|
105
115
|
"./switch.css": "./src/controls/switch/style.css",
|
|
116
|
+
"./textarea": {
|
|
117
|
+
"types": "./types/controls/textarea.d.ts",
|
|
118
|
+
"import": "./src/controls/textarea/index.js"
|
|
119
|
+
},
|
|
120
|
+
"./textarea.css": "./src/controls/textarea/style.css",
|
|
121
|
+
"./file-upload": {
|
|
122
|
+
"types": "./types/controls/file-upload.d.ts",
|
|
123
|
+
"import": "./src/controls/file-upload/index.js"
|
|
124
|
+
},
|
|
125
|
+
"./file-upload.css": "./src/controls/file-upload/style.css",
|
|
106
126
|
"./card": {
|
|
107
127
|
"types": "./types/surfaces/card.d.ts",
|
|
108
128
|
"import": "./src/surfaces/card/index.js"
|
|
@@ -280,28 +300,28 @@
|
|
|
280
300
|
"**/*.css"
|
|
281
301
|
],
|
|
282
302
|
"peerDependencies": {
|
|
283
|
-
"@inglorious/charts": "
|
|
284
|
-
"@inglorious/
|
|
285
|
-
"@inglorious/web": "6.
|
|
286
|
-
"@inglorious/
|
|
303
|
+
"@inglorious/charts": "10.0.0",
|
|
304
|
+
"@inglorious/store": "11.0.0",
|
|
305
|
+
"@inglorious/web": "6.4.0",
|
|
306
|
+
"@inglorious/utils": "3.8.0"
|
|
287
307
|
},
|
|
288
308
|
"devDependencies": {
|
|
289
309
|
"@fontsource/material-symbols-outlined": "^5.2.36",
|
|
290
310
|
"@fortawesome/fontawesome-free": "^7.2.0",
|
|
291
|
-
"@storybook/addon-docs": "^10.
|
|
292
|
-
"@storybook/web-components-vite": "^10.
|
|
311
|
+
"@storybook/addon-docs": "^10.5.6",
|
|
312
|
+
"@storybook/web-components-vite": "^10.5.6",
|
|
293
313
|
"happy-dom": "^15.11.0",
|
|
294
314
|
"jsdom": "^25.0.0",
|
|
295
315
|
"lucide": "^0.575.0",
|
|
296
316
|
"prettier": "^3.6.2",
|
|
297
|
-
"storybook": "^10.
|
|
317
|
+
"storybook": "^10.5.6",
|
|
298
318
|
"vite": "^7.3.1",
|
|
299
319
|
"vitest": "^4.0.15",
|
|
300
|
-
"@inglorious/
|
|
320
|
+
"@inglorious/eslint-config": "1.1.2",
|
|
321
|
+
"@inglorious/web": "6.4.0",
|
|
301
322
|
"@inglorious/vite-plugin-vue": "1.0.1",
|
|
302
|
-
"@inglorious/
|
|
303
|
-
"@inglorious/
|
|
304
|
-
"@inglorious/eslint-config": "1.1.2"
|
|
323
|
+
"@inglorious/vite-plugin-jsx": "2.0.0",
|
|
324
|
+
"@inglorious/store": "11.0.0"
|
|
305
325
|
},
|
|
306
326
|
"engines": {
|
|
307
327
|
"node": ">= 22"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
@import "./combobox/style.css";
|
|
2
1
|
@import "./button/style.css";
|
|
3
2
|
@import "./button-group/style.css";
|
|
4
3
|
@import "./checkbox/style.css";
|
|
4
|
+
@import "./combobox/style.css";
|
|
5
5
|
@import "./fab/style.css";
|
|
6
6
|
@import "./icon-button/style.css";
|
|
7
7
|
@import "./input/style.css";
|
|
@@ -10,3 +10,5 @@
|
|
|
10
10
|
@import "./select/style.css";
|
|
11
11
|
@import "./slider/style.css";
|
|
12
12
|
@import "./switch/style.css";
|
|
13
|
+
@import "./textarea/style.css";
|
|
14
|
+
@import "./file-upload/style.css";
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createRender } from "../../stories/notifyStory.js"
|
|
2
|
+
import { FileUpload } from "./index.js"
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Controls/FileUpload",
|
|
6
|
+
tags: ["autodocs"],
|
|
7
|
+
render: createRender(FileUpload),
|
|
8
|
+
argTypes: {
|
|
9
|
+
label: {
|
|
10
|
+
control: "text",
|
|
11
|
+
description: "Field label rendered above the upload area.",
|
|
12
|
+
},
|
|
13
|
+
name: {
|
|
14
|
+
control: "text",
|
|
15
|
+
description: "Native HTML file input name attribute.",
|
|
16
|
+
},
|
|
17
|
+
accept: {
|
|
18
|
+
control: "text",
|
|
19
|
+
description: "Accepted file types, such as .pdf,.png,image/*.",
|
|
20
|
+
},
|
|
21
|
+
isMultiple: {
|
|
22
|
+
control: "boolean",
|
|
23
|
+
description: "Allows selecting multiple files.",
|
|
24
|
+
},
|
|
25
|
+
hint: {
|
|
26
|
+
control: "text",
|
|
27
|
+
description: "Helper text shown below the field when there is no error.",
|
|
28
|
+
},
|
|
29
|
+
error: {
|
|
30
|
+
control: "text",
|
|
31
|
+
description: "Validation message shown below the field.",
|
|
32
|
+
},
|
|
33
|
+
isDisabled: {
|
|
34
|
+
control: "boolean",
|
|
35
|
+
description: "Disables user input and interaction.",
|
|
36
|
+
},
|
|
37
|
+
isRequired: {
|
|
38
|
+
control: "boolean",
|
|
39
|
+
description: "Marks the field as required.",
|
|
40
|
+
},
|
|
41
|
+
isFullWidth: {
|
|
42
|
+
control: "boolean",
|
|
43
|
+
description: "Expands the upload area width to 100% of its container.",
|
|
44
|
+
},
|
|
45
|
+
selectedFiles: {
|
|
46
|
+
control: "object",
|
|
47
|
+
description: "Current list of selected file names for display.",
|
|
48
|
+
},
|
|
49
|
+
onChange: { action: "onChange" },
|
|
50
|
+
onBlur: { action: "onBlur" },
|
|
51
|
+
onFocus: { action: "onFocus" },
|
|
52
|
+
},
|
|
53
|
+
parameters: {
|
|
54
|
+
docs: {
|
|
55
|
+
description: {
|
|
56
|
+
component:
|
|
57
|
+
"Upload area for files with native input semantics, validation, and a clean drag-and-drop style.",
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const Default = {}
|
|
64
|
+
Default.args = {
|
|
65
|
+
label: "Resume",
|
|
66
|
+
name: "resume",
|
|
67
|
+
accept: ".pdf,.doc,.docx",
|
|
68
|
+
isMultiple: false,
|
|
69
|
+
hint: "Upload your resume in PDF or DOC format.",
|
|
70
|
+
error: "",
|
|
71
|
+
isDisabled: false,
|
|
72
|
+
isRequired: false,
|
|
73
|
+
isFullWidth: false,
|
|
74
|
+
selectedFiles: [],
|
|
75
|
+
title: "Choose file",
|
|
76
|
+
description: "or drag and drop here",
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const Selected = {}
|
|
80
|
+
Selected.args = {
|
|
81
|
+
...Default.args,
|
|
82
|
+
label: "Attachments",
|
|
83
|
+
isMultiple: true,
|
|
84
|
+
selectedFiles: ["brief.pdf", "notes.md"],
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const Error = {}
|
|
88
|
+
Error.args = {
|
|
89
|
+
...Default.args,
|
|
90
|
+
label: "Invoice",
|
|
91
|
+
error: "Only PDF files under 5MB are allowed.",
|
|
92
|
+
selectedFiles: ["invoice.png"],
|
|
93
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
.iw-upload {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: var(--iw-space-1);
|
|
5
|
+
font-family: var(--iw-font-family-sans);
|
|
6
|
+
|
|
7
|
+
&.iw-upload-full-width .iw-upload-field-box {
|
|
8
|
+
width: 100%;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.iw-upload-label {
|
|
12
|
+
font-size: var(--iw-font-size-sm);
|
|
13
|
+
font-weight: var(--iw-font-weight-normal);
|
|
14
|
+
color: var(--iw-color-text);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.iw-upload-required {
|
|
18
|
+
color: var(--iw-color-error);
|
|
19
|
+
margin-left: var(--iw-space-1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.iw-upload-field-box {
|
|
23
|
+
position: relative;
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
min-height: 7rem;
|
|
28
|
+
padding: var(--iw-space-4);
|
|
29
|
+
border: 1px dashed var(--iw-input-border);
|
|
30
|
+
border-radius: var(--iw-input-radius);
|
|
31
|
+
background: var(--iw-input-bg);
|
|
32
|
+
color: var(--iw-color-text);
|
|
33
|
+
transition: all var(--iw-transition-fast);
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
|
|
36
|
+
&:hover:not(:disabled) {
|
|
37
|
+
background: var(--iw-input-bg-hover);
|
|
38
|
+
border-color: var(--iw-input-border-hover);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&:focus-within {
|
|
42
|
+
border-color: var(--iw-input-border-focus);
|
|
43
|
+
box-shadow: var(--iw-input-shadow-focus);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&.iw-upload-field-error {
|
|
47
|
+
border-color: var(--iw-color-error);
|
|
48
|
+
|
|
49
|
+
&:focus-within {
|
|
50
|
+
border-color: var(--iw-color-error);
|
|
51
|
+
box-shadow: 0 0 0 1px var(--iw-color-error);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.iw-upload-input {
|
|
57
|
+
position: absolute;
|
|
58
|
+
inset: 0;
|
|
59
|
+
opacity: 0;
|
|
60
|
+
cursor: pointer;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.iw-upload-content {
|
|
64
|
+
display: flex;
|
|
65
|
+
flex-direction: column;
|
|
66
|
+
align-items: center;
|
|
67
|
+
gap: var(--iw-space-1);
|
|
68
|
+
pointer-events: none;
|
|
69
|
+
text-align: center;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.iw-upload-title {
|
|
73
|
+
font-weight: var(--iw-font-weight-medium);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.iw-upload-description {
|
|
77
|
+
color: var(--iw-color-text-muted);
|
|
78
|
+
font-size: var(--iw-font-size-sm);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.iw-upload-field-summary {
|
|
82
|
+
font-size: var(--iw-font-size-sm);
|
|
83
|
+
color: var(--iw-color-text-muted);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.iw-upload-hint,
|
|
87
|
+
.iw-upload-error-message {
|
|
88
|
+
font-size: var(--iw-font-size-sm);
|
|
89
|
+
line-height: var(--iw-line-height-normal);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.iw-upload-hint {
|
|
93
|
+
color: var(--iw-color-text-muted);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.iw-upload-error-message {
|
|
97
|
+
color: var(--iw-color-error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('../../../types/controls/file-upload').FileUploadProps} FileUploadProps
|
|
3
|
+
* @typedef {import('@inglorious/web').TemplateResult} TemplateResult
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { html } from "@inglorious/web"
|
|
7
|
+
import { classMap } from "@inglorious/web/directives/class-map"
|
|
8
|
+
import { ref } from "@inglorious/web/directives/ref"
|
|
9
|
+
|
|
10
|
+
import { applyElementProps } from "../../shared/applyElementProps.js"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Renders a labeled file upload area with optional summary, hint, and error text.
|
|
14
|
+
* Supports drag-and-drop handling through file input semantics.
|
|
15
|
+
* @param {FileUploadProps} props
|
|
16
|
+
* @returns {TemplateResult}
|
|
17
|
+
*/
|
|
18
|
+
export function render(props) {
|
|
19
|
+
const {
|
|
20
|
+
id,
|
|
21
|
+
name = "",
|
|
22
|
+
label,
|
|
23
|
+
hint,
|
|
24
|
+
error,
|
|
25
|
+
accept,
|
|
26
|
+
isMultiple = false,
|
|
27
|
+
isDisabled = false,
|
|
28
|
+
isRequired = false,
|
|
29
|
+
isFullWidth = false,
|
|
30
|
+
selectedFiles = [],
|
|
31
|
+
title = "Choose files",
|
|
32
|
+
description = "or drag and drop here",
|
|
33
|
+
onChange,
|
|
34
|
+
onBlur,
|
|
35
|
+
onFocus,
|
|
36
|
+
...rest
|
|
37
|
+
} = props
|
|
38
|
+
|
|
39
|
+
const uploadId = id || name || "file-upload"
|
|
40
|
+
|
|
41
|
+
const wrapperClasses = {
|
|
42
|
+
"iw-upload": true,
|
|
43
|
+
"iw-upload-full-width": isFullWidth,
|
|
44
|
+
"iw-upload-disabled": isDisabled,
|
|
45
|
+
"iw-upload-has-error": !!error,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const fieldClasses = {
|
|
49
|
+
"iw-upload-field-box": true,
|
|
50
|
+
"iw-upload-field-error": !!error,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const summaryText =
|
|
54
|
+
selectedFiles.length > 0 ? selectedFiles.join(", ") : "No file selected"
|
|
55
|
+
|
|
56
|
+
return html`
|
|
57
|
+
<div class=${classMap(wrapperClasses)}>
|
|
58
|
+
${label
|
|
59
|
+
? html`
|
|
60
|
+
<label for=${uploadId} class="iw-upload-label">
|
|
61
|
+
${label}
|
|
62
|
+
${isRequired
|
|
63
|
+
? html`<span class="iw-upload-required">*</span>`
|
|
64
|
+
: null}
|
|
65
|
+
</label>
|
|
66
|
+
`
|
|
67
|
+
: null}
|
|
68
|
+
|
|
69
|
+
<div class=${classMap(fieldClasses)}>
|
|
70
|
+
<input
|
|
71
|
+
id=${uploadId}
|
|
72
|
+
name=${name}
|
|
73
|
+
type="file"
|
|
74
|
+
accept=${accept ?? ""}
|
|
75
|
+
?multiple=${isMultiple}
|
|
76
|
+
?disabled=${isDisabled}
|
|
77
|
+
?required=${isRequired}
|
|
78
|
+
class="iw-upload-input"
|
|
79
|
+
@change=${(event) => onChange?.(event.target.files)}
|
|
80
|
+
@blur=${onBlur}
|
|
81
|
+
@focus=${onFocus}
|
|
82
|
+
${ref((element) => applyElementProps(element, rest))}
|
|
83
|
+
/>
|
|
84
|
+
|
|
85
|
+
<div class="iw-upload-content">
|
|
86
|
+
<span class="iw-upload-title">${title}</span>
|
|
87
|
+
<span class="iw-upload-description">${description}</span>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<div class="iw-upload-field-summary">${summaryText}</div>
|
|
92
|
+
|
|
93
|
+
${error
|
|
94
|
+
? html`<span class="iw-upload-error-message">${error}</span>`
|
|
95
|
+
: hint
|
|
96
|
+
? html`<span class="iw-upload-hint">${hint}</span>`
|
|
97
|
+
: null}
|
|
98
|
+
</div>
|
|
99
|
+
`
|
|
100
|
+
}
|
|
@@ -1,12 +1,45 @@
|
|
|
1
|
+
import { html } from "@inglorious/web"
|
|
2
|
+
|
|
1
3
|
import { createRender } from "../../stories/notifyStory.js"
|
|
2
4
|
import { Input } from "."
|
|
3
5
|
|
|
6
|
+
const nativeInputTypes = [
|
|
7
|
+
"text",
|
|
8
|
+
"password",
|
|
9
|
+
"email",
|
|
10
|
+
"number",
|
|
11
|
+
"tel",
|
|
12
|
+
"url",
|
|
13
|
+
"search",
|
|
14
|
+
"date",
|
|
15
|
+
"time",
|
|
16
|
+
"datetime-local",
|
|
17
|
+
"month",
|
|
18
|
+
"week",
|
|
19
|
+
"color",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
const nativeInputDefaults = {
|
|
23
|
+
text: { label: "Text", value: "Hello world" },
|
|
24
|
+
password: { label: "Password", value: "secret123" },
|
|
25
|
+
email: { label: "Email", value: "you@example.com" },
|
|
26
|
+
number: { label: "Number", value: "42" },
|
|
27
|
+
tel: { label: "Phone", value: "+1 555 123 4567" },
|
|
28
|
+
url: { label: "Website", value: "https://example.com" },
|
|
29
|
+
search: { label: "Search", value: "inglorious" },
|
|
30
|
+
date: { label: "Date", value: "2026-08-10" },
|
|
31
|
+
time: { label: "Time", value: "09:30" },
|
|
32
|
+
"datetime-local": { label: "Date and time", value: "2026-08-10T09:30" },
|
|
33
|
+
month: { label: "Month", value: "2026-08" },
|
|
34
|
+
week: { label: "Week", value: "2026-W32" },
|
|
35
|
+
color: { label: "Color", value: "#7c3aed" },
|
|
36
|
+
}
|
|
37
|
+
|
|
4
38
|
export default {
|
|
5
39
|
title: "Controls/Input",
|
|
6
40
|
tags: ["autodocs"],
|
|
7
41
|
render: createRender(Input),
|
|
8
42
|
argTypes: {
|
|
9
|
-
// ...notifyActionArgType,
|
|
10
43
|
label: {
|
|
11
44
|
control: "text",
|
|
12
45
|
description: "Field label rendered above the input.",
|
|
@@ -19,9 +52,9 @@ export default {
|
|
|
19
52
|
control: "text",
|
|
20
53
|
description: "Native HTML input name attribute.",
|
|
21
54
|
},
|
|
22
|
-
|
|
55
|
+
inputType: {
|
|
23
56
|
control: "select",
|
|
24
|
-
options:
|
|
57
|
+
options: nativeInputTypes,
|
|
25
58
|
description: "Native HTML input type.",
|
|
26
59
|
},
|
|
27
60
|
inputmode: {
|
|
@@ -101,6 +134,28 @@ Default.args = {
|
|
|
101
134
|
isFullWidth: false,
|
|
102
135
|
}
|
|
103
136
|
|
|
137
|
+
export const ManagedNativeTypes = {
|
|
138
|
+
render: (args) => html`
|
|
139
|
+
<div style="display: grid; gap: 1rem; max-width: 40rem;">
|
|
140
|
+
${nativeInputTypes.map((inputType) =>
|
|
141
|
+
Input.render({
|
|
142
|
+
...args,
|
|
143
|
+
...nativeInputDefaults[inputType],
|
|
144
|
+
name: `${inputType}-field`,
|
|
145
|
+
label: nativeInputDefaults[inputType].label,
|
|
146
|
+
inputType,
|
|
147
|
+
value: nativeInputDefaults[inputType].value,
|
|
148
|
+
}),
|
|
149
|
+
)}
|
|
150
|
+
</div>
|
|
151
|
+
`,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
ManagedNativeTypes.args = {
|
|
155
|
+
...Default.args,
|
|
156
|
+
label: "Managed native types",
|
|
157
|
+
}
|
|
158
|
+
|
|
104
159
|
export const WithHint = {}
|
|
105
160
|
WithHint.args = {
|
|
106
161
|
...Default.args,
|
|
@@ -179,3 +234,55 @@ Number.args = {
|
|
|
179
234
|
inputmode: "decimal",
|
|
180
235
|
"data-testid": "amount-input",
|
|
181
236
|
}
|
|
237
|
+
|
|
238
|
+
export const Date = {}
|
|
239
|
+
Date.args = {
|
|
240
|
+
...Default.args,
|
|
241
|
+
label: "Date",
|
|
242
|
+
inputType: "date",
|
|
243
|
+
value: "2026-08-10",
|
|
244
|
+
min: "2024-01-01",
|
|
245
|
+
max: "2027-12-31",
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export const Time = {}
|
|
249
|
+
Time.args = {
|
|
250
|
+
...Default.args,
|
|
251
|
+
label: "Time",
|
|
252
|
+
inputType: "time",
|
|
253
|
+
value: "09:30",
|
|
254
|
+
min: "08:00",
|
|
255
|
+
max: "18:00",
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export const DateTimeLocal = {}
|
|
259
|
+
DateTimeLocal.args = {
|
|
260
|
+
...Default.args,
|
|
261
|
+
label: "Date and time",
|
|
262
|
+
inputType: "datetime-local",
|
|
263
|
+
value: "2026-08-10T09:30",
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export const Month = {}
|
|
267
|
+
Month.args = {
|
|
268
|
+
...Default.args,
|
|
269
|
+
label: "Month",
|
|
270
|
+
inputType: "month",
|
|
271
|
+
value: "2026-08",
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export const Week = {}
|
|
275
|
+
Week.args = {
|
|
276
|
+
...Default.args,
|
|
277
|
+
label: "Week",
|
|
278
|
+
inputType: "week",
|
|
279
|
+
value: "2026-W32",
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export const Color = {}
|
|
283
|
+
Color.args = {
|
|
284
|
+
...Default.args,
|
|
285
|
+
label: "Color",
|
|
286
|
+
inputType: "color",
|
|
287
|
+
value: "#7c3aed",
|
|
288
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
.iw-textarea-field {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: var(--iw-space-1);
|
|
5
|
+
font-family: var(--iw-font-family-sans);
|
|
6
|
+
|
|
7
|
+
&.iw-textarea-full-width .iw-textarea {
|
|
8
|
+
width: 100%;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.iw-textarea-label {
|
|
12
|
+
font-size: var(--iw-font-size-sm);
|
|
13
|
+
font-weight: var(--iw-font-weight-normal);
|
|
14
|
+
color: var(--iw-color-text);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.iw-textarea-required {
|
|
18
|
+
color: var(--iw-color-error);
|
|
19
|
+
margin-left: var(--iw-space-1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.iw-textarea {
|
|
23
|
+
min-height: 3rem;
|
|
24
|
+
width: min(100%, 100%);
|
|
25
|
+
resize: none;
|
|
26
|
+
padding: var(--iw-space-2) var(--iw-space-3);
|
|
27
|
+
font-family: inherit;
|
|
28
|
+
font-size: var(--iw-font-size-base);
|
|
29
|
+
line-height: 1.5;
|
|
30
|
+
color: var(--iw-input-text);
|
|
31
|
+
background-color: var(--iw-input-bg);
|
|
32
|
+
border: 1px solid var(--iw-input-border);
|
|
33
|
+
border-radius: var(--iw-input-radius);
|
|
34
|
+
outline: none;
|
|
35
|
+
transition: all var(--iw-transition-fast);
|
|
36
|
+
|
|
37
|
+
&::placeholder {
|
|
38
|
+
color: var(--iw-input-text-placeholder);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&:hover:not(:disabled) {
|
|
42
|
+
background-color: var(--iw-input-bg-hover);
|
|
43
|
+
border-color: var(--iw-input-border-hover);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&:focus:not(:disabled) {
|
|
47
|
+
background-color: var(--iw-input-bg-focus);
|
|
48
|
+
border-color: var(--iw-input-border-focus);
|
|
49
|
+
box-shadow: var(--iw-input-shadow-focus);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&:disabled {
|
|
53
|
+
opacity: 0.5;
|
|
54
|
+
cursor: not-allowed;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&.iw-textarea-auto-size {
|
|
58
|
+
field-sizing: content;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&.iw-textarea-resizable {
|
|
62
|
+
resize: vertical;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
&.iw-textarea-error {
|
|
66
|
+
border-color: var(--iw-color-error);
|
|
67
|
+
|
|
68
|
+
&:focus {
|
|
69
|
+
border-color: var(--iw-color-error);
|
|
70
|
+
box-shadow: 0 0 0 1px var(--iw-color-error);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&.iw-textarea-sm {
|
|
75
|
+
padding: var(--iw-space-1) var(--iw-space-2);
|
|
76
|
+
font-size: var(--iw-font-size-sm);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&.iw-textarea-lg {
|
|
80
|
+
padding: var(--iw-space-3) var(--iw-space-4);
|
|
81
|
+
font-size: var(--iw-font-size-lg);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.iw-textarea-hint,
|
|
86
|
+
.iw-textarea-error-message {
|
|
87
|
+
font-size: var(--iw-font-size-sm);
|
|
88
|
+
line-height: var(--iw-line-height-normal);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.iw-textarea-hint {
|
|
92
|
+
color: var(--iw-color-text-muted);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.iw-textarea-error-message {
|
|
96
|
+
color: var(--iw-color-error);
|
|
97
|
+
}
|
|
98
|
+
}
|