@inglorious/ui 0.1.0 → 1.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 (283) hide show
  1. package/README.md +45 -0
  2. package/package.json +191 -16
  3. package/src/all.css +7 -0
  4. package/src/controls/button/button.stories.js +35 -15
  5. package/src/controls/button/index.js +1 -3
  6. package/src/controls/button/style.css +80 -37
  7. package/src/controls/button/template.js +23 -26
  8. package/src/controls/button-group/button-group.stories.js +19 -15
  9. package/src/controls/button-group/index.js +1 -2
  10. package/src/controls/button-group/style.css +0 -7
  11. package/src/controls/button-group/template.js +46 -56
  12. package/src/controls/checkbox/checkbox.stories.js +16 -13
  13. package/src/controls/checkbox/index.js +1 -2
  14. package/src/controls/checkbox/style.css +23 -2
  15. package/src/controls/checkbox/template.js +20 -18
  16. package/src/controls/combobox/combobox.stories.js +92 -0
  17. package/src/controls/{select → combobox}/handlers.js +8 -5
  18. package/src/controls/combobox/helpers.js +91 -0
  19. package/src/controls/combobox/index.js +43 -0
  20. package/src/controls/combobox/style.css +203 -0
  21. package/src/controls/combobox/template.js +340 -0
  22. package/src/controls/controls.css +12 -0
  23. package/src/controls/fab/fab.stories.js +11 -11
  24. package/src/controls/fab/index.js +1 -2
  25. package/src/controls/fab/template.js +21 -19
  26. package/src/controls/icon-button/icon-button.stories.js +8 -10
  27. package/src/controls/icon-button/index.js +1 -2
  28. package/src/controls/icon-button/template.js +13 -19
  29. package/src/controls/input/index.js +1 -2
  30. package/src/controls/input/input.stories.js +24 -23
  31. package/src/controls/input/style.css +9 -7
  32. package/src/controls/input/template.js +28 -31
  33. package/src/controls/radio-group/index.js +1 -2
  34. package/src/controls/radio-group/radio-group.stories.js +11 -8
  35. package/src/controls/radio-group/style.css +22 -1
  36. package/src/controls/radio-group/template.js +20 -15
  37. package/src/controls/rating/index.js +1 -2
  38. package/src/controls/rating/rating.stories.js +7 -10
  39. package/src/controls/rating/style.css +1 -2
  40. package/src/controls/rating/template.js +20 -17
  41. package/src/controls/select/helpers.js +2 -21
  42. package/src/controls/select/index.js +1 -13
  43. package/src/controls/select/select.stories.js +68 -64
  44. package/src/controls/select/style.css +66 -189
  45. package/src/controls/select/template.js +77 -406
  46. package/src/controls/slider/index.js +1 -2
  47. package/src/controls/slider/slider.stories.js +15 -12
  48. package/src/controls/slider/style.css +24 -3
  49. package/src/controls/slider/template.js +30 -23
  50. package/src/controls/switch/index.js +1 -2
  51. package/src/controls/switch/style.css +23 -2
  52. package/src/controls/switch/switch.stories.js +14 -11
  53. package/src/controls/switch/template.js +18 -16
  54. package/src/data-display/avatar/avatar.stories.js +106 -0
  55. package/src/data-display/avatar/index.js +3 -0
  56. package/src/data-display/avatar/style.css +64 -0
  57. package/src/data-display/avatar/template.js +81 -0
  58. package/src/data-display/badge/badge.stories.js +64 -0
  59. package/src/data-display/badge/index.js +3 -0
  60. package/src/data-display/badge/style.css +84 -0
  61. package/src/data-display/badge/template.js +46 -0
  62. package/src/data-display/chip/chip.stories.js +57 -0
  63. package/src/data-display/chip/index.js +3 -0
  64. package/src/data-display/chip/style.css +84 -0
  65. package/src/data-display/chip/template.js +32 -0
  66. package/src/data-display/data-display.css +11 -0
  67. package/src/data-display/data-grid/base.css +58 -0
  68. package/src/data-display/data-grid/data-grid.stories.js +158 -0
  69. package/src/data-display/data-grid/filters/helpers.js +8 -0
  70. package/src/data-display/data-grid/filters/index.js +21 -0
  71. package/src/data-display/data-grid/filters/input.js +24 -0
  72. package/src/data-display/data-grid/filters/range.js +48 -0
  73. package/src/data-display/data-grid/filters/select.js +17 -0
  74. package/src/data-display/data-grid/handlers.js +523 -0
  75. package/src/data-display/data-grid/helpers.js +248 -0
  76. package/src/data-display/data-grid/index.js +64 -0
  77. package/src/data-display/data-grid/style.css +14 -0
  78. package/src/data-display/data-grid/template.js +458 -0
  79. package/src/data-display/data-grid/theme.css +148 -0
  80. package/src/data-display/divider/divider.stories.js +48 -0
  81. package/src/data-display/divider/index.js +3 -0
  82. package/src/data-display/divider/style.css +18 -0
  83. package/src/data-display/divider/template.js +17 -0
  84. package/src/data-display/icon/icon-implementations.mdx +160 -0
  85. package/src/data-display/icon/icon-utf8.stories.js +156 -0
  86. package/src/data-display/icon/icon.stories.js +38 -0
  87. package/src/data-display/icon/index.js +3 -0
  88. package/src/data-display/icon/style.css +17 -0
  89. package/src/data-display/icon/template.js +19 -0
  90. package/src/data-display/list/handlers.js +25 -0
  91. package/src/data-display/list/index.js +4 -0
  92. package/src/data-display/list/list.stories.js +187 -0
  93. package/src/data-display/list/style.css +119 -0
  94. package/src/data-display/list/template.js +302 -0
  95. package/src/data-display/material-icon/index.js +3 -0
  96. package/src/data-display/material-icon/material-icon.stories.js +99 -0
  97. package/src/data-display/material-icon/style.css +27 -0
  98. package/src/data-display/material-icon/template.js +21 -0
  99. package/src/data-display/table/index.js +1 -0
  100. package/src/data-display/table/style.css +42 -0
  101. package/src/data-display/table/table.stories.js +40 -0
  102. package/src/data-display/table/template.js +114 -0
  103. package/src/data-display/tooltip/index.js +3 -0
  104. package/src/data-display/tooltip/style.css +57 -0
  105. package/src/data-display/tooltip/template.js +58 -0
  106. package/src/data-display/tooltip/tooltip.stories.js +44 -0
  107. package/src/data-display/typography/index.js +3 -0
  108. package/src/data-display/typography/style.css +49 -0
  109. package/src/data-display/typography/template.js +110 -0
  110. package/src/data-display/typography/typography.stories.js +48 -0
  111. package/src/data-display/virtual-list/handlers.js +68 -0
  112. package/src/data-display/virtual-list/index.js +4 -0
  113. package/src/data-display/virtual-list/template.js +101 -0
  114. package/src/examples/dashboard/app-drawer.js +255 -0
  115. package/src/examples/dashboard/app-header.js +149 -0
  116. package/src/examples/dashboard/dashboard.js +85 -0
  117. package/src/examples/dashboard/dashboard.stories.js +47 -0
  118. package/src/examples/dashboard/data.js +205 -0
  119. package/src/examples/dashboard/mode.js +27 -0
  120. package/src/examples/dashboard/primitive-content.js +1325 -0
  121. package/src/examples/dashboard/primitive-section.js +158 -0
  122. package/src/examples/dashboard/router.js +13 -0
  123. package/src/examples/dashboard/social-card.js +73 -0
  124. package/src/examples/dashboard/stat-card.js +84 -0
  125. package/src/examples/dashboard/style.css +339 -0
  126. package/src/examples/dashboard/theme-utils.js +95 -0
  127. package/src/examples/dashboard/theme.js +27 -0
  128. package/src/examples/dashboard/traffic-card.js +108 -0
  129. package/src/examples/dashboard/traffic-sales-card.js +267 -0
  130. package/src/feedback/alert/alert.stories.js +70 -0
  131. package/src/feedback/alert/index.js +3 -0
  132. package/src/feedback/alert/style.css +98 -0
  133. package/src/feedback/alert/template.js +74 -0
  134. package/src/feedback/backdrop/backdrop.stories.js +21 -0
  135. package/src/feedback/backdrop/index.js +3 -0
  136. package/src/feedback/backdrop/style.css +25 -0
  137. package/src/feedback/backdrop/template.js +31 -0
  138. package/src/feedback/dialog/dialog.stories.js +27 -0
  139. package/src/feedback/dialog/index.js +3 -0
  140. package/src/feedback/dialog/style.css +68 -0
  141. package/src/feedback/dialog/template.js +64 -0
  142. package/src/feedback/feedback.css +6 -0
  143. package/src/feedback/progress/index.js +3 -0
  144. package/src/feedback/progress/progress.stories.js +54 -0
  145. package/src/feedback/progress/style.css +95 -0
  146. package/src/feedback/progress/template.js +88 -0
  147. package/src/feedback/skeleton/index.js +3 -0
  148. package/src/feedback/skeleton/skeleton.stories.js +44 -0
  149. package/src/feedback/skeleton/style.css +41 -0
  150. package/src/feedback/skeleton/template.js +48 -0
  151. package/src/feedback/snackbar/index.js +3 -0
  152. package/src/feedback/snackbar/snackbar.stories.js +25 -0
  153. package/src/feedback/snackbar/style.css +64 -0
  154. package/src/feedback/snackbar/template.js +55 -0
  155. package/src/index.js +32 -1
  156. package/src/layout/container/container.stories.js +105 -0
  157. package/src/layout/container/index.js +3 -0
  158. package/src/layout/container/style.css +34 -0
  159. package/src/layout/container/template.js +119 -0
  160. package/src/layout/flex/flex.stories.js +28 -10
  161. package/src/layout/flex/index.js +1 -2
  162. package/src/layout/flex/style.css +20 -0
  163. package/src/layout/flex/template.js +40 -13
  164. package/src/layout/grid/grid.stories.js +46 -30
  165. package/src/layout/grid/index.js +1 -2
  166. package/src/layout/grid/style.css +20 -0
  167. package/src/layout/grid/template.js +100 -20
  168. package/src/layout/layout.css +3 -0
  169. package/src/navigation/bottom-navigation/bottom-navigation.stories.js +33 -0
  170. package/src/navigation/bottom-navigation/index.js +1 -0
  171. package/src/navigation/bottom-navigation/style.css +32 -0
  172. package/src/navigation/bottom-navigation/template.js +74 -0
  173. package/src/navigation/breadcrumbs/breadcrumbs.stories.js +33 -0
  174. package/src/navigation/breadcrumbs/index.js +1 -0
  175. package/src/navigation/breadcrumbs/style.css +27 -0
  176. package/src/navigation/breadcrumbs/template.js +79 -0
  177. package/src/navigation/drawer/drawer.stories.js +60 -0
  178. package/src/navigation/drawer/index.js +3 -0
  179. package/src/navigation/drawer/style.css +125 -0
  180. package/src/navigation/drawer/template.js +131 -0
  181. package/src/navigation/link/index.js +3 -0
  182. package/src/navigation/link/link.stories.js +53 -0
  183. package/src/navigation/link/style.css +40 -0
  184. package/src/navigation/link/template.js +53 -0
  185. package/src/navigation/menu/index.js +1 -0
  186. package/src/navigation/menu/menu.stories.js +36 -0
  187. package/src/navigation/menu/style.css +44 -0
  188. package/src/navigation/menu/template.js +81 -0
  189. package/src/navigation/navigation.css +9 -0
  190. package/src/navigation/pagination/index.js +1 -0
  191. package/src/navigation/pagination/pagination.stories.js +61 -0
  192. package/src/navigation/pagination/style.css +29 -0
  193. package/src/navigation/pagination/template.js +140 -0
  194. package/src/navigation/speed-dial/index.js +1 -0
  195. package/src/navigation/speed-dial/speed-dial.stories.js +40 -0
  196. package/src/navigation/speed-dial/style.css +38 -0
  197. package/src/navigation/speed-dial/template.js +68 -0
  198. package/src/navigation/stepper/index.js +1 -0
  199. package/src/navigation/stepper/stepper.stories.js +35 -0
  200. package/src/navigation/stepper/style.css +49 -0
  201. package/src/navigation/stepper/template.js +61 -0
  202. package/src/navigation/tabs/index.js +1 -0
  203. package/src/navigation/tabs/style.css +35 -0
  204. package/src/navigation/tabs/tabs.stories.js +40 -0
  205. package/src/navigation/tabs/template.js +79 -0
  206. package/src/overview.mdx +39 -0
  207. package/src/stories/notifyStory.js +22 -25
  208. package/src/styles/base.css +2 -0
  209. package/src/styles/reset.css +15 -0
  210. package/src/{themes → styles/themes}/bootstrap.css +2 -0
  211. package/src/{themes → styles/themes}/inglorious.css +9 -1
  212. package/src/{themes → styles/themes}/material.css +2 -0
  213. package/src/{tokens/index.css → styles/tokens.css} +9 -0
  214. package/src/surfaces/accordion/accordion.stories.js +60 -0
  215. package/src/surfaces/accordion/index.js +1 -0
  216. package/src/surfaces/accordion/style.css +64 -0
  217. package/src/surfaces/accordion/template.js +85 -0
  218. package/src/surfaces/app-bar/app-bar.stories.js +109 -0
  219. package/src/surfaces/app-bar/index.js +3 -0
  220. package/src/surfaces/app-bar/style.css +109 -0
  221. package/src/surfaces/app-bar/template.js +78 -0
  222. package/src/surfaces/card/card.stories.js +108 -0
  223. package/src/surfaces/card/index.js +1 -0
  224. package/src/surfaces/card/style.css +107 -0
  225. package/src/surfaces/card/template.js +163 -0
  226. package/src/surfaces/paper/index.js +3 -0
  227. package/src/surfaces/paper/paper.stories.js +97 -0
  228. package/src/surfaces/paper/style.css +73 -0
  229. package/src/surfaces/paper/template.js +76 -0
  230. package/src/surfaces/surfaces.css +4 -0
  231. package/types/controls/button-group.d.ts +8 -7
  232. package/types/controls/button.d.ts +10 -7
  233. package/types/controls/checkbox.d.ts +8 -6
  234. package/types/controls/combobox.d.ts +66 -0
  235. package/types/controls/fab.d.ts +6 -5
  236. package/types/controls/icon-button.d.ts +8 -7
  237. package/types/controls/input.d.ts +18 -11
  238. package/types/controls/radio-group.d.ts +7 -5
  239. package/types/controls/rating.d.ts +6 -5
  240. package/types/controls/select.d.ts +11 -34
  241. package/types/controls/slider.d.ts +8 -6
  242. package/types/controls/switch.d.ts +7 -5
  243. package/types/data-display/avatar.d.ts +30 -0
  244. package/types/data-display/badge.d.ts +20 -0
  245. package/types/data-display/chip.d.ts +25 -0
  246. package/types/data-display/data-grid.d.ts +151 -0
  247. package/types/data-display/divider.d.ts +14 -0
  248. package/types/data-display/icon.d.ts +16 -0
  249. package/types/data-display/list.d.ts +66 -0
  250. package/types/data-display/material-icon.d.ts +15 -0
  251. package/types/data-display/table.d.ts +45 -0
  252. package/types/data-display/tooltip.d.ts +20 -0
  253. package/types/data-display/typography.d.ts +28 -0
  254. package/types/data-display/virtual-list.d.ts +94 -0
  255. package/types/feedback/alert.d.ts +22 -0
  256. package/types/feedback/backdrop.d.ts +17 -0
  257. package/types/feedback/dialog.d.ts +21 -0
  258. package/types/feedback/progress.d.ts +18 -0
  259. package/types/feedback/skeleton.d.ts +18 -0
  260. package/types/feedback/snackbar.d.ts +19 -0
  261. package/types/index.d.ts +92 -14
  262. package/types/layout/container.d.ts +28 -0
  263. package/types/layout/flex.d.ts +16 -5
  264. package/types/layout/grid.d.ts +15 -4
  265. package/types/navigation/bottom-navigation.d.ts +33 -0
  266. package/types/navigation/breadcrumbs.d.ts +29 -0
  267. package/types/navigation/drawer.d.ts +23 -0
  268. package/types/navigation/link.d.ts +22 -0
  269. package/types/navigation/menu.d.ts +32 -0
  270. package/types/navigation/pagination.d.ts +50 -0
  271. package/types/navigation/speed-dial.d.ts +35 -0
  272. package/types/navigation/stepper.d.ts +26 -0
  273. package/types/navigation/tabs.d.ts +31 -0
  274. package/types/surfaces/accordion.d.ts +32 -0
  275. package/types/surfaces/app-bar.d.ts +25 -0
  276. package/types/surfaces/card.d.ts +39 -0
  277. package/types/surfaces/paper.d.ts +28 -0
  278. package/src/shared/withRenderValidation.js +0 -19
  279. package/src/widgets/card/card.stories.js +0 -135
  280. package/src/widgets/card/index.js +0 -4
  281. package/src/widgets/card/style.css +0 -53
  282. package/src/widgets/card/template.js +0 -97
  283. package/types/widgets/card.d.ts +0 -21
