@nxgt/material 3.54.0 → 3.55.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 (71) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -0
  3. package/dist/{async-slice-DDSsekfm.js → async-slice-yhXT9cml.js} +2 -2
  4. package/dist/{button-Ct8DSLVv.js → button-CD7f4KFL.js} +1 -1
  5. package/dist/charts.js +3 -3
  6. package/dist/{chip-BzoNsd-W.js → chip-Cl7Wm8Pn.js} +2 -2
  7. package/dist/{code-editor-DsLQeiZc.js → code-editor-tOhXy6Qo.js} +6 -6
  8. package/dist/code-editor.js +5 -5
  9. package/dist/{code-language-items-4zXlIEZ0.js → code-language-items-BxlY6onk.js} +2 -2
  10. package/dist/components/components.css +4 -0
  11. package/dist/components/ui/display/seat-ring/seat-ring-index.css +125 -0
  12. package/dist/components/ui/display/seat-ring/seat-ring-ring.css +87 -0
  13. package/dist/components/ui/display/seat-ring/seat-ring.css +139 -0
  14. package/dist/{components-DFG2mgsM.js → components-B58ZWZYR.js} +15485 -15285
  15. package/dist/components.js +26 -26
  16. package/dist/{dialog-DwPmwmA3.js → dialog-BzfHcRo6.js} +4 -4
  17. package/dist/dnd.js +1 -1
  18. package/dist/{dropdown-menu-CDN6Nqx6.js → dropdown-menu-DUZF4xAJ.js} +1 -1
  19. package/dist/editor.js +9 -9
  20. package/dist/{empty-state-Bb9W9did.js → empty-state-D9o2id1p.js} +2 -2
  21. package/dist/{escape-owner-DI_lg2ID.js → escape-owner-BYs2_7T5.js} +1 -1
  22. package/dist/{field-blur-context-Dg1nwWOV.js → field-blur-context-ZsK8OTNg.js} +1 -1
  23. package/dist/{field-blur-BcJH8H9B.js → field-blur-r1tHwqdF.js} +1 -1
  24. package/dist/hooks.js +2 -2
  25. package/dist/{hover-card-Qse4gnop.js → hover-card-NfF8taLj.js} +2 -2
  26. package/dist/{i18n-provider-DlVPS58N.js → i18n-provider-TQAEPlJ5.js} +1 -1
  27. package/dist/i18n.js +5 -5
  28. package/dist/{icon-badge-DVPBQOKe.js → icon-badge-BlaY_a-P.js} +3 -3
  29. package/dist/{icon-button-C3wDxsh6.js → icon-button-B8tdlP6R.js} +1 -1
  30. package/dist/lib/components/ui/display/index.d.ts +1 -0
  31. package/dist/lib/components/ui/display/seat-ring/index.d.ts +2 -0
  32. package/dist/lib/components/ui/display/seat-ring/partials/empty-seat.d.ts +5 -0
  33. package/dist/lib/components/ui/display/seat-ring/partials/seat-body.d.ts +9 -0
  34. package/dist/lib/components/ui/display/seat-ring/partials/seat-item.d.ts +17 -0
  35. package/dist/lib/components/ui/display/seat-ring/seat-ring.d.ts +9 -0
  36. package/dist/lib/components/ui/display/seat-ring/seat-ring.utils.d.ts +9 -0
  37. package/dist/lib/components/ui/display/seat-ring/types.d.ts +67 -0
  38. package/dist/lib/components/ui/display/seat-ring/use-seat-ring.d.ts +12 -0
  39. package/dist/lib/components/ui/fields/contacts/placeholders.d.ts +1 -1
  40. package/dist/lib/i18n/resources/en/en.d.ts +3 -0
  41. package/dist/lib/i18n/resources/en/material.json.d.ts +3 -0
  42. package/dist/lib/i18n/resources/fr/fr.d.ts +3 -0
  43. package/dist/lib/i18n/resources/fr/material.json.d.ts +3 -0
  44. package/dist/lib/i18n/resources/resources.d.ts +6 -0
  45. package/dist/lib/i18n/translator.d.ts +1 -1
  46. package/dist/lib.js +1 -1
  47. package/dist/main.js +43 -43
  48. package/dist/map.js +8 -8
  49. package/dist/material.css +1 -1
  50. package/dist/pdf-reader.js +1 -1
  51. package/dist/print.js +2 -2
  52. package/dist/{public-BoVE0ffh.js → public-tWgM204K.js} +9 -9
  53. package/dist/{rich-code-block-DAUM7Yh_.js → rich-code-block-0OcsqURY.js} +5 -5
  54. package/dist/{sortable-provider-BLXsGE_0.js → sortable-provider-DzFAlPU_.js} +2 -2
  55. package/dist/{spinner-Rg4PnBPH.js → spinner-GKZcQmrR.js} +1 -1
  56. package/dist/{stored-language-B1lJMPbR.js → stored-language-B39mABN7.js} +2 -0
  57. package/dist/theme-picker.js +2 -2
  58. package/dist/{theme-toggle-jVdxF_mc.js → theme-toggle-C8idk_jQ.js} +1 -1
  59. package/dist/{toolbar-items-BFY_hns5.js → toolbar-items-BrJI-BCs.js} +4 -4
  60. package/dist/{translate-material-q-JNxP1m.js → translate-material-hUA-UAP6.js} +2 -2
  61. package/dist/{translator-BU1o3_l9.js → translator-1ql2sxrx.js} +1 -1
  62. package/dist/{use-chat-composer-DGbDuIUa.js → use-chat-composer-DQpb8ZXV.js} +16 -16
  63. package/dist/{use-heading-spy-CP63sAcS.js → use-heading-spy-vlPOI1Aj.js} +1 -1
  64. package/dist/{use-material-translation-nNF8fUXz.js → use-material-translation-B1p5y3s9.js} +2 -2
  65. package/docs/components/data-display.md +65 -0
  66. package/docs/previews/data-display-seatring.webp +0 -0
  67. package/lib/components/components.css +4 -0
  68. package/lib/components/ui/display/seat-ring/seat-ring-index.css +125 -0
  69. package/lib/components/ui/display/seat-ring/seat-ring-ring.css +87 -0
  70. package/lib/components/ui/display/seat-ring/seat-ring.css +139 -0
  71. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @nxgt/material
