reshaped 3.8.0-canary.6 → 3.8.0-canary.7

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 (55) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/bundle.css +1 -1
  3. package/dist/bundle.js +10 -10
  4. package/dist/components/DropdownMenu/DropdownMenu.js +4 -4
  5. package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +2 -2
  6. package/dist/components/Flyout/utilities/flyout.js +1 -1
  7. package/dist/components/Flyout/utilities/getPositionFallbacks.js +3 -3
  8. package/dist/components/Flyout/utilities/isFullyVisible.d.ts +0 -2
  9. package/dist/components/Flyout/utilities/isFullyVisible.js +5 -7
  10. package/dist/components/Hidden/Hidden.js +2 -1
  11. package/dist/components/MenuItem/MenuItem.module.css +1 -1
  12. package/dist/components/Popover/Popover.js +2 -2
  13. package/dist/components/Popover/Popover.module.css +1 -1
  14. package/dist/components/Popover/Popover.types.d.ts +2 -0
  15. package/dist/components/Reshaped/Reshaped.css +1 -1
  16. package/dist/components/Resizable/Resizable.js +4 -3
  17. package/dist/components/Select/Select.d.ts +8 -1
  18. package/dist/components/Select/Select.js +22 -48
  19. package/dist/components/Select/Select.module.css +1 -1
  20. package/dist/components/Select/Select.types.d.ts +56 -38
  21. package/dist/components/Select/SelectCustom.d.ts +3 -0
  22. package/dist/components/Select/SelectCustom.js +11 -0
  23. package/dist/components/Select/SelectCustomControlled.d.ts +4 -0
  24. package/dist/components/Select/SelectCustomControlled.js +88 -0
  25. package/dist/components/Select/SelectCustomUncontrolled.d.ts +4 -0
  26. package/dist/components/Select/SelectCustomUncontrolled.js +15 -0
  27. package/dist/components/Select/SelectEndContent.d.ts +3 -0
  28. package/dist/components/Select/SelectEndContent.js +12 -0
  29. package/dist/components/Select/SelectNative.d.ts +4 -0
  30. package/dist/components/Select/SelectNative.js +29 -0
  31. package/dist/components/Select/SelectOption.d.ts +4 -0
  32. package/dist/components/Select/SelectOption.js +15 -0
  33. package/dist/components/Select/SelectOptionGroup.d.ts +4 -0
  34. package/dist/components/Select/SelectOptionGroup.js +11 -0
  35. package/dist/components/Select/SelectRoot.d.ts +4 -0
  36. package/dist/components/Select/SelectRoot.js +21 -0
  37. package/dist/components/Select/SelectStartContent.d.ts +3 -0
  38. package/dist/components/Select/SelectStartContent.js +20 -0
  39. package/dist/components/Select/SelectTrigger.d.ts +4 -0
  40. package/dist/components/Select/SelectTrigger.js +16 -0
  41. package/dist/components/Select/tests/Select.stories.d.ts +35 -10
  42. package/dist/components/Select/tests/Select.stories.js +447 -175
  43. package/dist/components/Stepper/Stepper.js +2 -2
  44. package/dist/components/Stepper/Stepper.types.d.ts +2 -0
  45. package/dist/components/Stepper/tests/Stepper.stories.d.ts +1 -0
  46. package/dist/components/Stepper/tests/Stepper.stories.js +23 -0
  47. package/dist/components/Table/Table.js +6 -3
  48. package/dist/components/Timeline/Timeline.js +3 -2
  49. package/dist/components/Timeline/tests/Timeline.stories.js +0 -3
  50. package/dist/components/View/View.js +6 -4
  51. package/dist/utilities/props.d.ts +3 -0
  52. package/dist/utilities/props.js +19 -0
  53. package/package.json +1 -1
  54. package/dist/components/Select/tests/Select.test.stories.d.ts +0 -27
  55. package/dist/components/Select/tests/Select.test.stories.js +0 -132
@@ -14,8 +14,8 @@ import s from "./DropdownMenu.module.css";
14
14
  const DropdownMenuSubContext = React.createContext(null);
15
15
  const DropdownMenuSubTriggerContext = React.createContext(false);
16
16
  const DropdownMenu = (props) => {
17
- const { children, position = "bottom-start", triggerType = "click", trapFocusMode = "action-menu", ...popoverProps } = props;
18
- return (_jsx(Popover, { ...popoverProps, position: position, padding: 0, trapFocusMode: trapFocusMode, triggerType: triggerType, children: children }));
17
+ const { children, position = "bottom-start", triggerType = "click", trapFocusMode = "action-menu", borderRadius = "small", ...popoverProps } = props;
18
+ return (_jsx(Popover, { ...popoverProps, position: position, padding: 0, trapFocusMode: trapFocusMode, triggerType: triggerType, borderRadius: borderRadius, disableHideAnimation: true, children: children }));
19
19
  };
