@crisp-ui-kit/crisp 0.43.0 → 0.44.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.
@@ -21,7 +21,12 @@ const config = (0, core_1.defineRecipe)({
21
21
  name: "contextmenu",
22
22
  base: `display: contents; font-family: ${tokens_1.contract.font.sans};`,
23
23
  globalCss: `
24
- .crisp-contextmenu-content { font-family: ${tokens_1.contract.font.sans}; position: fixed; z-index: 70; min-width: 200px; box-sizing: border-box; padding: ${tokens_1.contract.space["1"]}; border-radius: ${tokens_1.contract.radius.xl}; background: ${tokens_1.contract.bgPopover}; box-shadow: ${tokens_1.elevation.floating}; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
24
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
25
+ on document.body while open (Zag re-enables it only on layers IT
26
+ tracks), and the portaled content is outside Zag's knowledge -- it
27
+ inherited the lock, unclickable, hit-testing right through to
28
+ whatever real element sat behind it. */
29
+ .crisp-contextmenu-content { font-family: ${tokens_1.contract.font.sans}; position: fixed; z-index: 70; pointer-events: auto; min-width: 200px; box-sizing: border-box; padding: ${tokens_1.contract.space["1"]}; border-radius: ${tokens_1.contract.radius.xl}; background: ${tokens_1.contract.bgPopover}; box-shadow: ${tokens_1.elevation.floating}; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
25
30
  .crisp-contextmenu-item { display: flex; align-items: center; gap: ${tokens_1.contract.space["2"]}; width: 100%; height: ${tokens_1.contract.size.menuRow}; box-sizing: border-box; padding: 0 ${tokens_1.contract.space["2"]}; margin: 0; border: none; border-radius: ${tokens_1.contract.radius.md}; background: none; color: ${tokens_1.contract.fgPrimary}; font-family: inherit; font-size: ${tokens_1.contract.text.lg}; text-align: start; white-space: nowrap; cursor: pointer; }
26
31
  .crisp-contextmenu-item svg { flex-shrink: 0; color: ${tokens_1.contract.fgMuted}; }
27
32
  .crisp-contextmenu-item:hover { background: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 6%, transparent); }
@@ -26,9 +26,14 @@ const config = (0, core_1.defineRecipe)({
26
26
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
27
27
  `,
28
28
  globalCss: `
29
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
30
+ on document.body while open (Zag re-enables it only on layers IT
31
+ tracks), and the portaled content is outside Zag's knowledge -- it
32
+ inherited the lock, so every item was unclickable, hit-testing right
33
+ through to whatever real element sat behind it. */
29
34
  .crisp-menu-content {
30
35
  font-family: ${tokens_1.contract.font.sans}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
31
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: ${tokens_1.contract.space.px};
36
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: ${tokens_1.contract.space.px};
32
37
  min-width: 200px; max-height: 360px; overflow-y: auto; padding: ${tokens_1.contract.space["1"]};
33
38
  border-radius: ${tokens_1.contract.radius.xl}; background: ${tokens_1.contract.bgPopover};
34
39
  box-shadow: ${tokens_1.elevation.floating};
@@ -44,9 +44,14 @@ const config = (0, core_1.defineRecipe)({
44
44
  & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); }
45
45
  `,
46
46
  globalCss: `
47
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
48
+ on document.body while open (Zag re-enables it only on layers IT
49
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
50
+ inherited the lock, so every option was unclickable, hit-testing
51
+ right through to whatever real element sat behind it. */
47
52
  .crisp-multiselect-listbox {
48
53
  font-family: ${tokens_1.contract.font.sans}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
49
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: ${tokens_1.contract.space.px};
54
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: ${tokens_1.contract.space.px};
50
55
  max-height: 300px; overflow-y: auto; padding: ${tokens_1.contract.space["1"]};
51
56
  border-radius: ${tokens_1.contract.radius.xl}; background: ${tokens_1.contract.bgPopover};
52
57
  box-shadow: ${tokens_1.elevation.floating};
@@ -26,7 +26,12 @@ const config = (0, core_1.defineRecipe)({
26
26
  name: "popover",
27
27
  base: `display: contents; font-family: ${tokens_1.contract.font.sans};`,
28
28
  globalCss: `
29
- .crisp-popover-content { font-family: ${tokens_1.contract.font.sans}; position: fixed; z-index: 70; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: ${tokens_1.contract.space["1"]}; border-radius: ${tokens_1.contract.radius.xl}; background: ${tokens_1.contract.bgPopover}; color: ${tokens_1.contract.fgPrimary}; box-shadow: ${tokens_1.elevation.floating}; opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
29
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
30
+ on document.body while open (Zag re-enables it only on layers IT
31
+ tracks), and the portaled content is outside Zag's knowledge -- it
32
+ inherited the lock, unclickable, hit-testing right through to
33
+ whatever real element sat behind it. */
34
+ .crisp-popover-content { font-family: ${tokens_1.contract.font.sans}; position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: ${tokens_1.contract.space["1"]}; border-radius: ${tokens_1.contract.radius.xl}; background: ${tokens_1.contract.bgPopover}; color: ${tokens_1.contract.fgPrimary}; box-shadow: ${tokens_1.elevation.floating}; opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
30
35
  .crisp-popover-content[data-align="end"] { transform-origin: top right; }
31
36
  .crisp-popover-content[data-up] { transform-origin: bottom left; }
32
37
  `,
@@ -44,9 +44,14 @@ const config = (0, core_1.defineRecipe)({
44
44
  & .crisp-select-trigger[data-open] .crisp-select-chevron { transform: rotate(180deg); }
45
45
  `,
46
46
  globalCss: `
47
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
48
+ on document.body while open (Zag re-enables it only on layers IT
49
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
50
+ inherited the lock, so every option was unclickable, hit-testing
51
+ right through to whatever real element sat behind it. */
47
52
  .crisp-select-listbox {
48
53
  font-family: ${tokens_1.contract.font.sans}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
49
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: ${tokens_1.contract.space.px};
54
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: ${tokens_1.contract.space.px};
50
55
  max-height: 280px; overflow-y: auto; padding: ${tokens_1.contract.space["1"]};
51
56
  border-radius: ${tokens_1.contract.radius.xl}; background: ${tokens_1.contract.bgPopover};
52
57
  box-shadow: ${tokens_1.elevation.floating};
@@ -72,6 +72,19 @@ function RecordPanel({ record, columns, onClose, className, closeLabel = "Close
72
72
  // both close on the same keypress, since neither knows about the other --
73
73
  // none of the five are built on this listener or registered anywhere it
74
74
  // can see, only on the shared floating-stack this checks instead.
75
+ //
76
+ // The listener has to run in the CAPTURE phase, not bubble (#376): Menu's
77
+ // own Escape handling is a React onKeyDown on its content div -- a bubble
78
+ // -phase synthetic handler, which fires (and, closing Menu, synchronously
79
+ // unregisters it from the floating stack) BEFORE a bubble-phase listener
80
+ // on `document` ever sees the event. `hasOpenFloatingLayer()` read AFTER
81
+ // that already reflects Menu's own reaction, not the state Escape actually
82
+ // arrived in, so it raced and lost every time -- confirmed by logging the
83
+ // registration order in a real browser, not by reasoning about it. Capture
84
+ // fires top-down, before Menu's bubble handler runs at all, so the check
85
+ // sees the state as it stood when the key was pressed. This mirrors how
86
+ // Zag's own `trackEscapeKeydown` (Dialog/Drawer's Escape handling) already
87
+ // listens on `document` in capture, for the same reason.
75
88
  React.useEffect(() => {
76
89
  if (!record)
77
90
  return;
@@ -80,8 +93,8 @@ function RecordPanel({ record, columns, onClose, className, closeLabel = "Close
80
93
  return;
81
94
  onClose();
82
95
  };
83
- document.addEventListener("keydown", onKey);
84
- return () => document.removeEventListener("keydown", onKey);
96
+ document.addEventListener("keydown", onKey, true);
97
+ return () => document.removeEventListener("keydown", onKey, true);
85
98
  }, [record, onClose]);
86
99
  if (!record)
87
100
  return null;
@@ -1,5 +1,10 @@
1
1
 
2
- .crisp-contextmenu-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
2
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
3
+ on document.body while open (Zag re-enables it only on layers IT
4
+ tracks), and the portaled content is outside Zag's knowledge -- it
5
+ inherited the lock, unclickable, hit-testing right through to
6
+ whatever real element sat behind it. */
7
+ .crisp-contextmenu-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; pointer-events: auto; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
3
8
  .crisp-contextmenu-item { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; height: var(--crisp-size-menuRow); box-sizing: border-box; padding: 0 var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); text-align: start; white-space: nowrap; cursor: pointer; }
4
9
  .crisp-contextmenu-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
5
10
  .crisp-contextmenu-item:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
@@ -1,6 +1,11 @@
1
1
  @layer crisp-components {
2
2
 
3
- .crisp-contextmenu-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
3
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
4
+ on document.body while open (Zag re-enables it only on layers IT
5
+ tracks), and the portaled content is outside Zag's knowledge -- it
6
+ inherited the lock, unclickable, hit-testing right through to
7
+ whatever real element sat behind it. */
8
+ .crisp-contextmenu-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; pointer-events: auto; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
4
9
  .crisp-contextmenu-item { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; height: var(--crisp-size-menuRow); box-sizing: border-box; padding: 0 var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); text-align: start; white-space: nowrap; cursor: pointer; }
5
10
  .crisp-contextmenu-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
6
11
  .crisp-contextmenu-item:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
@@ -18,7 +18,12 @@ const config = defineRecipe({
18
18
  name: "contextmenu",
19
19
  base: `display: contents; font-family: ${c.font.sans};`,
20
20
  globalCss: `
21
- .crisp-contextmenu-content { font-family: ${c.font.sans}; position: fixed; z-index: 70; min-width: 200px; box-sizing: border-box; padding: ${c.space["1"]}; border-radius: ${c.radius.xl}; background: ${c.bgPopover}; box-shadow: ${e.floating}; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
21
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
22
+ on document.body while open (Zag re-enables it only on layers IT
23
+ tracks), and the portaled content is outside Zag's knowledge -- it
24
+ inherited the lock, unclickable, hit-testing right through to
25
+ whatever real element sat behind it. */
26
+ .crisp-contextmenu-content { font-family: ${c.font.sans}; position: fixed; z-index: 70; pointer-events: auto; min-width: 200px; box-sizing: border-box; padding: ${c.space["1"]}; border-radius: ${c.radius.xl}; background: ${c.bgPopover}; box-shadow: ${e.floating}; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
22
27
  .crisp-contextmenu-item { display: flex; align-items: center; gap: ${c.space["2"]}; width: 100%; height: ${c.size.menuRow}; box-sizing: border-box; padding: 0 ${c.space["2"]}; margin: 0; border: none; border-radius: ${c.radius.md}; background: none; color: ${c.fgPrimary}; font-family: inherit; font-size: ${c.text.lg}; text-align: start; white-space: nowrap; cursor: pointer; }
23
28
  .crisp-contextmenu-item svg { flex-shrink: 0; color: ${c.fgMuted}; }
24
29
  .crisp-contextmenu-item:hover { background: color-mix(in srgb, ${c.fgPrimary} 6%, transparent); }
@@ -23,9 +23,14 @@ const config = defineRecipe({
23
23
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
24
24
  `,
25
25
  globalCss: `
26
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
27
+ on document.body while open (Zag re-enables it only on layers IT
28
+ tracks), and the portaled content is outside Zag's knowledge -- it
29
+ inherited the lock, so every item was unclickable, hit-testing right
30
+ through to whatever real element sat behind it. */
26
31
  .crisp-menu-content {
27
32
  font-family: ${c.font.sans}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
28
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: ${c.space.px};
33
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: ${c.space.px};
29
34
  min-width: 200px; max-height: 360px; overflow-y: auto; padding: ${c.space["1"]};
30
35
  border-radius: ${c.radius.xl}; background: ${c.bgPopover};
31
36
  box-shadow: ${e.floating};
@@ -41,9 +41,14 @@ const config = defineRecipe({
41
41
  & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); }
42
42
  `,
43
43
  globalCss: `
44
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
45
+ on document.body while open (Zag re-enables it only on layers IT
46
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
47
+ inherited the lock, so every option was unclickable, hit-testing
48
+ right through to whatever real element sat behind it. */
44
49
  .crisp-multiselect-listbox {
45
50
  font-family: ${c.font.sans}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
46
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: ${c.space.px};
51
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: ${c.space.px};
47
52
  max-height: 300px; overflow-y: auto; padding: ${c.space["1"]};
48
53
  border-radius: ${c.radius.xl}; background: ${c.bgPopover};
49
54
  box-shadow: ${e.floating};
@@ -23,7 +23,12 @@ const config = defineRecipe({
23
23
  name: "popover",
24
24
  base: `display: contents; font-family: ${c.font.sans};`,
25
25
  globalCss: `
26
- .crisp-popover-content { font-family: ${c.font.sans}; position: fixed; z-index: 70; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: ${c.space["1"]}; border-radius: ${c.radius.xl}; background: ${c.bgPopover}; color: ${c.fgPrimary}; box-shadow: ${e.floating}; opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
26
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
27
+ on document.body while open (Zag re-enables it only on layers IT
28
+ tracks), and the portaled content is outside Zag's knowledge -- it
29
+ inherited the lock, unclickable, hit-testing right through to
30
+ whatever real element sat behind it. */
31
+ .crisp-popover-content { font-family: ${c.font.sans}; position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: ${c.space["1"]}; border-radius: ${c.radius.xl}; background: ${c.bgPopover}; color: ${c.fgPrimary}; box-shadow: ${e.floating}; opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
27
32
  .crisp-popover-content[data-align="end"] { transform-origin: top right; }
28
33
  .crisp-popover-content[data-up] { transform-origin: bottom left; }
29
34
  `,
@@ -41,9 +41,14 @@ const config = defineRecipe({
41
41
  & .crisp-select-trigger[data-open] .crisp-select-chevron { transform: rotate(180deg); }
42
42
  `,
43
43
  globalCss: `
44
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
45
+ on document.body while open (Zag re-enables it only on layers IT
46
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
47
+ inherited the lock, so every option was unclickable, hit-testing
48
+ right through to whatever real element sat behind it. */
44
49
  .crisp-select-listbox {
45
50
  font-family: ${c.font.sans}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
46
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: ${c.space.px};
51
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: ${c.space.px};
47
52
  max-height: 280px; overflow-y: auto; padding: ${c.space["1"]};
48
53
  border-radius: ${c.radius.xl}; background: ${c.bgPopover};
49
54
  box-shadow: ${e.floating};
@@ -36,6 +36,19 @@ export function RecordPanel({ record, columns, onClose, className, closeLabel =
36
36
  // both close on the same keypress, since neither knows about the other --
37
37
  // none of the five are built on this listener or registered anywhere it
38
38
  // can see, only on the shared floating-stack this checks instead.
39
+ //
40
+ // The listener has to run in the CAPTURE phase, not bubble (#376): Menu's
41
+ // own Escape handling is a React onKeyDown on its content div -- a bubble
42
+ // -phase synthetic handler, which fires (and, closing Menu, synchronously
43
+ // unregisters it from the floating stack) BEFORE a bubble-phase listener
44
+ // on `document` ever sees the event. `hasOpenFloatingLayer()` read AFTER
45
+ // that already reflects Menu's own reaction, not the state Escape actually
46
+ // arrived in, so it raced and lost every time -- confirmed by logging the
47
+ // registration order in a real browser, not by reasoning about it. Capture
48
+ // fires top-down, before Menu's bubble handler runs at all, so the check
49
+ // sees the state as it stood when the key was pressed. This mirrors how
50
+ // Zag's own `trackEscapeKeydown` (Dialog/Drawer's Escape handling) already
51
+ // listens on `document` in capture, for the same reason.
39
52
  React.useEffect(() => {
40
53
  if (!record)
41
54
  return;
@@ -44,8 +57,8 @@ export function RecordPanel({ record, columns, onClose, className, closeLabel =
44
57
  return;
45
58
  onClose();
46
59
  };
47
- document.addEventListener("keydown", onKey);
48
- return () => document.removeEventListener("keydown", onKey);
60
+ document.addEventListener("keydown", onKey, true);
61
+ return () => document.removeEventListener("keydown", onKey, true);
49
62
  }, [record, onClose]);
50
63
  if (!record)
51
64
  return null;
package/dist/menu.css CHANGED
@@ -1,7 +1,12 @@
1
1
 
2
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
3
+ on document.body while open (Zag re-enables it only on layers IT
4
+ tracks), and the portaled content is outside Zag's knowledge -- it
5
+ inherited the lock, so every item was unclickable, hit-testing right
6
+ through to whatever real element sat behind it. */
2
7
  .crisp-menu-content {
3
8
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
4
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
9
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
5
10
  min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1);
6
11
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
7
12
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
@@ -1,8 +1,13 @@
1
1
  @layer crisp-components {
2
2
 
3
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
4
+ on document.body while open (Zag re-enables it only on layers IT
5
+ tracks), and the portaled content is outside Zag's knowledge -- it
6
+ inherited the lock, so every item was unclickable, hit-testing right
7
+ through to whatever real element sat behind it. */
3
8
  .crisp-menu-content {
4
9
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
5
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
10
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
6
11
  min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1);
7
12
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
8
13
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
@@ -1,7 +1,12 @@
1
1
 
2
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
3
+ on document.body while open (Zag re-enables it only on layers IT
4
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
5
+ inherited the lock, so every option was unclickable, hit-testing
6
+ right through to whatever real element sat behind it. */
2
7
  .crisp-multiselect-listbox {
3
8
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
4
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
9
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
5
10
  max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1);
6
11
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
7
12
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
@@ -1,8 +1,13 @@
1
1
  @layer crisp-components {
2
2
 
3
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
4
+ on document.body while open (Zag re-enables it only on layers IT
5
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
6
+ inherited the lock, so every option was unclickable, hit-testing
7
+ right through to whatever real element sat behind it. */
3
8
  .crisp-multiselect-listbox {
4
9
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
5
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
10
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
6
11
  max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1);
7
12
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
8
13
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
package/dist/popover.css CHANGED
@@ -1,5 +1,10 @@
1
1
 
2
- .crisp-popover-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
2
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
3
+ on document.body while open (Zag re-enables it only on layers IT
4
+ tracks), and the portaled content is outside Zag's knowledge -- it
5
+ inherited the lock, unclickable, hit-testing right through to
6
+ whatever real element sat behind it. */
7
+ .crisp-popover-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
3
8
  .crisp-popover-content[data-align="end"] { transform-origin: top right; }
4
9
  .crisp-popover-content[data-up] { transform-origin: bottom left; }
5
10
 
@@ -1,6 +1,11 @@
1
1
  @layer crisp-components {
2
2
 
3
- .crisp-popover-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
3
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
4
+ on document.body while open (Zag re-enables it only on layers IT
5
+ tracks), and the portaled content is outside Zag's knowledge -- it
6
+ inherited the lock, unclickable, hit-testing right through to
7
+ whatever real element sat behind it. */
8
+ .crisp-popover-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
4
9
  .crisp-popover-content[data-align="end"] { transform-origin: top right; }
5
10
  .crisp-popover-content[data-up] { transform-origin: bottom left; }
6
11
 
package/dist/select.css CHANGED
@@ -1,7 +1,12 @@
1
1
 
2
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
3
+ on document.body while open (Zag re-enables it only on layers IT
4
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
5
+ inherited the lock, so every option was unclickable, hit-testing
6
+ right through to whatever real element sat behind it. */
2
7
  .crisp-select-listbox {
3
8
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
4
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
9
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
5
10
  max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1);
6
11
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
7
12
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
@@ -1,8 +1,13 @@
1
1
  @layer crisp-components {
2
2
 
3
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
4
+ on document.body while open (Zag re-enables it only on layers IT
5
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
6
+ inherited the lock, so every option was unclickable, hit-testing
7
+ right through to whatever real element sat behind it. */
3
8
  .crisp-select-listbox {
4
9
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
5
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
10
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
6
11
  max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1);
7
12
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
8
13
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
package/dist/styles.css CHANGED
@@ -459,7 +459,12 @@
459
459
  }
460
460
 
461
461
 
462
- .crisp-contextmenu-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
462
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
463
+ on document.body while open (Zag re-enables it only on layers IT
464
+ tracks), and the portaled content is outside Zag's knowledge -- it
465
+ inherited the lock, unclickable, hit-testing right through to
466
+ whatever real element sat behind it. */
467
+ .crisp-contextmenu-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; pointer-events: auto; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
463
468
  .crisp-contextmenu-item { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; height: var(--crisp-size-menuRow); box-sizing: border-box; padding: 0 var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); text-align: start; white-space: nowrap; cursor: pointer; }
464
469
  .crisp-contextmenu-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
465
470
  .crisp-contextmenu-item:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
@@ -985,9 +990,14 @@
985
990
  }
986
991
 
987
992
 
993
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
994
+ on document.body while open (Zag re-enables it only on layers IT
995
+ tracks), and the portaled content is outside Zag's knowledge -- it
996
+ inherited the lock, so every item was unclickable, hit-testing right
997
+ through to whatever real element sat behind it. */
988
998
  .crisp-menu-content {
989
999
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
990
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1000
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
991
1001
  min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1);
992
1002
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
993
1003
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
@@ -1031,9 +1041,14 @@
1031
1041
  }
1032
1042
 
1033
1043
 
1044
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
1045
+ on document.body while open (Zag re-enables it only on layers IT
1046
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
1047
+ inherited the lock, so every option was unclickable, hit-testing
1048
+ right through to whatever real element sat behind it. */
1034
1049
  .crisp-multiselect-listbox {
1035
1050
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1036
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1051
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1037
1052
  max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1);
1038
1053
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
1039
1054
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
@@ -1095,7 +1110,12 @@
1095
1110
  }
1096
1111
 
1097
1112
 
1098
- .crisp-popover-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1113
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
1114
+ on document.body while open (Zag re-enables it only on layers IT
1115
+ tracks), and the portaled content is outside Zag's knowledge -- it
1116
+ inherited the lock, unclickable, hit-testing right through to
1117
+ whatever real element sat behind it. */
1118
+ .crisp-popover-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1099
1119
  .crisp-popover-content[data-align="end"] { transform-origin: top right; }
1100
1120
  .crisp-popover-content[data-up] { transform-origin: bottom left; }
1101
1121
 
@@ -1261,9 +1281,14 @@
1261
1281
  }
1262
1282
 
1263
1283
 
1284
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
1285
+ on document.body while open (Zag re-enables it only on layers IT
1286
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
1287
+ inherited the lock, so every option was unclickable, hit-testing
1288
+ right through to whatever real element sat behind it. */
1264
1289
  .crisp-select-listbox {
1265
1290
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1266
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1291
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1267
1292
  max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1);
1268
1293
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
1269
1294
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
@@ -460,7 +460,12 @@
460
460
  }
461
461
 
462
462
 
463
- .crisp-contextmenu-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
463
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
464
+ on document.body while open (Zag re-enables it only on layers IT
465
+ tracks), and the portaled content is outside Zag's knowledge -- it
466
+ inherited the lock, unclickable, hit-testing right through to
467
+ whatever real element sat behind it. */
468
+ .crisp-contextmenu-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; pointer-events: auto; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
464
469
  .crisp-contextmenu-item { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; height: var(--crisp-size-menuRow); box-sizing: border-box; padding: 0 var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); text-align: start; white-space: nowrap; cursor: pointer; }
465
470
  .crisp-contextmenu-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
466
471
  .crisp-contextmenu-item:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
@@ -986,9 +991,14 @@
986
991
  }
987
992
 
988
993
 
994
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
995
+ on document.body while open (Zag re-enables it only on layers IT
996
+ tracks), and the portaled content is outside Zag's knowledge -- it
997
+ inherited the lock, so every item was unclickable, hit-testing right
998
+ through to whatever real element sat behind it. */
989
999
  .crisp-menu-content {
990
1000
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
991
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1001
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
992
1002
  min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1);
993
1003
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
994
1004
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
@@ -1032,9 +1042,14 @@
1032
1042
  }
1033
1043
 
1034
1044
 
1045
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
1046
+ on document.body while open (Zag re-enables it only on layers IT
1047
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
1048
+ inherited the lock, so every option was unclickable, hit-testing
1049
+ right through to whatever real element sat behind it. */
1035
1050
  .crisp-multiselect-listbox {
1036
1051
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1037
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1052
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1038
1053
  max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1);
1039
1054
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
1040
1055
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
@@ -1096,7 +1111,12 @@
1096
1111
  }
1097
1112
 
1098
1113
 
1099
- .crisp-popover-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1114
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
1115
+ on document.body while open (Zag re-enables it only on layers IT
1116
+ tracks), and the portaled content is outside Zag's knowledge -- it
1117
+ inherited the lock, unclickable, hit-testing right through to
1118
+ whatever real element sat behind it. */
1119
+ .crisp-popover-content { font-family: var(--crisp-font-sans); position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1100
1120
  .crisp-popover-content[data-align="end"] { transform-origin: top right; }
1101
1121
  .crisp-popover-content[data-up] { transform-origin: bottom left; }
1102
1122
 
@@ -1262,9 +1282,14 @@
1262
1282
  }
1263
1283
 
1264
1284
 
1285
+ /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
1286
+ on document.body while open (Zag re-enables it only on layers IT
1287
+ tracks), and the portaled listbox is outside Zag's knowledge -- it
1288
+ inherited the lock, so every option was unclickable, hit-testing
1289
+ right through to whatever real element sat behind it. */
1265
1290
  .crisp-select-listbox {
1266
1291
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1267
- position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1292
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1268
1293
  max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1);
1269
1294
  border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
1270
1295
  box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crisp-ui-kit/crisp",
3
- "version": "0.43.0",
3
+ "version": "0.44.0",
4
4
  "description": "A lean React design system, measured pixel-for-pixel from Attio.",
5
5
  "license": "MIT",
6
6
  "type": "module",