@crisp-ui-kit/crisp 0.38.0 → 0.39.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 (36) hide show
  1. package/dist/cjs/components/contextmenu/contextmenu.js +1 -1
  2. package/dist/cjs/components/contextmenu/contextmenu.recipe.js +22 -10
  3. package/dist/cjs/components/menu/menu.js +1 -1
  4. package/dist/cjs/components/menu/menu.recipe.js +32 -20
  5. package/dist/cjs/components/multiselect/multiselect.js +1 -1
  6. package/dist/cjs/components/multiselect/multiselect.recipe.js +37 -22
  7. package/dist/cjs/components/popover/popover.js +1 -1
  8. package/dist/cjs/components/popover/popover.recipe.js +19 -4
  9. package/dist/cjs/components/select/select.js +1 -1
  10. package/dist/cjs/components/select/select.recipe.js +28 -15
  11. package/dist/cjs/core/floating-portal.js +55 -2
  12. package/dist/contextmenu.css +11 -9
  13. package/dist/contextmenu.layered.css +11 -9
  14. package/dist/esm/components/contextmenu/contextmenu.js +1 -1
  15. package/dist/esm/components/contextmenu/contextmenu.recipe.js +22 -10
  16. package/dist/esm/components/menu/menu.js +1 -1
  17. package/dist/esm/components/menu/menu.recipe.js +32 -20
  18. package/dist/esm/components/multiselect/multiselect.js +1 -1
  19. package/dist/esm/components/multiselect/multiselect.recipe.js +37 -22
  20. package/dist/esm/components/popover/popover.js +1 -1
  21. package/dist/esm/components/popover/popover.recipe.js +19 -4
  22. package/dist/esm/components/select/select.js +1 -1
  23. package/dist/esm/components/select/select.recipe.js +28 -15
  24. package/dist/esm/core/floating-portal.js +22 -2
  25. package/dist/menu.css +34 -19
  26. package/dist/menu.layered.css +34 -19
  27. package/dist/multiselect.css +34 -21
  28. package/dist/multiselect.layered.css +34 -21
  29. package/dist/popover.css +5 -3
  30. package/dist/popover.layered.css +5 -3
  31. package/dist/select.css +27 -14
  32. package/dist/select.layered.css +27 -14
  33. package/dist/styles.css +111 -66
  34. package/dist/styles.layered.css +111 -66
  35. package/dist/types/core/floating-portal.d.ts +17 -3
  36. package/package.json +3 -3
@@ -459,17 +459,19 @@
459
459
  }
460
460
  }
461
461
 
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); } }
464
+ .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
+ .crisp-contextmenu-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
466
+ .crisp-contextmenu-item:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
467
+ .crisp-contextmenu-item--danger { color: var(--crisp-bg-danger); }
468
+ .crisp-contextmenu-item--danger svg { color: var(--crisp-bg-danger); }
469
+ .crisp-contextmenu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
470
+ .crisp-contextmenu-shortcut { margin-inline-start: auto; padding-inline-start: var(--crisp-space-3); color: var(--crisp-fg-muted); font-size: var(--crisp-text-sm); }
471
+ .crisp-contextmenu-sep { height: 1px; margin: var(--crisp-space-1) 0; border: none; background: var(--crisp-border-subtle); }
472
+
462
473
  .crisp-contextmenu {
463
474
  display: contents; font-family: var(--crisp-font-sans);
464
- & .crisp-contextmenu-content { 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); } }
465
- & .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; }
466
- & .crisp-contextmenu-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
467
- & .crisp-contextmenu-item:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
468
- & .crisp-contextmenu-item--danger { color: var(--crisp-bg-danger); }
469
- & .crisp-contextmenu-item--danger svg { color: var(--crisp-bg-danger); }
470
- & .crisp-contextmenu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
471
- & .crisp-contextmenu-shortcut { margin-inline-start: auto; padding-inline-start: var(--crisp-space-3); color: var(--crisp-fg-muted); font-size: var(--crisp-text-sm); }
472
- & .crisp-contextmenu-sep { height: 1px; margin: var(--crisp-space-1) 0; border: none; background: var(--crisp-border-subtle); }
473
475
  }
474
476
 