2
2
 
3
+ ## 3.55.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1930](https://github.com/softistx/nxgt-material/pull/1930) [`ea953b1`](https://github.com/softistx/nxgt-material/commit/ea953b15b2d0878c065d4df29d8d5e9e2e5e94cd) Thanks [@SteveGT96](https://github.com/SteveGT96)! - New `SeatRing`: participants as seats around a circle, or in a two-column grid when its own box is narrow (a container query, so it follows a column or a dialog, not the window). Each seat takes an avatar (default: the label's initials), a label, a status written in words with a tone, a badge and `disabled` / `empty` flags; `renderAvatar`, `renderStatus`, `renderBadge`, `renderEmptySeat` and `centerSlot` replace the defaults, `highlightedId` marks whose turn it is, and `size` is `sm`, `md` or `lg`. Without `selectionMode` it is a `list`; with `selectionMode="single"` or `"multiple"` (`value`, `defaultValue`, `onValueChange`) it is a `listbox` of `option`s with a roving tab stop: arrows, Home and End move, Space or Enter picks, and the selection is shown with a check as well as a tint. New `material.seat-ring.empty` key in English and French. Closes [#1911](https://github.com/softistx/nxgt-material/issues/1911).
8
+
3
9
  ## 3.54.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -599,6 +599,7 @@ Not components: what the stylesheet gives any element.
599
599
  | --- | --- | --- | --- |