@@ -0,0 +1,255 @@
1
+ import { html } from "@inglorious/web"
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 = {
11
+ create(entity) {
12
+ entity.items ??= getDefaultItems()
13
+ },
14
+
15
+ toggle(entity) {
16
+ entity.isOpen = !entity.isOpen
17
+ entity.isHidden = !entity.isHidden
18
+ },
19
+
20
+ collapseToggle(entity) {
21
+ entity.isCollapsed = !entity.isCollapsed
22
+ },
23
+
24
+ itemToggle(entity, payload) {
25
+ if (!payload?.path?.length) return
26
+ entity.items = toggleItemByPath(
27
+ entity.items ?? getDefaultItems(),
28
+ payload.path,
29
+ )
30
+ },
31
+
32
+ render(entity, api) {
33
+ const items = mapItemsForRender(entity.items ?? [], api)
34
+
35
+ return drawer.render({
36
+ ...entity,
37
+ anchor: "left",
38
+ onClose: () => api.notify(`#${entity.id}:toggle`),
39
+ onCollapseToggle: () => api.notify(`#${entity.id}:collapseToggle`),
40
+ title: flex.render({
41
+ align: "center",
42
+ gap: "sm",
43
+ padding: "md",
44
+ className: "iw-dashboard-brand",
45
+ children: [
46
+ avatar.render({ src: "/transparent.png", shape: "square" }),
47
+ html`<span class="iw-dashboard-brand-title">Inglorious UI</span>`,
48
+ ],
49
+ }),
50
+ children: html`
51
+ ${list.render({
52
+ isInset: true,
53
+ padding: "sm",
54
+ items,
55
+ onItemToggle: (_, path) =>
56
+ api.notify(`#${entity.id}:itemToggle`, { path }),
57
+ })}
58
+ `,
59
+ })
60
+ },
61
+ }
62
+
63
+ function mapItemsForRender(items, api) {
64
+ const router = api.getEntity("router")
65
+
66
+ return items.map((item) => {
67
+ const mappedItem = { ...item }
68
+
69
+ if (item.icon) {
70
+ mappedItem.icon = materialIcon.render({ name: item.icon, size: "lg" })
71
+ }
72
+
73
+ if (item.badge) {
74
+ mappedItem.action = badge.render(item.badge)
75
+ }
76
+
77
+ if (item.href) {
78
+ mappedItem.onClick = () => api.notify("#router:navigate", item.href)
79
+ }
80
+
81
+ if (router.path === item.href) {
82
+ mappedItem.isSelected = true
83
+ }
84
+
85
+ if (Array.isArray(item.children)) {
86
+ mappedItem.children = mapItemsForRender(item.children, api)
87
+ }
88
+
89
+ return mappedItem
90
+ })
91
+ }
92
+
93
+ function getDefaultItems() {
94
+ return [
95
+ {
96
+ id: "dashboard",
97
+ primary: "Dashboard",
98
+ icon: "speed",
99
+ href: "/",
100
+ badge: {
101
+ color: "info",
102
+ children: "NEW",
103
+ size: "sm",
104
+ },
105
+ },
106
+ { id: "primitives-title", title: "Primitives" },
107
+ {
108
+ id: "layout",
109
+ primary: "Layout",
110
+ icon: "grid_view",
111
+ children: [
112
+ { id: "container", primary: "Container", href: "/layout/container" },
113
+ { id: "flex", primary: "Flex", href: "/layout/flex" },
114
+ { id: "grid", primary: "Grid", href: "/layout/grid" },
115
+ ],
116
+ },
117
+ {
118
+ id: "controls",
119
+ primary: "Controls",
120
+ icon: "buttons_alt",
121
+ children: [
122
+ { id: "button", primary: "Button", href: "/controls/button" },
123
+ {
124
+ id: "button-group",
125
+ primary: "Button Group",
126
+ href: "/controls/button-group",
127
+ },
128
+ { id: "checkbox", primary: "Checkbox", href: "/controls/checkbox" },
129
+ { id: "combobox", primary: "Combobox", href: "/controls/combobox" },
130
+ { id: "fab", primary: "Fab", href: "/controls/fab" },
131
+ {
132
+ id: "icon-button",
133
+ primary: "Icon Button",
134
+ href: "/controls/icon-button",
135
+ },
136
+ { id: "input", primary: "Input", href: "/controls/input" },
137
+ {
138
+ id: "radio-group",
139
+ primary: "Radio Group",
140
+ href: "/controls/radio-group",
141
+ },
142
+ { id: "rating", primary: "Rating", href: "/controls/rating" },
143
+ { id: "select", primary: "Select", href: "/controls/select" },
144
+ { id: "slider", primary: "Slider", href: "/controls/slider" },
145
+ { id: "switch", primary: "Switch", href: "/controls/switch" },
146
+ ],
147
+ },
148
+ {
149
+ id: "data-display",
150
+ primary: "Data Display",
151
+ icon: "database",
152
+ children: [
153
+ { id: "avatar", primary: "Avatar", href: "/data-display/avatar" },
154
+ { id: "badge", primary: "Badge", href: "/data-display/badge" },
155
+ { id: "chip", primary: "Chip", href: "/data-display/chip" },
156
+ {
157
+ id: "data-grid",
158
+ primary: "Data Grid",
159
+ href: "/data-display/data-grid",
160
+ },
161
+ { id: "divider", primary: "Divider", href: "/data-display/divider" },
162
+ { id: "icon", primary: "Icon", href: "/data-display/icon" },
163
+ { id: "list", primary: "List", href: "/data-display/list" },
164
+ {
165
+ id: "material-icon",
166
+ primary: "Material Icon",
167
+ href: "/data-display/material-icon",
168
+ },
169
+ { id: "table", primary: "Table", href: "/data-display/table" },
170
+ { id: "tooltip", primary: "Tooltip", href: "/data-display/tooltip" },
171
+ {
172
+ id: "typography",
173
+ primary: "Typography",
174
+ href: "/data-display/typography",
175
+ },
176
+ ],
177
+ },
178
+ {
179
+ id: "feedback",
180
+ primary: "Feedback",
181
+ icon: "notifications",
182
+ children: [
183
+ { id: "alert", primary: "Alert", href: "/feedback/alert" },
184
+ { id: "backdrop", primary: "Backdrop", href: "/feedback/backdrop" },
185
+ { id: "dialog", primary: "Dialog", href: "/feedback/dialog" },
186
+ { id: "progress", primary: "Progress", href: "/feedback/progress" },
187
+ { id: "skeleton", primary: "Skeleton", href: "/feedback/skeleton" },
188
+ { id: "snackbar", primary: "Snackbar", href: "/feedback/snackbar" },
189
+ ],
190
+ },
191
+ {
192
+ id: "navigation",
193
+ primary: "Navigation",
194
+ icon: "explore",
195
+ children: [
196
+ {
197
+ id: "bottom-navigation",
198
+ primary: "Bottom Navigation",
199
+ href: "/navigation/bottom-navigation",
200
+ },
201
+ {
202
+ id: "breadcrumbs",
203
+ primary: "Breadcrumbs",
204
+ href: "/navigation/breadcrumbs",
205
+ },
206
+ { id: "drawer", primary: "Drawer", href: "/navigation/drawer" },
207
+ { id: "link", primary: "Link", href: "/navigation/link" },
208
+ { id: "menu", primary: "Menu", href: "/navigation/menu" },
209
+ {
210
+ id: "pagination",
211
+ primary: "Pagination",
212
+ href: "/navigation/pagination",
213
+ },
214
+ {
215
+ id: "speed-dial",
216
+ primary: "Speed Dial",
217
+ href: "/navigation/speed-dial",
218
+ },
219
+ { id: "stepper", primary: "Stepper", href: "/navigation/stepper" },
220
+ { id: "tabs", primary: "Tabs", href: "/navigation/tabs" },
221
+ ],
222
+ },
223
+ {
224
+ id: "surfaces",
225
+ primary: "Surfaces",
226
+ icon: "layers",
227
+ children: [
228
+ { id: "accordion", primary: "Accordion", href: "/surfaces/accordion" },
229
+ { id: "app-bar", primary: "App Bar", href: "/surfaces/app-bar" },
230
+ { id: "card", primary: "Card", href: "/surfaces/card" },
231
+ { id: "paper", primary: "Paper", href: "/surfaces/paper" },
232
+ ],
233
+ },
234
+ ]
235
+ }
236
+
237
+ function toggleItemByPath(items, path) {
238
+ if (!Array.isArray(items) || path.length === 0) return items
239
+
240
+ const [index, ...rest] = path
241
+ return items.map((item, itemIndex) => {
242
+ if (itemIndex !== index || !item || typeof item !== "object") return item
243
+
244
+ if (rest.length === 0) {
245
+ const isExpanded = !!item.isExpanded
246
+ return { ...item, isExpanded: !isExpanded }
247
+ }
248
+
249
+ const children = Array.isArray(item.children)
250
+ ? toggleItemByPath(item.children, rest)
251
+ : item.children
252
+
253
+ return { ...item, children }
254
+ })
255
+ }
@@ -0,0 +1,149 @@
1
+ import { html } from "@inglorious/web"
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"
11
+
12
+ export const appHeader = {
13
+ render(entity, api) {
14
+ const themeEntity = api.getEntity("theme")
15
+ const modeEntity = api.getEntity("mode")
16
+ const themeMode = modeEntity?.mode ?? "auto"
17
+ const themeName = themeEntity?.theme ?? "inglorious"
18
+ const themeIcon =
19
+ themeName === "bootstrap"
20
+ ? "fa-brands fa-bootstrap"
21
+ : themeName === "material"
22
+ ? "fa-brands fa-android"
23
+ : "fa-solid fa-gamepad"
24
+ const modeIcon =
25
+ themeMode === "light"
26
+ ? "light_mode"
27
+ : themeMode === "dark"
28
+ ? "dark_mode"
29
+ : "contrast"
30
+
31
+ return html`
32
+ <div class="iw-dashboard-header">
33
+ ${appBar.render({
34
+ position: "static",
35
+ elevated: false,
36
+ children: html`
37
+ ${flex.render({
38
+ justify: "between",
39
+ align: "center",
40
+ gap: "md",
41
+ className: "iw-dashboard-header-row",
42
+ children: [
43
+ button.render({
44
+ color: "secondary",
45
+ variant: "ghost",
46
+ shape: "square",
47
+ children: materialIcon.render({ name: "menu", size: "lg" }),
48
+ "aria-label": "Toggle navigation",
49
+ onClick: () => api.notify(`#appDrawer:toggle`),
50
+ }),
51
+ flex.render({
52
+ align: "center",
53
+ gap: "sm",
54
+ className: "iw-dashboard-header-nav",
55
+ children: [
56
+ button.render({
57
+ color: "secondary",
58
+ variant: "ghost",
59
+ children: "Dashboard",
60
+ }),
61
+ button.render({
62
+ color: "secondary",
63
+ variant: "ghost",
64
+ children: "Users",
65
+ }),
66
+ button.render({
67
+ color: "secondary",
68
+ variant: "ghost",
69
+ children: "Settings",
70
+ }),
71
+ ],
72
+ }),
73
+ flex.render({
74
+ align: "center",
75
+ gap: "sm",
76
+ className: "iw-dashboard-header-actions",
77
+ children: [
78
+ button.render({
79
+ color: "secondary",
80
+ variant: "ghost",
81
+ shape: "square",
82
+ children: materialIcon.render({
83
+ name: "notifications",
84
+ size: "lg",
85
+ }),
86
+ "aria-label": "Notifications",
87
+ }),
88
+ button.render({
89
+ color: "secondary",
90
+ variant: "ghost",
91
+ shape: "square",
92
+ children: materialIcon.render({
93
+ name: "format_list_bulleted",
94
+ }),
95
+ "aria-label": "Tasks",
96
+ }),
97
+ button.render({
98
+ color: "secondary",
99
+ variant: "ghost",
100
+ shape: "square",
101
+ children: materialIcon.render({
102
+ name: "mail",
103
+ size: "lg",
104
+ }),
105
+ "aria-label": "Messages",
106
+ }),
107
+ divider.render({ orientation: "vertical" }),
108
+
109
+ button.render({
110
+ color: "secondary",
111
+ variant: "ghost",
112
+ shape: "square",
113
+ children: icon.render({
114
+ children: html`<i class=${themeIcon}></i>`,
115
+ size: "lg",
116
+ }),
117
+ "aria-label": `Theme: ${themeName}`,
118
+ onClick: () => api.notify("#theme:toggle"),
119
+ }),
120
+ button.render({
121
+ color: "secondary",
122
+ variant: "ghost",
123
+ shape: "square",
124
+ children: materialIcon.render({
125
+ name: modeIcon,
126
+ size: "lg",
127
+ }),
128
+ "aria-label": `Mode: ${themeMode}`,
129
+ onClick: () => api.notify("#mode:toggle"),
130
+ }),
131
+ divider.render({ orientation: "vertical" }),
132
+ avatar.render({ src: "/antony.jpeg" }),
133
+ ],
134
+ }),
135
+ ],
136
+ })}
137
+ `,
138
+ })}
139
+ ${flex.render({
140
+ align: "center",
141
+ className: "iw-dashboard-header-row iw-dashboard-breadcrumbs",
142
+ children: breadcrumbs.render({
143
+ items: [{ label: "Home", href: "#" }, { label: "Dashboard" }],
144
+ }),
145
+ })}
146
+ </div>
147
+ `
148
+ },
149
+ }
@@ -0,0 +1,85 @@
1
+ import { html } from "@inglorious/web"
2
+
3
+ import { container } from "../../layout/container/index.js"
4
+ import { flex } from "../../layout/flex/index.js"
5
+ import { grid } from "../../layout/grid/index.js"
6
+ import { appHeader } from "./app-header.js"
7
+ import { socialCards, statCards } from "./data.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 dashboard = {
14
+ render(entity, api) {
15
+ const appDrawer = api.getEntity("appDrawer")
16
+ const router = api.getEntity("router")
17
+
18
+ const dashboardClassName = [
19
+ "iw-dashboard",
20
+ appDrawer.isHidden && "iw-dashboard-drawer-hidden",
21
+ appDrawer.isCollapsed && "iw-dashboard-drawer-collapsed",
22
+ ]
23
+ .filter(Boolean)
24
+ .join(" ")
25
+
26
+ const isDashboardRoot = !router || router.path === "/"
27
+
28
+ let mainContent
29
+ if (isDashboardRoot) {
30
+ mainContent = flex.render({
31
+ direction: "column",
32
+ gap: "lg",
33
+ children: [
34
+ grid.render({
35
+ minColumnWidth: "18rem",
36
+ gap: "lg",
37
+ children: statCards.map((card) => statCard.render(card, api)),
38
+ }),
39
+ trafficCard.render(entity, api),
40
+ grid.render({
41
+ columns: 3,
42
+ gap: "lg",
43
+ children: socialCards.map((card) => socialCard.render(card, api)),
44
+ }),
45
+ trafficSalesCard.render(entity, api),
46
+ ],
47
+ })
48
+ } else {
49
+ mainContent = api.render("primitiveSection")
50
+ }
51
+
52
+ return flex.render({
53
+ direction: "column",
54
+ className: dashboardClassName,
55
+ children: [
56
+ api.render("appDrawer"),
57
+ flex.render({
58
+ element: "main",
59
+ direction: "column",
60
+ className: "iw-dashboard-main",
61
+ children: [
62
+ appHeader.render(entity, api),
63
+ container.render({
64
+ maxWidth: "xl",
65
+ padding: "lg",
66
+ className: "iw-dashboard-container",
67
+ children: mainContent,
68
+ }),
69
+ flex.render({
70
+ element: "footer",
71
+ justify: "between",
72
+ gap: "md",
73
+ padding: "md",
74
+ className: "iw-dashboard-footer",
75
+ children: [
76
+ html`<div>Admin dashboard example © 2026</div>`,
77
+ html`<div>Built with Inglorious UI primitives and charts</div>`,
78
+ ],
79
+ }),
80
+ ],
81
+ }),
82
+ ],
83
+ })
84
+ },
85
+ }
@@ -0,0 +1,47 @@
1
+ import "./style.css"
2
+
3
+ import { areaChart, barChart, lineChart } from "@inglorious/charts"
4
+
5
+ import {
6
+ createEntityRender,
7
+ notifyActionArgType,
8
+ } from "../../stories/notifyStory.js"
9
+ import { appDrawer } from "./app-drawer.js"
10
+ import { dashboard } from "./dashboard.js"
11
+ import { mode } from "./mode.js"
12
+ import { primitiveSection } from "./primitive-section.js"
13
+ import { theme } from "./theme.js"
14
+
15
+ export default {
16
+ title: "Examples/AdminDashboard",
17
+ tags: ["autodocs"],
18
+ render: createEntityRender({
19
+ theme,
20
+ mode,
21
+ appDrawer,
22
+ dashboard,
23
+ primitiveSection,
24
+ area: areaChart,
25
+ bar: barChart,
26
+ line: lineChart,
27
+ }),
28
+ argTypes: {
29
+ ...notifyActionArgType,
30
+ },
31
+ parameters: {
32
+ layout: "fullscreen",
33
+ docs: {
34
+ description: {
35
+ component:
36
+ "A composed admin dashboard example built from existing navigation, surface, data-display, feedback, and chart primitives.",
37
+ },
38
+ },
39
+ },
40
+ }
41
+
42
+ export const Default = {
43
+ args: {
44
+ id: "dashboard",
45
+ type: "dashboard",
46
+ },
47
+ }