@inglorious/ui 9.10.0 → 9.10.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": "9.10.0",
3
+ "version": "9.10.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",
@@ -354,6 +354,7 @@
354
354
  "@inglorious/vite-plugin-jsx": "2.0.6",
355
355
  "@inglorious/vite-plugin-vue": "1.0.7",
356
356
  "@inglorious/web": "6.14.0",
357
+ "@lit-labs/ssr": "^4.1.0",
357
358
  "@storybook/addon-docs": "^10.6.5",
358
359
  "@storybook/web-components-vite": "^10.6.5",
359
360
  "happy-dom": "^20.14.0",
@@ -9,6 +9,7 @@ import { ref } from "@inglorious/web/directives/ref"
9
9
  import { when } from "@inglorious/web/directives/when"
10
10
 
11
11
  import { applyElementProps } from "../../shared/apply-element-props.js"
12
+ import { liveBoolean } from "../../shared/live-boolean.js"
12
13
 
13
14
  /**
14
15
  * Renders a labeled checkbox for boolean input.
@@ -51,7 +52,8 @@ export function render(props) {
51
52
  class="iw-checkbox-input"
52
53
  type="checkbox"
53
54
  name=${name}
54
- .checked=${isChecked}
55
+ ?checked=${isChecked}
56
+ ${liveBoolean("checked", isChecked)}
55
57
  ?disabled=${isDisabled}
56
58
  ?required=${isRequired}
57
59
  @change=${(event) => onChange?.(event.target.checked)}
@@ -46,6 +46,7 @@ export function open(entity) {
46
46
  /** @param {SelectEntity} entity */
47
47
  export function close(entity) {
48
48
  entity.isOpen = false
49
+ entity.searchTerm = ""
49
50
  entity.focusedIndex = NONE
50
51
  }
51
52
 