600
600
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-avatar.webp" width="120" alt="Avatar"> | [`Avatar`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#avatar), `AvatarImage`, `AvatarFallback`, `AvatarBase` | Image with a fallback and an optional online / offline dot; `shape` clips it to an expressive shape; the initials scale with the size (40 % of the diameter); `tone` colours the fallback. | `Avatar`, `AvatarImage`, `AvatarFallback` |
601
601
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-avatargroup.webp" width="120" alt="AvatarGroup"> | [`AvatarGroup`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#avatargroup) | Overlapping avatars with a `+N` overflow. | `AvatarGroup` |
602
+ | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-seatring.webp" width="120" alt="SeatRing"> | [`SeatRing`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#seatring) | Participants as seats around a circle, or in a grid on a narrow box; avatar, name, status, badge and centre slots; optionally a listbox to pick one or several (`selectionMode`). | — |
602
603
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-shape.webp" width="120" alt="Shape"> | [`Shape`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#shape) | Material 3 Expressive's 35 shapes and a squircle as a backdrop, an icon container or a mask for a photo, with a morph; eight tones or an app tone. | — |
603
604
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-badge.webp" width="120" alt="Badge"> | [`Badge`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#badge) | Status pill, 20 px: default, secondary, error, success, info, warning, `soft` (tonal, for states), outlined; an optional decorative `icon` before the words. | `Badge` |
604
605
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-countbadge.webp" width="120" alt="CountBadge"> | [`CountBadge`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#countbadge) | Count in the corner of its children, capped at `99+` and hidden at 0; `animated` pops it in when it changes. | `CountBadge` |
@@ -1,5 +1,5 @@
1
- import { i as e, r as t, t as n } from "./stored-language-B1lJMPbR.js";
2
- import { r } from "./translator-BU1o3_l9.js";
1
+ import { i as e, r as t, t as n } from "./stored-language-B39mABN7.js";
2
+ import { r } from "./translator-1ql2sxrx.js";
3
3
  import { t as i } from "./_baseIsEqual-C6ksIHya.js";
4
4
  import { useMemo as a } from "react";
5
5
  import { asyncThunkCreator as o, buildCreateSlice as s } from "@reduxjs/toolkit";
@@ -1,7 +1,7 @@
1
1
  import { t as e } from "./utils-BLfntITJ.js";
2
2
  import { t } from "./is-production-GLw59WU8.js";
3
3
  import { n, t as r } from "./dist-DVRQkaTK.js";
4
- import { n as i, r as a, t as o } from "./spinner-Rg4PnBPH.js";
4
+ import { n as i, r as a, t as o } from "./spinner-GKZcQmrR.js";
5
5
  import { a as s, i as c, n as l, o as u, s as d, t as f } from "./use-click-lock-BZYtTmVt.js";
6
6
  import { t as p } from "./button-group-context-CaP0X5p_.js";
7
7
  import { t as m } from "./has-text-content-Ds2dkHX_.js";
package/dist/charts.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { t as e } from "./ui.utils-CAnKTCw5.js";
2
2
  import { t } from "./utils-BLfntITJ.js";
3
3
  import { t as n } from "./warn-once-C_e47JM8.js";
4
- import { t as r } from "./use-material-translation-nNF8fUXz.js";
5
- import { t as i } from "./button-Ct8DSLVv.js";
4
+ import { t as r } from "./use-material-translation-B1p5y3s9.js";
5
+ import { t as i } from "./button-CD7f4KFL.js";
6
6
  import { t as a } from "./use-ssr-media-query-C6M5m8sf.js";
7
7
  import { i as o, n as s, r as c, t as l } from "./util-4heV2LPI.js";
8
8
  import { t as u } from "./useIsomorphicLayoutEffect-DfgAhWcH.js";
9
- import { t as d } from "./chip-BzoNsd-W.js";
9
+ import { t as d } from "./chip-Cl7Wm8Pn.js";
10
10
  import { c as f, d as p, f as m, i as h, o as g, p as _, s as v, t as y } from "./line-path-C5pZGC49.js";
11
11
  import { t as b } from "./live-status-BGPaN8r8.js";
12
12
  import { t as x } from "./linear-G97mfnKF.js";