475
477
  @media (prefers-reduced-motion: reduce) {
@@ -982,27 +984,42 @@
982
984
  & .crisp-linechart-axis-title { margin-top: var(--crisp-space-1); padding-inline-start: var(--crisp-linechart-yaxis-width); text-align: center; font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
983
985
  }
984
986
 
987
+
988
+ .crisp-menu-content {
989
+ 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);
991
+ min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1);
992
+ border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
993
+ 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);
994
+ transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease;
995
+ }
996
+ .crisp-menu-content[data-align="end"] { transform-origin: top right; }
997
+ .crisp-menu-content[data-up] { transform-origin: bottom left; }
998
+ .crisp-menu-content[data-up][data-align="end"] { transform-origin: bottom right; }
999
+ .crisp-menu-content { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1000
+
1001
+ .crisp-menu-item {
1002
+ box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); flex-shrink: 0;
1003
+ margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md);
1004
+ font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: start; cursor: pointer; white-space: nowrap;
1005
+ }
1006
+ .crisp-menu-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
1007
+ .crisp-menu-item:focus { outline: none; }
1008
+ .crisp-menu-item:hover:not([data-disabled]), .crisp-menu-item:focus-visible:not([data-disabled]), .crisp-menu-item[data-highlighted]:not([data-disabled]) { background: var(--crisp-bg-raised); }
1009
+ .crisp-menu-item[data-disabled] { opacity: 0.5; cursor: not-allowed; }
1010
+ .crisp-menu-item--danger { color: var(--crisp-bg-danger); }
1011
+ .crisp-menu-item--danger svg { color: var(--crisp-bg-danger); }
1012
+ .crisp-menu-item--danger:hover, .crisp-menu-item--danger:focus-visible, .crisp-menu-item--danger[data-highlighted] { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
1013
+ .crisp-menu-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
1014
+ .crisp-menu-item-shortcut { flex-shrink: 0; margin-inline-start: var(--crisp-space-3); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); letter-spacing: 0.02em; }
1015
+ .crisp-menu-item-check { flex-shrink: 0; color: var(--crisp-bg-brand-solid); }
1016
+ .crisp-menu-item-check--placeholder { width: 15px; }
1017
+
1018
+ .crisp-menu-sep { height: 1px; flex-shrink: 0; border: none; margin: var(--crisp-space-1) calc(-1 * var(--crisp-space-1)); background: var(--crisp-border-subtle); }
1019
+ .crisp-menu-label { padding: var(--crisp-space-1-5) var(--crisp-space-2) var(--crisp-space-0-5); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
1020
+
985
1021
  .crisp-menu {
986
1022
  position: relative; display: inline-flex; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
987
- & .crisp-menu-content { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); min-width: 200px; max-height: 360px; overflow-y: auto; 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); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
988
- & .crisp-menu-content[data-align="end"] { transform-origin: top right; }
989
- & .crisp-menu-content[data-up] { transform-origin: bottom left; }
990
- & .crisp-menu-content[data-up][data-align="end"] { transform-origin: bottom right; }
991
- & .crisp-menu-content { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
992
- & .crisp-menu-item { box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); flex-shrink: 0; margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: start; cursor: pointer; white-space: nowrap; }
993
- & .crisp-menu-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
994
- & .crisp-menu-item:focus { outline: none; }
995
- & .crisp-menu-item:hover:not([data-disabled]), & .crisp-menu-item:focus-visible:not([data-disabled]), & .crisp-menu-item[data-highlighted]:not([data-disabled]) { background: var(--crisp-bg-raised); }
996
- & .crisp-menu-item[data-disabled] { opacity: 0.5; cursor: not-allowed; }
997
- & .crisp-menu-item--danger { color: var(--crisp-bg-danger); }
998
- & .crisp-menu-item--danger svg { color: var(--crisp-bg-danger); }
999
- & .crisp-menu-item--danger:hover, & .crisp-menu-item--danger:focus-visible, & .crisp-menu-item--danger[data-highlighted] { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
1000
- & .crisp-menu-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
1001
- & .crisp-menu-item-shortcut { flex-shrink: 0; margin-inline-start: var(--crisp-space-3); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); letter-spacing: 0.02em; }
1002
- & .crisp-menu-item-check { flex-shrink: 0; color: var(--crisp-bg-brand-solid); }
1003
- & .crisp-menu-item-check--placeholder { width: 15px; }
1004
- & .crisp-menu-sep { height: 1px; flex-shrink: 0; border: none; margin: var(--crisp-space-1) calc(-1 * var(--crisp-space-1)); background: var(--crisp-border-subtle); }
1005
- & .crisp-menu-label { padding: var(--crisp-space-1-5) var(--crisp-space-2) var(--crisp-space-0-5); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
1006
1023
  }
1007
1024
 
1008
1025
  @media (prefers-reduced-motion: reduce) {
@@ -1013,6 +1030,40 @@
1013
1030
  }
1014
1031
  }
1015
1032
 
