@inglorious/ui 1.0.1 → 2.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.
Files changed (206) hide show
  1. package/package.json +11 -9
  2. package/src/controls/button/button.stories.js +2 -2
  3. package/src/controls/button/index.js +1 -1
  4. package/src/controls/button/template.js +2 -2
  5. package/src/controls/button-group/button-group.stories.js +2 -2
  6. package/src/controls/button-group/index.js +1 -1
  7. package/src/controls/button-group/template.js +4 -4
  8. package/src/controls/checkbox/checkbox.stories.js +2 -2
  9. package/src/controls/checkbox/index.js +1 -1
  10. package/src/controls/checkbox/template.js +2 -2
  11. package/src/controls/combobox/combobox.stories.js +3 -3
  12. package/src/controls/combobox/index.js +2 -2
  13. package/src/controls/combobox/template.js +35 -14
  14. package/src/controls/fab/fab.stories.js +2 -2
  15. package/src/controls/fab/index.js +1 -1
  16. package/src/controls/fab/template.js +4 -4
  17. package/src/controls/icon-button/icon-button.stories.js +2 -2
  18. package/src/controls/icon-button/index.js +1 -1
  19. package/src/controls/icon-button/template.js +4 -4
  20. package/src/controls/input/index.js +1 -1
  21. package/src/controls/input/input.stories.js +2 -2
  22. package/src/controls/input/template.js +2 -2
  23. package/src/controls/radio-group/index.js +1 -1
  24. package/src/controls/radio-group/radio-group.stories.js +2 -2
  25. package/src/controls/radio-group/template.js +2 -2
  26. package/src/controls/rating/index.js +1 -1
  27. package/src/controls/rating/rating.stories.js +2 -2
  28. package/src/controls/rating/template.js +2 -2
  29. package/src/controls/select/index.js +1 -1
  30. package/src/controls/select/select.stories.js +2 -2
  31. package/src/controls/select/template.js +2 -2
  32. package/src/controls/slider/index.js +1 -1
  33. package/src/controls/slider/slider.stories.js +2 -2
  34. package/src/controls/slider/template.js +2 -2
  35. package/src/controls/switch/index.js +1 -1
  36. package/src/controls/switch/switch.stories.js +2 -2
  37. package/src/controls/switch/template.js +2 -2
  38. package/src/data-display/avatar/avatar.stories.js +2 -2
  39. package/src/data-display/avatar/index.js +1 -1
  40. package/src/data-display/avatar/template.js +2 -1
  41. package/src/data-display/badge/badge.stories.js +2 -2
  42. package/src/data-display/badge/index.js +1 -1
  43. package/src/data-display/badge/template.js +7 -0
  44. package/src/data-display/chip/chip.stories.js +2 -2
  45. package/src/data-display/chip/index.js +1 -1
  46. package/src/data-display/chip/template.js +7 -0
  47. package/src/data-display/data-grid/data-grid.stories.js +4 -4
  48. package/src/data-display/data-grid/filters/index.js +10 -10
  49. package/src/data-display/data-grid/filters/input.js +3 -3
  50. package/src/data-display/data-grid/filters/range.js +4 -4
  51. package/src/data-display/data-grid/filters/select.js +3 -3
  52. package/src/data-display/data-grid/index.js +2 -2
  53. package/src/data-display/data-grid/template.js +40 -28
  54. package/src/data-display/divider/divider.stories.js +2 -2
  55. package/src/data-display/divider/index.js +1 -1
  56. package/src/data-display/divider/template.js +7 -0
  57. package/src/data-display/icon/icon-implementations.mdx +4 -4
  58. package/src/data-display/icon/icon-utf8.stories.js +9 -9
  59. package/src/data-display/icon/icon.stories.js +2 -2
  60. package/src/data-display/icon/index.js +1 -1
  61. package/src/data-display/icon/template.js +7 -0
  62. package/src/data-display/list/index.js +2 -2
  63. package/src/data-display/list/list.stories.js +2 -2
  64. package/src/data-display/list/template.js +22 -13
  65. package/src/data-display/material-icon/index.js +1 -1
  66. package/src/data-display/material-icon/material-icon.stories.js +2 -2
  67. package/src/data-display/material-icon/template.js +7 -0
  68. package/src/data-display/table/index.js +1 -1
  69. package/src/data-display/table/table.stories.js +2 -2
  70. package/src/data-display/table/template.js +19 -1
  71. package/src/data-display/tooltip/index.js +1 -1
  72. package/src/data-display/tooltip/template.js +2 -0
  73. package/src/data-display/tooltip/tooltip.stories.js +2 -2
  74. package/src/data-display/typography/index.js +1 -1
  75. package/src/data-display/typography/template.js +2 -0
  76. package/src/data-display/typography/typography.stories.js +2 -2
  77. package/src/data-display/virtual-list/index.js +1 -1
  78. package/src/data-display/virtual-list/template.js +4 -2
  79. package/src/examples/dashboard/app-drawer.js +15 -15
  80. package/src/examples/dashboard/app-header.js +33 -33
  81. package/src/examples/dashboard/dashboard-jsx.jsx +76 -0
  82. package/src/examples/dashboard/dashboard-vue.vue +68 -0
  83. package/src/examples/dashboard/dashboard.js +43 -42
  84. package/src/examples/dashboard/dashboard.stories.js +46 -16
  85. package/src/examples/dashboard/mode.js +1 -1
  86. package/src/examples/dashboard/primitive-content.js +248 -248
  87. package/src/examples/dashboard/primitive-section.js +25 -25
  88. package/src/examples/dashboard/router.js +1 -1
  89. package/src/examples/dashboard/social-card.js +14 -14
  90. package/src/examples/dashboard/stat-card.js +12 -12
  91. package/src/examples/dashboard/theme.js +1 -1
  92. package/src/examples/dashboard/traffic-card.js +22 -22
  93. package/src/examples/dashboard/traffic-sales-card.js +39 -39
  94. package/src/feedback/alert/alert.stories.js +2 -2
  95. package/src/feedback/alert/index.js +2 -2
  96. package/src/feedback/alert/template.js +2 -0
  97. package/src/feedback/backdrop/backdrop.stories.js +2 -2
  98. package/src/feedback/backdrop/index.js +2 -2
  99. package/src/feedback/backdrop/template.js +2 -0
  100. package/src/feedback/dialog/dialog.stories.js +2 -2
  101. package/src/feedback/dialog/index.js +2 -2
  102. package/src/feedback/dialog/template.js +2 -0
  103. package/src/feedback/progress/index.js +1 -1
  104. package/src/feedback/progress/progress.stories.js +2 -2
  105. package/src/feedback/progress/template.js +3 -1
  106. package/src/feedback/skeleton/index.js +2 -2
  107. package/src/feedback/skeleton/skeleton.stories.js +2 -2
  108. package/src/feedback/skeleton/template.js +2 -0
  109. package/src/feedback/snackbar/index.js +2 -2
  110. package/src/feedback/snackbar/snackbar.stories.js +2 -2
  111. package/src/feedback/snackbar/template.js +2 -0
  112. package/src/index.js +45 -45
  113. package/src/layout/container/container.stories.js +3 -3
  114. package/src/layout/container/index.js +1 -1
  115. package/src/layout/container/template.js +2 -0
  116. package/src/layout/flex/flex.stories.js +2 -2
  117. package/src/layout/flex/index.js +1 -1
  118. package/src/layout/flex/template.js +2 -3
  119. package/src/layout/grid/grid.stories.js +2 -2
  120. package/src/layout/grid/index.js +1 -1
  121. package/src/layout/grid/template.js +2 -3
  122. package/src/navigation/bottom-navigation/bottom-navigation.stories.js +2 -2
  123. package/src/navigation/bottom-navigation/index.js +1 -1
  124. package/src/navigation/bottom-navigation/template.js +16 -2
  125. package/src/navigation/breadcrumbs/breadcrumbs.stories.js +2 -2
  126. package/src/navigation/breadcrumbs/index.js +1 -1
  127. package/src/navigation/breadcrumbs/template.js +16 -2
  128. package/src/navigation/drawer/drawer.stories.js +2 -2
  129. package/src/navigation/drawer/index.js +1 -1
  130. package/src/navigation/drawer/template.js +15 -13
  131. package/src/navigation/link/index.js +2 -2
  132. package/src/navigation/link/link.stories.js +2 -2
  133. package/src/navigation/link/template.js +2 -0
  134. package/src/navigation/menu/index.js +1 -1
  135. package/src/navigation/menu/menu.stories.js +2 -2
  136. package/src/navigation/menu/template.js +15 -1
  137. package/src/navigation/pagination/index.js +1 -1
  138. package/src/navigation/pagination/pagination.stories.js +2 -2
  139. package/src/navigation/pagination/template.js +20 -4
  140. package/src/navigation/speed-dial/index.js +1 -1
  141. package/src/navigation/speed-dial/speed-dial.stories.js +2 -2
  142. package/src/navigation/speed-dial/template.js +15 -1
  143. package/src/navigation/stepper/index.js +1 -1
  144. package/src/navigation/stepper/stepper.stories.js +2 -2
  145. package/src/navigation/stepper/template.js +15 -1
  146. package/src/navigation/tabs/index.js +1 -1
  147. package/src/navigation/tabs/tabs.stories.js +2 -2
  148. package/src/navigation/tabs/template.js +17 -1
  149. package/src/surfaces/accordion/accordion.stories.js +2 -2
  150. package/src/surfaces/accordion/index.js +1 -1
  151. package/src/surfaces/accordion/template.js +15 -1
  152. package/src/surfaces/app-bar/app-bar.stories.js +2 -2
  153. package/src/surfaces/app-bar/index.js +1 -1
  154. package/src/surfaces/app-bar/template.js +2 -0
  155. package/src/surfaces/card/card.stories.js +2 -2
  156. package/src/surfaces/card/index.js +1 -1
  157. package/src/surfaces/card/template.js +19 -1
  158. package/src/surfaces/paper/index.js +2 -2
  159. package/src/surfaces/paper/paper.stories.js +3 -3
  160. package/src/surfaces/paper/template.js +2 -0
  161. package/types/controls/button-group.d.ts +1 -1
  162. package/types/controls/button.d.ts +2 -2
  163. package/types/controls/checkbox.d.ts +1 -1
  164. package/types/controls/combobox.d.ts +2 -1
  165. package/types/controls/fab.d.ts +1 -1
  166. package/types/controls/icon-button.d.ts +1 -1
  167. package/types/controls/input.d.ts +1 -1
  168. package/types/controls/radio-group.d.ts +1 -1
  169. package/types/controls/rating.d.ts +1 -1
  170. package/types/controls/select.d.ts +1 -1
  171. package/types/controls/slider.d.ts +1 -1
  172. package/types/controls/switch.d.ts +1 -1
  173. package/types/data-display/avatar.d.ts +1 -1
  174. package/types/data-display/badge.d.ts +1 -1
  175. package/types/data-display/chip.d.ts +1 -1
  176. package/types/data-display/data-grid.d.ts +2 -1
  177. package/types/data-display/divider.d.ts +1 -1
  178. package/types/data-display/icon.d.ts +1 -1
  179. package/types/data-display/list.d.ts +2 -1
  180. package/types/data-display/material-icon.d.ts +1 -1
  181. package/types/data-display/table.d.ts +2 -1
  182. package/types/data-display/tooltip.d.ts +1 -1
  183. package/types/data-display/typography.d.ts +1 -1
  184. package/types/data-display/virtual-list.d.ts +1 -1
  185. package/types/feedback/alert.d.ts +1 -1
  186. package/types/feedback/backdrop.d.ts +1 -1
  187. package/types/feedback/dialog.d.ts +1 -1
  188. package/types/feedback/progress.d.ts +1 -1
  189. package/types/feedback/skeleton.d.ts +1 -1
  190. package/types/feedback/snackbar.d.ts +1 -1
  191. package/types/layout/container.d.ts +1 -1
  192. package/types/layout/flex.d.ts +1 -1
  193. package/types/layout/grid.d.ts +1 -1
  194. package/types/navigation/bottom-navigation.d.ts +2 -1
  195. package/types/navigation/breadcrumbs.d.ts +2 -1
  196. package/types/navigation/drawer.d.ts +1 -1
  197. package/types/navigation/link.d.ts +1 -1
  198. package/types/navigation/menu.d.ts +2 -1
  199. package/types/navigation/pagination.d.ts +2 -1
  200. package/types/navigation/speed-dial.d.ts +2 -1
  201. package/types/navigation/stepper.d.ts +2 -1
  202. package/types/navigation/tabs.d.ts +2 -1
  203. package/types/surfaces/accordion.d.ts +2 -1
  204. package/types/surfaces/app-bar.d.ts +1 -1
  205. package/types/surfaces/card.d.ts +2 -1
  206. package/types/surfaces/paper.d.ts +1 -1