@@ -1,7 +1,7 @@
1
1
  import { t as e } from "./utils-BLfntITJ.js";
2
- import { r as t } from "./spinner-Rg4PnBPH.js";
2
+ import { r as t } from "./spinner-GKZcQmrR.js";
3
3
  import { s as n } from "./use-click-lock-BZYtTmVt.js";
4
- import { t as r } from "./use-material-translation-nNF8fUXz.js";
4
+ import { t as r } from "./use-material-translation-B1p5y3s9.js";
5
5
  import { t as i } from "./react-node-text-Crkpfpco.js";
6
6
  import { cloneElement as a, isValidElement as o } from "react";
7
7
  import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
@@ -2,13 +2,13 @@ import { r as e } from "./rolldown-runtime-BFFgcFxR.js";
2
2
  import { t } from "./utils-BLfntITJ.js";
3
3
  import { t as n } from "./is-production-GLw59WU8.js";
4
4
  import { a as r } from "./dist-lmHmz_bu.js";
5
- import { c as i, d as a, f as o, n as s, t as c } from "./dropdown-menu-CDN6Nqx6.js";
6
- import { a as l, i as u, n as d } from "./field-blur-context-Dg1nwWOV.js";
7
- import { a as f, d as p, r as m, t as h, u as g } from "./toolbar-items-BFY_hns5.js";
8
- import { t as _ } from "./use-material-translation-nNF8fUXz.js";
9
- import { i as v, n as y, o as b, t as x } from "./code-language-items-4zXlIEZ0.js";
5
+ import { c as i, d as a, f as o, n as s, t as c } from "./dropdown-menu-DUZF4xAJ.js";
6
+ import { a as l, i as u, n as d } from "./field-blur-context-ZsK8OTNg.js";
7
+ import { a as f, d as p, r as m, t as h, u as g } from "./toolbar-items-BrJI-BCs.js";
8
+ import { t as _ } from "./use-material-translation-B1p5y3s9.js";
9
+ import { i as v, n as y, o as b, t as x } from "./code-language-items-BxlY6onk.js";
10
10
  import { t as S } from "./useIsomorphicLayoutEffect-DfgAhWcH.js";
11
- import { n as C, t as w } from "./escape-owner-DI_lg2ID.js";
11
+ import { n as C, t as w } from "./escape-owner-BYs2_7T5.js";
12
12
  import { t as T } from "./skeleton-DSdtr2qc.js";
13
13
  import { t as E } from "./react-node-text-Crkpfpco.js";
14
14
  import D, { memo as O, useCallback as ee, useEffect as k, useId as A, useImperativeHandle as j, useMemo as M, useRef as N, useState as P } from "react";
@@ -1,14 +1,14 @@
1
1
  import { t as e } from "./utils-BLfntITJ.js";
2
2
  import { a as t } from "./dist-lmHmz_bu.js";
3
- import { d as n, r, t as i, u as a } from "./toolbar-items-BFY_hns5.js";
4
- import { t as o } from "./use-material-translation-nNF8fUXz.js";
5
- import { i as s, n as c, o as l } from "./code-language-items-4zXlIEZ0.js";
6
- import { r as u, t as d } from "./field-blur-BcJH8H9B.js";
3
+ import { d as n, r, t as i, u as a } from "./toolbar-items-BrJI-BCs.js";
4
+ import { t as o } from "./use-material-translation-B1p5y3s9.js";
5
+ import { i as s, n as c, o as l } from "./code-language-items-BxlY6onk.js";
6
+ import { r as u, t as d } from "./field-blur-r1tHwqdF.js";
7
7
  import { t as f } from "./skeleton-DSdtr2qc.js";
8
8
  import { t as p } from "./live-status-BGPaN8r8.js";
9
9
  import { t as m } from "./use-mobile-BDro060N.js";
10
10
  import { t as h } from "./react-node-text-Crkpfpco.js";
