@inglorious/ui 8.1.1 → 8.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inglorious/ui",
3
- "version": "8.1.1",
3
+ "version": "8.2.1",
4
4
  "description": "A design system for Inglorious Web with render-function components and customizable themes",
5
5
  "author": "Matteo Antony Mistretta <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
6
6
  "license": "MIT",
@@ -310,8 +310,8 @@
310
310
  "@iconify-icons/fa7-regular": "^2.0.0",
311
311
  "@iconify-icons/fa7-solid": "^2.0.0",
312
312
  "@iconify-icons/material-symbols": "^2.0.6",
313
- "@inglorious/charts": "10.0.7",
314
- "@inglorious/eslint-config": "1.1.2",
313
+ "@inglorious/charts": "11.1.0",
314
+ "@inglorious/eslint-config": "1.1.3",
315
315
  "@inglorious/store": "11.0.4",
316
316
  "@inglorious/vite-plugin-jsx": "2.0.4",
317
317
  "@inglorious/vite-plugin-vue": "1.0.5",
@@ -321,6 +321,7 @@
321
321
  "happy-dom": "^20.14.0",
322
322
  "jsdom": "^30.0.1",
323
323
  "prettier": "^3.9.6",
324
+ "remark-gfm": "^4.0.1",
324
325
  "storybook": "^10.6.0",
325
326
  "vite": "^8.2.2",
326
327
  "vitest": "^5.0.0"
@@ -8,6 +8,8 @@
8
8
  font-size: var(--iw-font-size-base);
9
9
  font-weight: var(--iw-font-weight-normal);
10
10
  line-height: var(--iw-line-height-normal);
11
+ text-transform: var(--iw-label-text-transform);
12
+ letter-spacing: var(--iw-label-letter-spacing);
11
13
  text-decoration: none;
12
14
  white-space: nowrap;
13
15
  cursor: pointer;
@@ -9,7 +9,7 @@ import {
9
9
  } from "../../stories/notifyStory.js"
10
10
  import { Icon } from "."
11
11
 