20
20
  const DropdownMenuContent = (props) => {
21
21
  const { children, attributes, className } = props;
@@ -62,9 +62,9 @@ const DropdownMenuItem = (props) => {
62
62
  return (_jsx(MenuItem, { ...props, roundedCorners: true, className: [s.item, props.className], attributes: { role: "menuitem", ...props.attributes }, onClick: handleClick }));
63
63
  };
64
64
  const DropdownMenuSubMenu = (props) => {
65
- const { children } = props;
65
+ const { children, position = "end-top", contentGap = 0.5, ...dropdownMenuProps } = props;
66
66
  const dropdownMenuRef = React.useRef(null);
67
- return (_jsx(DropdownMenuSubContext.Provider, { value: dropdownMenuRef, children: _jsx(DropdownMenu, { triggerType: "hover", position: "end-top", contentGap: 0.5, instanceRef: dropdownMenuRef, children: children }) }));
67
+ return (_jsx(DropdownMenuSubContext.Provider, { value: dropdownMenuRef, children: _jsx(DropdownMenu, { ...dropdownMenuProps, triggerType: "hover", position: position, contentGap: contentGap, instanceRef: dropdownMenuRef, children: children }) }));
68
68
  };
69
69
  const DropdownMenuSubTriggerItem = (props) => {
70
70
  const { children, attributes, ...menuItemProps } = props;
@@ -3,7 +3,7 @@ import type { PopoverProps, PopoverInstance } from "../Popover";
3
3
  import type { MenuItemProps } from "../MenuItem";
4
4
  import type { FlyoutContentProps } from "../Flyout";
5
5
  export type Instance = PopoverInstance;
6
- export type Props = Pick<PopoverProps, "children" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "triggerType" | "contentGap" | "contentShift" | "onOpen" | "onClose" | "active" | "defaultActive" | "width" | "disableHideAnimation" | "disableCloseOnOutsideClick" | "instanceRef" | "containerRef" | "originCoordinates"> & {
6
+ export type Props = Pick<PopoverProps, "children" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "triggerType" | "contentGap" | "contentShift" | "onOpen" | "onClose" | "active" | "defaultActive" | "width" | "disableHideAnimation" | "disableCloseOnOutsideClick" | "instanceRef" | "containerRef" | "originCoordinates" | "borderRadius" | "elevation" | "initialFocusRef"> & {
7
7
  /** Change component trap focus keyboard behavior and shortcuts */
8
8
  trapFocusMode?: Extract<PopoverProps["trapFocusMode"], "action-menu" | "selection-menu"> | false;
9
9
  };
@@ -16,5 +16,5 @@ export type SectionProps = {
16
16
  export type SubMenuProps = {
17
17
  /** Node for inserting children */
18
18
  children: React.ReactNode;
19
- };
19
+ } & Pick<PopoverProps, "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "contentGap" | "contentShift" | "width" | "containerRef">;
20
20
  export type SubTriggerProps = Omit<MenuItemProps, "endSlot" | "roundedCorners">;
@@ -64,7 +64,6 @@ const flyout = (args) => {
64
64
  flyoutBounds: calculated.boundaries,
65
65
  visualContainerBounds,
66
66
  renderContainerBounds,
67
- container,
68
67
  });
69
68
  };
70
69
  let calculated = null;
@@ -72,6 +71,7 @@ const flyout = (args) => {
72
71
  testOrder.some((currentPosition) => {
73
72
  const tested = applyPosition(currentPosition);
74
73
  const visible = testVisibility(tested);
74
+ console.log(currentPosition, tested, visible ? "yes" : "no");
75
75
  if (visible)
76
76
  calculated = tested;
77
77
  return visible;
@@ -14,7 +14,7 @@ const fallbackOrder = {
14
14
  };
15
15
  // Get an order of positions to try to fit flyout on the screen based on its starting position
16
16
  const getPositionFallbacks = (position, availableFallbacks) => {
17
- const result = [position];
17
+ const result = new Set([position]);
18
18
  const chunks = position.split("-");
19
19
  const [firstChunk] = chunks;
20
20
  const passedPositionOrder = positions[firstChunk];
@@ -31,9 +31,9 @@ const getPositionFallbacks = (position, availableFallbacks) => {
31
31
  const position = fallbackOrder[index];
32
32
  if (availableFallbacks?.indexOf(position) === -1)
33
33
  return;
34
- result.push(position);
34
+ result.add(position);
35
35
  });
36
36
  });
37
- return result;
37
+ return Array.from(result);
38
38
  };
39
39
  export default getPositionFallbacks;
@@ -8,7 +8,5 @@ declare const isFullyVisible: (args: {
8
8
  visualContainerBounds: DOMRect;
9
9
  /** Bounds of the container where flyout content is rendered */
10
10
  renderContainerBounds: DOMRect;
11
- /** Container where the flyout content is rendered */
12
- container: HTMLElement;
13
11
  }) => boolean;
14
12
  export default isFullyVisible;
@@ -2,20 +2,18 @@
2
2
  * Check if element visually fits within its render container
3
3
  */
4
4
  const isFullyVisible = (args) => {
5
- const { flyoutBounds, visualContainerBounds, renderContainerBounds, container } = args;
6
- const scrollX = container === document.body ? window.scrollX : container.scrollLeft;
7
- const scrollY = container === document.body ? window.scrollY : container.scrollTop;
8
- if (renderContainerBounds.left + flyoutBounds.left - scrollX < visualContainerBounds.left) {
5
+ const { flyoutBounds, visualContainerBounds, renderContainerBounds } = args;
6
+ if (renderContainerBounds.left + flyoutBounds.left < visualContainerBounds.left) {
9
7
  return false;
10
8
  }
11
- if (renderContainerBounds.top + flyoutBounds.top - scrollY < visualContainerBounds.top) {
9
+ if (renderContainerBounds.top + flyoutBounds.top < visualContainerBounds.top) {
12
10
  return false;
13
11
  }
14
- if (renderContainerBounds.left + flyoutBounds.left + flyoutBounds.width - scrollX >
12
+ if (renderContainerBounds.left + flyoutBounds.left + flyoutBounds.width >
15
13
  visualContainerBounds.right) {
16
14
  return false;
17
15
  }
18
- if (renderContainerBounds.top + flyoutBounds.top + flyoutBounds.height - scrollY >
16
+ if (renderContainerBounds.top + flyoutBounds.top + flyoutBounds.height >
19
17
  visualContainerBounds.bottom) {
20
18
  return false;
21
19
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { classNames, responsiveClassNames } from "../../utilities/props.js";
2
+ import { classNames, responsiveClassNames, setComponentChildId } from "../../utilities/props.js";
3
3
  import s from "./Hidden.module.css";
4
4
  const Hidden = (props) => {
5
5
  const { as: TagName = "div", children, visibility, hide } = props;
@@ -7,4 +7,5 @@ const Hidden = (props) => {
7
7
  return _jsx(TagName, { className: rootClassNames, children: children });
8
8
  };
9
9
  Hidden.displayName = "Hidden";
10
+ setComponentChildId(Hidden, "Hidden");
10
11
  export default Hidden;
@@ -1 +1 @@
1
- .root,button.root{background-color:var(--rs-menu-item-bg-color);color:var(--rs-menu-item-color);display:block;font-family:var(--rs-font-family-body);font-weight:var(--rs-font-weight-medium);padding:var(--rs-p-v) var(--rs-p-h);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:background-color,transform,box-shadow}.icon{color:var(--rs-menu-item-icon-color,inherit)}.content,.icon{transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:color}.--rounded-corners{border-radius:var(--rs-menu-item-radius)}.--size-small{--rs-p-v:var(--rs-unit-x1);--rs-p-h:var(--rs-unit-x2);--rs-menu-item-radius:var(--rs-radius-small)}.--size-medium,.--size-small{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-medium{--rs-p-v:var(--rs-unit-x2);--rs-p-h:var(--rs-unit-x3);--rs-menu-item-radius:var(--rs-radius-small)}.--size-large{--rs-p-v:var(--rs-unit-x3);--rs-p-h:var(--rs-unit-x4);--rs-menu-item-radius:var(--rs-radius-medium);font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--color-neutral{--rs-menu-item-icon-color:var(--rs-color-foreground-neutral-faded)}.--color-neutral.--highlighted,.--color-neutral.--selected,.--color-neutral[data-rs-focus]{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-neutral),32%)}@media (hover:hover) and (pointer:fine){.--color-neutral:hover{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-neutral),32%)}}.--color-critical{--rs-menu-item-color:var(--rs-color-foreground-critical)}.--color-critical.--highlighted,.--color-critical.--selected,.--color-critical[data-rs-focus]{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-critical),12%)}@media (hover:hover) and (pointer:fine){.--color-critical:hover{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-critical),12%)}}.--color-primary{--rs-menu-item-icon-color:var(--rs-color-foreground-neutral-faded)}.--color-primary.--highlighted,.--color-primary[data-rs-focus]{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-neutral),32%)}@media (hover:hover) and (pointer:fine){.--color-primary:hover{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-neutral),32%)}}.--color-primary.--selected,.--color-primary.--selected:hover{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-primary),12%);--rs-menu-item-color:var(--rs-color-foreground-primary);--rs-menu-item-icon-color:var(--rs-color-foreground-primary)}.--selected,.--selected:hover{cursor:default}.--disabled,.--disabled:hover{--rs-menu-item-color:var(--rs-color-foreground-disabled);--rs-menu-item-bg-color:none;--rs-menu-item-icon-color:var(--rs-color-foreground-disabled)}button.root{width:100%}.aligner button.root{box-sizing:initial}@media (--rs-viewport-m ){.--rounded-corners-true--m{border-radius:var(--rs-menu-item-radius)}.--rounded-corners-false--m{border-radius:0}.--size-small--m{--rs-p-v:var(--rs-unit-x1);--rs-p-h:var(--rs-unit-x2);--rs-menu-item-radius:var(--rs-radius-small)}.--size-medium--m,.--size-small--m{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-medium--m{--rs-p-v:var(--rs-unit-x2);--rs-p-h:var(--rs-unit-x3);--rs-menu-item-radius:var(--rs-radius-small)}.--size-large--m{--rs-p-v:var(--rs-unit-x3);--rs-p-h:var(--rs-unit-x4);--rs-menu-item-radius:var(--rs-radius-medium);font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}@media (--rs-viewport-l ){.--rounded-corners-true--l{border-radius:var(--rs-menu-item-radius)}.--rounded-corners-false--l{border-radius:0}.--size-small--l{--rs-p-v:var(--rs-unit-x1);--rs-p-h:var(--rs-unit-x2);--rs-menu-item-radius:var(--rs-radius-small)}.--size-medium--l,.--size-small--l{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-medium--l{--rs-p-v:var(--rs-unit-x2);--rs-p-h:var(--rs-unit-x3);--rs-menu-item-radius:var(--rs-radius-small)}.--size-large--l{--rs-p-v:var(--rs-unit-x3);--rs-p-h:var(--rs-unit-x4);--rs-menu-item-radius:var(--rs-radius-medium);font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}@media (--rs-viewport-xl ){.--rounded-corners-true--xl{border-radius:var(--rs-menu-item-radius)}.--rounded-corners-false--xl{border-radius:0}.--size-small--xl{--rs-p-v:var(--rs-unit-x1);--rs-p-h:var(--rs-unit-x2);--rs-menu-item-radius:var(--rs-radius-small)}.--size-medium--xl,.--size-small--xl{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-medium--xl{--rs-p-v:var(--rs-unit-x2);--rs-p-h:var(--rs-unit-x3);--rs-menu-item-radius:var(--rs-radius-small)}.--size-large--xl{--rs-p-v:var(--rs-unit-x3);--rs-p-h:var(--rs-unit-x4);--rs-menu-item-radius:var(--rs-radius-medium);font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}
1
+ .root,button.root{background-color:var(--rs-menu-item-bg-color);color:var(--rs-menu-item-color);display:block;font-family:var(--rs-font-family-body);font-weight:var(--rs-font-weight-medium);padding:var(--rs-p-v) var(--rs-p-h);transition:background-color var(--rs-duration-fast) var(--rs-easing-standard)}.root[role=option],button.root[role=option]{transition:none}[data-rs-keyboard] .root[role=option]:focus,[data-rs-keyboard] button.root[role=option]:focus{background-color:rgba(var(--rs-color-rgb-background-neutral),32%);box-shadow:none}.icon{color:var(--rs-menu-item-icon-color,inherit)}.content,.icon{transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:color}.--rounded-corners{border-radius:var(--rs-menu-item-radius)}.--size-small{--rs-p-v:var(--rs-unit-x1);--rs-p-h:var(--rs-unit-x2);--rs-menu-item-radius:var(--rs-radius-small)}.--size-medium,.--size-small{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-medium{--rs-p-v:var(--rs-unit-x2);--rs-p-h:var(--rs-unit-x3);--rs-menu-item-radius:var(--rs-radius-small)}.--size-large{--rs-p-v:var(--rs-unit-x3);--rs-p-h:var(--rs-unit-x4);--rs-menu-item-radius:var(--rs-radius-medium);font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--color-neutral{--rs-menu-item-icon-color:var(--rs-color-foreground-neutral-faded)}.--color-neutral.--highlighted,.--color-neutral.--selected,.--color-neutral[data-rs-focus]{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-neutral),32%)}@media (hover:hover) and (pointer:fine){.--color-neutral:hover{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-neutral),32%)}}.--color-critical{--rs-menu-item-color:var(--rs-color-foreground-critical)}.--color-critical.--highlighted,.--color-critical.--selected,.--color-critical[data-rs-focus]{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-critical),12%)}@media (hover:hover) and (pointer:fine){.--color-critical:hover{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-critical),12%)}}.--color-primary{--rs-menu-item-icon-color:var(--rs-color-foreground-neutral-faded)}.--color-primary.--highlighted,.--color-primary[data-rs-focus]{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-neutral),32%)}@media (hover:hover) and (pointer:fine){.--color-primary:hover{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-neutral),32%)}}.--color-primary.--selected,.--color-primary.--selected:hover{--rs-menu-item-bg-color:rgba(var(--rs-color-rgb-background-primary),12%);--rs-menu-item-color:var(--rs-color-foreground-primary);--rs-menu-item-icon-color:var(--rs-color-foreground-primary)}.--selected,.--selected:hover{cursor:default}.--disabled,.--disabled:hover{--rs-menu-item-color:var(--rs-color-foreground-disabled);--rs-menu-item-bg-color:none;--rs-menu-item-icon-color:var(--rs-color-foreground-disabled)}button.root{width:100%}.aligner button.root{box-sizing:initial}@media (--rs-viewport-m ){.--rounded-corners-true--m{border-radius:var(--rs-menu-item-radius)}.--rounded-corners-false--m{border-radius:0}.--size-small--m{--rs-p-v:var(--rs-unit-x1);--rs-p-h:var(--rs-unit-x2);--rs-menu-item-radius:var(--rs-radius-small)}.--size-medium--m,.--size-small--m{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-medium--m{--rs-p-v:var(--rs-unit-x2);--rs-p-h:var(--rs-unit-x3);--rs-menu-item-radius:var(--rs-radius-small)}.--size-large--m{--rs-p-v:var(--rs-unit-x3);--rs-p-h:var(--rs-unit-x4);--rs-menu-item-radius:var(--rs-radius-medium);font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}@media (--rs-viewport-l ){.--rounded-corners-true--l{border-radius:var(--rs-menu-item-radius)}.--rounded-corners-false--l{border-radius:0}.--size-small--l{--rs-p-v:var(--rs-unit-x1);--rs-p-h:var(--rs-unit-x2);--rs-menu-item-radius:var(--rs-radius-small)}.--size-medium--l,.--size-small--l{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-medium--l{--rs-p-v:var(--rs-unit-x2);--rs-p-h:var(--rs-unit-x3);--rs-menu-item-radius:var(--rs-radius-small)}.--size-large--l{--rs-p-v:var(--rs-unit-x3);--rs-p-h:var(--rs-unit-x4);--rs-menu-item-radius:var(--rs-radius-medium);font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}@media (--rs-viewport-xl ){.--rounded-corners-true--xl{border-radius:var(--rs-menu-item-radius)}.--rounded-corners-false--xl{border-radius:0}.--size-small--xl{--rs-p-v:var(--rs-unit-x1);--rs-p-h:var(--rs-unit-x2);--rs-menu-item-radius:var(--rs-radius-small)}.--size-medium--xl,.--size-small--xl{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-medium--xl{--rs-p-v:var(--rs-unit-x2);--rs-p-h:var(--rs-unit-x3);--rs-menu-item-radius:var(--rs-radius-small)}.--size-large--xl{--rs-p-v:var(--rs-unit-x3);--rs-p-h:var(--rs-unit-x4);--rs-menu-item-radius:var(--rs-radius-medium);font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}
@@ -5,11 +5,11 @@ import Dismissible from "../Dismissible/index.js";
5
5
  import s from "./Popover.module.css";
6
6
  import { resolveMixin } from "../../styles/mixin.js";
7
7
  const Popover = (props) => {
8
- const { width, variant = "elevated", triggerType = "click", position = "bottom", elevation, ...flyoutProps } = props;
8
+ const { width, variant = "elevated", triggerType = "click", position = "bottom", elevation, borderRadius, ...flyoutProps } = props;
9
9
  const padding = props.padding ?? (variant === "headless" ? 0 : 4);
10
10
  const trapFocusMode = props.trapFocusMode ?? (triggerType === "hover" ? "content-menu" : undefined);
11
11
  const mixinStyles = resolveMixin({ padding });
12
- const contentClassName = classNames(s.content, !!width && s["content--has-width"], variant && s[`content--variant-${variant}`], elevation && s[`content--elevation-${elevation}`], mixinStyles.classNames);
12
+ const contentClassName = classNames(s.content, !!width && s["content--has-width"], variant && s[`content--variant-${variant}`], elevation && s[`content--elevation-${elevation}`], borderRadius && s[`content--radius-${borderRadius}`], mixinStyles.classNames);
13
13
  return (_jsx(Flyout, { ...flyoutProps, position: position, trapFocusMode: trapFocusMode, triggerType: triggerType, width: width, contentClassName: contentClassName, contentAttributes: { style: { ...mixinStyles.variables } } }));
14
14
  };
15
15
  const PopoverDismissible = (props) => {
@@ -1 +1 @@
1
- .content{max-width:360px}.content--variant-elevated{background:var(--rs-color-background-elevation-overlay);border-radius:var(--rs-radius-medium);box-shadow:var(--rs-shadow-border-faded),var(--rs-shadow-overlay);color:var(--rs-color-foreground-neutral);min-width:220px;overflow:hidden}.content--variant-elevated.content--elevation-raised{box-shadow:var(--rs-shadow-border-faded),var(--rs-shadow-raised)}.content.content--has-width{max-width:none;min-width:0}@media (--rs-viewport-s ){.content{max-width:none}}
1
+ .content{max-width:360px}.content--variant-elevated{background:var(--rs-color-background-elevation-overlay);border-radius:var(--rs-radius-medium);box-shadow:var(--rs-shadow-border-faded),var(--rs-shadow-overlay);color:var(--rs-color-foreground-neutral);min-width:220px}.content--variant-elevated.content--elevation-raised{box-shadow:var(--rs-shadow-border-faded),var(--rs-shadow-raised)}.content--radius-small{border-radius:var(--rs-radius-small)}.content.content--has-width{max-width:none;min-width:0}@media (--rs-viewport-s ){.content{max-width:none}}
@@ -8,6 +8,8 @@ export type Props = Pick<FlyoutProps, "id" | "position" | "forcePosition" | "fal
8
8
  padding?: number;
9
9
  /** Component elevation level */
10
10
  elevation?: "raised" | "overlay";
11
+ /** Border radius for the content */
12
+ borderRadius?: "small" | "medium";
11
13
  /** @deprecated use Flyout utility instead, will be removed in v4 */
12
14
  variant?: "elevated" | "headless";
13
15
  };
@@ -1 +1 @@
1
- @layer rs.reset{[data-rs-theme]{--rs-radius-circular:9999px;--rs-shadow-border-faded:0px 0px 0px 1px var(--rs-color-border-neutral-faded)}[data-rs-theme] blockquote,[data-rs-theme] body,[data-rs-theme] dd,[data-rs-theme] dl,[data-rs-theme] figcaption,[data-rs-theme] figure,[data-rs-theme] h1,[data-rs-theme] h2,[data-rs-theme] h3,[data-rs-theme] h4,[data-rs-theme] h5,[data-rs-theme] h6,[data-rs-theme] li,[data-rs-theme] ol,[data-rs-theme] p,[data-rs-theme] ul{margin:0;padding:0}[data-rs-theme] ol[class],[data-rs-theme] ul[class]{list-style:none}[data-rs-theme] textarea{resize:vertical}[data-rs-theme] table{border-collapse:collapse;border-spacing:0}[data-rs-theme] fieldset{border:0;margin:0;padding:0}[data-rs-theme] img{display:block;max-width:100%}[data-rs-theme] button,[data-rs-theme] input,[data-rs-theme] select,[data-rs-theme] textarea{font:inherit}[data-rs-theme] option{background:var(--rs-color-background-elevation-base)}[data-rs-theme] label{cursor:pointer}[data-rs-theme] input::placeholder,[data-rs-theme] textarea::placeholder{color:var(--rs-color-foreground-disabled)}html[data-rs-theme]{-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;font-size:100%;text-rendering:optimizelegibility;touch-action:manipulation}[data-rs-theme] *{box-sizing:border-box}[data-rs-theme] body,html[data-rs-theme]{background:var(--rs-color-background-page);color:var(--rs-color-foreground-neutral);min-height:100vh;scroll-behavior:smooth}}[data-rs-theme] body,[data-rs-theme]:not(html){font-family:var(--rs-font-family-body);font-size:var(--rs-font-size-body-3);font-weight:var(--rs-font-weight-regular);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}[data-rs-color-mode=light]{color-scheme:light}[data-rs-color-mode=dark]{color-scheme:dark}@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:.01ms!important}}[data-rs-no-transition] *,[data-rs-no-transition] :after,[data-rs-no-transition] :before{transition:none!important}
1
+ @layer rs.reset{[data-rs-theme]{--rs-radius-circular:9999px;--rs-shadow-border-faded:0px 0px 0px 1px var(--rs-color-border-neutral-faded) inset}[data-rs-theme] blockquote,[data-rs-theme] body,[data-rs-theme] dd,[data-rs-theme] dl,[data-rs-theme] figcaption,[data-rs-theme] figure,[data-rs-theme] h1,[data-rs-theme] h2,[data-rs-theme] h3,[data-rs-theme] h4,[data-rs-theme] h5,[data-rs-theme] h6,[data-rs-theme] li,[data-rs-theme] ol,[data-rs-theme] p,[data-rs-theme] ul{margin:0;padding:0}[data-rs-theme] ol[class],[data-rs-theme] ul[class]{list-style:none}[data-rs-theme] textarea{resize:vertical}[data-rs-theme] table{border-collapse:collapse;border-spacing:0}[data-rs-theme] fieldset{border:0;margin:0;padding:0}[data-rs-theme] img{display:block;max-width:100%}[data-rs-theme] button,[data-rs-theme] input,[data-rs-theme] select,[data-rs-theme] textarea{font:inherit}[data-rs-theme] option{background:var(--rs-color-background-elevation-base)}[data-rs-theme] label{cursor:pointer}[data-rs-theme] input::placeholder,[data-rs-theme] textarea::placeholder{color:var(--rs-color-foreground-disabled)}html[data-rs-theme]{-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;font-size:100%;text-rendering:optimizelegibility;touch-action:manipulation}[data-rs-theme] *{box-sizing:border-box}[data-rs-theme] body,html[data-rs-theme]{background:var(--rs-color-background-page);color:var(--rs-color-foreground-neutral);min-height:100vh;scroll-behavior:smooth}}[data-rs-theme] body,[data-rs-theme]:not(html){font-family:var(--rs-font-family-body);font-size:var(--rs-font-size-body-3);font-weight:var(--rs-font-weight-regular);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}[data-rs-color-mode=light]{color-scheme:light}[data-rs-color-mode=dark]{color-scheme:dark}@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:.01ms!important}}[data-rs-no-transition] *,[data-rs-no-transition] :after,[data-rs-no-transition] :before{transition:none!important}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import React from "react";
4
- import { classNames } from "../../utilities/props.js";
4
+ import { classNames, setComponentChildId, isMatchingComponentChildId } from "../../utilities/props.js";
5
5
  import View from "../View/index.js";
6
6
  import ResizableHandle, { ResizableHandleContext } from "./ResizableHandle.js";
7
7
  import s from "./Resizable.module.css";
@@ -113,10 +113,10 @@ const Resizable = (props) => {
113
113
  }, [horizontal]);
114
114
  const output = React.Children.map(children, (child) => {
115
115
  const isComponent = React.isValidElement(child);
116
- if (isComponent && child.props && child.type !== Resizable.Item) {
116
+ if (isComponent && child.props && !isMatchingComponentChildId(child, "Resizable.Item")) {
117
117
  return (_jsx(ResizableHandleContext.Provider, { value: { containerRef, index: currentHandleIndex++, onDrag, direction }, children: child }));
118
118
  }
119
- if (isComponent && child.props && child.type === Resizable.Item) {
119
+ if (isComponent && child.props && isMatchingComponentChildId(child, "Resizable.Item")) {
120
120
  const index = currentHandleIndex;
121
121
  return (_jsx(PrivateResizableItem, { ...child.props, index: currentItemIndex++, ref: (el) => {
122
122
  itemsRef.current[index] = { el, props: child.props };
@@ -127,6 +127,7 @@ const Resizable = (props) => {
127
127
  return (_jsx(View, { attributes: { ...attributes, ref: containerRef }, className: rootClassNames, height: height, direction: direction, align: "stretch", gap: gap, children: output }));
128
128
  };
129
129
  Resizable.Item = () => null;
130
+ setComponentChildId(Resizable.Item, "Resizable.Item");
130
131
  Resizable.Handle = ResizableHandle;
131
132
  Resizable.displayName = "Resizable";
132
133
  export default Resizable;
@@ -1,4 +1,11 @@
1
1
  import React from "react";
2
2
  import type * as T from "./Select.types";
3
- declare const Select: React.FC<T.Props>;
3
+ import SelectOption from "./SelectOption";
4
+ import SelectOptionGroup from "./SelectOptionGroup";
5
+ import SelectCustom from "./SelectCustom";
6
+ declare const Select: React.FC<T.NativeProps> & {
7
+ Custom: typeof SelectCustom;
8
+ Option: typeof SelectOption;
9
+ OptionGroup: typeof SelectOptionGroup;
10
+ };
4
11
  export default Select;
@@ -1,53 +1,27 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
2
  import React from "react";
4
- import Icon from "../Icon/index.js";
5
- import { useFormControl } from "../FormControl/index.js";
6
- import Actionable from "../Actionable/index.js";
7
- import Text from "../Text/index.js";
8
- import IconArrow from "../../icons/ChevronVertical.js";
9
- import { classNames, responsiveClassNames, responsivePropDependency } from "../../utilities/props.js";
10
- import useElementId from "../../hooks/useElementId.js";
11
- import s from "./Select.module.css";
3
+ import SelectNative from "./SelectNative.js";
4
+ import SelectRoot from "./SelectRoot.js";
5
+ import SelectTrigger from "./SelectTrigger.js";
6
+ import SelectOption from "./SelectOption.js";
7
+ import SelectOptionGroup from "./SelectOptionGroup.js";
8
+ import SelectCustom from "./SelectCustom.js";
12
9
  const Select = (props) => {
13
- const { onChange, onClick, onFocus, onBlur, name, value, defaultValue, placeholder, options, children, icon, startSlot, size = "medium", variant = "outline", className, attributes, } = props;
14
- const [empty, setEmpty] = React.useState(value === undefined ? !defaultValue : !value);
15
- const formControl = useFormControl();
16
- const id = useElementId(props.id);
17
- const inputId = formControl?.attributes?.id || props.inputAttributes?.id || id;
18
- const disabled = formControl?.disabled || props.disabled;
19
- const hasError = formControl?.hasError || props.hasError;
20
- const inputAttributes = { ...props.inputAttributes, ...formControl?.attributes };
21
- const rootClassName = classNames(s.root, className, size && responsiveClassNames(s, "--size", size), hasError && s["--status-error"], disabled && s["--disabled"], empty && options && s["--placeholder"], variant && s[`--variant-${variant}`]);
22
- const handleChange = (event) => {
23
- const nextValue = event.target.value;
24
- // Uncontrolled placeholder
25
- if (value === undefined)
26
- setEmpty(!nextValue);
27
- if (!onChange)
28
- return;
29
- onChange({ name, value: nextValue, event });
30
- };
31
- // Controlled placeholder
32
- React.useEffect(() => {
33
- if (value === undefined)
34
- return;
35
- setEmpty(!value);
36
- }, [value]);
37
- const startContent = (startSlot || icon) && (_jsx("div", { className: s.slot, children: icon ? (_jsx(Icon, { size: responsivePropDependency(size, (size) => {
38
- if (size === "large")
39
- return 5;
40
- if (size === "xlarge")
41
- return 6;
42
- return 4;
43
- }), svg: icon })) : (startSlot) }));
44
- return (_jsxs("div", { ...attributes, className: rootClassName, children: [options ? (_jsxs(_Fragment, { children: [startContent, _jsxs("select", { ...inputAttributes, onFocus: (onFocus || inputAttributes?.onFocus), onBlur: (onBlur || inputAttributes?.onBlur), className: s.input, disabled: disabled, name: name, value: value, defaultValue: defaultValue, onChange: handleChange, id: inputId, children: [placeholder && _jsx("option", { value: "", children: placeholder }), options.map((option) => (_jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value)))] })] })) : (_jsxs(_Fragment, { children: [_jsxs(Actionable, { className: s.input, disabled: disabled, disableFocusRing: true, onClick: onClick, attributes: {
45
- ...inputAttributes,
46
- onFocus: onFocus || inputAttributes?.onFocus,
47
- onBlur: onBlur || inputAttributes?.onBlur,
48
- }, children: [startContent, children ? _jsx(Text, { maxLines: 1, children: children }) : null, placeholder && !children ? _jsx(Text, { color: "neutral-faded", children: placeholder }) : null] }), _jsx("input", { type: "hidden", value: value, name: name })] })), _jsx("div", { className: s.arrow, children: _jsx(Icon, { svg: IconArrow, color: disabled ? "disabled" : "neutral-faded", size: responsivePropDependency(size, (size) => {
49
- return size === "large" || size === "xlarge" ? 5 : 4;
50
- }) }) })] }));
10
+ const { children } = props;
11
+ return (_jsx(SelectRoot, { ...props, children: (props) => {
12
+ const { options } = props;
13
+ const hasOptionChildren = React.Children.toArray(children).some((child) => {
14
+ return React.isValidElement(child) && child.type === "option";
15
+ });
16
+ const hasOptions = Boolean(options || hasOptionChildren);
17
+ if (!hasOptions) {
18
+ return _jsx(SelectTrigger, { ...props, children: children });
19
+ }
20
+ return (_jsxs(SelectNative, { ...props, children: [options?.map((option) => (_jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value))), children] }));
21
+ } }));
51
22
  };
52
23
  Select.displayName = "Select";
24
+ Select.Custom = SelectCustom;
25
+ Select.Option = SelectOption;
26
+ Select.OptionGroup = SelectOptionGroup;
53
27
  export default Select;
@@ -1 +1 @@
1
- .root{background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);display:flex;overflow:hidden;padding:calc(var(--rs-unit-x1) - 1px) 0;position:relative;z-index:0}.root:focus-within{border-color:var(--rs-color-border-primary);box-shadow:0 0 0 1px var(--rs-color-border-primary)}.input{align-items:center;-webkit-appearance:none;appearance:none;background:none;border:0;box-sizing:border-box;color:var(--rs-color-foreground-neutral);cursor:pointer;display:flex;flex-grow:1;font-family:var(--rs-font-family-body);font-weight:var(--rs-font-weight-regular);outline:none;padding-inline-end:calc(var(--rs-select-chevron-size) + var(--rs-select-gap) * 2 + var(--rs-unit-x1));padding-inline-start:var(--rs-select-gap);position:relative;text-overflow:ellipsis;width:100%;z-index:1}.input::-ms-expand{display:none}.slot{align-items:center;display:flex;flex-shrink:0;padding-inline-start:var(--rs-select-gap);position:relative;z-index:5}.input .slot{padding-inline-end:var(--rs-select-gap);padding-inline-start:0}.arrow{color:var(--rs-color-foreground-neutral-faded);display:flex;inset-block-start:50%;inset-inline-end:var(--rs-select-gap);pointer-events:none;position:absolute;transform:translateY(-50%);z-index:5}.--size-small{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-small .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:0}.--size-medium{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-medium .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-large{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-large .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x2)}.--size-xlarge{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-xlarge .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}.root.--variant-faded{background:var(--rs-color-background-neutral-faded);border-color:transparent}.root.--variant-faded:focus-within{border-color:var(--rs-color-border-primary)}.root.--variant-headless{background:transparent;border-color:transparent}.root.--variant-headless.--status-error,.root.--variant-headless.--status-error:focus-within,.root.--variant-headless:focus-within{border-color:transparent;box-shadow:none}.root.--status-error{border-color:var(--rs-color-border-critical)}.root.--status-error:focus-within{border-color:var(--rs-color-border-primary)}.root.--placeholder .input{color:var(--rs-color-foreground-disabled)}.root.--disabled{background:var(--rs-color-background-disabled-faded);border-color:var(--rs-color-border-disabled)}.root.--disabled .arrow,.root.--disabled .input{color:var(--rs-color-foreground-disabled);cursor:not-allowed}@media (--rs-viewport-s ) and (hover:none){.input{font-size:var(--rs-font-size-body-2)!important}}@media (--rs-viewport-m ){.--size-small--m{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-small--m .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:0}.--size-medium--m{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-medium--m .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-large--m{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-large--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x2)}.--size-xlarge--m{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-xlarge--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}}@media (--rs-viewport-l ){.--size-small--l{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-small--l .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:0}.--size-medium--l{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-medium--l .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-large--l{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-large--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x2)}.--size-xlarge--l{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-xlarge--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}}@media (--rs-viewport-xl ){.--size-small--xl{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-small--xl .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:0}.--size-medium--xl{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-medium--xl .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-large--xl{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-large--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x2)}.--size-xlarge--xl{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-xlarge--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}}
1
+ .root{background:var(--rs-color-background-elevation-base);display:flex;overflow:hidden;position:relative;z-index:0}.root,.root:after{border-radius:var(--rs-select-radius)}.root:after{box-shadow:var(--rs-shadow-border-faded);content:"";inset:0;pointer-events:none;position:absolute}[data-rs-keyboard] .root:focus-within{box-shadow:0 0 0 1px var(--rs-color-border-primary)}[data-rs-keyboard] .root:focus-within:after{box-shadow:0 0 0 1px var(--rs-color-border-primary) inset}.input{align-items:center;-webkit-appearance:none;appearance:none;background:none;border:0;box-sizing:border-box;color:var(--rs-color-foreground-neutral);cursor:pointer;display:flex;flex-grow:1;font-family:var(--rs-font-family-body);font-weight:var(--rs-font-weight-regular);outline:none;padding-inline-end:calc(var(--rs-select-chevron-size) + var(--rs-select-gap) * 2 + var(--rs-unit-x1));padding-inline-start:var(--rs-select-gap);position:relative;text-overflow:ellipsis;width:100%;z-index:1}.input::-ms-expand{display:none}.input.input--placeholder{color:var(--rs-color-foreground-disabled)}.slot{align-items:center;display:flex;flex-shrink:0;padding-inline-start:var(--rs-select-gap);position:relative;z-index:5}.input .slot{padding-inline-end:var(--rs-select-gap);padding-inline-start:0}.arrow{color:var(--rs-color-foreground-neutral-faded);display:flex;inset-block-start:50%;inset-inline-end:var(--rs-select-gap);pointer-events:none;position:absolute;transform:translateY(-50%);z-index:5}.--size-small{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);--rs-select-radius:var(--rs-radius-small)}.--size-small .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-medium{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);--rs-select-radius:var(--rs-radius-small)}.--size-medium .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x2)}.--size-large{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);--rs-select-radius:var(--rs-radius-medium)}.--size-large .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}.--size-xlarge{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);--rs-select-radius:var(--rs-radius-medium)}.--size-xlarge .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x4)}.root.--variant-faded{background:var(--rs-color-background-neutral-faded)}.root.--variant-faded:after{box-shadow:none}.root.--variant-faded:focus-within{border-color:var(--rs-color-border-primary)}.root.--variant-headless{background:transparent}.root.--variant-headless:after{box-shadow:none}.root.--variant-headless.--status-error,.root.--variant-headless.--status-error:focus-within,.root.--variant-headless:focus-within{border-color:transparent}.root.--variant-headless.--status-error:after,.root.--variant-headless.--status-error:focus-within:after,.root.--variant-headless:focus-within:after{box-shadow:none}.root.--status-error{box-shadow:0 0 0 1px var(--rs-color-border-critical)}.root.--status-error:after{box-shadow:0 0 0 1px var(--rs-color-border-critical) inset}.root.--disabled{background:var(--rs-color-background-disabled-faded);border-color:var(--rs-color-border-disabled)}.root.--disabled .arrow,.root.--disabled .input{color:var(--rs-color-foreground-disabled);cursor:not-allowed}@media (--rs-viewport-s ) and (hover:none){.input{font-size:var(--rs-font-size-body-2)!important}}@media (--rs-viewport-m ){.--size-small--m{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);--rs-select-radius:var(--rs-radius-small)}.--size-small--m .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-medium--m{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);--rs-select-radius:var(--rs-radius-small)}.--size-medium--m .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x2)}.--size-large--m{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);--rs-select-radius:var(--rs-radius-medium)}.--size-large--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}.--size-xlarge--m{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);--rs-select-radius:var(--rs-radius-medium)}.--size-xlarge--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x4)}}@media (--rs-viewport-l ){.--size-small--l{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);--rs-select-radius:var(--rs-radius-small)}.--size-small--l .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-medium--l{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);--rs-select-radius:var(--rs-radius-small)}.--size-medium--l .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x2)}.--size-large--l{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);--rs-select-radius:var(--rs-radius-medium)}.--size-large--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}.--size-xlarge--l{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);--rs-select-radius:var(--rs-radius-medium)}.--size-xlarge--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x4)}}@media (--rs-viewport-xl ){.--size-small--xl{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);--rs-select-radius:var(--rs-radius-small)}.--size-small--xl .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-medium--xl{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);--rs-select-radius:var(--rs-radius-small)}.--size-medium--xl .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x2)}.--size-large--xl{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);--rs-select-radius:var(--rs-radius-medium)}.--size-large--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}.--size-xlarge--xl{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);--rs-select-radius:var(--rs-radius-medium)}.--size-xlarge--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x4)}}
@@ -1,10 +1,10 @@
1
1
  import React from "react";