11
- import { a as g, c as _, d as v, f as y, i as b, l as x, m as S, o as C, p as w, r as T, s as E, t as D, u as O } from "./code-editor-DsLQeiZc.js";
11
+ import { a as g, c as _, d as v, f as y, i as b, l as x, m as S, o as C, p as w, r as T, s as E, t as D, u as O } from "./code-editor-tOhXy6Qo.js";
12
12
  import { useEffect as k, useRef as A, useState as j } from "react";
13
13
  import { Fragment as M, jsx as N, jsxs as P } from "react/jsx-runtime";
14
14
  import { ChevronDown as F, ChevronUp as I, Columns2 as L } from "lucide-react";
@@ -1,5 +1,5 @@
1
- import { d as e, f as t } from "./dropdown-menu-CDN6Nqx6.js";
2
- import { t as n } from "./use-material-translation-nNF8fUXz.js";
1
+ import { d as e, f as t } from "./dropdown-menu-DUZF4xAJ.js";
2
+ import { t as n } from "./use-material-translation-B1p5y3s9.js";
3
3
  import { t as r } from "./live-status-BGPaN8r8.js";
4
4
  import { useEffect as i, useRef as a, useState as o } from "react";
5
5
  import { jsx as s } from "react/jsx-runtime";
@@ -134,6 +134,10 @@
134
134
  @import "./ui/display/period-cards/period-cards.css";
135
135
  @import "./ui/layout/sidebar/sidebar-tokens.css";
136
136
  @import "./ui/display/avatar/avatar.css";
137
+ /* SeatRing: seats as a grid or on a circle by its own width. */
138
+ @import "./ui/display/seat-ring/seat-ring.css";
139
+ @import "./ui/display/seat-ring/seat-ring-index.css";
140
+ @import "./ui/display/seat-ring/seat-ring-ring.css";
137
141
  /* Alert and Banner span the row in the form grids (#1497). */
138
142
  @import "./ui/feedback/alert/alert.css";
139
143
  @import "./ui/display/stat-card/stat-card.css";