12
- const unicodeList = {
12
+ const UnicodeList = {
13
13
  ...VirtualList,
14
14
 
15
15
  create(entity) {
@@ -38,7 +38,7 @@ const unicodeList = {
38
38
  render(entity, api) {
39
39
  return VirtualList.render(entity, {
40
40
  ...api,
41
- getType: () => unicodeList,
41
+ getType: () => UnicodeList,
42
42
  })
43
43
  },
44
44
 
@@ -88,7 +88,7 @@ const unicodeList = {
88
88
 
89
89
  export default {
90
90
  title: "Data Display/Icon",
91
- render: createEntityRender({ unicodeList }),
91
+ render: createEntityRender({ UnicodeList }),
92
92
  argTypes: {
93
93
  ...notifyActionArgType,
94
94
  start: {
@@ -15,6 +15,15 @@
15
15
  width: 100%;
16
16
  }
17
17
 
18
+ &.iw-table-wrapping {
19
+ min-width: 0;
20
+
21
+ .iw-table-header-cell,
22
+ .iw-table-cell {
23
+ overflow-wrap: anywhere;
24
+ }
25
+ }
26
+
18
27
  &.iw-table-striped {
19
28
  .iw-table-row-even {
20
29
  background: color-mix(
@@ -10,6 +10,11 @@ export default {
10
10
  rows: { control: "object", description: "Row records." },
11
11
  isFullWidth: { control: "boolean", description: "Stretch table width." },
12
12
  isStriped: { control: "boolean", description: "Enable zebra rows." },
13
+ isWrapping: {
14
+ control: "boolean",
15
+ description:
16
+ "Wrap cell content to fit the container instead of scrolling.",
17
+ },
13
18
  onRowClick: { action: "onRowClick" },
14
19
  },
15
20
  parameters: {
@@ -37,6 +37,7 @@ export const Table = {
37
37
  rows = [],
38
38
  isFullWidth = false,
39
39
  isStriped = false,
40
+ isWrapping = false,
40
41
  onRowClick,
41
42
  ...rest
42
43
  } = props
@@ -45,6 +46,7 @@ export const Table = {
45
46
  "iw-table": true,
46
47
  "iw-table-full-width": isFullWidth,
47
48
  "iw-table-striped": isStriped,
49
+ "iw-table-wrapping": isWrapping,
48
50
  }
49
51
 
50
52
  return html`
@@ -45,12 +45,17 @@ export function scroll(entity, containerEl) {
45
45
  */
46
46
  export function mount(entity, containerEl) {
47
47
  const firstItem = containerEl.querySelector("[data-index]")
48
- if (!firstItem) return
48
+ // A list not laid out yet, such as one rendered into a detached element,
49
+ // measures 0: keep the estimate, and measure again on a later render.
50
+ if (!firstItem?.offsetHeight) return
49
51
 
50
52
  entity.itemHeight = firstItem.offsetHeight
51
53
  entity.visibleRange = {
52
54
  start: 0,
53
- end: Math.ceil(entity.viewportHeight / entity.itemHeight),
55
+ end: Math.min(
56
+ Math.ceil(entity.viewportHeight / entity.itemHeight),
57
+ entity.items?.length ?? Infinity,
58
+ ),
54
59
  }
55
60
  }
56
61
 
@@ -11,6 +11,31 @@ import { styleMap } from "@inglorious/web/directives/style-map"
11
11
 
12
12
  const PRETTY_INDEX = 1
13
13
 
14
+ // The list elements already being measured. Every update re-renders, and
15
+ // measuring is an update, so measuring on each render would loop forever.
16
+ const measured = new WeakSet()
17
+
18
+ /**
19
+ * Notifies `mount` once per list element, after a frame and once it is in the
20
+ * document: before that it has no layout to measure.
21
+ * @param {HTMLElement} el
22
+ * @param {VirtualListEntity} entity
23
+ * @param {Api} api
24
+ */
25
+ function measureOnce(el, entity, api) {
26
+ if (measured.has(el)) return
27
+ measured.add(el)
28
+
29
+ const measure = () => {
30
+ if (!el.isConnected) {
31
+ requestAnimationFrame(measure)
32
+ return
33
+ }
34
+ api.notify(`#${entity.id}:mount`, el)
35
+ }
36
+ requestAnimationFrame(measure)
37
+ }
38
+
14
39
  /**
15
40
  * Renders a virtualized list that only mounts visible items for performance.
16
41
  * Uses item height estimates to compute scroll ranges and notifies on mount/scroll.
@@ -49,11 +74,7 @@ export function render(entity, api) {
49
74
  style=${styleMap({ height: `${viewportHeight}px`, overflow: "auto" })}
50
75
  @scroll=${(e) => api.notify(`#${entity.id}:scroll`, e.currentTarget)}
51
76
  ${ref((el) => {
52
- if (el && !itemHeight) {
53
- queueMicrotask(() => {
54
- api.notify(`#${entity.id}:mount`, el)
55
- })
56
- }
77
+ if (el && !itemHeight) measureOnce(el, entity, api)
57
78
  })}
58
79
  >
59
80
  <div
@@ -1,4 +1,4 @@
1
- import { Chart } from "@inglorious/charts"
1
+ import { Area, Chart } from "@inglorious/charts"
2
2
  import { html } from "@inglorious/web"
3
3
 
4
4
  import { Divider } from "../../data-display/divider"
@@ -55,7 +55,7 @@ export const SocialCard = {
55
55
  height: 200,
56
56
  padding: 0,
57
57
  children: [
58
- Chart.Area({
58
+ Area({
59
59
  dataKey: "value",
60
60
  stroke: "rgba(255,255,255,0.9)",
61
61
  fill: "rgba(255,255,255,0.35)",
@@ -1,5 +1,5 @@
1
1
  import moreVertOutline from "@iconify-icons/material-symbols/more-vert-outline"
2
- import { Chart } from "@inglorious/charts"
2
+ import { Area, Bar, Chart, Dots, Line } from "@inglorious/charts"
3
3
  import { html } from "@inglorious/web"
4
4
 
5
5
  import { Button } from "../../controls/button"
@@ -66,20 +66,16 @@ export const StatCard = {
66
66
  const children = []
67
67
 
68
68
  if (entity.chartType === "area") {
69
- children.push(
70
- Chart.Area({ dataKey: "value", fill: "rgba(255,255,255,0.3)" }),
71
- )
69
+ children.push(Area({ dataKey: "value", fill: "rgba(255,255,255,0.3)" }))
72
70
  } else if (entity.chartType === "bar") {
73
- children.push(
74
- Chart.Bar({ dataKey: "value", fill: "rgba(255,255,255,0.3)" }),
75
- )
71
+ children.push(Bar({ dataKey: "value", fill: "rgba(255,255,255,0.3)" }))
76
72
  } else if (entity.chartType === "line") {
77
- children.push(Chart.Line({ dataKey: "value", stroke: "white" }))
73
+ children.push(Line({ dataKey: "value", stroke: "white" }))
78
74
  }
79
75
 
80
76
  if (entity.hasDots) {
81
77
  children.push(
82
- Chart.Dots({ dataKey: "value", stroke: "white", fill: "#39a2f1" }),
78
+ Dots({ dataKey: "value", stroke: "white", fill: "#39a2f1" }),
83
79
  )
84
80
  }
85
81
 
@@ -1,5 +1,12 @@
1
1
  import downloadOutline from "@iconify-icons/material-symbols/download-outline"
2
- import { Chart } from "@inglorious/charts"
2
+ import {
3
+ Area,
4
+ CartesianGrid,
5
+ Chart,
6
+ Tooltip,
7
+ XAxis,
8
+ YAxis,
9
+ } from "@inglorious/charts"
3
10
  import { html } from "@inglorious/web"
4
11
 
5
12
  import { Button } from "../../controls/button"
@@ -94,15 +101,15 @@ export const TrafficCard = {
94
101
  height: 320,
95
102
  dataKeys: ["visits", "unique"],
96
103
  children: [
97
- Chart.CartesianGrid({
104
+ CartesianGrid({
98
105
  stroke: "rgba(255,255,255,0.08)",
99
106
  strokeDasharray: "4 4",
100
107
  }),
101
- Chart.XAxis({ dataKey: "month" }),
102
- Chart.YAxis({ width: "auto" }),
103
- Chart.Area({ dataKey: "visits", stroke: "#39a2f1", strokeWidth: 3 }),
104
- Chart.Area({ dataKey: "unique", stroke: "#2eb85c", strokeWidth: 3 }),
105
- Chart.Tooltip({}),
108
+ XAxis({ dataKey: "month" }),
109
+ YAxis(),
110
+ Area({ dataKey: "visits", stroke: "#39a2f1", strokeWidth: 3 }),
111
+ Area({ dataKey: "unique", stroke: "#2eb85c", strokeWidth: 3 }),
112
+ Tooltip({}),
106
113
  ],
107
114
  },
108
115
  api,
@@ -77,6 +77,7 @@ export function render(props) {
77
77
  class=${classMap({
78
78
  "iw-progress": true,
79
79
  "iw-progress-linear": true,
80
+ [`iw-progress-${color}`]: true,
80
81
  "iw-progress-indeterminate": progress == null,
81
82
  ...extraClasses,
82
83
  })}
@@ -22,6 +22,8 @@
22
22
  align-items: center;
23
23
  gap: var(--iw-space-2);
24
24
  padding: var(--iw-space-3) var(--iw-space-4);
25
+ text-transform: var(--iw-label-text-transform);
26
+ letter-spacing: var(--iw-label-letter-spacing);
25
27
  cursor: pointer;
26
28
  }
27
29
 
@@ -33,6 +33,10 @@
33
33
  --iw-color-accent-hover: #c2185b;
34
34
  --iw-color-accent-active: #ad1457;
35
35
 
36
+ /* Buttons and tabs carry their labels in capitals, as Material does. */
37
+ --iw-label-text-transform: uppercase;
38
+ --iw-label-letter-spacing: 0.06em;
39
+
36
40
  /* ========================================
37
41
  COMPONENT TOKENS
38
42
  ======================================== */
@@ -125,6 +125,10 @@
125
125
  --iw-line-height-normal: 1.5;
126
126
  --iw-line-height-relaxed: 1.75;
127
127
 
128
+ /* Labels of buttons and tabs: a theme can set them in capitals. */
129
+ --iw-label-text-transform: none;
130
+ --iw-label-letter-spacing: normal;
131
+
128
132
  /* ========================================
129
133
  SHADOWS
130
134
  ======================================== */
@@ -7,7 +7,14 @@ export interface ButtonGroupItem {
7
7
  children?: TemplateResult | string | number
8
8
  isDisabled?: boolean
9
9
  variant?: "default" | "outline" | "ghost"
10
- color?: "primary" | "secondary" | "success" | "warning" | "error" | "info"
10
+ color?:
11
+ | "default"
12
+ | "primary"
13
+ | "secondary"
14
+ | "success"
15
+ | "warning"
16
+ | "error"
17
+ | "info"
11
18
  size?: "sm" | "md" | "lg"
12
19
  icon?: string
13
20
  iconAfter?: string
@@ -23,7 +30,14 @@ export interface ButtonGroupProps {
23
30
  isAttached?: boolean
24
31
  size?: "sm" | "md" | "lg"
25
32
  variant?: "default" | "outline" | "ghost"
26
- color?: "primary" | "secondary" | "success" | "warning" | "error" | "info"
33
+ color?:
34
+ | "default"
35
+ | "primary"
36
+ | "secondary"
37
+ | "success"
38
+ | "warning"
39
+ | "error"
40
+ | "info"
27
41
  isDisabled?: boolean
28
42
  onChange?: (value?: string | string[]) => void
29
43
  [key: string]: unknown
@@ -5,7 +5,14 @@ export interface ButtonProps {
5
5
  type: "Button"
6
6
  children?: TemplateResult | string | number
7
7
  variant?: "default" | "outline" | "ghost"
8
- color?: "primary" | "secondary" | "success" | "warning" | "error" | "info"
8
+ color?:
9
+ | "default"
10
+ | "primary"
11
+ | "secondary"
12
+ | "success"
13
+ | "warning"
14
+ | "error"
15
+ | "info"
9
16
  size?: "sm" | "md" | "lg"
10
17
  shape?: "rectangle" | "pill" | "round" | "square"
11
18
  isDisabled?: boolean
@@ -3,7 +3,14 @@ import type { TemplateResult } from "@inglorious/web"
3
3
  export interface FabProps {
4
4
  id?: string
5
5
  children?: TemplateResult | string | number
6
- color?: "primary" | "secondary" | "success" | "warning" | "error" | "info"
6
+ color?:
7
+ | "default"
8
+ | "primary"
9
+ | "secondary"
10
+ | "success"
11
+ | "warning"
12
+ | "error"
13
+ | "info"
7
14
  size?: "sm" | "md" | "lg"
8
15
  isDisabled?: boolean
9
16
  type?: "button" | "submit" | "reset" | "menu"
@@ -9,7 +9,14 @@ export interface IconButtonProps {
9
9
  direction?: "row" | "column"
10
10
  ariaLabel?: string
11
11
  variant?: "default" | "outline" | "ghost"
12
- color?: "primary" | "secondary" | "success" | "warning" | "error" | "info"
12
+ color?:
13
+ | "default"
14
+ | "primary"
15
+ | "secondary"
16
+ | "success"
17
+ | "warning"
18
+ | "error"
19
+ | "info"
13
20
  size?: "sm" | "md" | "lg"
14
21
  isDisabled?: boolean
15
22
  isFullWidth?: boolean
@@ -17,6 +17,7 @@ export interface TableProps {
17
17
  rows?: TableRow[]
18
18
  isFullWidth?: boolean
19
19
  isStriped?: boolean
20
+ isWrapping?: boolean
20
21
  onRowClick?: (row: TableRow) => void
21
22
  [key: string]: unknown
22
23
  }
@@ -9,7 +9,7 @@ export interface TooltipProps {
9
9
  isOpen?: boolean
10
10
  maxWidth?: string
11
11
  className?: string
12
- onClick: () => void
12
+ onClick?: () => void
13
13
  [key: string]: unknown
14
14
  }
15
15
 
@@ -5,6 +5,14 @@ export interface ProgressProps {
5
5
  type?: string
6
6
  variant?: "linear" | "circular"
7
7
  value?: number
8
+ color?:
9
+ | "default"
10
+ | "primary"
11
+ | "secondary"
12
+ | "success"
13
+ | "warning"
14
+ | "error"
15
+ | "info"
8
16
  size?: number
9
17
  thickness?: number
10
18
  className?: string
@@ -15,7 +15,7 @@ export interface TabsProps {
15
15
  id?: string
16
16
  type?: string
17
17
  items?: TabItem[]
18
- value?: string | number
18
+ value?: string | number | null
19
19
  isCentered?: boolean
20
20
  isFullWidth?: boolean
21
21
  onChange?: (value: string | number) => void