@@ -67,7 +68,7 @@ export function optionSelect(entity, option, api) {
67
68
  if (normalizedOption.isDisabled) return
68
69
  const optionValue = getOptionValue(normalizedOption)
69
70
 
70
- if (normalizedOption.isCreated) {
71
+ if (normalizedOption.isCreated || entity.searchTerm) {
71
72
  entity.searchTerm = ""
72
73
  entity.focusedIndex = NONE
73
74
  }
@@ -12,6 +12,7 @@ import { when } from "@inglorious/web/directives/when"
12
12
 
13
13
  import { Chip } from "../../data-display/chip/index.js"
14
14
  import { fallbackLabel } from "../../shared/fallback-label.js"
15
+ import { liveBoolean } from "../../shared/live-boolean.js"
15
16
  import { syncPopover } from "../../shared/top-layer.js"
16
17
  import {
17
18
  formatOption,
@@ -384,7 +385,8 @@ export const Combobox = {
384
385
  () =>
385
386
  html`<input
386
387
  type="checkbox"
387
- .checked=${isSelected}
388
+ ?checked=${isSelected}
389
+ ${liveBoolean("checked", isSelected)}
388
390
  ?disabled=${!!normalized.isDisabled}
389
391
  />`,
390
392
  )}
@@ -9,6 +9,7 @@ import { ref } from "@inglorious/web/directives/ref"
9
9
  import { when } from "@inglorious/web/directives/when"
10
10
 
11
11
  import { applyElementProps } from "../../shared/apply-element-props.js"
12
+ import { liveBoolean } from "../../shared/live-boolean.js"
12
13
 
13
14
  /**
14
15
  * Renders a group of radio options for single selection.
@@ -72,7 +73,8 @@ export function render(props) {
72
73
  type="radio"
73
74
  name=${groupName || nothing}
74
75
  value=${optionValue}
75
- .checked=${value === optionValue}
76
+ ?checked=${value === optionValue}
77
+ ${liveBoolean("checked", value === optionValue)}
76
78
  ?disabled=${isDisabled || optionDisabled}
77
79
  @change=${(event) => onChange?.(event.target.value)}
78
80
  ${ref((element) => applyElementProps(element, optionRest))}
@@ -6,6 +6,8 @@
6
6
  import { html, nothing } from "@inglorious/web"
7
7
  import { classMap } from "@inglorious/web/directives/class-map"
8
8
 
9
+ import { liveBoolean } from "../../shared/live-boolean.js"
10
+
9
11
  const DEFAULT_VALUE = 0
10
12
  const DEFAULT_MAX = 5
11
13
  const INDEX_TO_RATING = 1
@@ -62,7 +64,8 @@ export function render(props) {
62
64
  name=${groupName || nothing}
63
65
  value=${ratingValue}
64
66
  aria-label=${`${ratingValue} of ${max}`}
65
- .checked=${ratingValue === value}
67
+ ?checked=${ratingValue === value}
68
+ ${liveBoolean("checked", ratingValue === value)}
66
69
  @change=${() => onChange?.(ratingValue)}
67
70
  />
68
71
  <span aria-hidden="true">${isActive ? symbol : emptySymbol}</span>
@@ -10,6 +10,7 @@ import { when } from "@inglorious/web/directives/when"
10
10
 
11
11
  import { Icon } from "../../data-display/icon/index.js"
12
12
  import { fallbackLabel } from "../../shared/fallback-label.js"
13
+ import { liveBoolean } from "../../shared/live-boolean.js"
13
14
  import { formatOption, getOptionValue, isOptionSelected } from "./helpers.js"
14
15
 
15
16
  /**
@@ -111,10 +112,6 @@ export const Select = {
111
112
  "iw-select-control-error": !!error,
112
113
  }
113
114
 
114
- const selectedOption = options.find(
115
- (option) => getOptionValue(option) === value,
116
- )
117
-
118
115
  return html`<div class="iw-select-frame" @click=${openFromArrowStrip}>
119
116
  ${when(icon, () => Icon.render({ children: icon, size }))}
120
117
 
@@ -137,15 +134,11 @@ export const Select = {
137
134
  (option) => getOptionValue(option),
138
135
  (option) => {
139
136
  const {
140
- value,
137
+ value: optionValue,
141
138
  label,
142
139
  isDisabled: isOptionDisabled,
143
140
  } = formatOption(option)
144
- const isSelected = isOptionSelected(
145
- option,
146
- selectedOption?.value,
147
- isMulti,
148
- )
141
+ const isSelected = isOptionSelected(option, value, isMulti)
149
142
 
150
143
  const optionClasses = {
151
144
  "iw-select-option": true,
@@ -153,8 +146,9 @@ export const Select = {
153
146
  }
154
147
 
155
148
  return html`<option
156
- value=${value}
157
- .selected=${value === selectedOption?.value}
149
+ value=${optionValue}
150
+ ?selected=${isSelected}
151
+ ${liveBoolean("selected", isSelected)}
158
152
  ?disabled=${isOptionDisabled}
159
153
  class=${classMap(optionClasses)}
160
154
  >
@@ -9,6 +9,7 @@ import { ref } from "@inglorious/web/directives/ref"
9
9
  import { when } from "@inglorious/web/directives/when"
10
10
 
11
11
  import { applyElementProps } from "../../shared/apply-element-props.js"
12
+ import { liveBoolean } from "../../shared/live-boolean.js"
12
13
 
13
14
  /**
14
15
  * Renders a toggle switch backed by a checkbox input, which `role="switch"`
@@ -49,7 +50,8 @@ export function render(props) {
49
50
  type="checkbox"
50
51
  role="switch"
51
52
  name=${name}
52
- .checked=${isChecked}
53
+ ?checked=${isChecked}
54
+ ${liveBoolean("checked", isChecked)}
53
55
  ?disabled=${isDisabled}
54
56
  @change=${(event) => onChange?.(event.target.checked)}
55
57
  ${ref((element) => applyElementProps(element, rest))}
@@ -13,6 +13,7 @@
13
13
  color: var(--iw-badge-on-accent);
14
14
  font-size: var(--iw-font-size-xs, 0.75rem);
15
15
  line-height: 1;
16
+ white-space: nowrap;
16
17
 
17
18
  &.iw-badge-sm {
18
19
  --iw-badge-shape-size: 0.5rem;
@@ -0,0 +1,17 @@
1
+ import { ref } from "@inglorious/web/directives/ref"
2
+
3
+ /**
4
+ * Keeps an element's `checked` or `selected` property in step with the state.
5
+ *
6
+ * A `.checked=${false}` binding can't be used instead: server rendering
7
+ * reflects it as `checked="false"`, which HTML reads as checked. Templates pair
8
+ * this with the boolean attribute (`?checked=${value}`), which renders right on
9
+ * the server but stops counting once the user has touched the control.
10
+ * @param {"checked" | "selected"} name
11
+ * @param {boolean} value
12
+ */
13
+ export function liveBoolean(name, value) {
14
+ return ref((element) => {
15
+ if (element) element[name] = value
16
+ })
17
+ }