@@ -0,0 +1,125 @@
1
+ /* SeatRing: the seat count `--n` and the seat's index `--i`, from data
2
+ * attributes, for the circle's trigonometry (seat-ring-ring.css). Server
3
+ * markup carries no `style`. Up to 10 seats (RING_LIMIT); more is a grid. */
4
+ @layer components {
5
+ .nxgt-seat-ring[data-count="1"] {
6
+ --n: 1;
7
+ }
8
+ .nxgt-seat-ring[data-count="2"] {
9
+ --n: 2;
10
+ }
11
+ .nxgt-seat-ring[data-count="3"] {
12
+ --n: 3;
13
+ }
14
+ .nxgt-seat-ring[data-count="4"] {
15
+ --n: 4;
16
+ }
17
+ .nxgt-seat-ring[data-count="5"] {
18
+ --n: 5;
19
+ }
20
+ .nxgt-seat-ring[data-count="6"] {
21
+ --n: 6;
22
+ }
23
+ .nxgt-seat-ring[data-count="7"] {
24
+ --n: 7;
25
+ }
26
+ .nxgt-seat-ring[data-count="8"] {
27
+ --n: 8;
28
+ }
29
+ .nxgt-seat-ring[data-count="9"] {
30
+ --n: 9;
31
+ }
32
+ .nxgt-seat-ring[data-count="10"] {
33
+ --n: 10;
34
+ }
35
+ .nxgt-seat-ring[data-count="11"] {
36
+ --n: 11;
37
+ }
38
+ .nxgt-seat-ring[data-count="12"] {
39
+ --n: 12;
40
+ }
41
+ .nxgt-seat-ring[data-count="13"] {
42
+ --n: 13;
43
+ }
44
+ .nxgt-seat-ring[data-count="14"] {
45
+ --n: 14;
46
+ }
47
+ .nxgt-seat-ring[data-count="15"] {
48
+ --n: 15;
49
+ }
50
+ .nxgt-seat-ring[data-count="16"] {
51
+ --n: 16;
52
+ }
53
+ .nxgt-seat-ring[data-count="17"] {
54
+ --n: 17;
55
+ }
56
+ .nxgt-seat-ring[data-count="18"] {
57
+ --n: 18;
58
+ }
59
+ .nxgt-seat-ring[data-count="19"] {
60
+ --n: 19;
61
+ }
62
+ .nxgt-seat-ring[data-count="20"] {
63
+ --n: 20;
64
+ }
65
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="0"] {
66
+ --i: 0;
67
+ }
68
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="1"] {
69
+ --i: 1;
70
+ }
71
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="2"] {
72
+ --i: 2;
73
+ }
74
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="3"] {
75
+ --i: 3;
76
+ }
77
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="4"] {
78
+ --i: 4;
79
+ }
80
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="5"] {
81
+ --i: 5;
82
+ }
83
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="6"] {
84
+ --i: 6;
85
+ }
86
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="7"] {
87
+ --i: 7;
88
+ }
89
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="8"] {
90
+ --i: 8;
91
+ }
92
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="9"] {
93
+ --i: 9;
94
+ }
95
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="10"] {
96
+ --i: 10;
97
+ }
98
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="11"] {
99
+ --i: 11;
100
+ }
101
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="12"] {
102
+ --i: 12;
103
+ }
104
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="13"] {
105
+ --i: 13;
106
+ }
107
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="14"] {
108
+ --i: 14;
109
+ }
110
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="15"] {
111
+ --i: 15;
112
+ }
113
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="16"] {
114
+ --i: 16;
115
+ }
116
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="17"] {
117
+ --i: 17;
118
+ }
119
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="18"] {
120
+ --i: 18;
121
+ }
122
+ .nxgt-seat-ring [data-slot="seat-ring-seat"][data-index="19"] {
123
+ --i: 19;
124
+ }
125
+ }
@@ -0,0 +1,87 @@
1
+ /* SeatRing's circle: CSS trigonometry on `--i`, `--n` (seat-ring-index.css)
2
+ * and `--seat-dir` (-1 in a right-to-left box, so the ring is mirrored). The
3
+ * three container queries only switch `--ring-k` on the orbit once the box
4
+ * fits the seat size (32rem small, 38rem medium, 46rem large); every rule
5
+ * below reads it, as 0 (the grid of seat-ring.css) or 1 (the circle), so the
6
+ * circle's rules are written once. */
7
+ @layer components {
8
+ @container seat-ring (min-width: 32rem) {
9
+ .nxgt-seat-ring[data-layout="ring"][data-size="sm"]
10
+ [data-slot="seat-ring-orbit"] {
11
+ --ring-k: 1;
12
+ --ring-abs: absolute;
13
+ --ring-block: block;
14
+ --ring-ratio: 1;
15
+ --ring-margin: auto;
16
+ --ring-size: min(
17
+ 100%,
18
+ max(calc(var(--seat) * 3.2), calc(var(--seat) * (var(--n) * 0.6 + 1))),
19
+ 56rem
20
+ );
21
+ --ring-w: var(--seat);
22
+ }
23
+ }
24
+ @container seat-ring (min-width: 38rem) {
25
+ .nxgt-seat-ring[data-layout="ring"][data-size="md"]
26
+ [data-slot="seat-ring-orbit"] {
27
+ --ring-k: 1;
28
+ --ring-abs: absolute;
29
+ --ring-block: block;
30
+ --ring-ratio: 1;
31
+ --ring-margin: auto;
32
+ --ring-size: min(
33
+ 100%,
34
+ max(calc(var(--seat) * 3.2), calc(var(--seat) * (var(--n) * 0.6 + 1))),
35
+ 56rem
36
+ );
37
+ --ring-w: var(--seat);
38
+ }
39
+ }
40
+ @container seat-ring (min-width: 46rem) {
41
+ .nxgt-seat-ring[data-layout="ring"][data-size="lg"]
42
+ [data-slot="seat-ring-orbit"] {
43
+ --ring-k: 1;
44
+ --ring-abs: absolute;
45
+ --ring-block: block;
46
+ --ring-ratio: 1;
47
+ --ring-margin: auto;
48
+ --ring-size: min(
49
+ 100%,
50
+ max(calc(var(--seat) * 3.2), calc(var(--seat) * (var(--n) * 0.6 + 1))),
51
+ 56rem
52
+ );
53
+ --ring-w: var(--seat);
54
+ }
55
+ }
56
+
57
+ .nxgt-seat-ring [data-slot="seat-ring-orbit"] {
58
+ position: relative;
59
+ display: var(--ring-block, flex);
60
+ inline-size: var(--ring-size, auto);
61
+ aspect-ratio: var(--ring-ratio, auto);
62
+ margin-inline: var(--ring-margin, 0);
63
+ }
64
+ .nxgt-seat-ring [data-slot="seat-ring-list"] {
65
+ position: var(--ring-abs, static);
66
+ inset: 0;
67
+ }
68
+ .nxgt-seat-ring [data-slot="seat-ring-seat"] {
69
+ --a: calc(360deg * var(--i, 0) / var(--n, 1));
70
+ position: var(--ring-abs, relative);
71
+ inline-size: var(--ring-w, auto);
72
+ left: calc(
73
+ var(--ring-k, 0) *
74
+ (50% + (50% - var(--seat) / 2) * sin(var(--a)) * var(--seat-dir))
75
+ );
76
+ top: calc(
77
+ var(--ring-k, 0) *
78
+ (50% - (50% - var(--seat) / 2) * cos(var(--a)))
79
+ );
80
+ translate: calc(var(--ring-k, 0) * -50%) calc(var(--ring-k, 0) * -50%);
81
+ }
82
+ .nxgt-seat-ring [data-slot="seat-ring-center"] {
83
+ position: var(--ring-abs, static);
84
+ /* The square inside the circle of seats: the orbit's radius less a seat and a half. */
85
+ inset: calc(50% - 0.5 * max(0px, 50% - 1.1 * var(--seat)));
86
+ }
87
+ }
@@ -0,0 +1,139 @@
1
+ /* SeatRing: seats as a grid of cards, or on a circle when the box is wide
2
+ * enough. The component is a size container, so the switch follows its own
3
+ * width (a column, a dialog, a phone), never the window. The ring is pure CSS
4
+ * (trigonometry on `--i`, the seat's index, and `--n`, their count, both set by
5
+ * the attribute rules below, so server markup carries no `style`). It holds up
6
+ * to 10 seats (RING_LIMIT); more is a grid. Selected: the primary tint, a
7
+ * border and a check mark, so colour is never the only cue. */
8
+ @layer components {
9
+ .nxgt-seat-ring {
10
+ --seat: 6rem;
11
+ --seat-avatar: 2.5rem;
12
+ --seat-dir: 1;
13
+ container: seat-ring / inline-size;
14
+ }
15
+ .nxgt-seat-ring:dir(rtl) {
16
+ --seat-dir: -1;
17
+ }
18
+ .nxgt-seat-ring[data-size="sm"] {
19
+ --seat: 4.75rem;
20
+ --seat-avatar: 2rem;
21
+ }
22
+ .nxgt-seat-ring[data-size="lg"] {
23
+ --seat: 8rem;
24
+ --seat-avatar: 3.5rem;
25
+ }
26
+
27
+ .nxgt-seat-ring [data-slot="seat-ring-orbit"] {
28
+ display: flex;
29
+ flex-direction: column;
30
+ gap: 0.75rem;
31
+ }
32
+ .nxgt-seat-ring [data-slot="seat-ring-center"] {
33
+ order: -1;
34
+ display: grid;
35
+ place-items: center;
36
+ text-align: center;
37
+ }
38
+ .nxgt-seat-ring [data-slot="seat-ring-list"] {
39
+ display: grid;
40
+ grid-template-columns: repeat(
41
+ auto-fill,
42
+ minmax(min(var(--seat), 100%), 1fr)
43
+ );
44
+ gap: 0.5rem;
45
+ margin: 0;
46
+ padding: 0;
47
+ list-style: none;
48
+ }
49
+ @container seat-ring (max-width: 30rem) {
50
+ .nxgt-seat-ring [data-slot="seat-ring-list"] {
51
+ grid-template-columns: repeat(2, minmax(0, 1fr));
52
+ }
53
+ }
54
+
55
+ .nxgt-seat-ring [data-slot="seat-ring-seat"] {
56
+ position: relative;
57
+ display: flex;
58
+ flex-direction: column;
59
+ align-items: center;
60
+ gap: 0.25rem;
61
+ min-inline-size: 0;
62
+ min-block-size: 2.75rem;
63
+ padding: 0.5rem 0.375rem;
64
+ border: 1px solid var(--border);
65
+ border-radius: var(--radius-lg, 0.75rem);
66
+ background: var(--card, var(--background));
67
+ color: var(--foreground);
68
+ text-align: center;
69
+ transition:
70
+ background-color 150ms,
71
+ border-color 150ms;
72
+ }
73
+ .nxgt-seat-ring [data-slot="seat-ring-label"] {
74
+ max-inline-size: 100%;
75
+ overflow-wrap: anywhere;
76
+ font-size: 0.875rem;
77
+ font-weight: 500;
78
+ line-height: 1.25;
79
+ }
80
+ .nxgt-seat-ring [data-slot="seat-ring-badge"] {
81
+ position: absolute;
82
+ inset-block-start: -0.5rem;
83
+ inset-inline-end: 0.25rem;
84
+ }
85
+ .nxgt-seat-ring [data-slot="seat-ring-mark"] {
86
+ position: absolute;
87
+ inset-block-start: 0.25rem;
88
+ inset-inline-start: 0.25rem;
89
+ display: grid;
90
+ inline-size: 1rem;
91
+ block-size: 1rem;
92
+ color: var(--primary-text, var(--primary));
93
+ }
94
+ .nxgt-seat-ring [data-slot="seat-ring-empty-circle"] {
95
+ inline-size: var(--seat-avatar);
96
+ block-size: var(--seat-avatar);
97
+ border: 2px dashed var(--border);
98
+ border-radius: 9999px;
99
+ }
100
+ .nxgt-seat-ring [data-empty] {
101
+ border-style: dashed;
102
+ background: transparent;
103
+ }
104
+ .nxgt-seat-ring [data-highlighted] {
105
+ border-color: var(--primary-indicator, var(--primary));
106
+ box-shadow: 0 0 0 2px var(--primary-indicator, var(--primary));
107
+ }
108
+ .nxgt-seat-ring [role="option"]:not([aria-disabled="true"]) {
109
+ cursor: pointer;
110
+ }
111
+ .nxgt-seat-ring [role="option"]:not([aria-disabled="true"]):hover {
112
+ background: color-mix(
113
+ in oklab,
114
+ var(--primary-text, var(--primary)) 8%,
115
+ var(--card, var(--background))
116
+ );
117
+ }
118
+ .nxgt-seat-ring [role="option"][aria-selected="true"] {
119
+ border-color: var(--primary-text, var(--primary));
120
+ background: color-mix(
121
+ in oklab,
122
+ var(--primary-text, var(--primary)) 12%,
123
+ var(--card, var(--background))
124
+ );
125
+ }
126
+ .nxgt-seat-ring [role="option"][aria-disabled="true"],
127
+ .nxgt-seat-ring [aria-disabled="true"] {
128
+ opacity: 0.6;
129
+ }
130
+ .nxgt-seat-ring [role="option"]:focus-visible {
131
+ outline: 2px solid var(--ring);
132
+ outline-offset: 2px;
133
+ }
134
+ @media (prefers-reduced-motion: reduce) {
135
+ .nxgt-seat-ring [data-slot="seat-ring-seat"] {
136
+ transition: none;
137
+ }
138
+ }
139
+ }