@inglorious/web 4.3.0 → 4.5.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/README.md CHANGED
@@ -95,7 +95,7 @@ This framework is ideal for both small apps and large business UIs.
95
95
 
96
96
  ## When NOT to Use Inglorious Web
97
97
 
98
- - You're frequently mutating thousands of items without virtualization (though our `list` component handles this elegantly)
98
+ - You're frequently mutating thousands of items without virtualization (use [Inglorious UI](https://inglorious.dev/ui))
99
99
  - You need framework-agnostic components for users who might not use Inglorious (use Web Components instead)
100
100
  - Your team is already deeply invested in React/Vue/Angular and migration costs outweigh benefits
101
101
 
@@ -1228,120 +1228,9 @@ The composition pattern keeps your code modular and reusable without introducing
1228
1228
 
1229
1229
  ---
1230
1230
 
1231
- ## Table
1231
+ ## UI Primitives ([Inglorious UI](https://inglorious.dev/ui))
1232
1232
 
1233
- `@inglorious/web` includes a `table` type for displaying data in a tabular format. It's designed to be flexible and customizable.
1234
-
1235
- ### 1. Add the `table` type
1236
-
1237
- To use it, import the `table` type and its CSS, then create an entity for your table. You must define the `data` to be displayed and can optionally provide `columns` definitions.
1238
-
1239
- ```javascript
1240
- // In your entity definition file
1241
- import { table } from "@inglorious/web/table"
1242
-
1243
- // Import base styles and a theme. You can create your own theme.
1244
- import "@inglorious/web/table/base.css"
1245
- import "@inglorious/web/table/theme.css"
1246
-
1247
- export default {
1248
- ...table,
1249
- data: [
1250
- { id: 1, name: "Product A", price: 100 },
1251
- { id: 2, name: "Product B", price: 150 },
1252
- ],
1253
- columns: [
1254
- { id: "id", label: "ID" },
1255
- { id: "name", label: "Product Name" },
1256
- { id: "price", label: "Price" },
1257
- ],
1258
- }
1259
- ```
1260
-
1261
- ### 2. Custom Rendering
1262
-
1263
- You can customize how data is rendered in the table cells by overriding the `renderValue` method. This is useful for formatting values or displaying custom content.
1264
-
1265
- 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.
1266
-
1267
- ```javascript
1268
- import { table } from "@inglorious/web/table"
1269
- import { format } from "date-fns"
1270
-
1271
- const formatters = {
1272
- isAvailable: (val) => (val ? "✔️" : "❌"),
1273
- createdAt: (val) => format(val, "dd/MM/yyyy HH:mm"),
1274
- }
1275
-
1276
- export const productTable = {
1277
- ...table,
1278
-
1279
- renderValue(value, column) {
1280
- return formatters[column.formatter]?.(value) ?? value
1281
- },
1282
- }
1283
- ```
1284
-
1285
- ### 3. Theming
1286
-
1287
- The table comes with a base stylesheet (`@inglorious/web/table/base.css`) and a default theme (`@inglorious/web/table/theme.css`). You can create your own theme by creating a new CSS file and styling the table elements to match your application's design.
1288
-
1289
- ---
1290
-
1291
- ## Select
1292
-
1293
- `@inglorious/web` includes a robust `select` type for handling dropdowns, supporting single/multi-select, filtering, and keyboard navigation.
1294
-
1295
- ### 1. Add the `select` type
1296
-
1297
- Import the `select` type and its CSS, then create an entity.
1298
-
1299
- ```javascript
1300
- import { createStore } from "@inglorious/web"
1301
- import { select } from "@inglorious/web/select"
1302
- // Import base styles and theme
1303
- import "@inglorious/web/select/base.css"
1304
- import "@inglorious/web/select/theme.css"
1305
-
1306
- const types = { select }
1307
-
1308
- const entities = {
1309
- countrySelect: {
1310
- type: "select",
1311
- options: [
1312
- { value: "us", label: "United States" },
1313
- { value: "ca", label: "Canada" },
1314
- { value: "fr", label: "France" },
1315
- ],
1316
- // Configuration
1317
- isMulti: false,
1318
- isSearchable: true,
1319
- placeholder: "Select a country...",
1320
- },
1321
- }
1322
-
1323
- const store = createStore({ types, entities })
1324
- ```
1325
-
1326
- ### 2. Render
1327
-
1328
- Render it like any other entity.
1329
-
1330
- ```javascript
1331
- const renderApp = (api) => {
1332
- return html` <div class="my-form">${api.render("countrySelect")}</div> `
1333
- }
1334
- ```
1335
-
1336
- ### 3. State & Events
1337
-
1338
- The `select` entity maintains its own state:
1339
-
1340
- - `selectedValue`: The current value (single value or array if `isMulti: true`).
1341
- - `isOpen`: Whether the dropdown is open.
1342
- - `searchTerm`: Current search input.
1343
-
1344
- It listens to internal events like `#<id>:toggle`, `#<id>:optionSelect`, etc. You typically don't need to manually dispatch these unless you are building custom controls around it.
1233
+ For ready-made UI primitives (controls, data display, navigation, feedback, layout, surfaces), use the **[Inglorious UI](https://inglorious.dev/ui)** design system. It follows the same entity/type pattern, so you can still override `render()` and `renderItem()` when you need custom behavior.
1345
1234
 
1346
1235
  ---
1347
1236
 
@@ -1425,79 +1314,6 @@ For a complete, working demo and helper components look at `examples/apps/web-fo
1425
1314
 
1426
1315
  ---
1427
1316
 
1428
- ## Virtualized lists
1429
-
1430
- `@inglorious/web` provides a small virtualized `list` type to efficiently render very long lists by only keeping visible items in the DOM. The `list` type is useful when you need to display large datasets without paying the full cost of mounting every element at once.
1431
-
1432
- Key features:
1433
-
1434
- - Renders only the visible slice of items and positions them absolutely inside a scrolling container.
1435
- - Automatically measures the first visible item height when not provided.
1436
- - Efficient scroll handling with simple buffer controls to avoid visual gaps.
1437
-
1438
- ### Typical entity shape
1439
-
1440
- When you add the `list` type to your store the entity can include these properties (the type will provide sensible defaults). Only `items` is required — all other properties are optional:
1441
-
1442
- - `items` (Array) — the dataset to render.
1443
- - `visibleRange` ({ start, end }) — current visible slice indices.
1444
- - `viewportHeight` (number) — height of the scrolling viewport in pixels.
1445
- - `itemHeight` (number | null) — fixed height for each item (when null, the type will measure the first item and use an estimated height).
1446
- - `estimatedHeight` (number) — fallback height used before measurement.
1447
- - `bufferSize` (number) — extra items to render before/after the visible range to reduce flicker during scrolling.
1448
-
1449
- ### Events & methods
1450
-
1451
- The `list` type listens for the following events on the target entity:
1452
-
1453
- - `#<id>:scroll` — payload is the scrolling container; updates `visibleRange` based on scroll position.
1454
- - `#<id>:measureHeight` — payload is the container element; used internally to measure the first item and compute `itemHeight`.
1455
-
1456
- It also expects the item type to export `renderItem(item, index, api)` so each visible item can be rendered using the project's entity-based render approach.
1457
-
1458
- ### Example
1459
-
1460
- 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.
1461
-
1462
- ```javascript
1463
- import { createStore, html } from "@inglorious/web"
1464
- import { list } from "@inglorious/web/list"
1465
-
1466
- // Extend the built-in list type to render product items
1467
- const productList = {
1468
- ...list,
1469
-
1470
- renderItem(item, index) {
1471
- return html`<div class="product">
1472
- ${index}: <strong>${item.name}</strong> — ${item.price}
1473
- </div>`
1474
- },
1475
- }
1476
-
1477
- const types = { list: productList }
1478
-
1479
- const entities = {
1480
- products: {
1481
- type: "list",
1482
- items: Array.from({ length: 10000 }, (_, i) => ({
1483
- name: `Product ${i}`,
1484
- price: `$${i}`,
1485
- })),
1486
- viewportHeight: 400,
1487
- estimatedHeight: 40,
1488
- bufferSize: 5,
1489
- },
1490
- }
1491
-
1492
- const store = createStore({ types, entities })
1493
-
1494
- // Render with api.render(entity.id) as usual — the list will call productList.renderItem for each visible item.
1495
- ```
1496
-
1497
- See `src/list.js` in the package for the implementation details and the `examples/apps/web-list` demo for a complete working example. In the demo the `productList` type extends the `list` type and provides `renderItem(item, index)` to render each visible item — see `examples/apps/web-list/src/product-list/product-list.js`.
1498
-
1499
- ---
1500
-
1501
1317
  ## Building Component Libraries with Inglorious Web
1502
1318
 
1503
1319
  **Inglorious types are uniquely suited for component libraries** because they're fully customizable through JavaScript's spread operator.
@@ -1507,22 +1323,20 @@ See `src/list.js` in the package for the implementation details and the `example
1507
1323
  **Library publishes types:**
1508
1324
 
1509
1325
  ```javascript
1510
- // @acme/design-system/table.js
1511
- export const table = {
1326
+ // @acme/design-system/data-grid.js
1327
+ export const dataGrid = {
1512
1328
  render(entity, api) {
1513
1329
  const type = api.getType(entity.type)
1514
1330
 
1515
1331
  return html`
1516
- <table>
1517
- ${entity.data.map((row) => type.renderRow(entity, row, api))}
1518
- </table>
1332
+ <div class="data-grid">
1333
+ ${entity.rows.map((row) => type.renderRow(entity, row, api))}
1334
+ </div>
1519
1335
  `
1520
1336
  },
1521
1337
 
1522
1338
  renderRow(entity, row, api) {
1523
- return html`<tr>
1524
- ${row.name}
1525
- </tr>`
1339
+ return html`<div class="data-grid-row">${row.name}</div>`
1526
1340
  },
1527
1341
 
1528
1342
  rowClick(entity, row) {
@@ -1534,26 +1348,26 @@ export const table = {
1534
1348
  **Users customize freely:**
1535
1349
 
1536
1350
  ```javascript
1537
- import { table } from "@acme/design-system/table"
1351
+ import { dataGrid } from "@acme/design-system/data-grid"
1538
1352
 
1539
1353
  // Use as-is
1540
- const simpleTable = { ...table }
1354
+ const simpleGrid = { ...dataGrid }
1541
1355
 
1542
1356
  // Override methods
1543
- const customTable = {
1544
- ...table,
1357
+ const customGrid = {
1358
+ ...dataGrid,
1545
1359
  renderRow(entity, row, api) {
1546
- return html`<tr class="custom">
1360
+ return html`<div class="data-grid-row custom">
1547
1361
  ${row.name} - ${row.email}
1548
- </tr>`
1362
+ </div>`
1549
1363
  },
1550
1364
  }
1551
1365
 
1552
1366
  // Compose with behaviors
1553
1367
  import { sortable, exportable } from "@acme/design-system/behaviors"
1554
1368
 
1555
- const advancedTable = [
1556
- table,
1369
+ const advancedGrid = [
1370
+ dataGrid,
1557
1371
  sortable,
1558
1372
  exportable,
1559
1373
  {
@@ -1584,7 +1398,7 @@ Inglorious Web works seamlessly with any Web Component library, such as Shoelace
1584
1398
 
1585
1399
  ### ⚠️ SSG/SSR Considerations
1586
1400
 
1587
- **Inglorious Web's built-in components** (`table`, `list`, `select`, `form`) are fully compatible with [@inglorious/ssx](https://npmjs.com/package/@inglorious/ssx) for static site generation. They render to complete HTML at build time and hydrate seamlessly on the client.
1401
+ **Inglorious Web's built-in form type** and **[Inglorious UI](https://inglorious.dev/ui) primitives** are fully compatible with [@inglorious/ssx](https://npmjs.com/package/@inglorious/ssx) for static site generation. They render to complete HTML at build time and hydrate seamlessly on the client.
1588
1402
 
1589
1403
  **Third-party Web Components** currently have limited SSR/SSG support. Most Web Component libraries (including Shoelace and Material Web Components) require client-side JavaScript to initialize and render, which means:
1590
1404
 
@@ -1598,7 +1412,7 @@ Inglorious Web works seamlessly with any Web Component library, such as Shoelace
1598
1412
  - Use Inglorious Web components for content that needs to be pre-rendered (product listings, blog posts, documentation)
1599
1413
  - Use Web Components for interactive, client-only features (color pickers, rich text editors, admin tools)
1600
1414
 
1601
- **Use Inglorious Web's built-in components when:**
1415
+ **Use Inglorious Web + [Inglorious UI](https://inglorious.dev/ui) primitives when:**
1602
1416
 
1603
1417
  - ✅ You want full architectural consistency
1604
1418
  - ✅ You need fine-grained control over behavior
@@ -1623,19 +1437,11 @@ Inglorious Web works seamlessly with any Web Component library, such as Shoelace
1623
1437
  ### Example: Hybrid Approach
1624
1438
 
1625
1439
  ```javascript
1626
- import { table } from "@inglorious/web/table"
1627
1440
  import "@shoelace-style/shoelace/dist/components/color-picker/color-picker.js"
1628
1441
 
1629
1442
  const types = {
1630
- // Inglorious Web component - full store integration
1631
- productTable: {
1632
- ...table,
1633
- data: products,
1634
- columns: [
1635
- { id: "name", label: "Product Name" },
1636
- { id: "price", label: "Price" },
1637
- ],
1638
- },
1443
+ // App-specific type - full store integration
1444
+ productTable,
1639
1445
 
1640
1446
  // Web Component - for specialized UI
1641
1447
  themeEditor: {
@@ -1788,11 +1594,8 @@ import {
1788
1594
  getFieldValue,
1789
1595
  isFieldTouched,
1790
1596
  } from "@inglorious/web/form"
1791
- import { list } from "@inglorious/web/list"
1792
1597
  import { router } from "@inglorious/web/router"
1793
- import { select } from "@inglorious/web/select"
1794
1598
  import { render, trigger } from "@inglorious/web/test"
1795
- import { table } from "@inglorious/web/table"
1796
1599
  ```
1797
1600
 
1798
1601
  ---
@@ -1825,7 +1628,7 @@ const myType = {
1825
1628
  2. **Avoid creating new objects in render** - Use entity properties, not inline `{}`
1826
1629
  3. **Use `repeat()` directive for lists** - Helps lit-html track item identity
1827
1630
  4. **Profile with browser DevTools** - Look for slow renders (>16ms)
1828
- 5. **Consider virtualization** - Use `list` type for 1000+ items
1631
+ 5. **Consider virtualization** - Use [Inglorious UI](https://inglorious.dev/ui) for 1000+ items
1829
1632
 
1830
1633
  If renders are slow:
1831
1634
 
@@ -1876,8 +1679,6 @@ Check out these demos to see `@inglorious/web` in action:
1876
1679
  - **[Web TodoMVC](https://github.com/IngloriousCoderz/inglorious-forge/tree/main/examples/apps/web-todomvc)** - A client-only TodoMVC implementation, a good starting point for learning the framework.
1877
1680
  - **[Web TodoMVC-CS](https://github.com/IngloriousCoderz/inglorious-forge/tree/main/examples/apps/web-todomvc-cs)** - A client-server version with JSON server, showing async event handlers and API integration with component organization (render/handlers modules).
1878
1681
  - **[Web Form](https://github.com/IngloriousCoderz/inglorious-forge/tree/main/examples/apps/web-form)** - Form handling with validation, arrays, and field helpers.
1879
- - **[Web List](https://github.com/IngloriousCoderz/inglorious-forge/tree/main/examples/apps/web-list)** - Virtualized list with `renderItem` helper for efficient rendering of large datasets.
1880
- - **[Web Table](https://github.com/IngloriousCoderz/inglorious-forge/tree/main/examples/apps/web-table)** - Table component with complex data display patterns.
1881
1682
  - **[Web Router](https://github.com/IngloriousCoderz/inglorious-forge/tree/main/examples/apps/web-router)** - Entity-based client-side routing with hash navigation.
1882
1683
 
1883
1684
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inglorious/web",
3
- "version": "4.3.0",
3
+ "version": "4.5.0",
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",
@@ -30,29 +30,14 @@
30
30
  "types": "./types/form.d.ts",
31
31
  "import": "./src/form/index.js"
32
32
  },
33
- "./list": {
34
- "types": "./types/list.d.ts",
35
- "import": "./src/list/index.js"
36
- },
33
+ "./hydrate": "./src/hydrate.js",
37
34
  "./router": {
38
35
  "types": "./types/router.d.ts",
39
36
  "import": "./src/router/index.js"
40
37
  },
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
- },
49
38
  "./test": {
50
39
  "import": "./src/test.js"
51
- },
52
- "./table/base.css": "./src/table/base.css",
53
- "./table/theme.css": "./src/table/theme.css",
54
- "./select/base.css": "./src/select/base.css",
55
- "./select/theme.css": "./src/select/theme.css"
40
+ }
56
41
  },
57
42
  "files": [
58
43
  "src",
@@ -67,14 +52,9 @@
67
52
  ],
68
53
  "dependencies": {
69
54
  "@lit-labs/ssr-client": "^1.1.8",
70
- "d3-array": "^3.2.4",
71
- "d3-format": "^3.1.0",
72
- "d3-scale": "^4.0.2",
73
- "d3-shape": "^3.2.0",
74
- "d3-time-format": "^4.1.0",
75
55
  "lit-html": "^3.3.1",
76
- "@inglorious/store": "9.6.0",
77
- "@inglorious/utils": "3.7.3"
56
+ "@inglorious/utils": "3.7.3",
57
+ "@inglorious/store": "9.6.0"
78
58
  },
79
59
  "devDependencies": {
80
60
  "prettier": "^3.6.2",