1033
+
1034
+ .crisp-multiselect-listbox {
1035
+ 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);
1037
+ max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1);
1038
+ border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
1039
+ 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);
1040
+ transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease;
1041
+ }
1042
+ .crisp-multiselect-listbox[data-up] { transform-origin: bottom left; }
1043
+ .crisp-multiselect-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1044
+ .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
1045
+ .crisp-multiselect-search svg { flex-shrink: 0; }
1046
+ .crisp-multiselect-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
1047
+ .crisp-multiselect-search input::placeholder { color: var(--crisp-fg-muted); }
1048
+ .crisp-multiselect-option {
1049
+ box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-menuRow); flex-shrink: 0;
1050
+ padding: 0 var(--crisp-space-2); margin: 0; border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; cursor: pointer; text-align: start;
1051
+ }
1052
+ .crisp-multiselect-option[data-highlighted] { background: var(--crisp-bg-raised); }
1053
+ .crisp-multiselect-option-chip { flex: 0 1 auto; min-width: 0; overflow: hidden; }
1054
+ .crisp-multiselect-check { flex-shrink: 0; margin-inline-start: auto; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: var(--crisp-radius-sm); box-shadow: inset 0 0 0 1.5px var(--crisp-border-default); color: transparent; }
1055
+ .crisp-multiselect-option[aria-selected="true"] .crisp-multiselect-check { background: var(--crisp-bg-brand-solid); box-shadow: none; color: #fff; }
1056
+ .crisp-multiselect-empty { padding: var(--crisp-space-3) var(--crisp-space-2); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
1057
+
1058
+ .crisp-recordstable-tag { display: inline-flex; align-items: center; height: var(--crisp-size-chip); padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-chip); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); }
1059
+ .crisp-recordstable-tag[data-tone="brand"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: color-mix(in srgb, var(--crisp-bg-brand-solid) 82%, var(--crisp-fg-primary)); }
1060
+ .crisp-recordstable-tag[data-tone="success"] { background: color-mix(in srgb, var(--crisp-bg-success) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-success) 78%, var(--crisp-fg-primary)); }
1061
+ .crisp-recordstable-tag[data-tone="warning"] { background: color-mix(in srgb, var(--crisp-bg-warning) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-warning) 82%, var(--crisp-fg-primary)); }
1062
+ .crisp-recordstable-tag[data-tone="danger"] { background: color-mix(in srgb, var(--crisp-bg-danger) 15%, transparent); color: color-mix(in srgb, var(--crisp-bg-danger) 80%, var(--crisp-fg-primary)); }
1063
+ .crisp-recordstable-tag[data-tone="purple"] { background: color-mix(in srgb, var(--crisp-bg-purple) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-purple) 80%, var(--crisp-fg-primary)); }
1064
+ .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); }
1065
+ .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
1066
+
1016
1067
  .crisp-multiselect {
1017
1068
  position: relative; display: inline-flex; width: 100%; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1018
1069
  & .crisp-multiselect-trigger { box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; min-width: 0; min-height: var(--crisp-size-menuRow); margin: 0; padding: var(--crisp-space-0-5) var(--crisp-space-1-5) var(--crisp-space-0-5) var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; text-align: start; transition: background-color .12s ease, box-shadow .12s ease; }
@@ -1023,27 +1074,6 @@
1023
1074
  & .crisp-multiselect-placeholder { color: var(--crisp-fg-muted); }
1024
1075
  & .crisp-multiselect-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
1025
1076
  & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); }
