@inglorious/web 2.6.1 → 3.0.1
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 +21 -15
- package/package.json +27 -4
- package/src/{form.js → form/index.js} +6 -6
- package/src/index.js +1 -6
- package/src/{list.js → list/index.js} +2 -2
- package/src/{router.js → router/index.js} +15 -3
- package/src/select/index.js +7 -0
- package/src/table/filters.js +5 -5
- package/src/table/index.js +7 -0
- package/src/table/rendering.js +2 -2
- package/src/table/theme.css +83 -83
- package/src/form.test.js +0 -372
- package/src/list.test.js +0 -228
- package/src/router.test.js +0 -208
- package/src/select.js +0 -7
- package/src/select.test.js +0 -415
- package/src/table.js +0 -7
- package/src/table.test.js +0 -393
package/README.md
CHANGED
|
@@ -371,7 +371,8 @@ To enable the router, add it to your store's types and create a `router` entity.
|
|
|
371
371
|
|
|
372
372
|
```javascript
|
|
373
373
|
// store.js
|
|
374
|
-
import { createStore, html
|
|
374
|
+
import { createStore, html } from "@inglorious/web"
|
|
375
|
+
import { router } from "@inglorious/web/router"
|
|
375
376
|
|
|
376
377
|
const types = {
|
|
377
378
|
// 1. Add the router type to your store's types
|
|
@@ -520,7 +521,8 @@ export const requireAuth = (type) => ({
|
|
|
520
521
|
|
|
521
522
|
```javascript
|
|
522
523
|
// store.js
|
|
523
|
-
import { createStore
|
|
524
|
+
import { createStore } from "@inglorious/web"
|
|
525
|
+
import { router } from "@inglorious/web/router"
|
|
524
526
|
import { requireAuth } from "./guards/require-auth.js"
|
|
525
527
|
import { adminPage } from "./pages/admin.js"
|
|
526
528
|
import { loginPage } from "./pages/login.js"
|
|
@@ -646,7 +648,7 @@ To use it, import the `table` type and its CSS, then create an entity for your t
|
|
|
646
648
|
|
|
647
649
|
```javascript
|
|
648
650
|
// In your entity definition file
|
|
649
|
-
import { table } from "@inglorious/web"
|
|
651
|
+
import { table } from "@inglorious/web/table"
|
|
650
652
|
|
|
651
653
|
// Import base styles and a theme. You can create your own theme.
|
|
652
654
|
import "@inglorious/web/table/base.css"
|
|
@@ -673,7 +675,7 @@ You can customize how data is rendered in the table cells by overriding the `ren
|
|
|
673
675
|
The example below from `examples/apps/web-table/src/product-table/product-table.js` shows how to format values based on a `formatter` property in the column definition.
|
|
674
676
|
|
|
675
677
|
```javascript
|
|
676
|
-
import { table } from "@inglorious/web"
|
|
678
|
+
import { table } from "@inglorious/web/table"
|
|
677
679
|
import { format } from "date-fns"
|
|
678
680
|
|
|
679
681
|
const formatters = {
|
|
@@ -705,7 +707,8 @@ The table comes with a base stylesheet (`@inglorious/web/table/base.css`) and a
|
|
|
705
707
|
Import the `select` type and its CSS, then create an entity.
|
|
706
708
|
|
|
707
709
|
```javascript
|
|
708
|
-
import { createStore
|
|
710
|
+
import { createStore } from "@inglorious/web"
|
|
711
|
+
import { select } from "@inglorious/web/select"
|
|
709
712
|
// Import base styles and theme
|
|
710
713
|
import "@inglorious/web/select/base.css"
|
|
711
714
|
import "@inglorious/web/select/theme.css"
|
|
@@ -765,7 +768,8 @@ It listens to internal events like `#<id>:toggle`, `#<id>:optionSelect`, etc. Yo
|
|
|
765
768
|
Include `form` in your `types` and create an entity for the form (use any id you like — `form` is used below for clarity):
|
|
766
769
|
|
|
767
770
|
```javascript
|
|
768
|
-
import { createStore
|
|
771
|
+
import { createStore } from "@inglorious/web"
|
|
772
|
+
import { form } from "@inglorious/web/form"
|
|
769
773
|
|
|
770
774
|
const types = { form }
|
|
771
775
|
|
|
@@ -866,7 +870,8 @@ It also expects the item type to export `renderItem(item, index, api)` so each v
|
|
|
866
870
|
Minimal example showing how to extend the `list` type to create a domain-specific list (e.g. `productList`) and provide a `renderItem(item, index, api)` helper.
|
|
867
871
|
|
|
868
872
|
```javascript
|
|
869
|
-
import { createStore, html
|
|
873
|
+
import { createStore, html } from "@inglorious/web"
|
|
874
|
+
import { list } from "@inglorious/web/list"
|
|
870
875
|
|
|
871
876
|
// Extend the built-in list type to render product items
|
|
872
877
|
const productList = {
|
|
@@ -952,18 +957,19 @@ import {
|
|
|
952
957
|
styleMap,
|
|
953
958
|
unsafeHTML,
|
|
954
959
|
when,
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
// form stuff
|
|
960
|
+
} from "@inglorious/web"
|
|
961
|
+
|
|
962
|
+
// Subpath imports for tree-shaking
|
|
963
|
+
import {
|
|
960
964
|
form,
|
|
961
965
|
getFieldError,
|
|
962
966
|
getFieldValue,
|
|
963
967
|
isFieldTouched,
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
} from "@inglorious/web"
|
|
968
|
+
} from "@inglorious/web/form"
|
|
969
|
+
import { list } from "@inglorious/web/list"
|
|
970
|
+
import { router } from "@inglorious/web/router"
|
|
971
|
+
import { select } from "@inglorious/web/select"
|
|
972
|
+
import { table } from "@inglorious/web/table"
|
|
967
973
|
```
|
|
968
974
|
|
|
969
975
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/web",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "A new web framework that leverages the power of the Inglorious Store combined with the performance and simplicity of lit-html.",
|
|
5
5
|
"author": "IceOnFire <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,6 +26,26 @@
|
|
|
26
26
|
"types": "./types/index.d.ts",
|
|
27
27
|
"import": "./src/index.js"
|
|
28
28
|
},
|
|
29
|
+
"./form": {
|
|
30
|
+
"types": "./types/form.d.ts",
|
|
31
|
+
"import": "./src/form/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./list": {
|
|
34
|
+
"types": "./types/list.d.ts",
|
|
35
|
+
"import": "./src/list/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./router": {
|
|
38
|
+
"types": "./types/router.d.ts",
|
|
39
|
+
"import": "./src/router/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./select": {
|
|
42
|
+
"types": "./types/select.d.ts",
|
|
43
|
+
"import": "./src/select/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./table": {
|
|
46
|
+
"types": "./types/table.d.ts",
|
|
47
|
+
"import": "./src/table/index.js"
|
|
48
|
+
},
|
|
29
49
|
"./table/base.css": "./src/table/base.css",
|
|
30
50
|
"./table/theme.css": "./src/table/theme.css",
|
|
31
51
|
"./select/base.css": "./src/select/base.css",
|
|
@@ -33,19 +53,22 @@
|
|
|
33
53
|
},
|
|
34
54
|
"files": [
|
|
35
55
|
"src",
|
|
56
|
+
"!src/**/*.test.js",
|
|
36
57
|
"types"
|
|
37
58
|
],
|
|
38
59
|
"publishConfig": {
|
|
39
60
|
"access": "public"
|
|
40
61
|
},
|
|
62
|
+
"sideEffects": [
|
|
63
|
+
"**/*.css"
|
|
64
|
+
],
|
|
41
65
|
"dependencies": {
|
|
42
66
|
"lit-html": "^3.3.1",
|
|
43
|
-
"@inglorious/store": "8.0.
|
|
44
|
-
"@inglorious/utils": "3.7.
|
|
67
|
+
"@inglorious/store": "8.0.1",
|
|
68
|
+
"@inglorious/utils": "3.7.1"
|
|
45
69
|
},
|
|
46
70
|
"devDependencies": {
|
|
47
71
|
"prettier": "^3.6.2",
|
|
48
|
-
"vite": "^7.1.3",
|
|
49
72
|
"vitest": "^4.0.15",
|
|
50
73
|
"@inglorious/eslint-config": "1.1.1"
|
|
51
74
|
},
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { clone, get, set } from "@inglorious/utils/data-structures/object.js"
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @typedef {import('
|
|
5
|
-
* @typedef {import('
|
|
6
|
-
* @typedef {import('
|
|
4
|
+
* @typedef {import('../../types/form.js').FormEntity} FormEntity
|
|
5
|
+
* @typedef {import('../../types/form.js').FormFieldChangePayload} FormFieldChangePayload
|
|
6
|
+
* @typedef {import('../../types/form.js').FormFieldBlurPayload} FormFieldBlurPayload
|
|
7
7
|
*
|
|
8
8
|
* @typedef {object} FormValidatePayload
|
|
9
9
|
* @property {string|number} entityId - The ID of the target form entity.
|
|
10
|
-
* @property {(values: object) => import('
|
|
10
|
+
* @property {(values: object) => import('../../types/form.js').FormErrors<object>} validate - A function that validates the entire form's values and returns a complete error object.
|
|
11
11
|
*
|
|
12
12
|
* @typedef {object} FormValidateAsyncPayload
|
|
13
13
|
* @property {string|number} entityId - The ID of the target form entity.
|
|
14
|
-
* @property {(values: object) => Promise<import('
|
|
14
|
+
* @property {(values: object) => Promise<import('../../types/form.js').FormErrors<object>>} validate - An async function that validates the entire form's values.
|
|
15
15
|
*
|
|
16
16
|
* @typedef {object} FormValidationCompletePayload
|
|
17
17
|
* @property {string|number} entityId - The ID of the target form entity.
|
|
18
|
-
* @property {import('
|
|
18
|
+
* @property {import('../../types/form.js').FormErrors<object>} errors - The validation errors.
|
|
19
19
|
* @property {boolean} isValid - Whether the form is valid.
|
|
20
20
|
*
|
|
21
21
|
* @typedef {object} FormValidationErrorPayload
|
package/src/index.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
export { form, getFieldError, getFieldValue, isFieldTouched } from "./form.js"
|
|
2
|
-
export { list } from "./list.js"
|
|
3
1
|
export { mount } from "./mount.js"
|
|
4
|
-
export { router } from "./router.js"
|
|
5
|
-
export { select } from "./select.js"
|
|
6
|
-
export { table } from "./table.js"
|
|
7
2
|
export { createStore } from "@inglorious/store"
|
|
8
3
|
export { createDevtools } from "@inglorious/store/client/devtools.js"
|
|
9
4
|
export { createSelector } from "@inglorious/store/select.js"
|
|
10
|
-
export { trigger } from "@inglorious/store/test"
|
|
5
|
+
export { trigger } from "@inglorious/store/test.js"
|
|
11
6
|
export { html, render, svg } from "lit-html"
|
|
12
7
|
export { choose } from "lit-html/directives/choose.js"
|
|
13
8
|
export { classMap } from "lit-html/directives/class-map.js"
|
|
@@ -6,8 +6,8 @@ const LIST_START = 0
|
|
|
6
6
|
const PRETTY_INDEX = 1
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* @typedef {import('
|
|
10
|
-
* @typedef {import('
|
|
9
|
+
* @typedef {import('../../types/list').ListEntity} ListEntity
|
|
10
|
+
* @typedef {import('../../types/mount').Api} Api
|
|
11
11
|
* @typedef {import('lit-html').TemplateResult} TemplateResult
|
|
12
12
|
*/
|
|
13
13
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import("
|
|
3
|
-
* @typedef {import("
|
|
4
|
-
* @typedef {import("
|
|
2
|
+
* @typedef {import("../../types/router").RouterType} RouterType
|
|
3
|
+
* @typedef {import("../../types/router").RouterEntity} RouterEntity
|
|
4
|
+
* @typedef {import("../../types/router").Api} Api
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const SKIP_FULL_MATCH_GROUP = 1 // .match() result at index 0 is the full string
|
|
@@ -83,6 +83,18 @@ export const router = {
|
|
|
83
83
|
})
|
|
84
84
|
},
|
|
85
85
|
|
|
86
|
+
create(entity) {
|
|
87
|
+
entity.routes ??= {}
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
routeAdd(entity, route) {
|
|
91
|
+
entity.routes[route.path] = route.entityType
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
routeRemove(entity, path) {
|
|
95
|
+
delete [entity.routes[path]]
|
|
96
|
+
},
|
|
97
|
+
|
|
86
98
|
/**
|
|
87
99
|
* Handles navigation to a new route.
|
|
88
100
|
* @param {RouterEntity} entity - The router entity.
|
package/src/table/filters.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { choose, html } from "@inglorious/web"
|
|
2
2
|
|
|
3
|
-
import { dateFilter } from "./filters/date"
|
|
4
|
-
import { numberFilter } from "./filters/number"
|
|
5
|
-
import { rangeFilter } from "./filters/range"
|
|
6
|
-
import { selectFilter } from "./filters/select"
|
|
7
|
-
import { textFilter } from "./filters/text"
|
|
3
|
+
import { dateFilter } from "./filters/date.js"
|
|
4
|
+
import { numberFilter } from "./filters/number.js"
|
|
5
|
+
import { rangeFilter } from "./filters/range.js"
|
|
6
|
+
import { selectFilter } from "./filters/select.js"
|
|
7
|
+
import { textFilter } from "./filters/text.js"
|
|
8
8
|
|
|
9
9
|
export const filters = {
|
|
10
10
|
render(entity, column, api) {
|
package/src/table/rendering.js
CHANGED
|
@@ -2,8 +2,8 @@ import { html } from "lit-html"
|
|
|
2
2
|
import { classMap } from "lit-html/directives/class-map.js"
|
|
3
3
|
import { ref } from "lit-html/directives/ref.js"
|
|
4
4
|
|
|
5
|
-
import { filters } from "./filters"
|
|
6
|
-
import { getPaginationInfo, getRows, getSortDirection } from "./logic"
|
|
5
|
+
import { filters } from "./filters.js"
|
|
6
|
+
import { getPaginationInfo, getRows, getSortDirection } from "./logic.js"
|
|
7
7
|
|
|
8
8
|
const DIVISOR = 2
|
|
9
9
|
const FIRST_PAGE = 0
|
package/src/table/theme.css
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
.iw-table {
|
|
2
|
-
.iw-table-header {
|
|
3
|
-
border-bottom: 1px solid grey;
|
|
4
|
-
padding: 1em 0;
|
|
5
|
-
row-gap: 1em;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.iw-table-header-row {
|
|
9
|
-
align-items: flex-start;
|
|
10
|
-
column-gap: 1em;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.iw-table-header-column {
|
|
14
|
-
row-gap: 0.5em;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.iw-table-header-title {
|
|
18
|
-
font-weight: bold;
|
|
19
|
-
white-space: nowrap;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.iw-table-body {
|
|
23
|
-
max-height: 35em;
|
|
24
|
-
overflow: auto;
|
|
25
|
-
border-bottom: 1px solid grey;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.iw-table-row {
|
|
29
|
-
align-items: center;
|
|
30
|
-
column-gap: 1em;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.iw-table-row-even {
|
|
34
|
-
background-color: aliceblue;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.iw-table-row-selected {
|
|
38
|
-
border-left: 1px solid cornflowerblue;
|
|
39
|
-
border-right: 1px solid cornflowerblue;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
:not(.iw-table-row-selected) + .iw-table-row-selected {
|
|
43
|
-
border-top: 1px solid cornflowerblue;
|
|
44
|
-
margin-top: -1px;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.iw-table-row-selected + :not(.iw-table-row-selected) {
|
|
48
|
-
border-top: 1px solid cornflowerblue;
|
|
49
|
-
margin-top: -1px;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.iw-table-cell {
|
|
53
|
-
padding: 1em;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.iw-table-cell-number,
|
|
57
|
-
.iw-table-cell-date {
|
|
58
|
-
text-align: right;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.iw-table-cell-boolean {
|
|
62
|
-
text-align: center;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.iw-table-footer {
|
|
66
|
-
padding: 1em 0;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.iw-table-footer-row {
|
|
70
|
-
justify-content: space-between;
|
|
71
|
-
align-items: center;
|
|
72
|
-
column-gap: 1em;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.iw-table-page-input {
|
|
76
|
-
min-width: 4em;
|
|
77
|
-
text-align: right;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.iw-table-pagination-button {
|
|
81
|
-
white-space: nowrap;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
1
|
+
.iw-table {
|
|
2
|
+
.iw-table-header {
|
|
3
|
+
border-bottom: 1px solid grey;
|
|
4
|
+
padding: 1em 0;
|
|
5
|
+
row-gap: 1em;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.iw-table-header-row {
|
|
9
|
+
align-items: flex-start;
|
|
10
|
+
column-gap: 1em;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.iw-table-header-column {
|
|
14
|
+
row-gap: 0.5em;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.iw-table-header-title {
|
|
18
|
+
font-weight: bold;
|
|
19
|
+
white-space: nowrap;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.iw-table-body {
|
|
23
|
+
max-height: 35em;
|
|
24
|
+
overflow: auto;
|
|
25
|
+
border-bottom: 1px solid grey;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.iw-table-row {
|
|
29
|
+
align-items: center;
|
|
30
|
+
column-gap: 1em;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.iw-table-row-even {
|
|
34
|
+
background-color: aliceblue;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.iw-table-row-selected {
|
|
38
|
+
border-left: 1px solid cornflowerblue;
|
|
39
|
+
border-right: 1px solid cornflowerblue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
:not(.iw-table-row-selected) + .iw-table-row-selected {
|
|
43
|
+
border-top: 1px solid cornflowerblue;
|
|
44
|
+
margin-top: -1px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.iw-table-row-selected + :not(.iw-table-row-selected) {
|
|
48
|
+
border-top: 1px solid cornflowerblue;
|
|
49
|
+
margin-top: -1px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.iw-table-cell {
|
|
53
|
+
padding: 1em;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.iw-table-cell-number,
|
|
57
|
+
.iw-table-cell-date {
|
|
58
|
+
text-align: right;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.iw-table-cell-boolean {
|
|
62
|
+
text-align: center;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.iw-table-footer {
|
|
66
|
+
padding: 1em 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.iw-table-footer-row {
|
|
70
|
+
justify-content: space-between;
|
|
71
|
+
align-items: center;
|
|
72
|
+
column-gap: 1em;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.iw-table-page-input {
|
|
76
|
+
min-width: 4em;
|
|
77
|
+
text-align: right;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.iw-table-pagination-button {
|
|
81
|
+
white-space: nowrap;
|
|
82
|
+
}
|
|
83
|
+
}
|