@@ -21,18 +21,30 @@
21
21
 
22
22
  import { classMap, html, ref, repeat, when } from "@inglorious/web"
23
23
 
24
- import { iconButton } from "../../controls/icon-button"
25
- import { flex } from "../../layout/flex"
24
+ import { IconButton } from "../../controls/icon-button"
25
+ import { Flex } from "../../layout/flex"
26
26
  import { applyElementProps } from "../../shared/applyElementProps.js"
27
27
 
28
28
  const PRETTY_INDEX = 1
29
29
 
30
- export const list = {
30
+ export const List = {
31
31
  /**
32
+ * Main entrypoint for the list component. It delegates to the base list renderer so overrides can reuse it.
33
+ * Lists support ordered/unordered modes, nested items, and optional dividers.
32
34
  * @param {ListProps} props
33
35
  * @returns {TemplateResult}
34
36
  */
35
37
  render(props) {
38
+ return this.renderList(props)
39
+ },
40
+
41
+ /**
42
+ * Renders the list container (ordered or unordered) and iterates items.
43
+ * Each item is delegated to `renderItem` for customization.
44
+ * @param {ListProps} props
45
+ * @returns {TemplateResult}
46
+ */
47
+ renderList(props) {
36
48
  const {
37
49
  type, // eslint-disable-line no-unused-vars
38
50
  items = [],
@@ -107,13 +119,10 @@ export const list = {
107
119
  },
108
120
 
109
121
  /**
122
+ * Renders a single list item, including icon, primary/secondary text, and actions.
123
+ * Handles item click/toggle wiring and nested children.
110
124
  * @param {ListProps} props
111
125
  * @param {{
112
- * item: ListItem,
113
- * meta: ListItemMeta,
114
- * index: number,
115
- * path: number[]
116
- * }} payload
117
126
  * @returns {TemplateResult}
118
127
  */
119
128
  renderItem(props, { item, meta, path }) {
@@ -149,7 +158,7 @@ export const list = {
149
158
  .filter(Boolean)
150
159
  .join(" ")
151
160
 
152
- return flex.render({
161
+ return Flex.render({
153
162
  element: "li",
154
163
  padding: "sm",
155
164
  direction: "column",
@@ -161,12 +170,12 @@ export const list = {
161
170
  props.onItemClick?.(raw ?? item, path)
162
171
  },
163
172
  children: [
164
- flex.render({
173
+ Flex.render({
165
174
  align: "center",
166
175
  gap: "sm",
167
176
  children: [
168
177
  when(icon, () =>
169
- iconButton.render({
178
+ IconButton.render({
170
179
  icon,
171
180
  size: "sm",
172
181
  color: "secondary",
@@ -175,7 +184,7 @@ export const list = {
175
184
  className: "iw-list-item-icon",
176
185
  }),
177
186
  ),
178
- flex.render({
187
+ Flex.render({
179
188
  direction: "column",
180
189
  gap: "sm",
181
190
  className: "iw-list-item-content",
@@ -195,7 +204,7 @@ export const list = {
195
204
  () =>
196
205
  html`<span class="iw-list-item-trailing">
197
206
  ${when(hasChildren, () =>
198
- iconButton.render({
207
+ IconButton.render({
199
208
  variant: "ghost",
200
209
  color: "secondary",
201
210
  size: "sm",
@@ -1,3 +1,3 @@
1
1
  import * as renderers from "./template.js"
2
2
 
3
- export const materialIcon = { ...renderers }
3
+ export const MaterialIcon = { ...renderers }
@@ -1,6 +1,6 @@
1
1
  import { html, repeat } from "@inglorious/web"
2
2
 
3
- import { materialIcon } from "."
3
+ import { MaterialIcon } from "."
4
4
 
5
5
  const materialIcons = [
6
6
  "search",
@@ -87,7 +87,7 @@ export const Gallery = {
87
87
  materialIcons,
88
88
  (name) => name,
89
89
  (name) =>
90
- materialIcon.render({
90
+ MaterialIcon.render({
91
91
  name,
92
92
  size,
93
93
  isFilled,
@@ -1,9 +1,16 @@
1
1
  /**
2
2
  * @typedef {import('../../../types/data-display/material-icon').MaterialIconProps} MaterialIconProps
3
+ * @typedef {import('@inglorious/web').TemplateResult} TemplateResult
3
4
  */
4
5
 
5
6
  import { classMap, html } from "@inglorious/web"
6
7
 
8
+ /**
9
+ * Renders a Material Symbols icon by name.
10
+ * Requires the Material Symbols font and supports filled and size variants.
11
+ * @param {MaterialIconProps} props
12
+ * @returns {TemplateResult}
13
+ */
7
14
  export function render(props) {
8
15
  const { name = "help", size = "md", isFilled = true, onClick } = props
9
16
 
@@ -1 +1 @@
1
- export { table } from "./template.js"
1
+ export { Table } from "./template.js"
@@ -1,10 +1,10 @@
1
1
  import { createRender } from "../../stories/notifyStory.js"
2
- import { table } from "."
2
+ import { Table } from "."
3
3
 
4
4
  export default {
5
5
  title: "Data Display/Table",
6
6
  tags: ["autodocs"],
7
- render: createRender(table),
7
+ render: createRender(Table),
8
8
  argTypes: {
9
9
  columns: { control: "object", description: "Column definitions." },
10
10
  rows: { control: "object", description: "Row records." },
@@ -11,12 +11,24 @@ import { applyElementProps } from "../../shared/applyElementProps.js"
11
11
  const EVEN_ROW_DIVISOR = 2
12
12
  const STRIPED_OFFSET = 1
13
13
 
14
- export const table = {
14
+ export const Table = {
15
15
  /**
16
+ * Main entrypoint for the table component. It delegates to the base table renderer so overrides can reuse it.
17
+ * Tables render columns and rows and can be striped or full width.
16
18
  * @param {TableProps} props
17
19
  * @returns {TemplateResult}
18
20
  */
19
21
  render(props) {
22
+ return this.renderTable(props)
23
+ },
24
+
25
+ /**
26
+ * Renders the table wrapper, header row, and body rows.
27
+ * Header and cells are delegated to `renderHeaderCell` and `renderCell`.
28
+ * @param {TableProps} props
29
+ * @returns {TemplateResult}
30
+ */
31
+ renderTable(props) {
20
32
  const {
21
33
  columns = [],
22
34
  rows = [],
@@ -61,6 +73,8 @@ export const table = {
61
73
  },
62
74
 
63
75
  /**
76
+ * Renders a single header cell label for a column.
77
+ * Override to customize header content or add controls.
64
78
  * @param {TableProps} _props
65
79
  * @param {{column: TableColumn, index: number}} payload
66
80
  * @returns {TemplateResult}
@@ -71,6 +85,8 @@ export const table = {
71
85
  },
72
86
 
73
87
  /**
88
+ * Renders a single table row and wires row click handlers.
89
+ * Cells are delegated to `renderCell`.
74
90
  * @param {TableProps} props
75
91
  * @param {{row: Record<string, unknown>, index: number}} payload
76
92
  * @returns {TemplateResult}
@@ -95,6 +111,8 @@ export const table = {
95
111
  },
96
112
 
97
113
  /**
114
+ * Renders a single table cell value for a column.
115
+ * Override to format values or inject custom content.
98
116
  * @param {TableProps} _props
99
117
  * @param {{column: TableColumn, row: Record<string, unknown>}} payload
100
118
  * @returns {TemplateResult}
@@ -1,3 +1,3 @@
1
1
  import * as renderers from "./template.js"
2
2
 
3
- export const tooltip = { ...renderers }
3
+ export const Tooltip = { ...renderers }
@@ -8,6 +8,8 @@ import { classMap, html, ref } from "@inglorious/web"
8
8
  import { applyElementProps } from "../../shared/applyElementProps.js"
9
9
 
10
10
  /**
11
+ * Renders a tooltip trigger and bubble with positional styling.
12
+ * Use `isOpen` to control visibility and `content` to set the tooltip body.
11
13
  * @param {TooltipProps} props
12
14
  * @returns {TemplateResult}
13
15
  */
@@ -1,12 +1,12 @@
1
1
  import { html } from "@inglorious/web"
2
2
 
3
3
  import { createRender } from "../../stories/notifyStory.js"
4
- import { tooltip } from "."
4
+ import { Tooltip } from "."
5
5
 
6
6
  export default {
7
7
  title: "Data Display/Tooltip",
8
8
  tags: ["autodocs"],
9
- render: createRender(tooltip),
9
+ render: createRender(Tooltip),
10
10
  argTypes: {
11
11
  content: { control: "text", description: "Tooltip text." },
12
12
  position: {
@@ -1,3 +1,3 @@
1
1
  import * as renderers from "./template.js"
2
2
 
3
- export const typography = { ...renderers }
3
+ export const Typography = { ...renderers }
@@ -8,6 +8,8 @@ import { classMap, html, ref } from "@inglorious/web"
8
8
  import { applyElementProps } from "../../shared/applyElementProps.js"
9
9
 
10
10
  /**
11
+ * Renders styled text with semantic variants such as headings, body, and caption.
12
+ * Supports alignment, weight, color, and gutter spacing.
11
13
  * @param {TypographyProps} props
12
14
  * @returns {TemplateResult}
13
15
  */
@@ -1,10 +1,10 @@
1
1
  import { createRender } from "../../stories/notifyStory.js"
2
- import { typography } from "."
2
+ import { Typography } from "."
3
3
 
4
4
  export default {
5
5
  title: "Data Display/Typography",
6
6
  tags: ["autodocs"],
7
- render: createRender(typography),
7
+ render: createRender(Typography),
8
8
  argTypes: {
9
9
  children: { control: "text", description: "Text content." },
10
10
  variant: {
@@ -1,4 +1,4 @@
1
1
  import * as handlers from "./handlers.js"
2
2
  import * as renderers from "./template.js"
3
3
 
4
- export const virtualList = { ...handlers, ...renderers }
4
+ export const VirtualList = { ...handlers, ...renderers }
@@ -9,7 +9,8 @@ import { html, ref, repeat, styleMap } from "@inglorious/web"
9
9
  const PRETTY_INDEX = 1
10
10
 
11
11
  /**
12
- * Renders the virtualized list component.
12
+ * Renders a virtualized list that only mounts visible items for performance.
13
+ * Uses item height estimates to compute scroll ranges and notifies on mount/scroll.
13
14
  * @param {VirtualListEntity} entity The list entity state.
14
15
  * @param {Api} api The API object.
15
16
  * @returns {TemplateResult} The rendered list.
@@ -85,7 +86,8 @@ export function render(entity, api) {
85
86
  }
86
87
 
87
88
  /**
88
- * Default item renderer.
89
+ * Default item renderer for a virtualized list item.
90
+ * Override to customize how each item is displayed.
89
91
  * @param {VirtualListEntity} entity The list entity.
90
92
  * @param {object} payload The payload for rendering the item.
91
93
  * @param {any} payload.item The item data.
@@ -1,13 +1,13 @@
1
1
  import { html } from "@inglorious/web"
2
2
 
3
- import { avatar } from "../../data-display/avatar"
4
- import { badge } from "../../data-display/badge"
5
- import { list } from "../../data-display/list"
6
- import { materialIcon } from "../../data-display/material-icon"
7
- import { flex } from "../../layout/flex"
8
- import { drawer } from "../../navigation/drawer"
9
-
10
- export const appDrawer = {
3
+ import { Avatar } from "../../data-display/avatar"
4
+ import { Badge } from "../../data-display/badge"
5
+ import { List } from "../../data-display/list"
6
+ import { MaterialIcon } from "../../data-display/material-icon"
7
+ import { Flex } from "../../layout/flex"
8
+ import { Drawer } from "../../navigation/drawer"
9
+
10
+ export const AppDrawer = {
11
11
  create(entity) {
12
12
  entity.items ??= getDefaultItems()
13
13
  },
@@ -32,23 +32,23 @@ export const appDrawer = {
32
32
  render(entity, api) {
33
33
  const items = mapItemsForRender(entity.items ?? [], api)
34
34
 
35
- return drawer.render({
35
+ return Drawer.render({
36
36
  ...entity,
37
37
  anchor: "left",
38
38
  onClose: () => api.notify(`#${entity.id}:toggle`),
39
39
  onCollapseToggle: () => api.notify(`#${entity.id}:collapseToggle`),
40
- title: flex.render({
40
+ title: Flex.render({
41
41
  align: "center",
42
42
  gap: "sm",
43
43
  padding: "md",
44
44
  className: "iw-dashboard-brand",
45
45
  children: [
46
- avatar.render({ src: "/transparent.png", shape: "square" }),
46
+ Avatar.render({ src: "/transparent.png", shape: "square" }),
47
47
  html`<span class="iw-dashboard-brand-title">Inglorious UI</span>`,
48
48
  ],
49
49
  }),
50
50
  children: html`
51
- ${list.render({
51
+ ${List.render({
52
52
  isInset: true,
53
53
  padding: "sm",
54
54
  items,
@@ -67,18 +67,18 @@ function mapItemsForRender(items, api) {
67
67
  const mappedItem = { ...item }
68
68
 
69
69
  if (item.icon) {
70
- mappedItem.icon = materialIcon.render({ name: item.icon, size: "lg" })
70
+ mappedItem.icon = MaterialIcon.render({ name: item.icon, size: "lg" })
71
71
  }
72
72
 
73
73
  if (item.badge) {
74
- mappedItem.action = badge.render(item.badge)
74
+ mappedItem.action = Badge.render(item.badge)
75
75
  }
76
76
 
77
77
  if (item.href) {
78
78
  mappedItem.onClick = () => api.notify("#router:navigate", item.href)
79
79
  }
80
80
 
81
- if (router.path === item.href) {
81
+ if (router?.path === item.href) {
82
82
  mappedItem.isSelected = true
83
83
  }
84
84
 
@@ -1,15 +1,15 @@
1
1
  import { html } from "@inglorious/web"
2
2
 
3
- import { button } from "../../controls/button"
4
- import { avatar } from "../../data-display/avatar"
5
- import { divider } from "../../data-display/divider"
6
- import { icon } from "../../data-display/icon"
7
- import { materialIcon } from "../../data-display/material-icon"
8
- import { flex } from "../../layout/flex"
9
- import { breadcrumbs } from "../../navigation/breadcrumbs"
10
- import { appBar } from "../../surfaces/app-bar"
3
+ import { Button } from "../../controls/button"
4
+ import { Avatar } from "../../data-display/avatar"
5
+ import { Divider } from "../../data-display/divider"
6
+ import { Icon } from "../../data-display/icon"
7
+ import { MaterialIcon } from "../../data-display/material-icon"
8
+ import { Flex } from "../../layout/flex"
9
+ import { Breadcrumbs } from "../../navigation/breadcrumbs"
10
+ import { AppBar } from "../../surfaces/app-bar"
11
11
 
12
- export const appHeader = {
12
+ export const AppHeader = {
13
13
  render(entity, api) {
14
14
  const themeEntity = api.getEntity("theme")
15
15
  const modeEntity = api.getEntity("mode")
@@ -30,116 +30,116 @@ export const appHeader = {
30
30
 
31
31
  return html`
32
32
  <div class="iw-dashboard-header">
33
- ${appBar.render({
33
+ ${AppBar.render({
34
34
  position: "static",
35
35
  elevated: false,
36
36
  children: html`
37
- ${flex.render({
37
+ ${Flex.render({
38
38
  justify: "between",
39
39
  align: "center",
40
40
  gap: "md",
41
41
  className: "iw-dashboard-header-row",
42
42
  children: [
43
- button.render({
43
+ Button.render({
44
44
  color: "secondary",
45
45
  variant: "ghost",
46
46
  shape: "square",
47
- children: materialIcon.render({ name: "menu", size: "lg" }),
47
+ children: MaterialIcon.render({ name: "menu", size: "lg" }),
48
48
  "aria-label": "Toggle navigation",
49
49
  onClick: () => api.notify(`#appDrawer:toggle`),
50
50
  }),
51
- flex.render({
51
+ Flex.render({
52
52
  align: "center",
53
53
  gap: "sm",
54
54
  className: "iw-dashboard-header-nav",
55
55
  children: [
56
- button.render({
56
+ Button.render({
57
57
  color: "secondary",
58
58
  variant: "ghost",
59
59
  children: "Dashboard",
60
60
  }),
61
- button.render({
61
+ Button.render({
62
62
  color: "secondary",
63
63
  variant: "ghost",
64
64
  children: "Users",
65
65
  }),
66
- button.render({
66
+ Button.render({
67
67
  color: "secondary",
68
68
  variant: "ghost",
69
69
  children: "Settings",
70
70
  }),
71
71
  ],
72
72
  }),
73
- flex.render({
73
+ Flex.render({
74
74
  align: "center",
75
75
  gap: "sm",
76
76
  className: "iw-dashboard-header-actions",
77
77
  children: [
78
- button.render({
78
+ Button.render({
79
79
  color: "secondary",
80
80
  variant: "ghost",
81
81
  shape: "square",
82
- children: materialIcon.render({
82
+ children: MaterialIcon.render({
83
83
  name: "notifications",
84
84
  size: "lg",
85
85
  }),
86
86
  "aria-label": "Notifications",
87
87
  }),
88
- button.render({
88
+ Button.render({
89
89
  color: "secondary",
90
90
  variant: "ghost",
91
91
  shape: "square",
92
- children: materialIcon.render({
92
+ children: MaterialIcon.render({
93
93
  name: "format_list_bulleted",
94
94
  }),
95
95
  "aria-label": "Tasks",
96
96
  }),
97
- button.render({
97
+ Button.render({
98
98
  color: "secondary",
99
99
  variant: "ghost",
100
100
  shape: "square",
101
- children: materialIcon.render({
101
+ children: MaterialIcon.render({
102
102
  name: "mail",
103
103
  size: "lg",
104
104
  }),
105
105
  "aria-label": "Messages",
106
106
  }),
107
- divider.render({ orientation: "vertical" }),
107
+ Divider.render({ orientation: "vertical" }),
108
108
 
109
- button.render({
109
+ Button.render({
110
110
  color: "secondary",
111
111
  variant: "ghost",
112
112
  shape: "square",
113
- children: icon.render({
113
+ children: Icon.render({
114
114
  children: html`<i class=${themeIcon}></i>`,
115
115
  size: "lg",
116
116
  }),
117
117
  "aria-label": `Theme: ${themeName}`,
118
118
  onClick: () => api.notify("#theme:toggle"),
119
119
  }),
120
- button.render({
120
+ Button.render({
121
121
  color: "secondary",
122
122
  variant: "ghost",
123
123
  shape: "square",
124
- children: materialIcon.render({
124
+ children: MaterialIcon.render({
125
125
  name: modeIcon,
126
126
  size: "lg",
127
127
  }),
128
128
  "aria-label": `Mode: ${themeMode}`,
129
129
  onClick: () => api.notify("#mode:toggle"),
130
130
  }),
131
- divider.render({ orientation: "vertical" }),
132
- avatar.render({ src: "/antony.jpeg" }),
131
+ Divider.render({ orientation: "vertical" }),
132
+ Avatar.render({ src: "/antony.jpeg" }),
133
133
  ],
134
134
  }),
135
135
  ],
136
136
  })}
137
137
  `,
138
138
  })}
139
- ${flex.render({
139
+ ${Flex.render({
140
140
  align: "center",
141
141
  className: "iw-dashboard-header-row iw-dashboard-breadcrumbs",
142
- children: breadcrumbs.render({
142
+ children: Breadcrumbs.render({
143
143
  items: [{ label: "Home", href: "#" }, { label: "Dashboard" }],
144
144
  }),
145
145
  })}
@@ -0,0 +1,76 @@
1
+ import { Container } from "../../layout/container/index.js"
2
+ import { Flex } from "../../layout/flex/index.js"
3
+ import { Grid } from "../../layout/grid/index.js"
4
+ import { AppDrawer } from "./app-drawer.js"
5
+ import { AppHeader } from "./app-header.js"
6
+ import { socialCards, statCards } from "./data.js"
7
+ import { PrimitiveSection } from "./primitive-section.js"
8
+ import { SocialCard } from "./social-card.js"
9
+ import { StatCard } from "./stat-card.js"
10
+ import { TrafficCard } from "./traffic-card.js"
11
+ import { TrafficSalesCard } from "./traffic-sales-card.js"
12
+
13
+ export const DashboardJsx = {
14
+ render(entity, api) {
15
+ const appDrawer = api.getEntity("appDrawer")
16
+ const dashboardClassName = [
17
+ "iw-dashboard",
18
+ appDrawer.isHidden && "iw-dashboard-drawer-hidden",
19
+ appDrawer.isCollapsed && "iw-dashboard-drawer-collapsed",
20
+ ]
21
+ .filter(Boolean)
22
+ .join(" ")
23
+
24
+ const router = api.getEntity("router")
25
+ const isDashboardRoot = !router || router.path === "/"
26
+
27
+ return (
28
+ <Flex direction="column" className={dashboardClassName}>
29
+ <AppDrawer />
30
+
31
+ <Flex element="main" direction="column" className="iw-dashboard-main">
32
+ <AppHeader />
33
+
34
+ <Container
35
+ maxWidth="xl"
36
+ padding="lg"
37
+ className="iw-dashboard-container"
38
+ >
39
+ {isDashboardRoot && (
40
+ <Flex direction="column" gap="lg">
41
+ <Grid minColumnWidth="18rem" gap="lg">
42
+ {statCards.map((card) => (
43
+ <StatCard key={card.id} {...card} />
44
+ ))}
45
+ </Grid>
46
+
47
+ <TrafficCard />
48
+
49
+ <Grid columns={3} gap="lg">
50
+ {socialCards.map((card) => (
51
+ <SocialCard key={card.id} {...card} />
52
+ ))}
53
+ </Grid>
54
+
55
+ <TrafficSalesCard />
56
+ </Flex>
57
+ )}
58
+
59
+ {!isDashboardRoot && <PrimitiveSection />}
60
+ </Container>
61
+
62
+ <Flex
63
+ element="footer"
64
+ justify="between"
65
+ gap="md"
66
+ padding="md"
67
+ className="iw-dashboard-footer"
68
+ >
69
+ <div>Admin dashboard example © 2026</div>
70
+ <div>Built with Inglorious UI primitives and charts</div>
71
+ </Flex>
72
+ </Flex>
73
+ </Flex>
74
+ )
75
+ },
76
+ }