2
2
  import type * as G from "../../types/global";
3
- import type { FormControlProps } from "../FormControl";
4
- import type { ActionableProps } from "../Actionable";
5
3
  import type { IconProps } from "../Icon";
4
+ import type { ActionableProps } from "../Actionable";
5
+ import type { MenuItemProps } from "../MenuItem";
6
6
  type Size = G.Responsive<"small" | "medium" | "large" | "xlarge">;
7
- type Option = {
7
+ type NativeOption = {
8
8
  /** Option text label */
9
9
  label: string;
10
10
  /** Option value used in the form submission */
@@ -12,40 +12,14 @@ type Option = {
12
12
  /** Disable the option from the selection */
13
13
  disabled?: boolean;
14
14
  };
15
- export type ButtonTriggerProps = {
16
- /** Callback when the button is clicked */
17
- onClick?: () => void;
18
- /** Node for inserting children */
19
- children?: React.ReactNode;
20
- /** Additional attributes for the input element */
21
- inputAttributes?: ActionableProps["attributes"];
22
- /** Callback when the input is focused */
23
- onFocus?: (e: React.FocusEvent<HTMLButtonElement>) => void;
24
- /** Callback when the input is blurred */
25
- onBlur?: (e: React.FocusEvent<HTMLButtonElement>) => void;
26
- /** Options for the select */
27
- options?: never;
28
- /** Callback when the input value changes */
29
- onChange?: never;
15
+ export type OptionProps = Pick<MenuItemProps, "attributes" | "children" | "className" | "disabled" | "endSlot" | "startSlot" | "icon" | "onClick"> & {
16
+ value: string;
30
17
  };
31
- export type SelectTriggerProps = {
32
- /** Options for the select */
33
- options: Option[];
34
- /** Callback when the input value changes */
35
- onChange?: G.ChangeHandler<string, React.ChangeEvent<HTMLSelectElement>>;
36
- /** Callback when the input is focused */
37
- onFocus?: (e: React.FocusEvent<HTMLSelectElement>) => void;
38
- /** Callback when the input is blurred */
39
- onBlur?: (e: React.FocusEvent<HTMLSelectElement>) => void;
40
- /** Additional attributes for the input element */
41
- inputAttributes?: G.Attributes<"select">;
42
- /** Callback when the button is clicked */
43
- onClick?: never;
44
- /** Node for inserting children */
45
- children?: never;
18
+ export type OptionGroupProps = {
19
+ label: string;
20
+ children: React.ReactNode;
46
21
  };
47
- type BaseProps = ((ButtonTriggerProps | SelectTriggerProps) & Pick<FormControlProps, "hasError">) & {
48
- /** Unique identifier for the select */
22
+ type BaseFragment = {
49
23
  id?: string;
50
24
  /** Name of the input element */
51
25
  name: string;
@@ -61,18 +35,62 @@ type BaseProps = ((ButtonTriggerProps | SelectTriggerProps) & Pick<FormControlPr
61
35
  icon?: IconProps["svg"];
62
36
  /** Node for inserting content before the select value */
63
37
  startSlot?: React.ReactNode;
38
+ /** Show an error state, automatically inherited when component is used inside FormControl */
39
+ hasError?: boolean;
40
+ /** Callback when the trigger is clicked */
41
+ onClick?: ActionableProps["onClick"];
64
42
  /** Additional classname for the root element */
65
43
  className?: G.ClassName;
66
44
  /** Additional attributes for the root element */
67
45
  attributes?: G.Attributes<"div">;
46
+ /** Node for inserting children */
47
+ children?: React.ReactNode;
48
+ };
49
+ export type CustomFragment = {
50
+ /** Options for the select */
51
+ options?: never;
52
+ /** Callback when the input value changes */
53
+ onChange?: G.ChangeHandler<string>;
54
+ /** Callback when the input is focused */
55
+ onFocus?: (e: React.FocusEvent<HTMLButtonElement>) => void;
56
+ /** Callback when the input is blurred */
57
+ onBlur?: (e: React.FocusEvent<HTMLButtonElement>) => void;
58
+ /** Additional attributes for the trigger element */
59
+ inputAttributes?: ActionableProps["attributes"];
60
+ };
61
+ export type NativeFragment = {
62
+ /** Options for the select */
63
+ /** @deprecated Use <option /> children instead */
64
+ options?: NativeOption[];
65
+ /** Callback when the input value changes */
66
+ onChange?: G.ChangeHandler<string, React.ChangeEvent<HTMLSelectElement>>;
67
+ /** Callback when the input is focused */
68
+ onFocus?: (e: React.FocusEvent<HTMLSelectElement>) => void;
69
+ /** Callback when the input is blurred */
70
+ onBlur?: (e: React.FocusEvent<HTMLSelectElement>) => void;
71
+ /** Additional attributes for the input element */
72
+ inputAttributes?: G.Attributes<"select">;
68
73
  };
69
- export type ControlledProps = BaseProps & {
74
+ export type ControlledFragment = {
70
75
  value: string;
71
76
  defaultValue?: never;
72
77
  };
73
- export type UncontrolledProps = BaseProps & {
78
+ export type UncontrolledFragment = {
74
79
  value?: never;
75
80
  defaultValue?: string;
76
81
  };
77
- export type Props = ControlledProps | UncontrolledProps;
82
+ export type NativeControlledProps = BaseFragment & NativeFragment & ControlledFragment;
83
+ export type NativeUncontrolledProps = BaseFragment & NativeFragment & UncontrolledFragment;
84
+ export type CustomControlledProps = BaseFragment & CustomFragment & ControlledFragment;
85
+ export type CustomUncontrolledProps = BaseFragment & CustomFragment & UncontrolledFragment;
86
+ export type NativeProps = NativeControlledProps | NativeUncontrolledProps;
87
+ export type CustomProps = CustomControlledProps | CustomUncontrolledProps;
88
+ export type Props = NativeControlledProps | NativeUncontrolledProps | CustomControlledProps | CustomUncontrolledProps;
89
+ export type TriggerProps = Pick<CustomControlledProps, "disabled" | "onClick" | "onFocus" | "onBlur" | "inputAttributes" | "startSlot" | "icon" | "size" | "placeholder" | "value" | "name" | "id"> & {
90
+ children?: React.ReactNode;
91
+ };
92
+ export type RootProps = Omit<Props, "children"> & {
93
+ children: (props: Omit<Props, "children">) => React.ReactNode;
94
+ };
95
+ export type SelectContextProps = CustomControlledProps;
78
96
  export {};
@@ -0,0 +1,3 @@
1
+ import type * as T from "./Select.types";
2
+ declare const SelectCustom: React.FC<T.CustomProps>;
3
+ export default SelectCustom;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import SelectCustomControlled from "./SelectCustomControlled.js";
3
+ import SelectCustomUncontrolled from "./SelectCustomUncontrolled.js";
4
+ const SelectCustom = (props) => {
5
+ const { value } = props;
6
+ if (value !== undefined)
7
+ return _jsx(SelectCustomControlled, { ...props });
8
+ return _jsx(SelectCustomUncontrolled, { ...props });
9
+ };
10
+ SelectCustom.displayName = "SelectCustom";
11
+ export default SelectCustom;
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ import type * as T from "./Select.types";
3
+ declare const SelectCustomControlled: React.FC<T.CustomControlledProps>;
4
+ export default SelectCustomControlled;
@@ -0,0 +1,88 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import DropdownMenu from "../DropdownMenu/index.js";
4
+ import Icon from "../Icon/index.js";
5
+ import CheckmarkIcon from "../../icons/Checkmark.js";
6
+ import { isMatchingComponentChildId, responsivePropDependency } from "../../utilities/props.js";
7
+ import SelectRoot from "./SelectRoot.js";
8
+ import SelectTrigger from "./SelectTrigger.js";
9
+ const SelectCustomControlled = (props) => {
10
+ const { children, value, name, placeholder, size } = props;
11
+ const initialFocusRef = React.useRef(null);
12
+ const searchStringRef = React.useRef("");
13
+ const searchTimeoutRef = React.useRef(null);
14
+ const dropdownRef = React.useRef(null);
15
+ const indexedOptions = [];
16
+ let selectedOption = null;
17
+ const traverseOptionList = (children) => {
18
+ return React.Children.map(children, (child, index) => {
19
+ if (!React.isValidElement(child))
20
+ return null;
21
+ if (isMatchingComponentChildId(child, "Select.Option")) {
22
+ const component = child;
23
+ const option = component.props;
24
+ const matchingValue = option.value === value;
25
+ const selected = matchingValue || (!placeholder && !value && index === 0);
26
+ if (selected)
27
+ selectedOption = option;
28
+ indexedOptions.push({
29
+ value: option.value,
30
+ text: typeof option.children === "string" ? option.children : option.value,
31
+ });
32
+ return React.cloneElement(component, {
33
+ key: option.value,
34
+ onClick: (e) => {
35
+ props.onChange?.({ value: option.value, name });
36
+ option.onClick?.(e);
37
+ },
38
+ startSlot: option?.startSlot || (value && _jsx(Icon, { svg: selected ? CheckmarkIcon : null })),
39
+ attributes: {
40
+ ...component.props.attributes,
41
+ ref: selected ? initialFocusRef : undefined,
42
+ },
43
+ });
44
+ }
45
+ if (isMatchingComponentChildId(child, "Select.OptionGroup")) {
46
+ const component = child;
47
+ const optionGroup = component.props;
48
+ return React.cloneElement(component, {
49
+ key: optionGroup.label,
50
+ children: traverseOptionList(optionGroup.children),
51
+ });
52
+ }
53
+ return null;
54
+ });
55
+ };
56
+ const resolvedChildren = traverseOptionList(children);
57
+ const handleKeyDown = (e) => {
58
+ const key = e.key;
59
+ // Only handle alphanumeric and space characters for type-ahead
60
+ if (key.length !== 1 || !key.match(/[\w\s]/))
61
+ return;
62
+ if (searchTimeoutRef.current)
63
+ clearTimeout(searchTimeoutRef.current);
64
+ searchStringRef.current += key.toLowerCase();
65
+ const matchingOption = indexedOptions.find((option) => option.text.toLowerCase().startsWith(searchStringRef.current));
66
+ if (matchingOption && dropdownRef.current) {
67
+ const button = dropdownRef.current.querySelector(`[value="${matchingOption.value}"]`);
68
+ button?.focus();
69
+ }
70
+ searchTimeoutRef.current = setTimeout(() => {
71
+ searchStringRef.current = "";
72
+ }, 1000);
73
+ };
74
+ return (_jsx(SelectRoot, { ...props, children: (props) => {
75
+ return (_jsxs(DropdownMenu, { width: "trigger", disableHideAnimation: true, position: "bottom", fallbackPositions: ["bottom", "top"], fallbackAdjustLayout: true, fallbackMinHeight: "150px", borderRadius: responsivePropDependency(size, (size) => size === "large" || size === "xlarge" ? "medium" : "small"), initialFocusRef: initialFocusRef, children: [_jsx(DropdownMenu.Trigger, { children: (attributes) => {
76
+ const triggerProps = {
77
+ ...props,
78
+ inputAttributes: {
79
+ ...props.inputAttributes,
80
+ ...attributes,
81
+ },
82
+ };
83
+ return (_jsx(SelectTrigger, { ...triggerProps, value: selectedOption?.value || "", children: value && selectedOption?.children }));
84
+ } }), _jsx(DropdownMenu.Content, { attributes: { ref: dropdownRef, onKeyDown: handleKeyDown }, children: resolvedChildren })] }));
85
+ } }));
86
+ };
87
+ SelectCustomControlled.displayName = "SelectCustomControlled";
88
+ export default SelectCustomControlled;
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ import type * as T from "./Select.types";
3
+ declare const SelectCustomUncontrolled: React.FC<T.CustomUncontrolledProps>;
4
+ export default SelectCustomUncontrolled;