1026
- & .crisp-multiselect-listbox { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 300px; overflow-y: auto; 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); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
1027
- & .crisp-multiselect-listbox[data-up] { transform-origin: bottom left; }
1028
- & .crisp-multiselect-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1029
- & .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
1030
- & .crisp-multiselect-search svg { flex-shrink: 0; }
1031
- & .crisp-multiselect-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
1032
- & .crisp-multiselect-search input::placeholder { color: var(--crisp-fg-muted); }
1033
- & .crisp-multiselect-option { box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-menuRow); flex-shrink: 0; padding: 0 var(--crisp-space-2); margin: 0; border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; cursor: pointer; text-align: start; }
1034
- & .crisp-multiselect-option[data-highlighted] { background: var(--crisp-bg-raised); }
1035
- & .crisp-multiselect-option-chip { flex: 0 1 auto; min-width: 0; overflow: hidden; }
1036
- & .crisp-multiselect-check { flex-shrink: 0; margin-inline-start: auto; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: var(--crisp-radius-sm); box-shadow: inset 0 0 0 1.5px var(--crisp-border-default); color: transparent; }
1037
- & .crisp-multiselect-option[aria-selected="true"] .crisp-multiselect-check { background: var(--crisp-bg-brand-solid); box-shadow: none; color: #fff; }
1038
- & .crisp-multiselect-empty { padding: var(--crisp-space-3) var(--crisp-space-2); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
1039
- & .crisp-recordstable-tag { display: inline-flex; align-items: center; height: var(--crisp-size-chip); padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-chip); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); }
1040
- & .crisp-recordstable-tag[data-tone="brand"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: color-mix(in srgb, var(--crisp-bg-brand-solid) 82%, var(--crisp-fg-primary)); }
1041
- & .crisp-recordstable-tag[data-tone="success"] { background: color-mix(in srgb, var(--crisp-bg-success) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-success) 78%, var(--crisp-fg-primary)); }
1042
- & .crisp-recordstable-tag[data-tone="warning"] { background: color-mix(in srgb, var(--crisp-bg-warning) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-warning) 82%, var(--crisp-fg-primary)); }
1043
- & .crisp-recordstable-tag[data-tone="danger"] { background: color-mix(in srgb, var(--crisp-bg-danger) 15%, transparent); color: color-mix(in srgb, var(--crisp-bg-danger) 80%, var(--crisp-fg-primary)); }
1044
- & .crisp-recordstable-tag[data-tone="purple"] { background: color-mix(in srgb, var(--crisp-bg-purple) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-purple) 80%, var(--crisp-fg-primary)); }
1045
- & .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); }
1046
- & .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
1047
1077
  }
1048
1078
  .crisp-multiselect--invalid_true {
1049
1079
  & .crisp-multiselect-trigger, & .crisp-multiselect-trigger:hover, & .crisp-multiselect-trigger[data-open], & .crisp-multiselect-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
@@ -1060,11 +1090,13 @@
1060
1090
  }
1061
1091
  }
1062
1092
 
1093
+
1094
+ .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); } }
1095
+ .crisp-popover-content[data-align="end"] { transform-origin: top right; }
1096
+ .crisp-popover-content[data-up] { transform-origin: bottom left; }
1097
+
1063
1098
  .crisp-popover {
1064
1099
  display: contents; font-family: var(--crisp-font-sans);
1065
- & .crisp-popover-content { 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); } }
1066
- & .crisp-popover-content[data-align="end"] { transform-origin: top right; }
1067
- & .crisp-popover-content[data-up] { transform-origin: bottom left; }
1068
1100
  }
1069
1101
 
1070
1102
  @media (prefers-reduced-motion: reduce) {
@@ -1224,6 +1256,33 @@
1224
1256
  }
1225
1257
  }
1226
1258
 
1259
+
1260
+ .crisp-select-listbox {
1261
+ font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1262
+ position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1263
+ max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1);
1264
+ border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
1265
+ 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);
1266
+ transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease;
1267
+ }
1268
+ .crisp-select-listbox[data-up] { transform-origin: bottom; }
1269
+ .crisp-select-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1270
+ .crisp-select-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
1271
+ .crisp-select-search svg { flex-shrink: 0; }
1272
+ .crisp-select-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
1273
+ .crisp-select-search input::placeholder { color: var(--crisp-fg-muted); }
1274
+ .crisp-select-empty { padding: var(--crisp-space-3) var(--crisp-space-2); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
1275
+ .crisp-select-option {
1276
+ box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-menuRow); flex-shrink: 0;
1277
+ padding: 0 var(--crisp-space-2); margin: 0; border: none; background: none; border-radius: var(--crisp-radius-md);
1278
+ font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: start; cursor: pointer; white-space: nowrap;
1279
+ }
1280
+ .crisp-select-option[data-highlighted] { background: var(--crisp-bg-raised); }
1281
+ .crisp-select-option[data-disabled] { opacity: 0.5; cursor: not-allowed; }
1282
+ .crisp-select-option-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: var(--crisp-radius-full); }
1283
+ .crisp-select-option-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
1284
+ .crisp-select-option-check { flex-shrink: 0; color: var(--crisp-bg-brand-solid); }
1285
+
1227
1286
  .crisp-select {
1228
1287
  position: relative; display: inline-flex; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1229
1288
  & .crisp-select-trigger { box-sizing: border-box; display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-menuRow); width: 100%; min-width: 0; margin: 0; padding: 0 var(--crisp-space-1-5) 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; transition: background-color .12s ease, box-shadow .12s ease; }
@@ -1234,20 +1293,6 @@
1234
1293
  & .crisp-select-placeholder { color: var(--crisp-fg-muted); }
1235
1294
  & .crisp-select-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
1236
1295
  & .crisp-select-trigger[data-open] .crisp-select-chevron { transform: rotate(180deg); }
