@nxgt/material 3.106.0 → 3.107.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.
@@ -1363,6 +1363,8 @@ import { Badge, ProductTile, ResponsiveGrid } from '@nxgt/material/components';
1363
1363
  </ResponsiveGrid>
1364
1364
  ```
1365
1365
 
1366
+ A `selected` tile gets `aria-pressed`, a tint, a 2px ring and a bar at the start. The edge is `--primary-indicator`, 3:1 or more against the Card in light and dark (the bar is the cue that does not rely on hue). The look is the `nxgt-tile-selected` class (from `tile-selected.css`).
1367
+
1366
1368
  | Prop | Type | Default | Effect |
1367
1369
  | --- | --- | --- | --- |
1368
1370
  | `title` | `ReactNode` | required | The name, up to two lines |
@@ -1370,14 +1372,21 @@ import { Badge, ProductTile, ResponsiveGrid } from '@nxgt/material/components';
1370
1372
  | `status` | `ReactNode` | none | The stock state, on its own line under the price (a `Badge`) |
1371
1373
  | `image` | `string` | none | The photo's URL (a square one fits best), in a tinted 4:3 well, lazy loaded, with an empty `alt` (the title names the tile). If it fails to load, the toned `icon` shape takes its place |
1372
1374
  | `imageFit` | `'contain' \| 'cover'` | `contain` | `contain` for a cut-out PNG or a packshot on white, `cover` for a full-bleed photo |
1373
- | `icon`, `tone`, `shape` | `IconName`, `Tone`, `ShapeName` | `primary`, `squircle` | Without an `image` (or when it fails), a toned shape with this icon, in the same 4:3 well, so tiles with and without a photo share one height |
1375
+ | `icon`, `tone`, `shape` | `IconName`, `Tone`, `ShapeName` | `primary`, `squircle` | Without an `image` (or when it fails), a toned shape with this icon, in the same 4:3 well (3:2 with `size="sm"`), so tiles with and without a photo share one height |
1374
1376
  | `media` | `ReactNode` | none | Your own media in place of the box; replaces `image` and `icon` |
1377
+ | `size` | `'md' \| 'sm'` | `md` | `sm` is the compact tile for a dense grid (`minItem` near 7.5 to 9rem, 6 to 7 columns on a desktop, 2 at 360 px): a 3:2 media box instead of 4:3, `p-1.5` instead of `p-2`, smaller name and price type, a smaller icon shape. It keeps the 44 px target and the accessible name |
1375
1378
  | `selected` | `boolean` | `false` | `aria-pressed`, a tint and a bar at the start (the item is in the basket) |
1376
1379
  | `disabled` | `boolean` | `false` | Dimmed and not tappable; its text, status included, is still read |
1377
1380
  | `asChild` | `boolean` | `false` | Render inside the one child (a router `Link`): `<ProductTile asChild title="…"><Link to="…" /></ProductTile>`. `selected` is then `aria-current`, `disabled` is `aria-disabled`, `tabIndex={-1}` and a cancelled click, so a link leaves the Tab order and Enter does not follow it; `onClick` is not called |
1378
1381
 
1379
1382
  The tile is one `button` named by its text: `getByRole('button', { name: /Orange juice.*1,500/ })`. It is a hairline card, at least 44 px high under a coarse pointer, and fills its grid cell (`h-full`): the name takes two lines and the status line is always reserved, so tiles of a row share one height. `minItem="9rem"` gives two columns at 360 px. It has a pressed state, a focus ring and a dark mode. It takes the `button`'s props, so `className` adds to it.
1380
1383
 
1384
+ ```tsx
1385
+ <ResponsiveGrid minItem="7.5rem" gap="sm">
1386
+ <ProductTile size="sm" title="Orange juice 1 L" price="1,500" icon="bottle-water" />
1387
+ </ResponsiveGrid>
1388
+ ```
1389
+
1381
1390
  **Storybook:** `Buttons & actions/ProductTile` · **Vue:** later
1382
1391
 
1383
1392
  ---
@@ -1163,6 +1163,8 @@ import { ListTile } from '@nxgt/material/components';
1163
1163
  <ListTile title="Notifications" subtitle="Email and push" href="/settings/notifications" />
1164
1164
  ```
1165
1165
 
1166
+ `selected` draws a tint, a 2px ring and a bar at the start, from `--primary-indicator` (and `--primary-text` for the tint in dark): the edge is 3:1 or more against the surface in light and dark, and the bar tells it apart without hue. A `divided` row keeps the bar only. The look is the `nxgt-tile-selected` class (`tile-selected.css`); a `className` of your own should not repaint its `background` or `box-shadow`.
1167
+
1166
1168
  A tile with an `href` ends with a discreet chevron after `trailing`: decorative (`aria-hidden`, so the link's name stays its text) and flipped in right-to-left. `chevron={false}` opts out; `chevron` on a button tile (an `onClick` that navigates) opts in.
1167
1169
 
1168
1170
  | Prop | Type | Default | Effect |
@@ -173,6 +173,8 @@ written at `=`.
173
173
  - The settlement row carries a tone: **success** while the payment covers the
174
174
  total (change may be `0`), **warning** while an amount is still due, with the
175
175
  figure emphasised (AA text on a tinted band, light and dark).
176
+ - The chips have a visible edge in the theme's AA primary text tone: 3:1
177
+ against the surface and 4.5:1 for the label, in light and dark.
176
178
  - The keys follow one scheme: digits neutral, the editing keys (C, backspace)
177
179
  one tone, the commit key filled primary, the quick amounts tonal chips in a
178
180
  two-column grid (an odd last chip takes the full row; amounts never
@@ -182,7 +184,12 @@ written at `=`.
182
184
  without one the commit key does nothing.
183
185
 
184
186
  Use `entry="minor"` for a till that types cents, and `size="large"` for a
185
- counter's touch screen.
187
+ counter's touch screen. A keypad docked permanently in a narrow column (a
188
+ till's quantity and cash pad beside the ticket) takes `size="compact"`:
189
+
190
+ ```tsx
191
+ <Keypad variant="cash" size="compact" total={17.35} currency="EUR" onTender={tender} />
192
+ ```
186
193
 
187
194
  ## Props
188
195
 
@@ -198,10 +205,11 @@ counter's touch screen.
198
205
  | `fractionDigits` | the currency's, else any | Decimals kept |
199
206
  | `min`, `max` | none | See [Limits](#limits) |
200
207
  | `keyboard` | `'focus'` | `'focus'`, `'global'` or `false` |
201
- | `size` | `'comfortable'` | `'comfortable'` or `'large'` |
208
+ | `size` | `'comfortable'` | `'comfortable'`, `'large'` or `'compact'` (docked use) |
202
209
  | `display` | `true`, `false` with a `binding` and no `operations` | Shows the amount above the keys |
203
- | `commitLabel` | translated "Enter" ("Tender" in cash) | The commit key's name and text |
210
+ | `commitLabel` | translated "Enter" ("Tender" in cash) | The commit key's name and text. A named key shows "✓ label" and takes a full-width row under the zero key, so a till's "Charge" reads whole |
204
211
  | `disabled` | `false` | Keys do nothing and say so (`aria-disabled`) |
212
+ | `placeholder` | none | Muted hint while the entry is empty, also with a `currency` (visual only, `aria-hidden`; not shown on an error) |
205
213
  | `label` | "Keypad" | The group's accessible name |
206
214
  | `variant`, `total`, `denominations`, `onTender` | `'standard'` | See [Cash](#cash) |
207
215
  | `className` | | On the root |
@@ -210,10 +218,17 @@ Types: `KeypadProps`, `KeypadEntry`, `KeypadOperation`, `KeypadVariant`, `Keypad
210
218
 
211
219
  ## Sizing and styles
212
220
 
213
- The keypad sizes by its own width with the calculator's bands (compact under
214
- 360px, wider keys from 600px) and is at most 24rem wide. `size="large"` gives
215
- taller keys. Colours and shapes follow the theme and dark mode through
216
- `styles.css`; the key rules are shared with the calculator in `calculator.css`.
221
+ The keypad sizes by its own width with the calculator's bands (a narrow band
222
+ under 360px, wider keys from 600px, automatic) and is at most 24rem wide. The
223
+ `size` prop is separate: `size="large"` gives
224
+ taller keys. `size="compact"` is for a keypad docked beside other content: 36px
225
+ keys, tighter gaps, a smaller display, and in cash a denser total and change
226
+ and the quick amounts (four at most) in two short columns, so none is cut at
227
+ 360px ("FCFA 20,000" fits). A 4-row pad with its display fits about
228
+ 320px of height (the cash variant a little more, and a named `commitLabel` key adds a fifth row). On a coarse pointer the keys
229
+ and the quick amounts stay at 44px, so a touch till gets the tighter gaps and
230
+ display but not shorter keys. Colours and shapes follow the theme and dark mode
231
+ through `styles.css`; the key rules are shared with the calculator in `calculator.css`.
217
232
 
218
233
  ## Accessibility
219
234
 
@@ -179,6 +179,8 @@
179
179
  @import "./ui/display/chip/chip-hairline.css";
180
180
  @import "./ui/display/chip/chip-soft.css";
181
181
  @import "./ui/display/chip/chip-tag.css";
182
+ /* Selected ProductTile and ListTile (#2925). */
183
+ @import "./ui/display/list-tile/tile-selected.css";
182
184
  /* Calendar: its look, then its motion (springs from motion.css). */
183
185
  @import "./ui/dates/calendar/calendar.css";
184
186
  @import "./ui/dates/calendar/calendar-expressive.css";
@@ -0,0 +1,34 @@
1
+ /* The selected look of ProductTile and ListTile (#2925): a tint, a 2px ring and a bar
2
+ * at the start. The ring and the bar are --primary-indicator, the theme's 3:1
3
+ * non-text primary (the lifted one in dark), so a selected tile is >=3:1 against
4
+ * the surface in light and dark; the tint is --primary-text in dark (the deep
5
+ * --primary gave ~1.1:1 over a Card). The bar is the cue that does not rely on
6
+ * hue. The label stays --foreground (>=4.5:1 on the tint). */
7
+ @layer components {
8
+ .nxgt-tile-selected {
9
+ --tile-on: color-mix(in oklab, var(--primary) 14%, var(--card));
10
+ --tile-edge: var(--primary-indicator);
11
+ --tile-bar: 3px;
12
+ box-shadow:
13
+ inset 0 0 0 2px var(--tile-edge),
14
+ inset var(--tile-bar) 0 0 0 var(--tile-edge);
15
+ background: var(--tile-on);
16
+ border-color: var(--tile-edge);
17
+ }
18
+ :is(.dark, [data-theme="dark"]) .nxgt-tile-selected {
19
+ --tile-on: color-mix(in oklab, var(--primary-text) 22%, var(--card));
20
+ }
21
+ .nxgt-tile-selected:dir(rtl) {
22
+ box-shadow:
23
+ inset 0 0 0 2px var(--tile-edge),
24
+ inset calc(var(--tile-bar) * -1) 0 0 0 var(--tile-edge);
25
+ }
26
+ /* A divided row is flat: the bar only, no ring. */
27
+ .nxgt-tile-selected.nxgt-tile-flat {
28
+ box-shadow: inset var(--tile-bar) 0 0 0 var(--tile-edge);
29
+ border-color: transparent;
30
+ }
31
+ .nxgt-tile-selected.nxgt-tile-flat:dir(rtl) {
32
+ box-shadow: inset calc(var(--tile-bar) * -1) 0 0 0 var(--tile-edge);
33
+ }
34
+ }
@@ -32,6 +32,9 @@
32
32
  .nxgt-calc-key[data-span="3"] {
33
33
  grid-column: span 3;
34
34
  }
35
+ .nxgt-calc-key[data-span="12"] {
36
+ grid-column: span 12;
37
+ }
35
38
  .nxgt-calc-key[data-span="9"] {
36
39
  grid-column: span 9;
37
40
  }
@@ -110,6 +110,24 @@
110
110
  --calc-key: 4.5rem;
111
111
  --calc-gap: 0.625rem;
112
112
  }
113
+ /* Compact: a keypad docked beside other content. Shorter keys, tighter gaps,
114
+ * display and cash rows. A coarse pointer keeps 44px keys (the Touch rule in
115
+ * calculator-bands.css) and chips (the block after the cash rules). */
116
+ .nxgt-keypad[data-size="compact"] .nxgt-calc-body {
117
+ --calc-key: 2.25rem;
118
+ --calc-gap: 0.25rem;
119
+ --calc-radius: 1rem;
120
+ --calc-result: 1.75rem;
121
+ gap: 0.375rem;
122
+ }
123
+ .nxgt-keypad[data-size="compact"] .nxgt-calc-key {
124
+ border-radius: 1rem;
125
+ font-size: 1.125rem;
126
+ }
127
+ .nxgt-keypad[data-size="compact"] .nxgt-calc-key[data-role="operator"],
128
+ .nxgt-keypad[data-size="compact"] .nxgt-calc-key[data-role="equals"] {
129
+ border-radius: 9999px;
130
+ }
113
131
  .nxgt-keypad-display {
114
132
  display: block;
115
133
  min-width: 0;
@@ -124,6 +142,15 @@
124
142
  direction: ltr;
125
143
  overflow-wrap: anywhere;
126
144
  }
145
+ .nxgt-keypad[data-size="compact"] .nxgt-keypad-display {
146
+ padding: 0.375rem 0.875rem;
147
+ }
148
+ .nxgt-keypad-display [data-placeholder] {
149
+ color: var(--muted-foreground);
150
+ font-size: 0.5em;
151
+ vertical-align: middle;
152
+ font-weight: 400;
153
+ }
127
154
  .nxgt-keypad-display[data-kind="error"] {
128
155
  color: var(--destructive);
129
156
  }
@@ -192,13 +219,14 @@
192
219
  padding-inline: 0.875rem;
193
220
  white-space: nowrap;
194
221
  min-height: max(calc(var(--calc-key) * 0.8), 2.75rem);
195
- border: 0;
196
222
  border-radius: 9999px;
197
- background: color-mix(
198
- in oklab,
199
- var(--primary) 16%,
200
- color-mix(in oklab, var(--foreground) 3%, var(--background))
201
- );
223
+ /* --primary is dark navy in dark mode, so a mix of it vanishes into the
224
+ * surface. --primary-text is the theme's AA primary for text, light in
225
+ * dark: 28 % of it tints the chip, 60 % draws its 1px edge (3:1 against the
226
+ * surface in light and dark, text at 8:1 and more). */
227
+ border: 1px solid
228
+ color-mix(in oklab, var(--primary-text) 60%, var(--background));
229
+ background: color-mix(in oklab, var(--primary-text) 28%, var(--background));
202
230
  color: var(--foreground);
203
231
  font: inherit;
204
232
  font-weight: 500;
@@ -213,3 +241,37 @@
213
241
  outline: 2px solid var(--ring);
214
242
  outline-offset: 2px;
215
243
  }
244
+
245
+ /* Keypad, compact: the cash rows and the quick amounts take less height. The
246
+ * amounts keep the two columns of the default size: four would give each a
247
+ * quarter of a 24rem keypad, less than "FCFA 20,000" needs, so they wrap to
248
+ * two short rows, and an amount too long for its half is cut with an ellipsis
249
+ * (its accessible name is the full amount). A coarse pointer keeps 44px chips. */
250
+ .nxgt-keypad[data-size="compact"] .nxgt-keypad-cash {
251
+ gap: 0.125rem;
252
+ }
253
+ .nxgt-keypad[data-size="compact"] .nxgt-keypad-cash > div {
254
+ padding-inline: 0.875rem;
255
+ }
256
+ .nxgt-keypad[data-size="compact"] .nxgt-keypad-cash dd {
257
+ font-size: 1rem;
258
+ }
259
+ .nxgt-keypad[data-size="compact"] .nxgt-keypad-cash [data-status] {
260
+ padding-block: 0.125rem;
261
+ border-radius: 0.75rem;
262
+ }
263
+ .nxgt-keypad[data-size="compact"] .nxgt-keypad-cash [data-status] dd {
264
+ font-size: 1.25rem;
265
+ }
266
+ .nxgt-keypad[data-size="compact"] .nxgt-keypad-shortcuts button {
267
+ min-height: 2rem;
268
+ padding-inline: 0.5rem;
269
+ font-size: 0.875rem;
270
+ overflow: hidden;
271
+ text-overflow: ellipsis;
272
+ }
273
+ @media (pointer: coarse) {
274
+ .nxgt-keypad[data-size="compact"] .nxgt-keypad-shortcuts button {
275
+ min-height: 2.75rem;
276
+ }
277
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxgt/material",
3
- "version": "3.106.0",
3
+ "version": "3.107.1",
4
4
  "license": "MIT",
5
5
  "bugs": {
6
6
  "email": "stevegires@gmail.com"