1237
- & .crisp-select-listbox { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 280px; overflow-y: auto; 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); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
1238
- & .crisp-select-listbox[data-up] { transform-origin: bottom; }
1239
- & .crisp-select-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1240
- & .crisp-select-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
1241
- & .crisp-select-search svg { flex-shrink: 0; }
1242
- & .crisp-select-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
1243
- & .crisp-select-search input::placeholder { color: var(--crisp-fg-muted); }
1244
- & .crisp-select-empty { padding: var(--crisp-space-3) var(--crisp-space-2); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
1245
- & .crisp-select-option { box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-menuRow); flex-shrink: 0; padding: 0 var(--crisp-space-2); margin: 0; border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: start; cursor: pointer; white-space: nowrap; }
1246
- & .crisp-select-option[data-highlighted] { background: var(--crisp-bg-raised); }
1247
- & .crisp-select-option[data-disabled] { opacity: 0.5; cursor: not-allowed; }
1248
- & .crisp-select-option-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: var(--crisp-radius-full); }
1249
- & .crisp-select-option-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
1250
- & .crisp-select-option-check { flex-shrink: 0; color: var(--crisp-bg-brand-solid); }
1251
1296
  }
1252
1297
  .crisp-select--variant_default {
1253
1298
 
@@ -1,4 +1,4 @@
1
- import type * as React from "react";
1
+ import * as React from "react";
2
2
  /**
3
3
  * Portals a floating layer (a `position: fixed` listbox/menu/popover
4
4
  * content) to `document.body` — exactly what Tooltip already did with a
@@ -19,7 +19,21 @@ import type * as React from "react";
19
19
  * starts `false` and is driven only by client interaction — never a prop a
20
20
  * fixture sets true at mount (unlike Dialog/Drawer/Command) — so this never
21
21
  * touches `document` during SSR, the same safety Tooltip already had.
22
+ *
23
+ * `sourceRef` is the caller's own root — still in its original DOM position,
24
+ * never portaled — used to carry a `data-theme` set on some ancestor of it
25
+ * onto the portaled content (#357). `[data-theme="dark"]` is a normal
26
+ * attribute selector: it needs the themed element to be an actual DOM
27
+ * ancestor, which a consumer that scopes theming below `<html>`/`<body>`
28
+ * (crisp's own visual-test harness does exactly this, per case) no longer
29
+ * is once the content moves to `document.body` — the popover rendered in
30
+ * the PAGE's theme instead of the SUBTREE's. Re-declaring the attribute
31
+ * directly on the portaled root re-establishes it for CSS attribute
32
+ * selectors AND for `var()` resolution, since a custom property set under
33
+ * `[data-theme="dark"] { --crisp-x: ... }` only reaches descendants of an
34
+ * element carrying that attribute.
22
35
  */
23
- export declare function FloatingPortal({ children, }: {
24
- children: React.ReactNode;
36
+ export declare function FloatingPortal({ children, sourceRef, }: {
37
+ children: React.ReactElement;
38
+ sourceRef: React.RefObject<HTMLElement | null>;
25
39
  }): React.ReactPortal;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crisp-ui-kit/crisp",
3
- "version": "0.38.0",
3
+ "version": "0.39.0",
4
4
  "description": "A lean React design system, measured pixel-for-pixel from Attio.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -434,8 +434,8 @@
434
434
  "lynx": "bun build/lynx-lint.mjs",
435
435
  "lynx:emit": "bun build/emit-lynx.mjs",
436
436
  "ssr": "bun scripts/ssr-check.tsx",
437
- "visual": "bun scripts/visual-page.tsx && playwright test",
438
- "visual:baseline": "bun run build && bun scripts/visual-page.tsx && docker run --rm -v \"$PWD\":/w -w /w mcr.microsoft.com/playwright:v1.63.0-noble npx playwright test --update-snapshots",
437
+ "visual": "bun scripts/visual-page.tsx && bun scripts/build-portal-fixture.mjs && playwright test",
438
+ "visual:baseline": "bun run build && bun scripts/visual-page.tsx && bun scripts/build-portal-fixture.mjs && docker run --rm -v \"$PWD\":/w -w /w mcr.microsoft.com/playwright:v1.63.0-noble npx playwright test --update-snapshots",
439
439
  "contrast": "bun scripts/contrast-page.tsx",
440
440
  "build:esm": "tsc -p tsconfig.esm.json && bun scripts/fix-esm-extensions.mjs",
441
441
  "build:cjs": "tsc -p tsconfig.cjs.json && bun scripts/finish-cjs.mjs",