@protonradio/proton-ui 0.12.4 → 0.12.6
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.
- package/README.md +10 -0
- package/dist/components/ActionMenu/ActionMenu.cjs.js.map +1 -1
- package/dist/components/ActionMenu/ActionMenu.es.js.map +1 -1
- package/dist/components/Banner/Banner.cjs.js.map +1 -1
- package/dist/components/Banner/Banner.es.js.map +1 -1
- package/dist/components/Button/Button.cjs.js.map +1 -1
- package/dist/components/Button/Button.es.js.map +1 -1
- package/dist/components/ButtonGroup/ButtonGroup.cjs.js +1 -1
- package/dist/components/ButtonGroup/ButtonGroup.cjs.js.map +1 -1
- package/dist/components/ButtonGroup/ButtonGroup.es.js +10 -10
- package/dist/components/ButtonGroup/ButtonGroup.es.js.map +1 -1
- package/dist/components/Checkbox/CheckboxInput/CheckboxInput.cjs.js.map +1 -1
- package/dist/components/Checkbox/CheckboxInput/CheckboxInput.es.js.map +1 -1
- package/dist/components/Checkbox/CheckboxRadioGroup/CheckboxRadioGroup.cjs.js.map +1 -1
- package/dist/components/Checkbox/CheckboxRadioGroup/CheckboxRadioGroup.es.js.map +1 -1
- package/dist/components/Input/BaseInput/Input.cjs.js.map +1 -1
- package/dist/components/Input/BaseInput/Input.es.js.map +1 -1
- package/dist/components/Input/OTPInput/OTPInput.cjs.js.map +1 -1
- package/dist/components/Input/OTPInput/OTPInput.es.js.map +1 -1
- package/dist/components/Popover/Popover.cjs.js +1 -1
- package/dist/components/Popover/Popover.cjs.js.map +1 -1
- package/dist/components/Popover/Popover.es.js +21 -14
- package/dist/components/Popover/Popover.es.js.map +1 -1
- package/dist/components/ScreenOverlay/ScreenOverlay.cjs.js.map +1 -1
- package/dist/components/ScreenOverlay/ScreenOverlay.es.js.map +1 -1
- package/dist/components/Select/Select.cjs.js.map +1 -1
- package/dist/components/Select/Select.es.js.map +1 -1
- package/dist/components/Text/TextEllipsis/TextEllipsis.cjs.js.map +1 -1
- package/dist/components/Text/TextEllipsis/TextEllipsis.es.js.map +1 -1
- package/dist/components/Tooltip/ResponsiveTooltip.cjs.js.map +1 -1
- package/dist/components/Tooltip/ResponsiveTooltip.es.js.map +1 -1
- package/dist/constants/breakpoint.cjs.js.map +1 -1
- package/dist/constants/breakpoint.es.js.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/dark.d.ts +0 -1
- package/dist/design/darkTheme/colors.cjs.js +1 -1
- package/dist/design/darkTheme/colors.cjs.js.map +1 -1
- package/dist/design/darkTheme/colors.es.js +7 -8
- package/dist/design/darkTheme/colors.es.js.map +1 -1
- package/dist/design/generateStylesheet.cjs.js.map +1 -1
- package/dist/design/generateStylesheet.es.js +0 -1
- package/dist/design/generateStylesheet.es.js.map +1 -1
- package/dist/design/lightTheme/colors.cjs.js +1 -1
- package/dist/design/lightTheme/colors.cjs.js.map +1 -1
- package/dist/design/lightTheme/colors.es.js +10 -11
- package/dist/design/lightTheme/colors.es.js.map +1 -1
- package/dist/hooks/useBreakpoint.cjs.js.map +1 -1
- package/dist/hooks/useBreakpoint.es.js.map +1 -1
- package/dist/hooks/useMergedRef.cjs.js.map +1 -1
- package/dist/hooks/useMergedRef.es.js.map +1 -1
- package/dist/hooks.d.ts +1 -3
- package/dist/index.d.ts +15 -11
- package/dist/light.d.ts +0 -1
- package/dist/style.css +1 -1
- package/dist/theme.d.ts +0 -1
- package/dist/utils/palette.cjs.js +1 -1
- package/dist/utils/palette.cjs.js.map +1 -1
- package/dist/utils/palette.es.js +64 -77
- package/dist/utils/palette.es.js.map +1 -1
- package/dist/utils.d.ts +0 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,6 +19,16 @@ npm run storybook
|
|
|
19
19
|
npm install @protonradio/proton-ui --save
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
Is simply installing `@protonradio/proton-ui` enough to import the styles?
|
|
23
|
+
|
|
24
|
+
No. You also need:
|
|
25
|
+
|
|
26
|
+
A global import of dist/style.css, for example `/src/index.css`:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
@import '../node_modules/@protonradio/proton-ui/dist/style.css';
|
|
30
|
+
```
|
|
31
|
+
|
|
22
32
|
### Project Structure
|
|
23
33
|
|
|
24
34
|
TODO: Explain project structure after treeshaking efforts have concluded
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionMenu.cjs.js","sources":["../../../src/components/ActionMenu/ActionMenu.tsx"],"sourcesContent":["\"use client\";\n\nimport { ReactNode, useEffect, useRef, useState } from \"react\";\n\nimport { useIsClosing } from \"../../hooks/useIsClosing\";\nimport { handleInternalNavigation, isUrlExternal } from \"../../utils\";\n\nimport { Button } from \"../Button/Button\";\nimport { ScreenOverlay } from \"../ScreenOverlay/ScreenOverlay\";\nimport { DropdownMenu } from \"radix-ui\";\nimport { ChevronLeft } from \"../Icon/IconComponents/ChevronLeft\";\nimport { ChevronRight } from \"../Icon/IconComponents/ChevronRight\";\n\nimport \"./ActionMenu.css\";\n\nexport interface ActionMenuAction {\n key: string;\n label?: ReactNode;\n description?: ReactNode;\n to?: string;\n onAction?: (key: string) => void;\n children?: ActionMenuAction[];\n}\n\nexport type ActionMenuSelectionMode = \"single\" | \"multiple\" | \"none\";\n\n/** Keys passed to `onSelectionChange` (Set of item keys, or `\"all\"`). */\nexport type ActionMenuSelection = \"all\" | Set<string>;\n\nexport interface ActionMenuProps {\n /** The actions of the menu\n * - type {@link ActionMenuAction}[]\n */\n actions?: ActionMenuAction[];\n\n /** The text of the cancel button */\n cancelButtonText?: string;\n\n /** The children of the menu */\n children?: ReactNode | ((props: { close: () => void }) => ReactNode);\n\n /** The test id of the menu */\n \"data-testid\"?: string;\n\n /** The keys of the disabled items\n * @default []\n */\n disabledKeys?: string[];\n\n /** Whether the menu is open\n * @default false\n */\n isOpen: boolean;\n\n /** The callback function to close the menu */\n onClose?: () => void;\n\n /** The callback function to change the selection\n * - type {@link ActionMenuSelection}\n */\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n\n /** The selection mode of the menu\n * @default \"single\"\n */\n selectionMode?: ActionMenuSelectionMode;\n\n /** The keys of the selected items */\n selectedKeys?: string[];\n\n /** Whether to show the cancel button */\n showCancel?: boolean;\n\n /** The title of the menu */\n title?: string;\n}\n\ntype ActionStack = {\n title: ReactNode | null;\n actions: ActionMenuAction[];\n key: string | null;\n previousKey: string | null;\n};\n\n/**\n * A controlled ActionMenu to display a menu of actions.\n * Renders a list of actions as a focusable menu, or non-focusable children.\n *\n * API:\n * - {@link ActionMenuProps}\n */\nexport const ActionMenu = ({\n isOpen,\n actions = [],\n children,\n showCancel = true,\n cancelButtonText = \"Cancel\",\n selectionMode = \"single\",\n selectedKeys,\n disabledKeys = [],\n onSelectionChange,\n onClose,\n title,\n \"data-testid\": testId,\n}: ActionMenuProps) => {\n const [contentHeight, setContentHeight] = useState<number>(0);\n const [stackHistory, setStackHistory] = useState<ActionStack[]>([]);\n const [currentActionStack, setCurrentActionStack] = useState<ActionStack>({\n title,\n actions,\n key: null,\n previousKey: null,\n });\n const contentRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const overlayRef = useRef<HTMLDivElement>(null);\n const { isClosing, handleClose } = useIsClosing({ onClose, overlayRef });\n\n const currentActions = currentActionStack.actions || [];\n const hasActions = currentActions && currentActions.length > 0;\n const hasContent = children || hasActions || showCancel;\n const isInSubmenu = stackHistory.length > 0;\n\n function handleSubmenuOpen(key: string) {\n const action = currentActions.find((action) => action.key === key);\n if (!action) {\n console.error(`Action with key ${key} not found`);\n return;\n }\n\n setStackHistory((prevStackHistory) => [\n ...prevStackHistory,\n currentActionStack,\n ]);\n setCurrentActionStack((prevStack) => ({\n title: action.label,\n actions: action.children || [],\n key: action.key,\n previousKey: prevStack.key,\n }));\n }\n\n function handleBack() {\n if (stackHistory.length > 0) {\n const previousStack = stackHistory[stackHistory.length - 1];\n setCurrentActionStack(previousStack);\n setStackHistory(stackHistory.slice(0, -1));\n }\n }\n\n // Re-measure the open menu's content height when stack history changes\n useEffect(() => {\n if (!isOpen) return;\n\n requestAnimationFrame(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight + 12);\n }\n });\n }, [isOpen, stackHistory, hasContent]);\n\n // Reset content height when menu closes or is closing\n useEffect(() => {\n if (!isOpen || isClosing) {\n setContentHeight(0);\n }\n }, [isOpen, isClosing]);\n\n if (!isOpen && !isClosing) return null;\n\n return (\n <ScreenOverlay fadeIn ref={overlayRef}>\n <DropdownMenu.Root\n modal\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) handleClose();\n }}\n >\n <DropdownMenu.Trigger asChild>\n {/* No visible trigger, menu is controlled by isOpen */}\n <div>{\"\"}</div>\n </DropdownMenu.Trigger>\n\n <div\n data-disable-document-scroll={isOpen}\n className=\"proton-ActionMenu__background-wrapper\"\n style={{ opacity: isClosing ? 0 : 1 }}\n >\n <div\n data-testid={testId || \"ActionMenu-wrapper\"}\n className=\"proton-ActionMenu__wrapper\"\n >\n <div\n className=\"proton-ActionMenu__card\"\n data-testid=\"ActionMenu-content\"\n style={{ height: `${contentHeight}px` }}\n >\n <div ref={menuRef} className=\"proton-ActionMenu__menu\">\n <DropdownMenu.Content loop sideOffset={8} ref={contentRef}>\n {hasContent && (\n <>\n {children && (\n <div className=\"proton-ActionMenu__content\">\n {typeof children === \"function\"\n ? children({ close: handleClose })\n : children}\n </div>\n )}\n\n {hasActions && (\n <ActionMenuList\n actions={currentActions}\n selectionMode={selectionMode}\n selectedKeys={selectedKeys}\n onSelectionChange={onSelectionChange}\n disabledKeys={disabledKeys}\n handleSubmenuOpen={handleSubmenuOpen}\n title={currentActionStack.title}\n isInSubmenu={isInSubmenu}\n handleBack={handleBack}\n previousMenuTitle={\n stackHistory[stackHistory.length - 1]?.title\n }\n />\n )}\n\n {showCancel && (\n <>\n <DropdownMenu.Separator />\n <DropdownMenu.Item className=\"proton-ActionMenu__cancel-button\">\n <Button\n data-testid=\"ActionMenuItem-cancel\"\n onPress={handleClose}\n fullWidth\n variant=\"secondary\"\n >\n {cancelButtonText}\n </Button>\n </DropdownMenu.Item>\n </>\n )}\n </>\n )}\n </DropdownMenu.Content>\n </div>\n </div>\n </div>\n </div>\n </DropdownMenu.Root>\n </ScreenOverlay>\n );\n};\n\ninterface ActionMenuListProps {\n actions: ActionMenuAction[];\n selectionMode: ActionMenuSelectionMode;\n selectedKeys?: string[];\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n disabledKeys?: string[];\n handleSubmenuOpen: (key: string) => void;\n title?: ReactNode;\n isInSubmenu?: boolean;\n handleBack?: () => void;\n previousMenuTitle?: ReactNode;\n}\n\nconst ActionMenuList = ({\n actions,\n selectionMode,\n selectedKeys = [],\n onSelectionChange,\n disabledKeys = [],\n handleSubmenuOpen,\n title,\n isInSubmenu = false,\n handleBack,\n previousMenuTitle,\n}: ActionMenuListProps) => {\n const ActionMenuItemMap = () => (\n <>\n {isInSubmenu && handleBack && (\n <div className=\"proton-ActionMenu__back-button-container\">\n <DropdownMenu.Item\n className=\"proton-ActionMenu__back-button\"\n onSelect={(event) => {\n event.preventDefault();\n handleBack();\n }}\n aria-label={`Go back to ${previousMenuTitle || \"previous menu\"}`}\n >\n <ChevronLeft size={16} />\n </DropdownMenu.Item>\n <div\n className=\"proton-ActionMenu__title\"\n role=\"banner\"\n aria-label={isInSubmenu ? `Submenu: ${title}` : `Menu: ${title}`}\n >\n <span>{title}</span>\n </div>\n <DropdownMenu.Separator />\n </div>\n )}\n\n {actions.map((action, i) => {\n const itemProps = actions[i];\n return (\n <ActionMenuItem\n key={action.key}\n item={action}\n isSubmenu={Boolean(itemProps.children?.length)}\n selectionMode={selectionMode}\n onSelectionChange={onSelectionChange}\n selectedKeys={selectedKeys}\n disabledKeys={disabledKeys}\n handleSubmenuOpen={handleSubmenuOpen}\n />\n );\n })}\n </>\n );\n\n return (\n <div\n aria-disabled={selectionMode === \"none\"}\n className=\"proton-ActionMenu__list\"\n role=\"menu\"\n aria-label={\n title ? `${isInSubmenu ? \"Submenu\" : \"Menu\"}: ${title}` : \"Action menu\"\n }\n aria-orientation=\"vertical\"\n >\n {selectionMode === \"single\" ? (\n <DropdownMenu.RadioGroup\n value={selectedKeys?.[0] || \"\"}\n onValueChange={(value) => {\n // Check if this is a submenu item - if so, don't trigger selection change\n const action = actions.find((action) => action.key === value);\n if (action?.children?.length) {\n return;\n }\n\n if (onSelectionChange) {\n onSelectionChange(new Set([value]));\n }\n }}\n >\n <ActionMenuItemMap />\n </DropdownMenu.RadioGroup>\n ) : (\n <DropdownMenu.Group>\n <ActionMenuItemMap />\n </DropdownMenu.Group>\n )}\n </div>\n );\n};\n\ninterface ActionMenuItemProps {\n to?: string;\n item: ActionMenuAction;\n isSubmenu?: boolean;\n selectionMode: ActionMenuSelectionMode;\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n selectedKeys?: string[];\n disabledKeys?: string[];\n handleSubmenuOpen: (key: string) => void;\n}\n\nconst ActionMenuItem = ({\n item,\n isSubmenu,\n selectionMode,\n onSelectionChange,\n selectedKeys = [],\n disabledKeys = [],\n handleSubmenuOpen,\n}: ActionMenuItemProps) => {\n const ref = useRef(null);\n const isExternal = item.to && isUrlExternal(item.to);\n const isDisabled = disabledKeys.includes(item.key);\n const isSelected = selectedKeys.includes(item.key);\n\n const radixItemProps = {\n className: \"proton-ActionMenu__item\",\n \"aria-label\": item.label\n ? `${item.label}${item.description ? `, ${item.description}` : \"\"}`\n : `ActionMenu-Item-${item.key}`,\n role: \"menuitem\",\n disabled: isDisabled,\n ref,\n };\n\n const onSelect = (event: Event) => {\n if (item?.children?.length) {\n event.preventDefault();\n handleSubmenuOpen(item.key);\n return;\n }\n if (item.onAction) {\n item.onAction(item.key);\n }\n };\n\n const content = (\n <>\n <div className=\"proton-ActionMenu__item-content\">\n <div className=\"proton-ActionMenu__item-label\">{item.label}</div>\n {item.description && (\n <div className=\"proton-ActionMenu__description\">\n {item.description}\n </div>\n )}\n </div>\n {isSubmenu && <ChevronRight size={16} />}\n </>\n );\n\n if (item.to) {\n return (\n <DropdownMenu.Item {...radixItemProps} key={item.key} asChild>\n <a\n aria-label={`ActionMenu-Item-${item.key}`}\n aria-disabled={isDisabled}\n aria-checked={isSelected}\n aria-expanded={isSubmenu ? false : undefined}\n href={item.to}\n target={isExternal ? \"_blank\" : undefined}\n rel={isExternal ? \"noopener noreferrer\" : undefined}\n onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {\n if (isExternal || !item.to) {\n return;\n }\n handleInternalNavigation(e, item.to);\n }}\n >\n {content}\n </a>\n </DropdownMenu.Item>\n );\n }\n\n if (selectionMode === \"multiple\") {\n return (\n <DropdownMenu.CheckboxItem\n {...radixItemProps}\n key={item.key}\n checked={isSelected}\n onSelect={onSelect}\n onCheckedChange={(checked: boolean) => {\n if (!onSelectionChange) return;\n\n const currentKeys = new Set(selectedKeys);\n if (checked) {\n currentKeys.add(item.key);\n } else {\n currentKeys.delete(item.key);\n }\n onSelectionChange(currentKeys);\n }}\n >\n {content}\n </DropdownMenu.CheckboxItem>\n );\n }\n\n return (\n <DropdownMenu.RadioItem\n {...radixItemProps}\n value={item.key}\n key={item.key}\n aria-checked={isSelected}\n aria-expanded={isSubmenu ? false : undefined}\n onSelect={onSelect}\n >\n {content}\n </DropdownMenu.RadioItem>\n );\n};\n"],"names":["ActionMenu","isOpen","actions","children","showCancel","cancelButtonText","selectionMode","selectedKeys","disabledKeys","onSelectionChange","onClose","title","testId","contentHeight","setContentHeight","useState","stackHistory","setStackHistory","currentActionStack","setCurrentActionStack","contentRef","useRef","menuRef","overlayRef","isClosing","handleClose","useIsClosing","currentActions","hasActions","hasContent","isInSubmenu","handleSubmenuOpen","key","action","prevStackHistory","prevStack","handleBack","previousStack","useEffect","jsx","ScreenOverlay","jsxs","DropdownMenu","open","Fragment","ActionMenuList","_a","Button","previousMenuTitle","ActionMenuItemMap","event","ChevronLeft","i","itemProps","ActionMenuItem","value","item","isSubmenu","ref","isExternal","isUrlExternal","isDisabled","isSelected","radixItemProps","onSelect","content","ChevronRight","createElement","e","handleInternalNavigation","checked","currentKeys"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActionMenu.cjs.js","sources":["../../../src/components/ActionMenu/ActionMenu.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactNode, useEffect, useRef, useState } from \"react\";\n\nimport { useIsClosing } from \"../../hooks/useIsClosing\";\nimport { handleInternalNavigation, isUrlExternal } from \"../../utils\";\n\nimport { Button } from \"../Button/Button\";\nimport { ScreenOverlay } from \"../ScreenOverlay/ScreenOverlay\";\nimport { DropdownMenu } from \"radix-ui\";\nimport { ChevronLeft } from \"../Icon/IconComponents/ChevronLeft\";\nimport { ChevronRight } from \"../Icon/IconComponents/ChevronRight\";\n\nimport \"./ActionMenu.css\";\n\nexport interface ActionMenuAction {\n key: string;\n label?: ReactNode;\n description?: ReactNode;\n to?: string;\n onAction?: (key: string) => void;\n children?: ActionMenuAction[];\n}\n\nexport type ActionMenuSelectionMode = \"single\" | \"multiple\" | \"none\";\n\n/** Keys passed to `onSelectionChange` (Set of item keys, or `\"all\"`). */\nexport type ActionMenuSelection = \"all\" | Set<string>;\n\nexport interface ActionMenuProps {\n /** The actions of the menu\n * - type {@link ActionMenuAction}[]\n */\n actions?: ActionMenuAction[];\n\n /** The text of the cancel button */\n cancelButtonText?: string;\n\n /** The children of the menu */\n children?: ReactNode | ((props: { close: () => void }) => ReactNode);\n\n /** The test id of the menu */\n \"data-testid\"?: string;\n\n /** The keys of the disabled items\n * @default []\n */\n disabledKeys?: string[];\n\n /** Whether the menu is open\n * @default false\n */\n isOpen: boolean;\n\n /** The callback function to close the menu */\n onClose?: () => void;\n\n /** The callback function to change the selection\n * - type {@link ActionMenuSelection}\n */\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n\n /** The selection mode of the menu\n * @default \"single\"\n */\n selectionMode?: ActionMenuSelectionMode;\n\n /** The keys of the selected items */\n selectedKeys?: string[];\n\n /** Whether to show the cancel button */\n showCancel?: boolean;\n\n /** The title of the menu */\n title?: string;\n}\n\ntype ActionStack = {\n title: ReactNode | null;\n actions: ActionMenuAction[];\n key: string | null;\n previousKey: string | null;\n};\n\n/**\n * A controlled ActionMenu to display a menu of actions.\n * Renders a list of actions as a focusable menu, or non-focusable children.\n *\n * API:\n * - {@link ActionMenuProps}\n */\nexport const ActionMenu = ({\n isOpen,\n actions = [],\n children,\n showCancel = true,\n cancelButtonText = \"Cancel\",\n selectionMode = \"single\",\n selectedKeys,\n disabledKeys = [],\n onSelectionChange,\n onClose,\n title,\n \"data-testid\": testId,\n}: ActionMenuProps) => {\n const [contentHeight, setContentHeight] = useState<number>(0);\n const [stackHistory, setStackHistory] = useState<ActionStack[]>([]);\n const [currentActionStack, setCurrentActionStack] = useState<ActionStack>({\n title,\n actions,\n key: null,\n previousKey: null,\n });\n const contentRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const overlayRef = useRef<HTMLDivElement>(null);\n const { isClosing, handleClose } = useIsClosing({ onClose, overlayRef });\n\n const currentActions = currentActionStack.actions || [];\n const hasActions = currentActions && currentActions.length > 0;\n const hasContent = children || hasActions || showCancel;\n const isInSubmenu = stackHistory.length > 0;\n\n function handleSubmenuOpen(key: string) {\n const action = currentActions.find((action) => action.key === key);\n if (!action) {\n console.error(`Action with key ${key} not found`);\n return;\n }\n\n setStackHistory((prevStackHistory) => [\n ...prevStackHistory,\n currentActionStack,\n ]);\n setCurrentActionStack((prevStack) => ({\n title: action.label,\n actions: action.children || [],\n key: action.key,\n previousKey: prevStack.key,\n }));\n }\n\n function handleBack() {\n if (stackHistory.length > 0) {\n const previousStack = stackHistory[stackHistory.length - 1];\n setCurrentActionStack(previousStack);\n setStackHistory(stackHistory.slice(0, -1));\n }\n }\n\n // Re-measure the open menu's content height when stack history changes\n useEffect(() => {\n if (!isOpen) return;\n\n requestAnimationFrame(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight + 12);\n }\n });\n }, [isOpen, stackHistory, hasContent]);\n\n // Reset content height when menu closes or is closing\n useEffect(() => {\n if (!isOpen || isClosing) {\n setContentHeight(0);\n }\n }, [isOpen, isClosing]);\n\n if (!isOpen && !isClosing) return null;\n\n return (\n <ScreenOverlay fadeIn ref={overlayRef}>\n <DropdownMenu.Root\n modal\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) handleClose();\n }}\n >\n <DropdownMenu.Trigger asChild>\n {/* No visible trigger, menu is controlled by isOpen */}\n <div>{\"\"}</div>\n </DropdownMenu.Trigger>\n\n <div\n data-disable-document-scroll={isOpen}\n className=\"proton-ActionMenu__background-wrapper\"\n style={{ opacity: isClosing ? 0 : 1 }}\n >\n <div\n data-testid={testId || \"ActionMenu-wrapper\"}\n className=\"proton-ActionMenu__wrapper\"\n >\n <div\n className=\"proton-ActionMenu__card\"\n data-testid=\"ActionMenu-content\"\n style={{ height: `${contentHeight}px` }}\n >\n <div ref={menuRef} className=\"proton-ActionMenu__menu\">\n <DropdownMenu.Content loop sideOffset={8} ref={contentRef}>\n {hasContent && (\n <>\n {children && (\n <div className=\"proton-ActionMenu__content\">\n {typeof children === \"function\"\n ? children({ close: handleClose })\n : children}\n </div>\n )}\n\n {hasActions && (\n <ActionMenuList\n actions={currentActions}\n selectionMode={selectionMode}\n selectedKeys={selectedKeys}\n onSelectionChange={onSelectionChange}\n disabledKeys={disabledKeys}\n handleSubmenuOpen={handleSubmenuOpen}\n title={currentActionStack.title}\n isInSubmenu={isInSubmenu}\n handleBack={handleBack}\n previousMenuTitle={\n stackHistory[stackHistory.length - 1]?.title\n }\n />\n )}\n\n {showCancel && (\n <>\n <DropdownMenu.Separator />\n <DropdownMenu.Item className=\"proton-ActionMenu__cancel-button\">\n <Button\n data-testid=\"ActionMenuItem-cancel\"\n onPress={handleClose}\n fullWidth\n variant=\"secondary\"\n >\n {cancelButtonText}\n </Button>\n </DropdownMenu.Item>\n </>\n )}\n </>\n )}\n </DropdownMenu.Content>\n </div>\n </div>\n </div>\n </div>\n </DropdownMenu.Root>\n </ScreenOverlay>\n );\n};\n\ninterface ActionMenuListProps {\n actions: ActionMenuAction[];\n selectionMode: ActionMenuSelectionMode;\n selectedKeys?: string[];\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n disabledKeys?: string[];\n handleSubmenuOpen: (key: string) => void;\n title?: ReactNode;\n isInSubmenu?: boolean;\n handleBack?: () => void;\n previousMenuTitle?: ReactNode;\n}\n\nconst ActionMenuList = ({\n actions,\n selectionMode,\n selectedKeys = [],\n onSelectionChange,\n disabledKeys = [],\n handleSubmenuOpen,\n title,\n isInSubmenu = false,\n handleBack,\n previousMenuTitle,\n}: ActionMenuListProps) => {\n const ActionMenuItemMap = () => (\n <>\n {isInSubmenu && handleBack && (\n <div className=\"proton-ActionMenu__back-button-container\">\n <DropdownMenu.Item\n className=\"proton-ActionMenu__back-button\"\n onSelect={(event) => {\n event.preventDefault();\n handleBack();\n }}\n aria-label={`Go back to ${previousMenuTitle || \"previous menu\"}`}\n >\n <ChevronLeft size={16} />\n </DropdownMenu.Item>\n <div\n className=\"proton-ActionMenu__title\"\n role=\"banner\"\n aria-label={isInSubmenu ? `Submenu: ${title}` : `Menu: ${title}`}\n >\n <span>{title}</span>\n </div>\n <DropdownMenu.Separator />\n </div>\n )}\n\n {actions.map((action, i) => {\n const itemProps = actions[i];\n return (\n <ActionMenuItem\n key={action.key}\n item={action}\n isSubmenu={Boolean(itemProps.children?.length)}\n selectionMode={selectionMode}\n onSelectionChange={onSelectionChange}\n selectedKeys={selectedKeys}\n disabledKeys={disabledKeys}\n handleSubmenuOpen={handleSubmenuOpen}\n />\n );\n })}\n </>\n );\n\n return (\n <div\n aria-disabled={selectionMode === \"none\"}\n className=\"proton-ActionMenu__list\"\n role=\"menu\"\n aria-label={\n title ? `${isInSubmenu ? \"Submenu\" : \"Menu\"}: ${title}` : \"Action menu\"\n }\n aria-orientation=\"vertical\"\n >\n {selectionMode === \"single\" ? (\n <DropdownMenu.RadioGroup\n value={selectedKeys?.[0] || \"\"}\n onValueChange={(value) => {\n // Check if this is a submenu item - if so, don't trigger selection change\n const action = actions.find((action) => action.key === value);\n if (action?.children?.length) {\n return;\n }\n\n if (onSelectionChange) {\n onSelectionChange(new Set([value]));\n }\n }}\n >\n <ActionMenuItemMap />\n </DropdownMenu.RadioGroup>\n ) : (\n <DropdownMenu.Group>\n <ActionMenuItemMap />\n </DropdownMenu.Group>\n )}\n </div>\n );\n};\n\ninterface ActionMenuItemProps {\n to?: string;\n item: ActionMenuAction;\n isSubmenu?: boolean;\n selectionMode: ActionMenuSelectionMode;\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n selectedKeys?: string[];\n disabledKeys?: string[];\n handleSubmenuOpen: (key: string) => void;\n}\n\nconst ActionMenuItem = ({\n item,\n isSubmenu,\n selectionMode,\n onSelectionChange,\n selectedKeys = [],\n disabledKeys = [],\n handleSubmenuOpen,\n}: ActionMenuItemProps) => {\n const ref = useRef(null);\n const isExternal = item.to && isUrlExternal(item.to);\n const isDisabled = disabledKeys.includes(item.key);\n const isSelected = selectedKeys.includes(item.key);\n\n const radixItemProps = {\n className: \"proton-ActionMenu__item\",\n \"aria-label\": item.label\n ? `${item.label}${item.description ? `, ${item.description}` : \"\"}`\n : `ActionMenu-Item-${item.key}`,\n role: \"menuitem\",\n disabled: isDisabled,\n ref,\n };\n\n const onSelect = (event: Event) => {\n if (item?.children?.length) {\n event.preventDefault();\n handleSubmenuOpen(item.key);\n return;\n }\n if (item.onAction) {\n item.onAction(item.key);\n }\n };\n\n const content = (\n <>\n <div className=\"proton-ActionMenu__item-content\">\n <div className=\"proton-ActionMenu__item-label\">{item.label}</div>\n {item.description && (\n <div className=\"proton-ActionMenu__description\">\n {item.description}\n </div>\n )}\n </div>\n {isSubmenu && <ChevronRight size={16} />}\n </>\n );\n\n if (item.to) {\n return (\n <DropdownMenu.Item {...radixItemProps} key={item.key} asChild>\n <a\n aria-label={`ActionMenu-Item-${item.key}`}\n aria-disabled={isDisabled}\n aria-checked={isSelected}\n aria-expanded={isSubmenu ? false : undefined}\n href={item.to}\n target={isExternal ? \"_blank\" : undefined}\n rel={isExternal ? \"noopener noreferrer\" : undefined}\n onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {\n if (isExternal || !item.to) {\n return;\n }\n handleInternalNavigation(e, item.to);\n }}\n >\n {content}\n </a>\n </DropdownMenu.Item>\n );\n }\n\n if (selectionMode === \"multiple\") {\n return (\n <DropdownMenu.CheckboxItem\n {...radixItemProps}\n key={item.key}\n checked={isSelected}\n onSelect={onSelect}\n onCheckedChange={(checked: boolean) => {\n if (!onSelectionChange) return;\n\n const currentKeys = new Set(selectedKeys);\n if (checked) {\n currentKeys.add(item.key);\n } else {\n currentKeys.delete(item.key);\n }\n onSelectionChange(currentKeys);\n }}\n >\n {content}\n </DropdownMenu.CheckboxItem>\n );\n }\n\n return (\n <DropdownMenu.RadioItem\n {...radixItemProps}\n value={item.key}\n key={item.key}\n aria-checked={isSelected}\n aria-expanded={isSubmenu ? false : undefined}\n onSelect={onSelect}\n >\n {content}\n </DropdownMenu.RadioItem>\n );\n};\n"],"names":["ActionMenu","isOpen","actions","children","showCancel","cancelButtonText","selectionMode","selectedKeys","disabledKeys","onSelectionChange","onClose","title","testId","contentHeight","setContentHeight","useState","stackHistory","setStackHistory","currentActionStack","setCurrentActionStack","contentRef","useRef","menuRef","overlayRef","isClosing","handleClose","useIsClosing","currentActions","hasActions","hasContent","isInSubmenu","handleSubmenuOpen","key","action","prevStackHistory","prevStack","handleBack","previousStack","useEffect","jsx","ScreenOverlay","jsxs","DropdownMenu","open","Fragment","ActionMenuList","_a","Button","previousMenuTitle","ActionMenuItemMap","event","ChevronLeft","i","itemProps","ActionMenuItem","value","item","isSubmenu","ref","isExternal","isUrlExternal","isDisabled","isSelected","radixItemProps","onSelect","content","ChevronRight","createElement","e","handleInternalNavigation","checked","currentKeys"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionMenu.es.js","sources":["../../../src/components/ActionMenu/ActionMenu.tsx"],"sourcesContent":["\"use client\";\n\nimport { ReactNode, useEffect, useRef, useState } from \"react\";\n\nimport { useIsClosing } from \"../../hooks/useIsClosing\";\nimport { handleInternalNavigation, isUrlExternal } from \"../../utils\";\n\nimport { Button } from \"../Button/Button\";\nimport { ScreenOverlay } from \"../ScreenOverlay/ScreenOverlay\";\nimport { DropdownMenu } from \"radix-ui\";\nimport { ChevronLeft } from \"../Icon/IconComponents/ChevronLeft\";\nimport { ChevronRight } from \"../Icon/IconComponents/ChevronRight\";\n\nimport \"./ActionMenu.css\";\n\nexport interface ActionMenuAction {\n key: string;\n label?: ReactNode;\n description?: ReactNode;\n to?: string;\n onAction?: (key: string) => void;\n children?: ActionMenuAction[];\n}\n\nexport type ActionMenuSelectionMode = \"single\" | \"multiple\" | \"none\";\n\n/** Keys passed to `onSelectionChange` (Set of item keys, or `\"all\"`). */\nexport type ActionMenuSelection = \"all\" | Set<string>;\n\nexport interface ActionMenuProps {\n /** The actions of the menu\n * - type {@link ActionMenuAction}[]\n */\n actions?: ActionMenuAction[];\n\n /** The text of the cancel button */\n cancelButtonText?: string;\n\n /** The children of the menu */\n children?: ReactNode | ((props: { close: () => void }) => ReactNode);\n\n /** The test id of the menu */\n \"data-testid\"?: string;\n\n /** The keys of the disabled items\n * @default []\n */\n disabledKeys?: string[];\n\n /** Whether the menu is open\n * @default false\n */\n isOpen: boolean;\n\n /** The callback function to close the menu */\n onClose?: () => void;\n\n /** The callback function to change the selection\n * - type {@link ActionMenuSelection}\n */\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n\n /** The selection mode of the menu\n * @default \"single\"\n */\n selectionMode?: ActionMenuSelectionMode;\n\n /** The keys of the selected items */\n selectedKeys?: string[];\n\n /** Whether to show the cancel button */\n showCancel?: boolean;\n\n /** The title of the menu */\n title?: string;\n}\n\ntype ActionStack = {\n title: ReactNode | null;\n actions: ActionMenuAction[];\n key: string | null;\n previousKey: string | null;\n};\n\n/**\n * A controlled ActionMenu to display a menu of actions.\n * Renders a list of actions as a focusable menu, or non-focusable children.\n *\n * API:\n * - {@link ActionMenuProps}\n */\nexport const ActionMenu = ({\n isOpen,\n actions = [],\n children,\n showCancel = true,\n cancelButtonText = \"Cancel\",\n selectionMode = \"single\",\n selectedKeys,\n disabledKeys = [],\n onSelectionChange,\n onClose,\n title,\n \"data-testid\": testId,\n}: ActionMenuProps) => {\n const [contentHeight, setContentHeight] = useState<number>(0);\n const [stackHistory, setStackHistory] = useState<ActionStack[]>([]);\n const [currentActionStack, setCurrentActionStack] = useState<ActionStack>({\n title,\n actions,\n key: null,\n previousKey: null,\n });\n const contentRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const overlayRef = useRef<HTMLDivElement>(null);\n const { isClosing, handleClose } = useIsClosing({ onClose, overlayRef });\n\n const currentActions = currentActionStack.actions || [];\n const hasActions = currentActions && currentActions.length > 0;\n const hasContent = children || hasActions || showCancel;\n const isInSubmenu = stackHistory.length > 0;\n\n function handleSubmenuOpen(key: string) {\n const action = currentActions.find((action) => action.key === key);\n if (!action) {\n console.error(`Action with key ${key} not found`);\n return;\n }\n\n setStackHistory((prevStackHistory) => [\n ...prevStackHistory,\n currentActionStack,\n ]);\n setCurrentActionStack((prevStack) => ({\n title: action.label,\n actions: action.children || [],\n key: action.key,\n previousKey: prevStack.key,\n }));\n }\n\n function handleBack() {\n if (stackHistory.length > 0) {\n const previousStack = stackHistory[stackHistory.length - 1];\n setCurrentActionStack(previousStack);\n setStackHistory(stackHistory.slice(0, -1));\n }\n }\n\n // Re-measure the open menu's content height when stack history changes\n useEffect(() => {\n if (!isOpen) return;\n\n requestAnimationFrame(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight + 12);\n }\n });\n }, [isOpen, stackHistory, hasContent]);\n\n // Reset content height when menu closes or is closing\n useEffect(() => {\n if (!isOpen || isClosing) {\n setContentHeight(0);\n }\n }, [isOpen, isClosing]);\n\n if (!isOpen && !isClosing) return null;\n\n return (\n <ScreenOverlay fadeIn ref={overlayRef}>\n <DropdownMenu.Root\n modal\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) handleClose();\n }}\n >\n <DropdownMenu.Trigger asChild>\n {/* No visible trigger, menu is controlled by isOpen */}\n <div>{\"\"}</div>\n </DropdownMenu.Trigger>\n\n <div\n data-disable-document-scroll={isOpen}\n className=\"proton-ActionMenu__background-wrapper\"\n style={{ opacity: isClosing ? 0 : 1 }}\n >\n <div\n data-testid={testId || \"ActionMenu-wrapper\"}\n className=\"proton-ActionMenu__wrapper\"\n >\n <div\n className=\"proton-ActionMenu__card\"\n data-testid=\"ActionMenu-content\"\n style={{ height: `${contentHeight}px` }}\n >\n <div ref={menuRef} className=\"proton-ActionMenu__menu\">\n <DropdownMenu.Content loop sideOffset={8} ref={contentRef}>\n {hasContent && (\n <>\n {children && (\n <div className=\"proton-ActionMenu__content\">\n {typeof children === \"function\"\n ? children({ close: handleClose })\n : children}\n </div>\n )}\n\n {hasActions && (\n <ActionMenuList\n actions={currentActions}\n selectionMode={selectionMode}\n selectedKeys={selectedKeys}\n onSelectionChange={onSelectionChange}\n disabledKeys={disabledKeys}\n handleSubmenuOpen={handleSubmenuOpen}\n title={currentActionStack.title}\n isInSubmenu={isInSubmenu}\n handleBack={handleBack}\n previousMenuTitle={\n stackHistory[stackHistory.length - 1]?.title\n }\n />\n )}\n\n {showCancel && (\n <>\n <DropdownMenu.Separator />\n <DropdownMenu.Item className=\"proton-ActionMenu__cancel-button\">\n <Button\n data-testid=\"ActionMenuItem-cancel\"\n onPress={handleClose}\n fullWidth\n variant=\"secondary\"\n >\n {cancelButtonText}\n </Button>\n </DropdownMenu.Item>\n </>\n )}\n </>\n )}\n </DropdownMenu.Content>\n </div>\n </div>\n </div>\n </div>\n </DropdownMenu.Root>\n </ScreenOverlay>\n );\n};\n\ninterface ActionMenuListProps {\n actions: ActionMenuAction[];\n selectionMode: ActionMenuSelectionMode;\n selectedKeys?: string[];\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n disabledKeys?: string[];\n handleSubmenuOpen: (key: string) => void;\n title?: ReactNode;\n isInSubmenu?: boolean;\n handleBack?: () => void;\n previousMenuTitle?: ReactNode;\n}\n\nconst ActionMenuList = ({\n actions,\n selectionMode,\n selectedKeys = [],\n onSelectionChange,\n disabledKeys = [],\n handleSubmenuOpen,\n title,\n isInSubmenu = false,\n handleBack,\n previousMenuTitle,\n}: ActionMenuListProps) => {\n const ActionMenuItemMap = () => (\n <>\n {isInSubmenu && handleBack && (\n <div className=\"proton-ActionMenu__back-button-container\">\n <DropdownMenu.Item\n className=\"proton-ActionMenu__back-button\"\n onSelect={(event) => {\n event.preventDefault();\n handleBack();\n }}\n aria-label={`Go back to ${previousMenuTitle || \"previous menu\"}`}\n >\n <ChevronLeft size={16} />\n </DropdownMenu.Item>\n <div\n className=\"proton-ActionMenu__title\"\n role=\"banner\"\n aria-label={isInSubmenu ? `Submenu: ${title}` : `Menu: ${title}`}\n >\n <span>{title}</span>\n </div>\n <DropdownMenu.Separator />\n </div>\n )}\n\n {actions.map((action, i) => {\n const itemProps = actions[i];\n return (\n <ActionMenuItem\n key={action.key}\n item={action}\n isSubmenu={Boolean(itemProps.children?.length)}\n selectionMode={selectionMode}\n onSelectionChange={onSelectionChange}\n selectedKeys={selectedKeys}\n disabledKeys={disabledKeys}\n handleSubmenuOpen={handleSubmenuOpen}\n />\n );\n })}\n </>\n );\n\n return (\n <div\n aria-disabled={selectionMode === \"none\"}\n className=\"proton-ActionMenu__list\"\n role=\"menu\"\n aria-label={\n title ? `${isInSubmenu ? \"Submenu\" : \"Menu\"}: ${title}` : \"Action menu\"\n }\n aria-orientation=\"vertical\"\n >\n {selectionMode === \"single\" ? (\n <DropdownMenu.RadioGroup\n value={selectedKeys?.[0] || \"\"}\n onValueChange={(value) => {\n // Check if this is a submenu item - if so, don't trigger selection change\n const action = actions.find((action) => action.key === value);\n if (action?.children?.length) {\n return;\n }\n\n if (onSelectionChange) {\n onSelectionChange(new Set([value]));\n }\n }}\n >\n <ActionMenuItemMap />\n </DropdownMenu.RadioGroup>\n ) : (\n <DropdownMenu.Group>\n <ActionMenuItemMap />\n </DropdownMenu.Group>\n )}\n </div>\n );\n};\n\ninterface ActionMenuItemProps {\n to?: string;\n item: ActionMenuAction;\n isSubmenu?: boolean;\n selectionMode: ActionMenuSelectionMode;\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n selectedKeys?: string[];\n disabledKeys?: string[];\n handleSubmenuOpen: (key: string) => void;\n}\n\nconst ActionMenuItem = ({\n item,\n isSubmenu,\n selectionMode,\n onSelectionChange,\n selectedKeys = [],\n disabledKeys = [],\n handleSubmenuOpen,\n}: ActionMenuItemProps) => {\n const ref = useRef(null);\n const isExternal = item.to && isUrlExternal(item.to);\n const isDisabled = disabledKeys.includes(item.key);\n const isSelected = selectedKeys.includes(item.key);\n\n const radixItemProps = {\n className: \"proton-ActionMenu__item\",\n \"aria-label\": item.label\n ? `${item.label}${item.description ? `, ${item.description}` : \"\"}`\n : `ActionMenu-Item-${item.key}`,\n role: \"menuitem\",\n disabled: isDisabled,\n ref,\n };\n\n const onSelect = (event: Event) => {\n if (item?.children?.length) {\n event.preventDefault();\n handleSubmenuOpen(item.key);\n return;\n }\n if (item.onAction) {\n item.onAction(item.key);\n }\n };\n\n const content = (\n <>\n <div className=\"proton-ActionMenu__item-content\">\n <div className=\"proton-ActionMenu__item-label\">{item.label}</div>\n {item.description && (\n <div className=\"proton-ActionMenu__description\">\n {item.description}\n </div>\n )}\n </div>\n {isSubmenu && <ChevronRight size={16} />}\n </>\n );\n\n if (item.to) {\n return (\n <DropdownMenu.Item {...radixItemProps} key={item.key} asChild>\n <a\n aria-label={`ActionMenu-Item-${item.key}`}\n aria-disabled={isDisabled}\n aria-checked={isSelected}\n aria-expanded={isSubmenu ? false : undefined}\n href={item.to}\n target={isExternal ? \"_blank\" : undefined}\n rel={isExternal ? \"noopener noreferrer\" : undefined}\n onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {\n if (isExternal || !item.to) {\n return;\n }\n handleInternalNavigation(e, item.to);\n }}\n >\n {content}\n </a>\n </DropdownMenu.Item>\n );\n }\n\n if (selectionMode === \"multiple\") {\n return (\n <DropdownMenu.CheckboxItem\n {...radixItemProps}\n key={item.key}\n checked={isSelected}\n onSelect={onSelect}\n onCheckedChange={(checked: boolean) => {\n if (!onSelectionChange) return;\n\n const currentKeys = new Set(selectedKeys);\n if (checked) {\n currentKeys.add(item.key);\n } else {\n currentKeys.delete(item.key);\n }\n onSelectionChange(currentKeys);\n }}\n >\n {content}\n </DropdownMenu.CheckboxItem>\n );\n }\n\n return (\n <DropdownMenu.RadioItem\n {...radixItemProps}\n value={item.key}\n key={item.key}\n aria-checked={isSelected}\n aria-expanded={isSubmenu ? false : undefined}\n onSelect={onSelect}\n >\n {content}\n </DropdownMenu.RadioItem>\n );\n};\n"],"names":["ActionMenu","isOpen","actions","children","showCancel","cancelButtonText","selectionMode","selectedKeys","disabledKeys","onSelectionChange","onClose","title","testId","contentHeight","setContentHeight","useState","stackHistory","setStackHistory","currentActionStack","setCurrentActionStack","contentRef","useRef","menuRef","overlayRef","isClosing","handleClose","useIsClosing","currentActions","hasActions","hasContent","isInSubmenu","handleSubmenuOpen","key","action","prevStackHistory","prevStack","handleBack","previousStack","useEffect","jsx","ScreenOverlay","jsxs","DropdownMenu","open","Fragment","ActionMenuList","_a","Button","previousMenuTitle","ActionMenuItemMap","event","ChevronLeft","i","itemProps","ActionMenuItem","value","item","isSubmenu","ref","isExternal","isUrlExternal","isDisabled","isSelected","radixItemProps","onSelect","content","ChevronRight","createElement","e","handleInternalNavigation","checked","currentKeys"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActionMenu.es.js","sources":["../../../src/components/ActionMenu/ActionMenu.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactNode, useEffect, useRef, useState } from \"react\";\n\nimport { useIsClosing } from \"../../hooks/useIsClosing\";\nimport { handleInternalNavigation, isUrlExternal } from \"../../utils\";\n\nimport { Button } from \"../Button/Button\";\nimport { ScreenOverlay } from \"../ScreenOverlay/ScreenOverlay\";\nimport { DropdownMenu } from \"radix-ui\";\nimport { ChevronLeft } from \"../Icon/IconComponents/ChevronLeft\";\nimport { ChevronRight } from \"../Icon/IconComponents/ChevronRight\";\n\nimport \"./ActionMenu.css\";\n\nexport interface ActionMenuAction {\n key: string;\n label?: ReactNode;\n description?: ReactNode;\n to?: string;\n onAction?: (key: string) => void;\n children?: ActionMenuAction[];\n}\n\nexport type ActionMenuSelectionMode = \"single\" | \"multiple\" | \"none\";\n\n/** Keys passed to `onSelectionChange` (Set of item keys, or `\"all\"`). */\nexport type ActionMenuSelection = \"all\" | Set<string>;\n\nexport interface ActionMenuProps {\n /** The actions of the menu\n * - type {@link ActionMenuAction}[]\n */\n actions?: ActionMenuAction[];\n\n /** The text of the cancel button */\n cancelButtonText?: string;\n\n /** The children of the menu */\n children?: ReactNode | ((props: { close: () => void }) => ReactNode);\n\n /** The test id of the menu */\n \"data-testid\"?: string;\n\n /** The keys of the disabled items\n * @default []\n */\n disabledKeys?: string[];\n\n /** Whether the menu is open\n * @default false\n */\n isOpen: boolean;\n\n /** The callback function to close the menu */\n onClose?: () => void;\n\n /** The callback function to change the selection\n * - type {@link ActionMenuSelection}\n */\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n\n /** The selection mode of the menu\n * @default \"single\"\n */\n selectionMode?: ActionMenuSelectionMode;\n\n /** The keys of the selected items */\n selectedKeys?: string[];\n\n /** Whether to show the cancel button */\n showCancel?: boolean;\n\n /** The title of the menu */\n title?: string;\n}\n\ntype ActionStack = {\n title: ReactNode | null;\n actions: ActionMenuAction[];\n key: string | null;\n previousKey: string | null;\n};\n\n/**\n * A controlled ActionMenu to display a menu of actions.\n * Renders a list of actions as a focusable menu, or non-focusable children.\n *\n * API:\n * - {@link ActionMenuProps}\n */\nexport const ActionMenu = ({\n isOpen,\n actions = [],\n children,\n showCancel = true,\n cancelButtonText = \"Cancel\",\n selectionMode = \"single\",\n selectedKeys,\n disabledKeys = [],\n onSelectionChange,\n onClose,\n title,\n \"data-testid\": testId,\n}: ActionMenuProps) => {\n const [contentHeight, setContentHeight] = useState<number>(0);\n const [stackHistory, setStackHistory] = useState<ActionStack[]>([]);\n const [currentActionStack, setCurrentActionStack] = useState<ActionStack>({\n title,\n actions,\n key: null,\n previousKey: null,\n });\n const contentRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const overlayRef = useRef<HTMLDivElement>(null);\n const { isClosing, handleClose } = useIsClosing({ onClose, overlayRef });\n\n const currentActions = currentActionStack.actions || [];\n const hasActions = currentActions && currentActions.length > 0;\n const hasContent = children || hasActions || showCancel;\n const isInSubmenu = stackHistory.length > 0;\n\n function handleSubmenuOpen(key: string) {\n const action = currentActions.find((action) => action.key === key);\n if (!action) {\n console.error(`Action with key ${key} not found`);\n return;\n }\n\n setStackHistory((prevStackHistory) => [\n ...prevStackHistory,\n currentActionStack,\n ]);\n setCurrentActionStack((prevStack) => ({\n title: action.label,\n actions: action.children || [],\n key: action.key,\n previousKey: prevStack.key,\n }));\n }\n\n function handleBack() {\n if (stackHistory.length > 0) {\n const previousStack = stackHistory[stackHistory.length - 1];\n setCurrentActionStack(previousStack);\n setStackHistory(stackHistory.slice(0, -1));\n }\n }\n\n // Re-measure the open menu's content height when stack history changes\n useEffect(() => {\n if (!isOpen) return;\n\n requestAnimationFrame(() => {\n if (contentRef.current) {\n setContentHeight(contentRef.current.scrollHeight + 12);\n }\n });\n }, [isOpen, stackHistory, hasContent]);\n\n // Reset content height when menu closes or is closing\n useEffect(() => {\n if (!isOpen || isClosing) {\n setContentHeight(0);\n }\n }, [isOpen, isClosing]);\n\n if (!isOpen && !isClosing) return null;\n\n return (\n <ScreenOverlay fadeIn ref={overlayRef}>\n <DropdownMenu.Root\n modal\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) handleClose();\n }}\n >\n <DropdownMenu.Trigger asChild>\n {/* No visible trigger, menu is controlled by isOpen */}\n <div>{\"\"}</div>\n </DropdownMenu.Trigger>\n\n <div\n data-disable-document-scroll={isOpen}\n className=\"proton-ActionMenu__background-wrapper\"\n style={{ opacity: isClosing ? 0 : 1 }}\n >\n <div\n data-testid={testId || \"ActionMenu-wrapper\"}\n className=\"proton-ActionMenu__wrapper\"\n >\n <div\n className=\"proton-ActionMenu__card\"\n data-testid=\"ActionMenu-content\"\n style={{ height: `${contentHeight}px` }}\n >\n <div ref={menuRef} className=\"proton-ActionMenu__menu\">\n <DropdownMenu.Content loop sideOffset={8} ref={contentRef}>\n {hasContent && (\n <>\n {children && (\n <div className=\"proton-ActionMenu__content\">\n {typeof children === \"function\"\n ? children({ close: handleClose })\n : children}\n </div>\n )}\n\n {hasActions && (\n <ActionMenuList\n actions={currentActions}\n selectionMode={selectionMode}\n selectedKeys={selectedKeys}\n onSelectionChange={onSelectionChange}\n disabledKeys={disabledKeys}\n handleSubmenuOpen={handleSubmenuOpen}\n title={currentActionStack.title}\n isInSubmenu={isInSubmenu}\n handleBack={handleBack}\n previousMenuTitle={\n stackHistory[stackHistory.length - 1]?.title\n }\n />\n )}\n\n {showCancel && (\n <>\n <DropdownMenu.Separator />\n <DropdownMenu.Item className=\"proton-ActionMenu__cancel-button\">\n <Button\n data-testid=\"ActionMenuItem-cancel\"\n onPress={handleClose}\n fullWidth\n variant=\"secondary\"\n >\n {cancelButtonText}\n </Button>\n </DropdownMenu.Item>\n </>\n )}\n </>\n )}\n </DropdownMenu.Content>\n </div>\n </div>\n </div>\n </div>\n </DropdownMenu.Root>\n </ScreenOverlay>\n );\n};\n\ninterface ActionMenuListProps {\n actions: ActionMenuAction[];\n selectionMode: ActionMenuSelectionMode;\n selectedKeys?: string[];\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n disabledKeys?: string[];\n handleSubmenuOpen: (key: string) => void;\n title?: ReactNode;\n isInSubmenu?: boolean;\n handleBack?: () => void;\n previousMenuTitle?: ReactNode;\n}\n\nconst ActionMenuList = ({\n actions,\n selectionMode,\n selectedKeys = [],\n onSelectionChange,\n disabledKeys = [],\n handleSubmenuOpen,\n title,\n isInSubmenu = false,\n handleBack,\n previousMenuTitle,\n}: ActionMenuListProps) => {\n const ActionMenuItemMap = () => (\n <>\n {isInSubmenu && handleBack && (\n <div className=\"proton-ActionMenu__back-button-container\">\n <DropdownMenu.Item\n className=\"proton-ActionMenu__back-button\"\n onSelect={(event) => {\n event.preventDefault();\n handleBack();\n }}\n aria-label={`Go back to ${previousMenuTitle || \"previous menu\"}`}\n >\n <ChevronLeft size={16} />\n </DropdownMenu.Item>\n <div\n className=\"proton-ActionMenu__title\"\n role=\"banner\"\n aria-label={isInSubmenu ? `Submenu: ${title}` : `Menu: ${title}`}\n >\n <span>{title}</span>\n </div>\n <DropdownMenu.Separator />\n </div>\n )}\n\n {actions.map((action, i) => {\n const itemProps = actions[i];\n return (\n <ActionMenuItem\n key={action.key}\n item={action}\n isSubmenu={Boolean(itemProps.children?.length)}\n selectionMode={selectionMode}\n onSelectionChange={onSelectionChange}\n selectedKeys={selectedKeys}\n disabledKeys={disabledKeys}\n handleSubmenuOpen={handleSubmenuOpen}\n />\n );\n })}\n </>\n );\n\n return (\n <div\n aria-disabled={selectionMode === \"none\"}\n className=\"proton-ActionMenu__list\"\n role=\"menu\"\n aria-label={\n title ? `${isInSubmenu ? \"Submenu\" : \"Menu\"}: ${title}` : \"Action menu\"\n }\n aria-orientation=\"vertical\"\n >\n {selectionMode === \"single\" ? (\n <DropdownMenu.RadioGroup\n value={selectedKeys?.[0] || \"\"}\n onValueChange={(value) => {\n // Check if this is a submenu item - if so, don't trigger selection change\n const action = actions.find((action) => action.key === value);\n if (action?.children?.length) {\n return;\n }\n\n if (onSelectionChange) {\n onSelectionChange(new Set([value]));\n }\n }}\n >\n <ActionMenuItemMap />\n </DropdownMenu.RadioGroup>\n ) : (\n <DropdownMenu.Group>\n <ActionMenuItemMap />\n </DropdownMenu.Group>\n )}\n </div>\n );\n};\n\ninterface ActionMenuItemProps {\n to?: string;\n item: ActionMenuAction;\n isSubmenu?: boolean;\n selectionMode: ActionMenuSelectionMode;\n onSelectionChange?: (keys: ActionMenuSelection) => void;\n selectedKeys?: string[];\n disabledKeys?: string[];\n handleSubmenuOpen: (key: string) => void;\n}\n\nconst ActionMenuItem = ({\n item,\n isSubmenu,\n selectionMode,\n onSelectionChange,\n selectedKeys = [],\n disabledKeys = [],\n handleSubmenuOpen,\n}: ActionMenuItemProps) => {\n const ref = useRef(null);\n const isExternal = item.to && isUrlExternal(item.to);\n const isDisabled = disabledKeys.includes(item.key);\n const isSelected = selectedKeys.includes(item.key);\n\n const radixItemProps = {\n className: \"proton-ActionMenu__item\",\n \"aria-label\": item.label\n ? `${item.label}${item.description ? `, ${item.description}` : \"\"}`\n : `ActionMenu-Item-${item.key}`,\n role: \"menuitem\",\n disabled: isDisabled,\n ref,\n };\n\n const onSelect = (event: Event) => {\n if (item?.children?.length) {\n event.preventDefault();\n handleSubmenuOpen(item.key);\n return;\n }\n if (item.onAction) {\n item.onAction(item.key);\n }\n };\n\n const content = (\n <>\n <div className=\"proton-ActionMenu__item-content\">\n <div className=\"proton-ActionMenu__item-label\">{item.label}</div>\n {item.description && (\n <div className=\"proton-ActionMenu__description\">\n {item.description}\n </div>\n )}\n </div>\n {isSubmenu && <ChevronRight size={16} />}\n </>\n );\n\n if (item.to) {\n return (\n <DropdownMenu.Item {...radixItemProps} key={item.key} asChild>\n <a\n aria-label={`ActionMenu-Item-${item.key}`}\n aria-disabled={isDisabled}\n aria-checked={isSelected}\n aria-expanded={isSubmenu ? false : undefined}\n href={item.to}\n target={isExternal ? \"_blank\" : undefined}\n rel={isExternal ? \"noopener noreferrer\" : undefined}\n onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {\n if (isExternal || !item.to) {\n return;\n }\n handleInternalNavigation(e, item.to);\n }}\n >\n {content}\n </a>\n </DropdownMenu.Item>\n );\n }\n\n if (selectionMode === \"multiple\") {\n return (\n <DropdownMenu.CheckboxItem\n {...radixItemProps}\n key={item.key}\n checked={isSelected}\n onSelect={onSelect}\n onCheckedChange={(checked: boolean) => {\n if (!onSelectionChange) return;\n\n const currentKeys = new Set(selectedKeys);\n if (checked) {\n currentKeys.add(item.key);\n } else {\n currentKeys.delete(item.key);\n }\n onSelectionChange(currentKeys);\n }}\n >\n {content}\n </DropdownMenu.CheckboxItem>\n );\n }\n\n return (\n <DropdownMenu.RadioItem\n {...radixItemProps}\n value={item.key}\n key={item.key}\n aria-checked={isSelected}\n aria-expanded={isSubmenu ? false : undefined}\n onSelect={onSelect}\n >\n {content}\n </DropdownMenu.RadioItem>\n );\n};\n"],"names":["ActionMenu","isOpen","actions","children","showCancel","cancelButtonText","selectionMode","selectedKeys","disabledKeys","onSelectionChange","onClose","title","testId","contentHeight","setContentHeight","useState","stackHistory","setStackHistory","currentActionStack","setCurrentActionStack","contentRef","useRef","menuRef","overlayRef","isClosing","handleClose","useIsClosing","currentActions","hasActions","hasContent","isInSubmenu","handleSubmenuOpen","key","action","prevStackHistory","prevStack","handleBack","previousStack","useEffect","jsx","ScreenOverlay","jsxs","DropdownMenu","open","Fragment","ActionMenuList","_a","Button","previousMenuTitle","ActionMenuItemMap","event","ChevronLeft","i","itemProps","ActionMenuItem","value","item","isSubmenu","ref","isExternal","isUrlExternal","isDisabled","isSelected","radixItemProps","onSelect","content","ChevronRight","createElement","e","handleInternalNavigation","checked","currentKeys"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Banner.cjs.js","sources":["../../../src/components/Banner/Banner.tsx"],"sourcesContent":["\"use client\";\n\nimport { ReactNode, createContext, isValidElement, useContext } from \"react\";\nimport { csx } from \"../../utils\";\nimport { Button, type ButtonProps } from \"../Button/Button\";\nimport { DangerCircle, SuccessCircle, WarningTriangle } from \"../Icon\";\n\nimport \"./Banner.css\";\n\nconst BANNER_ICON_COLORS = {\n success: \"var(--proton-color__success-light)\",\n warning: \"var(--proton-color__warning-light)\",\n danger: \"var(--proton-color__danger-light)\",\n} as const;\n\nconst BANNER_ICON_COMPONENTS = {\n success: SuccessCircle,\n warning: WarningTriangle,\n danger: DangerCircle,\n} as const;\n\nexport const BANNER_VARIANTS = {\n default: \"default\",\n success: \"success\",\n warning: \"warning\",\n danger: \"danger\",\n} as const;\n\nexport type BannerVariant = \"default\" | \"success\" | \"warning\" | \"danger\";\n\nconst BannerContext = createContext<BannerVariant | undefined>(undefined);\n\ninterface BannerIconProps {\n /**\n * Optional custom icon or children for the icon area.\n */\n children?: ReactNode;\n /**\n * The icon to display in the banner.\n * Can be a boolean to conditionally show or hide, or a ReactNode to provide a custom icon.\n */\n icon?: boolean | ReactNode;\n /**\n * The data-testid
|
|
1
|
+
{"version":3,"file":"Banner.cjs.js","sources":["../../../src/components/Banner/Banner.tsx"],"sourcesContent":["\"use client\";\n\nimport { ReactNode, createContext, isValidElement, useContext } from \"react\";\nimport { csx } from \"../../utils\";\nimport { Button, type ButtonProps } from \"../Button/Button\";\nimport { DangerCircle, SuccessCircle, WarningTriangle } from \"../Icon\";\n\nimport \"./Banner.css\";\n\nconst BANNER_ICON_COLORS = {\n success: \"var(--proton-color__success-light)\",\n warning: \"var(--proton-color__warning-light)\",\n danger: \"var(--proton-color__danger-light)\",\n} as const;\n\nconst BANNER_ICON_COMPONENTS = {\n success: SuccessCircle,\n warning: WarningTriangle,\n danger: DangerCircle,\n} as const;\n\nexport const BANNER_VARIANTS = {\n default: \"default\",\n success: \"success\",\n warning: \"warning\",\n danger: \"danger\",\n} as const;\n\nexport type BannerVariant = \"default\" | \"success\" | \"warning\" | \"danger\";\n\nconst BannerContext = createContext<BannerVariant | undefined>(undefined);\n\ninterface BannerIconProps {\n /**\n * Optional custom icon or children for the icon area.\n */\n children?: ReactNode;\n /**\n * The icon to display in the banner.\n * Can be a boolean to conditionally show or hide, or a ReactNode to provide a custom icon.\n */\n icon?: boolean | ReactNode;\n /**\n * The data-testid for the banner icon.\n */\n \"data-testid\"?: string;\n}\n\ninterface BannerProps extends BannerIconProps {\n /**\n * Compact padding around the content of the banner.\n * @default true\n */\n compact?: boolean;\n /**\n * The content to display within the banner.\n */\n children: ReactNode;\n /**\n * The data-testid for the banner.\n */\n \"data-testid\"?: string;\n /**\n * Round the corners of the banner.\n * @default true\n */\n rounded?: boolean;\n /**\n * The banner's visual aesthetic.\n * - type {@link BannerVariant}\n */\n variant?: BannerVariant;\n}\n\n/**\n * A banner used to display a success, warning, or error message.\n *\n * API:\n * - {@link BannerProps}\n * - extends {@link BannerIconProps}\n */\nconst Banner = ({\n variant = \"default\",\n rounded = true,\n icon = false,\n compact = true,\n children,\n \"data-testid\": dataTestId,\n}: BannerProps) => {\n return (\n <BannerContext.Provider value={variant}>\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={csx(\n \"proton-Banner\",\n `proton-Banner--${variant}`,\n rounded && \"proton-Banner--rounded\",\n )}\n data-testid={dataTestId}\n >\n <div\n className={csx(\n \"proton-Banner__wrapper\",\n compact && \"proton-Banner__wrapper--compact\",\n )}\n >\n <Banner.Icon icon={icon} />\n <div className=\"proton-Banner__content-wrapper\">\n <div className=\"proton-Banner__container\">{children}</div>\n </div>\n </div>\n </div>\n </BannerContext.Provider>\n );\n};\n\nBanner.displayName = \"ProtonUIBanner\";\n\nconst BannerTitle = ({\n children,\n \"data-testid\": dataTestId,\n}: {\n children: ReactNode;\n \"data-testid\"?: string;\n}) => {\n const variant = useContext(BannerContext);\n if (!variant) throw new Error(\"BannerTitle must be used within a Banner\");\n\n return (\n <h3\n className={csx(\n \"proton-Banner__title\",\n `proton-Banner--${variant}__title`,\n )}\n data-testid={dataTestId}\n >\n {children}\n </h3>\n );\n};\n\nBannerTitle.displayName = \"ProtonUIBanner.Title\";\n\nconst BannerContent = ({\n children,\n \"data-testid\": dataTestId,\n}: {\n children: ReactNode;\n \"data-testid\"?: string;\n}) => {\n const variant = useContext(BannerContext);\n if (!variant) throw new Error(\"BannerContent must be used within a Banner\");\n\n return (\n <p\n className={csx(\n \"proton-Banner__content\",\n `proton-Banner--${variant}__content`,\n )}\n data-testid={dataTestId}\n >\n {children}\n </p>\n );\n};\n\nBannerContent.displayName = \"ProtonUIBanner.Content\";\n\nfunction getIconContent(icon: ReactNode, variant: BannerVariant) {\n if (isValidElement(icon)) return icon;\n\n if (icon && variant !== \"default\") {\n const IconComponent = BANNER_ICON_COMPONENTS[variant];\n\n if (IconComponent) {\n return <IconComponent size={18} color={BANNER_ICON_COLORS[variant]} />;\n }\n }\n\n return null;\n}\n\nconst BannerIcon = ({ icon, \"data-testid\": dataTestId }: BannerIconProps) => {\n const variant = useContext(BannerContext);\n if (!variant) throw new Error(\"BannerIcon must be used within a Banner\");\n\n const iconContent = getIconContent(icon, variant);\n if (!iconContent) return null;\n\n return (\n <div\n aria-hidden=\"true\"\n data-testid={dataTestId}\n className={csx(\"proton-Banner__icon\", `proton-Banner--${variant}__icon`)}\n >\n {iconContent}\n </div>\n );\n};\n\nBannerIcon.displayName = \"ProtonUIBanner.Icon\";\n\nconst BannerAction = ({ children, ...buttonProps }: ButtonProps) => {\n return <Button {...buttonProps}>{children}</Button>;\n};\n\nBannerAction.displayName = \"ProtonUIBanner.Action\";\n\nconst BannerActions = ({ children }: { children: ReactNode }) => {\n return <div className=\"proton-Banner__actions\">{children}</div>;\n};\n\nBannerActions.displayName = \"ProtonUIBanner.Actions\";\n\n/**\n * Renders an h3 styled banner.\n */\nBanner.Title = BannerTitle;\n\n/**\n * Renders a p styled banner.\n */\nBanner.Content = BannerContent;\n\n/**\n * Renders an icon inline with the banner title.\n *\n * API:\n * - {@link BannerIconProps}\n */\nBanner.Icon = BannerIcon;\n\n/**\n * Renders a Proton Button.\n * - @prop buttonProps {@link ButtonProps}\n */\nBanner.Action = BannerAction;\n\n/**\n * Renders Proton Buttons in a responsive actions grid.\n */\nBanner.Actions = BannerActions;\n\nexport { Banner };\n"],"names":["BANNER_ICON_COLORS","BANNER_ICON_COMPONENTS","SuccessCircle","WarningTriangle","DangerCircle","BANNER_VARIANTS","BannerContext","createContext","Banner","variant","rounded","icon","compact","children","dataTestId","jsx","csx","jsxs","BannerTitle","useContext","BannerContent","getIconContent","isValidElement","IconComponent","BannerIcon","iconContent","BannerAction","buttonProps","Button","BannerActions"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Banner.es.js","sources":["../../../src/components/Banner/Banner.tsx"],"sourcesContent":["\"use client\";\n\nimport { ReactNode, createContext, isValidElement, useContext } from \"react\";\nimport { csx } from \"../../utils\";\nimport { Button, type ButtonProps } from \"../Button/Button\";\nimport { DangerCircle, SuccessCircle, WarningTriangle } from \"../Icon\";\n\nimport \"./Banner.css\";\n\nconst BANNER_ICON_COLORS = {\n success: \"var(--proton-color__success-light)\",\n warning: \"var(--proton-color__warning-light)\",\n danger: \"var(--proton-color__danger-light)\",\n} as const;\n\nconst BANNER_ICON_COMPONENTS = {\n success: SuccessCircle,\n warning: WarningTriangle,\n danger: DangerCircle,\n} as const;\n\nexport const BANNER_VARIANTS = {\n default: \"default\",\n success: \"success\",\n warning: \"warning\",\n danger: \"danger\",\n} as const;\n\nexport type BannerVariant = \"default\" | \"success\" | \"warning\" | \"danger\";\n\nconst BannerContext = createContext<BannerVariant | undefined>(undefined);\n\ninterface BannerIconProps {\n /**\n * Optional custom icon or children for the icon area.\n */\n children?: ReactNode;\n /**\n * The icon to display in the banner.\n * Can be a boolean to conditionally show or hide, or a ReactNode to provide a custom icon.\n */\n icon?: boolean | ReactNode;\n /**\n * The data-testid
|
|
1
|
+
{"version":3,"file":"Banner.es.js","sources":["../../../src/components/Banner/Banner.tsx"],"sourcesContent":["\"use client\";\n\nimport { ReactNode, createContext, isValidElement, useContext } from \"react\";\nimport { csx } from \"../../utils\";\nimport { Button, type ButtonProps } from \"../Button/Button\";\nimport { DangerCircle, SuccessCircle, WarningTriangle } from \"../Icon\";\n\nimport \"./Banner.css\";\n\nconst BANNER_ICON_COLORS = {\n success: \"var(--proton-color__success-light)\",\n warning: \"var(--proton-color__warning-light)\",\n danger: \"var(--proton-color__danger-light)\",\n} as const;\n\nconst BANNER_ICON_COMPONENTS = {\n success: SuccessCircle,\n warning: WarningTriangle,\n danger: DangerCircle,\n} as const;\n\nexport const BANNER_VARIANTS = {\n default: \"default\",\n success: \"success\",\n warning: \"warning\",\n danger: \"danger\",\n} as const;\n\nexport type BannerVariant = \"default\" | \"success\" | \"warning\" | \"danger\";\n\nconst BannerContext = createContext<BannerVariant | undefined>(undefined);\n\ninterface BannerIconProps {\n /**\n * Optional custom icon or children for the icon area.\n */\n children?: ReactNode;\n /**\n * The icon to display in the banner.\n * Can be a boolean to conditionally show or hide, or a ReactNode to provide a custom icon.\n */\n icon?: boolean | ReactNode;\n /**\n * The data-testid for the banner icon.\n */\n \"data-testid\"?: string;\n}\n\ninterface BannerProps extends BannerIconProps {\n /**\n * Compact padding around the content of the banner.\n * @default true\n */\n compact?: boolean;\n /**\n * The content to display within the banner.\n */\n children: ReactNode;\n /**\n * The data-testid for the banner.\n */\n \"data-testid\"?: string;\n /**\n * Round the corners of the banner.\n * @default true\n */\n rounded?: boolean;\n /**\n * The banner's visual aesthetic.\n * - type {@link BannerVariant}\n */\n variant?: BannerVariant;\n}\n\n/**\n * A banner used to display a success, warning, or error message.\n *\n * API:\n * - {@link BannerProps}\n * - extends {@link BannerIconProps}\n */\nconst Banner = ({\n variant = \"default\",\n rounded = true,\n icon = false,\n compact = true,\n children,\n \"data-testid\": dataTestId,\n}: BannerProps) => {\n return (\n <BannerContext.Provider value={variant}>\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={csx(\n \"proton-Banner\",\n `proton-Banner--${variant}`,\n rounded && \"proton-Banner--rounded\",\n )}\n data-testid={dataTestId}\n >\n <div\n className={csx(\n \"proton-Banner__wrapper\",\n compact && \"proton-Banner__wrapper--compact\",\n )}\n >\n <Banner.Icon icon={icon} />\n <div className=\"proton-Banner__content-wrapper\">\n <div className=\"proton-Banner__container\">{children}</div>\n </div>\n </div>\n </div>\n </BannerContext.Provider>\n );\n};\n\nBanner.displayName = \"ProtonUIBanner\";\n\nconst BannerTitle = ({\n children,\n \"data-testid\": dataTestId,\n}: {\n children: ReactNode;\n \"data-testid\"?: string;\n}) => {\n const variant = useContext(BannerContext);\n if (!variant) throw new Error(\"BannerTitle must be used within a Banner\");\n\n return (\n <h3\n className={csx(\n \"proton-Banner__title\",\n `proton-Banner--${variant}__title`,\n )}\n data-testid={dataTestId}\n >\n {children}\n </h3>\n );\n};\n\nBannerTitle.displayName = \"ProtonUIBanner.Title\";\n\nconst BannerContent = ({\n children,\n \"data-testid\": dataTestId,\n}: {\n children: ReactNode;\n \"data-testid\"?: string;\n}) => {\n const variant = useContext(BannerContext);\n if (!variant) throw new Error(\"BannerContent must be used within a Banner\");\n\n return (\n <p\n className={csx(\n \"proton-Banner__content\",\n `proton-Banner--${variant}__content`,\n )}\n data-testid={dataTestId}\n >\n {children}\n </p>\n );\n};\n\nBannerContent.displayName = \"ProtonUIBanner.Content\";\n\nfunction getIconContent(icon: ReactNode, variant: BannerVariant) {\n if (isValidElement(icon)) return icon;\n\n if (icon && variant !== \"default\") {\n const IconComponent = BANNER_ICON_COMPONENTS[variant];\n\n if (IconComponent) {\n return <IconComponent size={18} color={BANNER_ICON_COLORS[variant]} />;\n }\n }\n\n return null;\n}\n\nconst BannerIcon = ({ icon, \"data-testid\": dataTestId }: BannerIconProps) => {\n const variant = useContext(BannerContext);\n if (!variant) throw new Error(\"BannerIcon must be used within a Banner\");\n\n const iconContent = getIconContent(icon, variant);\n if (!iconContent) return null;\n\n return (\n <div\n aria-hidden=\"true\"\n data-testid={dataTestId}\n className={csx(\"proton-Banner__icon\", `proton-Banner--${variant}__icon`)}\n >\n {iconContent}\n </div>\n );\n};\n\nBannerIcon.displayName = \"ProtonUIBanner.Icon\";\n\nconst BannerAction = ({ children, ...buttonProps }: ButtonProps) => {\n return <Button {...buttonProps}>{children}</Button>;\n};\n\nBannerAction.displayName = \"ProtonUIBanner.Action\";\n\nconst BannerActions = ({ children }: { children: ReactNode }) => {\n return <div className=\"proton-Banner__actions\">{children}</div>;\n};\n\nBannerActions.displayName = \"ProtonUIBanner.Actions\";\n\n/**\n * Renders an h3 styled banner.\n */\nBanner.Title = BannerTitle;\n\n/**\n * Renders a p styled banner.\n */\nBanner.Content = BannerContent;\n\n/**\n * Renders an icon inline with the banner title.\n *\n * API:\n * - {@link BannerIconProps}\n */\nBanner.Icon = BannerIcon;\n\n/**\n * Renders a Proton Button.\n * - @prop buttonProps {@link ButtonProps}\n */\nBanner.Action = BannerAction;\n\n/**\n * Renders Proton Buttons in a responsive actions grid.\n */\nBanner.Actions = BannerActions;\n\nexport { Banner };\n"],"names":["BANNER_ICON_COLORS","BANNER_ICON_COMPONENTS","SuccessCircle","WarningTriangle","DangerCircle","BANNER_VARIANTS","BannerContext","createContext","Banner","variant","rounded","icon","compact","children","dataTestId","jsx","csx","jsxs","BannerTitle","useContext","BannerContent","getIconContent","isValidElement","IconComponent","BannerIcon","iconContent","BannerAction","buttonProps","Button","BannerActions"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.cjs.js","sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, MouseEvent } from \"react\";\n\nimport { csx } from \"../../utils/string\";\nimport {\n isUrlExternal,\n handleInternalNavigation,\n} from \"../../utils/navigation\";\nimport \"./Button.css\";\n\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"danger\"\n | \"translucent\";\n\nexport const ButtonVariants: Record<ButtonVariant, ButtonVariant> = {\n primary: \"primary\",\n secondary: \"secondary\",\n success: \"success\",\n danger: \"danger\",\n translucent: \"translucent\",\n};\n\nexport type ButtonSize = \"small\" | \"medium\" | \"large\" | \"xlarge\" | \"2xlarge\";\n\nexport const ButtonSizes: Record<ButtonSize, ButtonSize> = {\n small: \"small\",\n medium: \"medium\",\n large: \"large\",\n xlarge: \"xlarge\",\n \"2xlarge\": \"2xlarge\",\n};\n\nexport interface ButtonProps {\n /** The button's visual aesthetic\n * - type {@link ButtonVariant}\n */\n variant?: ButtonVariant;\n\n /** The size of the button\n * - type {@link ButtonSize}\n * @default \"medium\"\n */\n size?: ButtonSize;\n\n /** Should the button be full width?\n * @default false\n */\n fullWidth?: boolean;\n\n /** The prefix to display within the button */\n icon?:
|
|
1
|
+
{"version":3,"file":"Button.cjs.js","sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, type MouseEvent, type ReactNode, type RefObject } from \"react\";\n\nimport { csx } from \"../../utils/string\";\nimport {\n isUrlExternal,\n handleInternalNavigation,\n} from \"../../utils/navigation\";\nimport \"./Button.css\";\n\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"danger\"\n | \"translucent\";\n\nexport const ButtonVariants: Record<ButtonVariant, ButtonVariant> = {\n primary: \"primary\",\n secondary: \"secondary\",\n success: \"success\",\n danger: \"danger\",\n translucent: \"translucent\",\n};\n\nexport type ButtonSize = \"small\" | \"medium\" | \"large\" | \"xlarge\" | \"2xlarge\";\n\nexport const ButtonSizes: Record<ButtonSize, ButtonSize> = {\n small: \"small\",\n medium: \"medium\",\n large: \"large\",\n xlarge: \"xlarge\",\n \"2xlarge\": \"2xlarge\",\n};\n\nexport interface ButtonProps {\n /** The button's visual aesthetic\n * - type {@link ButtonVariant}\n */\n variant?: ButtonVariant;\n\n /** The size of the button\n * - type {@link ButtonSize}\n * @default \"medium\"\n */\n size?: ButtonSize;\n\n /** Should the button be full width?\n * @default false\n */\n fullWidth?: boolean;\n\n /** The prefix to display within the button */\n icon?: ReactNode;\n\n /** Should the button be non-interactive? */\n isDisabled?: boolean;\n\n /** The URL that the button should link to. Turns the element into an `a` tag. If the URL is external, you should pass the entire URL to the `to` prop (e.g. `https://example.com`). */\n to?: string;\n\n /** The target attribute for the link. Defaults to `_blank` if the URL is external. */\n target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\" | string;\n\n /** Called when the button is pressed (on release, not keydown) */\n onPress?: (e: MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => void;\n\n /** The type of button */\n type?: \"button\" | \"submit\" | \"reset\";\n\n /** The test ID for the button */\n \"data-testid\"?: string;\n\n /** The content to display within the button */\n children?: ReactNode;\n}\n\n/**\n * A customizable button component that can render as either a button or anchor element.\n *\n * API:\n * - {@link ButtonProps}\n */\nexport const Button = forwardRef<\n HTMLButtonElement | HTMLAnchorElement,\n ButtonProps\n>(\n (\n {\n variant = \"primary\",\n size = \"medium\",\n fullWidth = false,\n icon,\n to,\n target,\n onPress,\n type = \"button\",\n isDisabled,\n \"data-testid\": testId,\n children,\n }: ButtonProps,\n ref\n ) => {\n const isExternal = to && isUrlExternal(to);\n\n const commonProps = {\n className: csx(\n \"proton-Button\",\n `proton-Button--${variant}`,\n fullWidth && \"proton-Button--fullWidth\",\n isDisabled && \"proton-Button--disabled\",\n size && `proton-Button--${size}`\n ),\n \"data-testid\": testId,\n ...(to && { \"aria-disabled\": isDisabled }),\n ...(isDisabled && { tabIndex: -1 }),\n };\n\n const content = (\n <>\n {icon && (\n <div\n className={csx(\n \"proton-Button__icon-decorator\",\n fullWidth && \"proton-Button__icon-decorator--fullWidth\"\n )}\n >\n {icon}\n </div>\n )}\n {children && <div className=\"proton-Button__text\">{children}</div>}\n </>\n );\n\n if (to) {\n return (\n <a\n {...commonProps}\n href={to}\n target={target || (isExternal ? \"_blank\" : undefined)}\n rel={\n isExternal || target === \"_blank\"\n ? \"noopener noreferrer\"\n : undefined\n }\n ref={ref as RefObject<HTMLAnchorElement>}\n onClick={(e) => {\n if (isDisabled) {\n e.preventDefault();\n return;\n }\n\n if (!isExternal && !target) {\n handleInternalNavigation(e, to);\n }\n\n onPress?.(e);\n }}\n role=\"button\"\n >\n {content}\n </a>\n );\n }\n\n return (\n <button\n {...commonProps}\n type={type}\n disabled={isDisabled}\n ref={ref as RefObject<HTMLButtonElement>}\n onClick={(e) => {\n if (!isDisabled && onPress) {\n onPress(e);\n }\n }}\n >\n {content}\n </button>\n );\n }\n);\n\nButton.displayName = \"ProtonUIButton\";\n"],"names":["ButtonVariants","ButtonSizes","Button","forwardRef","variant","size","fullWidth","icon","to","target","onPress","type","isDisabled","testId","children","ref","isExternal","isUrlExternal","commonProps","csx","content","jsxs","Fragment","jsx","e","handleInternalNavigation"],"mappings":"mRAkBO,MAAMA,EAAuD,CAClE,QAAS,UACT,UAAW,YACX,QAAS,UACT,OAAQ,SACR,YAAa,aACf,EAIaC,EAA8C,CACzD,MAAO,QACP,OAAQ,SACR,MAAO,QACP,OAAQ,SACR,UAAW,SACb,EAkDaC,EAASC,EAAAA,WAIpB,CACE,CACE,QAAAC,EAAU,UACV,KAAAC,EAAO,SACP,UAAAC,EAAY,GACZ,KAAAC,EACA,GAAAC,EACA,OAAAC,EACA,QAAAC,EACA,KAAAC,EAAO,SACP,WAAAC,EACA,cAAeC,EACf,SAAAC,CAAA,EAEFC,IACG,CACH,MAAMC,EAAaR,GAAMS,EAAAA,cAAcT,CAAE,EAEnCU,EAAc,CAClB,UAAWC,EAAAA,IACT,gBACA,kBAAkBf,CAAO,GACzBE,GAAa,2BACbM,GAAc,0BACdP,GAAQ,kBAAkBA,CAAI,EAAA,EAEhC,cAAeQ,EACf,GAAIL,GAAM,CAAE,gBAAiBI,CAAA,EAC7B,GAAIA,GAAc,CAAE,SAAU,EAAA,CAAG,EAG7BQ,EACJC,EAAAA,kBAAAA,KAAAC,EAAAA,kBAAAA,SAAA,CACG,SAAA,CAAAf,GACCgB,EAAAA,kBAAAA,IAAC,MAAA,CACC,UAAWJ,EAAAA,IACT,gCACAb,GAAa,0CAAA,EAGd,SAAAC,CAAA,CAAA,EAGJO,GAAYS,EAAAA,kBAAAA,IAAC,MAAA,CAAI,UAAU,sBAAuB,SAAAT,CAAA,CAAS,CAAA,EAC9D,EAGF,OAAIN,EAEAe,EAAAA,kBAAAA,IAAC,IAAA,CACE,GAAGL,EACJ,KAAMV,EACN,OAAQC,IAAWO,EAAa,SAAW,QAC3C,IACEA,GAAcP,IAAW,SACrB,sBACA,OAEN,IAAAM,EACA,QAAUS,GAAM,CACd,GAAIZ,EAAY,CACdY,EAAE,eAAA,EACF,MACF,CAEI,CAACR,GAAc,CAACP,GAClBgB,EAAAA,yBAAyBD,EAAGhB,CAAE,EAGhCE,GAAA,MAAAA,EAAUc,EACZ,EACA,KAAK,SAEJ,SAAAJ,CAAA,CAAA,EAMLG,EAAAA,kBAAAA,IAAC,SAAA,CACE,GAAGL,EACJ,KAAAP,EACA,SAAUC,EACV,IAAAG,EACA,QAAUS,GAAM,CACV,CAACZ,GAAcF,GACjBA,EAAQc,CAAC,CAEb,EAEC,SAAAJ,CAAA,CAAA,CAGP,CACF,EAEAlB,EAAO,YAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.es.js","sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, MouseEvent } from \"react\";\n\nimport { csx } from \"../../utils/string\";\nimport {\n isUrlExternal,\n handleInternalNavigation,\n} from \"../../utils/navigation\";\nimport \"./Button.css\";\n\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"danger\"\n | \"translucent\";\n\nexport const ButtonVariants: Record<ButtonVariant, ButtonVariant> = {\n primary: \"primary\",\n secondary: \"secondary\",\n success: \"success\",\n danger: \"danger\",\n translucent: \"translucent\",\n};\n\nexport type ButtonSize = \"small\" | \"medium\" | \"large\" | \"xlarge\" | \"2xlarge\";\n\nexport const ButtonSizes: Record<ButtonSize, ButtonSize> = {\n small: \"small\",\n medium: \"medium\",\n large: \"large\",\n xlarge: \"xlarge\",\n \"2xlarge\": \"2xlarge\",\n};\n\nexport interface ButtonProps {\n /** The button's visual aesthetic\n * - type {@link ButtonVariant}\n */\n variant?: ButtonVariant;\n\n /** The size of the button\n * - type {@link ButtonSize}\n * @default \"medium\"\n */\n size?: ButtonSize;\n\n /** Should the button be full width?\n * @default false\n */\n fullWidth?: boolean;\n\n /** The prefix to display within the button */\n icon?:
|
|
1
|
+
{"version":3,"file":"Button.es.js","sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, type MouseEvent, type ReactNode, type RefObject } from \"react\";\n\nimport { csx } from \"../../utils/string\";\nimport {\n isUrlExternal,\n handleInternalNavigation,\n} from \"../../utils/navigation\";\nimport \"./Button.css\";\n\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"danger\"\n | \"translucent\";\n\nexport const ButtonVariants: Record<ButtonVariant, ButtonVariant> = {\n primary: \"primary\",\n secondary: \"secondary\",\n success: \"success\",\n danger: \"danger\",\n translucent: \"translucent\",\n};\n\nexport type ButtonSize = \"small\" | \"medium\" | \"large\" | \"xlarge\" | \"2xlarge\";\n\nexport const ButtonSizes: Record<ButtonSize, ButtonSize> = {\n small: \"small\",\n medium: \"medium\",\n large: \"large\",\n xlarge: \"xlarge\",\n \"2xlarge\": \"2xlarge\",\n};\n\nexport interface ButtonProps {\n /** The button's visual aesthetic\n * - type {@link ButtonVariant}\n */\n variant?: ButtonVariant;\n\n /** The size of the button\n * - type {@link ButtonSize}\n * @default \"medium\"\n */\n size?: ButtonSize;\n\n /** Should the button be full width?\n * @default false\n */\n fullWidth?: boolean;\n\n /** The prefix to display within the button */\n icon?: ReactNode;\n\n /** Should the button be non-interactive? */\n isDisabled?: boolean;\n\n /** The URL that the button should link to. Turns the element into an `a` tag. If the URL is external, you should pass the entire URL to the `to` prop (e.g. `https://example.com`). */\n to?: string;\n\n /** The target attribute for the link. Defaults to `_blank` if the URL is external. */\n target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\" | string;\n\n /** Called when the button is pressed (on release, not keydown) */\n onPress?: (e: MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => void;\n\n /** The type of button */\n type?: \"button\" | \"submit\" | \"reset\";\n\n /** The test ID for the button */\n \"data-testid\"?: string;\n\n /** The content to display within the button */\n children?: ReactNode;\n}\n\n/**\n * A customizable button component that can render as either a button or anchor element.\n *\n * API:\n * - {@link ButtonProps}\n */\nexport const Button = forwardRef<\n HTMLButtonElement | HTMLAnchorElement,\n ButtonProps\n>(\n (\n {\n variant = \"primary\",\n size = \"medium\",\n fullWidth = false,\n icon,\n to,\n target,\n onPress,\n type = \"button\",\n isDisabled,\n \"data-testid\": testId,\n children,\n }: ButtonProps,\n ref\n ) => {\n const isExternal = to && isUrlExternal(to);\n\n const commonProps = {\n className: csx(\n \"proton-Button\",\n `proton-Button--${variant}`,\n fullWidth && \"proton-Button--fullWidth\",\n isDisabled && \"proton-Button--disabled\",\n size && `proton-Button--${size}`\n ),\n \"data-testid\": testId,\n ...(to && { \"aria-disabled\": isDisabled }),\n ...(isDisabled && { tabIndex: -1 }),\n };\n\n const content = (\n <>\n {icon && (\n <div\n className={csx(\n \"proton-Button__icon-decorator\",\n fullWidth && \"proton-Button__icon-decorator--fullWidth\"\n )}\n >\n {icon}\n </div>\n )}\n {children && <div className=\"proton-Button__text\">{children}</div>}\n </>\n );\n\n if (to) {\n return (\n <a\n {...commonProps}\n href={to}\n target={target || (isExternal ? \"_blank\" : undefined)}\n rel={\n isExternal || target === \"_blank\"\n ? \"noopener noreferrer\"\n : undefined\n }\n ref={ref as RefObject<HTMLAnchorElement>}\n onClick={(e) => {\n if (isDisabled) {\n e.preventDefault();\n return;\n }\n\n if (!isExternal && !target) {\n handleInternalNavigation(e, to);\n }\n\n onPress?.(e);\n }}\n role=\"button\"\n >\n {content}\n </a>\n );\n }\n\n return (\n <button\n {...commonProps}\n type={type}\n disabled={isDisabled}\n ref={ref as RefObject<HTMLButtonElement>}\n onClick={(e) => {\n if (!isDisabled && onPress) {\n onPress(e);\n }\n }}\n >\n {content}\n </button>\n );\n }\n);\n\nButton.displayName = \"ProtonUIButton\";\n"],"names":["ButtonVariants","ButtonSizes","Button","forwardRef","variant","size","fullWidth","icon","to","target","onPress","type","isDisabled","testId","children","ref","isExternal","isUrlExternal","commonProps","csx","content","jsxs","Fragment","jsx","e","handleInternalNavigation"],"mappings":";;;;;AAkBO,MAAMA,IAAuD;AAAA,EAClE,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,aAAa;AACf,GAIaC,IAA8C;AAAA,EACzD,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,WAAW;AACb,GAkDaC,IAASC;AAAA,EAIpB,CACE;AAAA,IACE,SAAAC,IAAU;AAAA,IACV,MAAAC,IAAO;AAAA,IACP,WAAAC,IAAY;AAAA,IACZ,MAAAC;AAAA,IACA,IAAAC;AAAA,IACA,QAAAC;AAAA,IACA,SAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,YAAAC;AAAA,IACA,eAAeC;AAAA,IACf,UAAAC;AAAA,EAAA,GAEFC,MACG;AACH,UAAMC,IAAaR,KAAMS,EAAcT,CAAE,GAEnCU,IAAc;AAAA,MAClB,WAAWC;AAAA,QACT;AAAA,QACA,kBAAkBf,CAAO;AAAA,QACzBE,KAAa;AAAA,QACbM,KAAc;AAAA,QACdP,KAAQ,kBAAkBA,CAAI;AAAA,MAAA;AAAA,MAEhC,eAAeQ;AAAA,MACf,GAAIL,KAAM,EAAE,iBAAiBI,EAAA;AAAA,MAC7B,GAAIA,KAAc,EAAE,UAAU,GAAA;AAAA,IAAG,GAG7BQ,IACJC,gBAAAA,EAAAA,KAAAC,EAAAA,UAAA,EACG,UAAA;AAAA,MAAAf,KACCgB,gBAAAA,EAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWJ;AAAA,YACT;AAAA,YACAb,KAAa;AAAA,UAAA;AAAA,UAGd,UAAAC;AAAA,QAAA;AAAA,MAAA;AAAA,MAGJO,KAAYS,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAU,uBAAuB,UAAAT,EAAA,CAAS;AAAA,IAAA,GAC9D;AAGF,WAAIN,IAEAe,gBAAAA,EAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACE,GAAGL;AAAA,QACJ,MAAMV;AAAA,QACN,QAAQC,MAAWO,IAAa,WAAW;AAAA,QAC3C,KACEA,KAAcP,MAAW,WACrB,wBACA;AAAA,QAEN,KAAAM;AAAA,QACA,SAAS,CAACS,MAAM;AACd,cAAIZ,GAAY;AACd,YAAAY,EAAE,eAAA;AACF;AAAA,UACF;AAEA,UAAI,CAACR,KAAc,CAACP,KAClBgB,EAAyBD,GAAGhB,CAAE,GAGhCE,KAAA,QAAAA,EAAUc;AAAA,QACZ;AAAA,QACA,MAAK;AAAA,QAEJ,UAAAJ;AAAA,MAAA;AAAA,IAAA,IAMLG,gBAAAA,EAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACE,GAAGL;AAAA,QACJ,MAAAP;AAAA,QACA,UAAUC;AAAA,QACV,KAAAG;AAAA,QACA,SAAS,CAACS,MAAM;AACd,UAAI,CAACZ,KAAcF,KACjBA,EAAQc,CAAC;AAAA,QAEb;AAAA,QAEC,UAAAJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEAlB,EAAO,cAAc;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("../../node_modules/react/jsx-runtime.cjs.js"),x=require("react"),d=require("radix-ui");;/* empty css */function a({name:i="ButtonGroup",value:t,defaultValue:o,onChange:e,children:u,"data-testid":l}){const r=t!==void 0,[p,c]=x.useState(()=>o||""),G=r?t||"":p;return s.jsxRuntimeExports.jsx(d.RadioGroup.Root,{name:i,value:r?t:void 0,defaultValue:r?void 0:o,onValueChange:n=>{r||c(n),e==null||e(n)},orientation:"horizontal",className:"proton-ButtonGroup","data-value":G
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("../../node_modules/react/jsx-runtime.cjs.js"),x=require("react"),d=require("radix-ui");;/* empty css */function a({name:i="ButtonGroup",value:t,defaultValue:o,onChange:e,children:u,"data-testid":l}){const r=t!==void 0,[p,c]=x.useState(()=>o||""),G=r?t||"":p;return s.jsxRuntimeExports.jsx(d.RadioGroup.Root,{name:i,value:r?t:void 0,defaultValue:r?void 0:o,onValueChange:n=>{r||c(n),e==null||e(n)},orientation:"horizontal",className:"proton-ButtonGroup","data-value":G,"data-testid":l,"aria-label":i,children:u})}a.displayName="ProtonUIButtonGroup";a.Option=function({value:t,children:o,"data-testid":e}){const u=typeof o=="string"?o:t;return s.jsxRuntimeExports.jsx(d.RadioGroup.Item,{value:t,className:"proton-ButtonGroup__option","data-testid":e||void 0,"aria-label":u,children:o})};exports.ButtonGroup=a;
|
|
2
2
|
//# sourceMappingURL=ButtonGroup.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonGroup.cjs.js","sources":["../../../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactNode, useState } from \"react\";\nimport { RadioGroup as RadixRadioGroup } from \"radix-ui\";\n\nimport \"./ButtonGroup.css\";\n\nexport interface ButtonGroupProps {\n /**\n * The name of the ButtonGroup.\n */\n name?: string;\n /**\n * The value of the currently selected option in the ButtonGroup. Providing\n * this prop causes the component to become controlled.\n */\n value?: string;\n /**\n * The initially selected value of the ButtonGroup.\n */\n defaultValue?: string;\n /**\n * Called when the ButtonGroup's selected value changes.\n */\n onChange?: (value: string) => void;\n /**\n * The ButtonGroup.Option elements to be rendered as the selectable values.\n */\n children?: ReactNode;\n /** The test ID for the component. */\n \"data-testid\"?: string;\n}\n\n/**\n * A radio button group component that allows selection of a single option from multiple choices.\n *\n * API:\n * - {@link ButtonGroupProps}\n */\nexport function ButtonGroup({\n name = \"ButtonGroup\",\n value,\n defaultValue,\n onChange,\n children,\n \"data-testid\": testId,\n}: ButtonGroupProps) {\n const isControlled = value !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState(\n () => defaultValue || \"\"\n );\n const dataValue = isControlled ? (value || \"\") : uncontrolledValue;\n\n return (\n <RadixRadioGroup.Root\n name={name}\n value={isControlled ? value : undefined}\n defaultValue={isControlled ? undefined : defaultValue}\n onValueChange={(v) => {\n if (!isControlled) setUncontrolledValue(v);\n onChange?.(v);\n }}\n orientation=\"horizontal\"\n className=\"proton-ButtonGroup\"\n data-value={dataValue
|
|
1
|
+
{"version":3,"file":"ButtonGroup.cjs.js","sources":["../../../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactNode, useState } from \"react\";\nimport { RadioGroup as RadixRadioGroup } from \"radix-ui\";\n\nimport \"./ButtonGroup.css\";\n\nexport interface ButtonGroupProps {\n /**\n * The name of the ButtonGroup.\n */\n name?: string;\n /**\n * The value of the currently selected option in the ButtonGroup. Providing\n * this prop causes the component to become controlled.\n */\n value?: string;\n /**\n * The initially selected value of the ButtonGroup.\n */\n defaultValue?: string;\n /**\n * Called when the ButtonGroup's selected value changes.\n */\n onChange?: (value: string) => void;\n /**\n * The ButtonGroup.Option elements to be rendered as the selectable values.\n */\n children?: ReactNode;\n /** The test ID for the component. */\n \"data-testid\"?: string;\n}\n\n/**\n * A radio button group component that allows selection of a single option from multiple choices.\n *\n * API:\n * - {@link ButtonGroupProps}\n */\nexport function ButtonGroup({\n name = \"ButtonGroup\",\n value,\n defaultValue,\n onChange,\n children,\n \"data-testid\": testId,\n}: ButtonGroupProps) {\n const isControlled = value !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState(\n () => defaultValue || \"\"\n );\n const dataValue = isControlled ? (value || \"\") : uncontrolledValue;\n\n return (\n <RadixRadioGroup.Root\n name={name}\n value={isControlled ? value : undefined}\n defaultValue={isControlled ? undefined : defaultValue}\n onValueChange={(v) => {\n if (!isControlled) setUncontrolledValue(v);\n onChange?.(v);\n }}\n orientation=\"horizontal\"\n className=\"proton-ButtonGroup\"\n data-value={dataValue}\n data-testid={testId}\n aria-label={name}\n >\n {children}\n </RadixRadioGroup.Root>\n );\n}\n\nButtonGroup.displayName = \"ProtonUIButtonGroup\";\n\nexport interface ButtonGroupOptionProps {\n /**\n * The value of this option. When this option is selected, this value will\n * become the ButtonGroup's new `value`.\n */\n value: string;\n /**\n * The text or component to be rendered as this option's content.\n */\n children: ReactNode;\n /** The test ID for this option. */\n \"data-testid\"?: string;\n}\n\n/**\n * A radio button option for the ButtonGroup.\n *\n * API:\n * - {@link ButtonGroupOptionProps}\n */\nButtonGroup.Option = function ButtonGroupOption({\n value,\n children,\n \"data-testid\": testId,\n}: ButtonGroupOptionProps) {\n const accessibleLabel = typeof children === \"string\" ? children : value;\n\n return (\n <RadixRadioGroup.Item\n value={value}\n className=\"proton-ButtonGroup__option\"\n data-testid={testId || undefined}\n aria-label={accessibleLabel}\n >\n {children}\n </RadixRadioGroup.Item>\n );\n};\n"],"names":["ButtonGroup","name","value","defaultValue","onChange","children","testId","isControlled","uncontrolledValue","setUncontrolledValue","useState","dataValue","jsx","RadixRadioGroup","v","accessibleLabel"],"mappings":"4NAuCO,SAASA,EAAY,CAC1B,KAAAC,EAAO,cACP,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,SAAAC,EACA,cAAeC,CACjB,EAAqB,CACnB,MAAMC,EAAeL,IAAU,OACzB,CAACM,EAAmBC,CAAoB,EAAIC,EAAAA,SAChD,IAAMP,GAAgB,EAAA,EAElBQ,EAAYJ,EAAgBL,GAAS,GAAMM,EAEjD,OACEI,EAAAA,kBAAAA,IAACC,EAAAA,WAAgB,KAAhB,CACC,KAAAZ,EACA,MAAOM,EAAeL,EAAQ,OAC9B,aAAcK,EAAe,OAAYJ,EACzC,cAAgBW,GAAM,CACfP,GAAcE,EAAqBK,CAAC,EACzCV,GAAA,MAAAA,EAAWU,EACb,EACA,YAAY,aACZ,UAAU,qBACV,aAAYH,EACZ,cAAaL,EACb,aAAYL,EAEX,SAAAI,CAAA,CAAA,CAGP,CAEAL,EAAY,YAAc,sBAsB1BA,EAAY,OAAS,SAA2B,CAC9C,MAAAE,EACA,SAAAG,EACA,cAAeC,CACjB,EAA2B,CACzB,MAAMS,EAAkB,OAAOV,GAAa,SAAWA,EAAWH,EAElE,OACEU,EAAAA,kBAAAA,IAACC,EAAAA,WAAgB,KAAhB,CACC,MAAAX,EACA,UAAU,6BACV,cAAaI,GAAU,OACvB,aAAYS,EAEX,SAAAV,CAAA,CAAA,CAGP"}
|
|
@@ -3,30 +3,30 @@ import { useState as f } from "react";
|
|
|
3
3
|
import { RadioGroup as e } from "radix-ui";
|
|
4
4
|
/* empty css */
|
|
5
5
|
function p({
|
|
6
|
-
name:
|
|
6
|
+
name: i = "ButtonGroup",
|
|
7
7
|
value: t,
|
|
8
8
|
defaultValue: o,
|
|
9
9
|
onChange: a,
|
|
10
10
|
children: s,
|
|
11
11
|
"data-testid": d
|
|
12
12
|
}) {
|
|
13
|
-
const
|
|
13
|
+
const r = t !== void 0, [l, m] = f(
|
|
14
14
|
() => o || ""
|
|
15
|
-
), c =
|
|
15
|
+
), c = r ? t || "" : l;
|
|
16
16
|
return /* @__PURE__ */ u.jsx(
|
|
17
17
|
e.Root,
|
|
18
18
|
{
|
|
19
|
-
name:
|
|
20
|
-
value:
|
|
21
|
-
defaultValue:
|
|
19
|
+
name: i,
|
|
20
|
+
value: r ? t : void 0,
|
|
21
|
+
defaultValue: r ? void 0 : o,
|
|
22
22
|
onValueChange: (n) => {
|
|
23
|
-
|
|
23
|
+
r || m(n), a == null || a(n);
|
|
24
24
|
},
|
|
25
25
|
orientation: "horizontal",
|
|
26
26
|
className: "proton-ButtonGroup",
|
|
27
|
-
"data-value": c
|
|
28
|
-
"data-testid": d
|
|
29
|
-
"aria-label":
|
|
27
|
+
"data-value": c,
|
|
28
|
+
"data-testid": d,
|
|
29
|
+
"aria-label": i,
|
|
30
30
|
children: s
|
|
31
31
|
}
|
|
32
32
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonGroup.es.js","sources":["../../../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactNode, useState } from \"react\";\nimport { RadioGroup as RadixRadioGroup } from \"radix-ui\";\n\nimport \"./ButtonGroup.css\";\n\nexport interface ButtonGroupProps {\n /**\n * The name of the ButtonGroup.\n */\n name?: string;\n /**\n * The value of the currently selected option in the ButtonGroup. Providing\n * this prop causes the component to become controlled.\n */\n value?: string;\n /**\n * The initially selected value of the ButtonGroup.\n */\n defaultValue?: string;\n /**\n * Called when the ButtonGroup's selected value changes.\n */\n onChange?: (value: string) => void;\n /**\n * The ButtonGroup.Option elements to be rendered as the selectable values.\n */\n children?: ReactNode;\n /** The test ID for the component. */\n \"data-testid\"?: string;\n}\n\n/**\n * A radio button group component that allows selection of a single option from multiple choices.\n *\n * API:\n * - {@link ButtonGroupProps}\n */\nexport function ButtonGroup({\n name = \"ButtonGroup\",\n value,\n defaultValue,\n onChange,\n children,\n \"data-testid\": testId,\n}: ButtonGroupProps) {\n const isControlled = value !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState(\n () => defaultValue || \"\"\n );\n const dataValue = isControlled ? (value || \"\") : uncontrolledValue;\n\n return (\n <RadixRadioGroup.Root\n name={name}\n value={isControlled ? value : undefined}\n defaultValue={isControlled ? undefined : defaultValue}\n onValueChange={(v) => {\n if (!isControlled) setUncontrolledValue(v);\n onChange?.(v);\n }}\n orientation=\"horizontal\"\n className=\"proton-ButtonGroup\"\n data-value={dataValue
|
|
1
|
+
{"version":3,"file":"ButtonGroup.es.js","sources":["../../../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactNode, useState } from \"react\";\nimport { RadioGroup as RadixRadioGroup } from \"radix-ui\";\n\nimport \"./ButtonGroup.css\";\n\nexport interface ButtonGroupProps {\n /**\n * The name of the ButtonGroup.\n */\n name?: string;\n /**\n * The value of the currently selected option in the ButtonGroup. Providing\n * this prop causes the component to become controlled.\n */\n value?: string;\n /**\n * The initially selected value of the ButtonGroup.\n */\n defaultValue?: string;\n /**\n * Called when the ButtonGroup's selected value changes.\n */\n onChange?: (value: string) => void;\n /**\n * The ButtonGroup.Option elements to be rendered as the selectable values.\n */\n children?: ReactNode;\n /** The test ID for the component. */\n \"data-testid\"?: string;\n}\n\n/**\n * A radio button group component that allows selection of a single option from multiple choices.\n *\n * API:\n * - {@link ButtonGroupProps}\n */\nexport function ButtonGroup({\n name = \"ButtonGroup\",\n value,\n defaultValue,\n onChange,\n children,\n \"data-testid\": testId,\n}: ButtonGroupProps) {\n const isControlled = value !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState(\n () => defaultValue || \"\"\n );\n const dataValue = isControlled ? (value || \"\") : uncontrolledValue;\n\n return (\n <RadixRadioGroup.Root\n name={name}\n value={isControlled ? value : undefined}\n defaultValue={isControlled ? undefined : defaultValue}\n onValueChange={(v) => {\n if (!isControlled) setUncontrolledValue(v);\n onChange?.(v);\n }}\n orientation=\"horizontal\"\n className=\"proton-ButtonGroup\"\n data-value={dataValue}\n data-testid={testId}\n aria-label={name}\n >\n {children}\n </RadixRadioGroup.Root>\n );\n}\n\nButtonGroup.displayName = \"ProtonUIButtonGroup\";\n\nexport interface ButtonGroupOptionProps {\n /**\n * The value of this option. When this option is selected, this value will\n * become the ButtonGroup's new `value`.\n */\n value: string;\n /**\n * The text or component to be rendered as this option's content.\n */\n children: ReactNode;\n /** The test ID for this option. */\n \"data-testid\"?: string;\n}\n\n/**\n * A radio button option for the ButtonGroup.\n *\n * API:\n * - {@link ButtonGroupOptionProps}\n */\nButtonGroup.Option = function ButtonGroupOption({\n value,\n children,\n \"data-testid\": testId,\n}: ButtonGroupOptionProps) {\n const accessibleLabel = typeof children === \"string\" ? children : value;\n\n return (\n <RadixRadioGroup.Item\n value={value}\n className=\"proton-ButtonGroup__option\"\n data-testid={testId || undefined}\n aria-label={accessibleLabel}\n >\n {children}\n </RadixRadioGroup.Item>\n );\n};\n"],"names":["ButtonGroup","name","value","defaultValue","onChange","children","testId","isControlled","uncontrolledValue","setUncontrolledValue","useState","dataValue","jsx","RadixRadioGroup","v","accessibleLabel"],"mappings":";;;;AAuCO,SAASA,EAAY;AAAA,EAC1B,MAAAC,IAAO;AAAA,EACP,OAAAC;AAAA,EACA,cAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,eAAeC;AACjB,GAAqB;AACnB,QAAMC,IAAeL,MAAU,QACzB,CAACM,GAAmBC,CAAoB,IAAIC;AAAA,IAChD,MAAMP,KAAgB;AAAA,EAAA,GAElBQ,IAAYJ,IAAgBL,KAAS,KAAMM;AAEjD,SACEI,gBAAAA,EAAAA;AAAAA,IAACC,EAAgB;AAAA,IAAhB;AAAA,MACC,MAAAZ;AAAA,MACA,OAAOM,IAAeL,IAAQ;AAAA,MAC9B,cAAcK,IAAe,SAAYJ;AAAA,MACzC,eAAe,CAACW,MAAM;AACpB,QAAKP,KAAcE,EAAqBK,CAAC,GACzCV,KAAA,QAAAA,EAAWU;AAAA,MACb;AAAA,MACA,aAAY;AAAA,MACZ,WAAU;AAAA,MACV,cAAYH;AAAA,MACZ,eAAaL;AAAA,MACb,cAAYL;AAAA,MAEX,UAAAI;AAAA,IAAA;AAAA,EAAA;AAGP;AAEAL,EAAY,cAAc;AAsB1BA,EAAY,SAAS,SAA2B;AAAA,EAC9C,OAAAE;AAAA,EACA,UAAAG;AAAA,EACA,eAAeC;AACjB,GAA2B;AACzB,QAAMS,IAAkB,OAAOV,KAAa,WAAWA,IAAWH;AAElE,SACEU,gBAAAA,EAAAA;AAAAA,IAACC,EAAgB;AAAA,IAAhB;AAAA,MACC,OAAAX;AAAA,MACA,WAAU;AAAA,MACV,eAAaI,KAAU;AAAA,MACvB,cAAYS;AAAA,MAEX,UAAAV;AAAA,IAAA;AAAA,EAAA;AAGP;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckboxInput.cjs.js","sources":["../../../../src/components/Checkbox/CheckboxInput/CheckboxInput.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useEffect, useId, useRef, type ForwardedRef, type ReactNode, type ChangeEvent } from \"react\";\n\nimport { useMergedRef } from \"../../../hooks/useMergedRef\";\nimport { csx } from \"../../../utils\";\nimport { CheckboxIndicator } from \"../CheckboxIndicator\";\nimport \"./CheckboxInput.css\";\n\nexport interface CheckboxInputProps {\n /**\n * Whether the checkbox is checked (controlled mode).\n */\n checked?: boolean;\n\n /**\n * Whether the checkbox is checked by default (uncontrolled mode).\n */\n defaultChecked?: boolean;\n\n /** The error attribute of the checkbox input. */\n error?: ReactNode | string;\n\n /** The description attribute of the checkbox input. */\n description?: ReactNode | string;\n\n /** The test id attribute of the checkbox input. */\n \"data-testid\"?: string;\n\n /**\n * Callback fired when the checkbox state changes.\n */\n onChange?: (checked: boolean) => void;\n\n /**\n * Whether the checkbox is in an indeterminate state. Used for checkboxes that are neither checked nor unchecked.\n * @default false\n * @external https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/indeterminate\n * @reference @external https://medium.com/indigoag-eng/indeterminate-checkboxes-are-weird-704b246c0f19\n */\n indeterminate?: boolean;\n\n /** The id attribute of the checkbox input. */\n id?: string;\n\n /** Whether the checkbox is disabled.\n * @default false\n */\n isDisabled?: boolean;\n\n /** Whether the checkbox is required.\n * @default false\n */\n isRequired?: boolean;\n\n /** The name attribute of the checkbox input. */\n name: string;\n\n /** The label attribute of the checkbox input. */\n label?: string | ReactNode;\n\n /**\n * The value attribute of the checkbox input (for form submission).\n * @external https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#value\n */\n value?: string;\n\n /**\n * Whether the checkbox should be rendered as a round control (with a dot indicator when checked).\n * @default false\n */\n round?: boolean;\n}\n\n/**\n * A checkbox input component with support for labels, descriptions, error states, and controlled/uncontrolled modes.\n *\n * API:\n * - {@link CheckboxInputProps}\n */\nexport const CheckboxInput = forwardRef<HTMLInputElement, CheckboxInputProps>(\n (\n {\n checked: controlledChecked,\n defaultChecked,\n onChange,\n name,\n value,\n isDisabled = false,\n isRequired = false,\n id,\n \"data-testid\": testId,\n label,\n description,\n error,\n indeterminate = false,\n round = false,\n },\n forwardedRef: ForwardedRef<HTMLInputElement>,\n ) => {\n const checkboxRef = useRef<HTMLInputElement>(null);\n const setRefs = useMergedRef(checkboxRef, forwardedRef);\n const isControlled = controlledChecked !== undefined;\n const idBase = useId();\n\n // indeterminate state can only be set via JS\n useEffect(() => {\n if (checkboxRef.current) {\n checkboxRef.current.indeterminate = indeterminate;\n }\n }, [indeterminate]);\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n onChange?.(e.target.checked);\n };\n\n const checkboxId = id || `${idBase}-checkbox`;\n const errorId = typeof error === \"string\" ? `${idBase}-error` : undefined;\n const descriptionId =\n typeof description === \"string\" ? `${idBase}-description` : undefined;\n const ariaDescribedBy =\n [errorId, descriptionId].filter(Boolean).join(\" \") || undefined;\n\n return (\n <div>\n <div className={csx(isDisabled && \"proton-CheckboxInput--disabled\")}>\n <div\n className={csx(\n \"proton-CheckboxInput__container\",\n round && \"proton-CheckboxInput__container--round\",\n )}\n >\n {typeof label === \"string\" ? (\n <label\n htmlFor={checkboxId}\n className=\"proton-CheckboxInput__label\"\n >\n {label}\n </label>\n ) : (\n label\n )}\n\n <span className=\"proton-CheckboxInput__box\">\n <input\n ref={setRefs}\n id={checkboxId}\n name={name}\n type=\"checkbox\"\n {...(isControlled\n ? { checked: controlledChecked }\n : { defaultChecked })}\n value={value}\n disabled={isDisabled}\n required={isRequired}\n onChange={handleChange}\n className={csx(\n \"proton-CheckboxInput__input\",\n error && \"proton-CheckboxInput__input--error\",\n round && \"proton-CheckboxInput__input--round\",\n )}\n aria-label={!label ? name : undefined}\n aria-invalid={Boolean(error)}\n aria-errormessage={errorId}\n aria-describedby={ariaDescribedBy}\n data-testid={testId}\n />\n <CheckboxIndicator round={round} />\n </span>\n\n {typeof description === \"string\" ? (\n <div id={descriptionId} aria-live=\"polite\">\n {description}\n {isRequired && <span aria-hidden=\"true\"> *</span>}\n </div>\n ) : (\n description\n )}\n </div>\n </div>\n\n {typeof error === \"string\" ? (\n <div\n role=\"alert\"\n className={csx(\"proton-CheckboxInput__error\")}\n id={errorId}\n >\n {error}\n </div>\n ) : (\n error\n )}\n </div>\n );\n },\n);\n\nCheckboxInput.displayName = \"ProtonUICheckboxInput\";\n"],"names":["CheckboxInput","forwardRef","controlledChecked","defaultChecked","onChange","name","value","isDisabled","isRequired","id","testId","label","description","error","indeterminate","round","forwardedRef","checkboxRef","useRef","setRefs","useMergedRef","isControlled","idBase","useId","useEffect","handleChange","e","checkboxId","errorId","descriptionId","ariaDescribedBy","jsx","csx","jsxs","CheckboxIndicator"],"mappings":"oVAgFaA,EAAgBC,EAAAA,WAC3B,CACE,CACE,QAASC,EACT,eAAAC,EACA,SAAAC,EACA,KAAAC,EACA,MAAAC,EACA,WAAAC,EAAa,GACb,WAAAC,EAAa,GACb,GAAAC,EACA,cAAeC,EACf,MAAAC,EACA,YAAAC,EACA,MAAAC,EACA,cAAAC,EAAgB,GAChB,MAAAC,EAAQ,EAAA,EAEVC,IACG,CACH,MAAMC,EAAcC,EAAAA,OAAyB,IAAI,EAC3CC,EAAUC,EAAAA,aAAaH,EAAaD,CAAY,EAChDK,EAAenB,IAAsB,OACrCoB,EAASC,EAAAA,MAAA,EAGfC,EAAAA,UAAU,IAAM,CACVP,EAAY,UACdA,EAAY,QAAQ,cAAgBH,EAExC,EAAG,CAACA,CAAa,CAAC,EAElB,MAAMW,EAAgBC,GAAqC,CACzDtB,GAAA,MAAAA,EAAWsB,EAAE,OAAO,QACtB,EAEMC,EAAalB,GAAM,GAAGa,CAAM,YAC5BM,EAAU,OAAOf,GAAU,SAAW,GAAGS,CAAM,SAAW,OAC1DO,EACJ,OAAOjB,GAAgB,SAAW,GAAGU,CAAM,eAAiB,OACxDQ,EACJ,CAACF,EAASC,CAAa,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAK,OAExD,gCACG,MAAA,CACC,SAAA,CAAAE,wBAAC,MAAA,CAAI,UAAWC,EAAAA,IAAIzB,GAAc,gCAAgC,EAChE,SAAA0B,EAAAA,kBAAAA,KAAC,MAAA,CACC,UAAWD,EAAAA,IACT,kCACAjB,GAAS,wCAAA,EAGV,SAAA,CAAA,OAAOJ,GAAU,SAChBoB,EAAAA,kBAAAA,IAAC,QAAA,CACC,QAASJ,EACT,UAAU,8BAET,SAAAhB,CAAA,CAAA,EAGHA,EAGFsB,EAAAA,kBAAAA,KAAC,OAAA,CAAK,UAAU,4BACd,SAAA,CAAAF,EAAAA,kBAAAA,IAAC,QAAA,CACC,IAAKZ,EACL,GAAIQ,EACJ,KAAAtB,EACA,KAAK,WACJ,GAAIgB,EACD,CAAE,QAASnB,CAAA,EACX,CAAE,eAAAC,CAAA,EACN,MAAAG,EACA,SAAUC,EACV,SAAUC,EACV,SAAUiB,EACV,UAAWO,EAAAA,IACT,8BACAnB,GAAS,qCACTE,GAAS,oCAAA,EAEX,aAAaJ,EAAe,OAAPN,EACrB,eAAc,EAAQQ,EACtB,oBAAmBe,EACnB,mBAAkBE,EAClB,cAAapB,CAAA,CAAA,EAEfqB,wBAACG,EAAAA,mBAAkB,MAAAnB,CAAA,CAAc,CAAA,EACnC,EAEC,OAAOH,GAAgB,SACtBqB,EAAAA,kBAAAA,KAAC,OAAI,GAAIJ,EAAe,YAAU,SAC/B,SAAA,CAAAjB,EACAJ,GAAcuB,EAAAA,kBAAAA,IAAC,OAAA,CAAK,cAAY,OAAO,SAAA,IAAA,CAAO,CAAA,CAAA,CACjD,EAEAnB,CAAA,CAAA,CAAA,EAGN,EAEC,OAAOC,GAAU,SAChBkB,EAAAA,kBAAAA,IAAC,MAAA,CACC,KAAK,QACL,UAAWC,EAAAA,IAAI,6BAA6B,EAC5C,GAAIJ,EAEH,SAAAf,CAAA,CAAA,EAGHA,CAAA,EAEJ,CAEJ,CACF,EAEAb,EAAc,YAAc"}
|
|
1
|
+
{"version":3,"file":"CheckboxInput.cjs.js","sources":["../../../../src/components/Checkbox/CheckboxInput/CheckboxInput.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useEffect, useId, useRef, type ForwardedRef, type ReactNode, type ChangeEvent } from \"react\";\n\nimport { useMergedRef } from \"../../../hooks/useMergedRef\";\nimport { csx } from \"../../../utils\";\nimport { CheckboxIndicator } from \"../CheckboxIndicator\";\nimport \"./CheckboxInput.css\";\n\nexport interface CheckboxInputProps {\n /**\n * Whether the checkbox is checked (controlled mode).\n */\n checked?: boolean;\n\n /**\n * Whether the checkbox is checked by default (uncontrolled mode).\n */\n defaultChecked?: boolean;\n\n /** The error attribute of the checkbox input. */\n error?: ReactNode | string;\n\n /** The description attribute of the checkbox input. */\n description?: ReactNode | string;\n\n /** The test id attribute of the checkbox `input` element. */\n \"data-testid\"?: string;\n\n /**\n * Callback fired when the checkbox state changes.\n */\n onChange?: (checked: boolean) => void;\n\n /**\n * Whether the checkbox is in an indeterminate state. Used for checkboxes that are neither checked nor unchecked.\n * @default false\n * @external https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/indeterminate\n * @reference @external https://medium.com/indigoag-eng/indeterminate-checkboxes-are-weird-704b246c0f19\n */\n indeterminate?: boolean;\n\n /** The id attribute of the checkbox input. */\n id?: string;\n\n /** Whether the checkbox is disabled.\n * @default false\n */\n isDisabled?: boolean;\n\n /** Whether the checkbox is required.\n * @default false\n */\n isRequired?: boolean;\n\n /** The name attribute of the checkbox input. */\n name: string;\n\n /** The label attribute of the checkbox input. */\n label?: string | ReactNode;\n\n /**\n * The value attribute of the checkbox input (for form submission).\n * @external https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#value\n */\n value?: string;\n\n /**\n * Whether the checkbox should be rendered as a round control (with a dot indicator when checked).\n * @default false\n */\n round?: boolean;\n}\n\n/**\n * A checkbox input component with support for labels, descriptions, error states, and controlled/uncontrolled modes.\n *\n * API:\n * - {@link CheckboxInputProps}\n */\nexport const CheckboxInput = forwardRef<HTMLInputElement, CheckboxInputProps>(\n (\n {\n checked: controlledChecked,\n defaultChecked,\n onChange,\n name,\n value,\n isDisabled = false,\n isRequired = false,\n id,\n \"data-testid\": testId,\n label,\n description,\n error,\n indeterminate = false,\n round = false,\n },\n forwardedRef: ForwardedRef<HTMLInputElement>,\n ) => {\n const checkboxRef = useRef<HTMLInputElement>(null);\n const setRefs = useMergedRef(checkboxRef, forwardedRef);\n const isControlled = controlledChecked !== undefined;\n const idBase = useId();\n\n // indeterminate state can only be set via JS\n useEffect(() => {\n if (checkboxRef.current) {\n checkboxRef.current.indeterminate = indeterminate;\n }\n }, [indeterminate]);\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n onChange?.(e.target.checked);\n };\n\n const checkboxId = id || `${idBase}-checkbox`;\n const errorId = typeof error === \"string\" ? `${idBase}-error` : undefined;\n const descriptionId =\n typeof description === \"string\" ? `${idBase}-description` : undefined;\n const ariaDescribedBy =\n [errorId, descriptionId].filter(Boolean).join(\" \") || undefined;\n\n return (\n <div>\n <div className={csx(isDisabled && \"proton-CheckboxInput--disabled\")}>\n <div\n className={csx(\n \"proton-CheckboxInput__container\",\n round && \"proton-CheckboxInput__container--round\",\n )}\n >\n {typeof label === \"string\" ? (\n <label\n htmlFor={checkboxId}\n className=\"proton-CheckboxInput__label\"\n >\n {label}\n </label>\n ) : (\n label\n )}\n\n <span className=\"proton-CheckboxInput__box\">\n <input\n ref={setRefs}\n id={checkboxId}\n name={name}\n type=\"checkbox\"\n {...(isControlled\n ? { checked: controlledChecked }\n : { defaultChecked })}\n value={value}\n disabled={isDisabled}\n required={isRequired}\n onChange={handleChange}\n className={csx(\n \"proton-CheckboxInput__input\",\n error && \"proton-CheckboxInput__input--error\",\n round && \"proton-CheckboxInput__input--round\",\n )}\n aria-label={!label ? name : undefined}\n aria-invalid={Boolean(error)}\n aria-errormessage={errorId}\n aria-describedby={ariaDescribedBy}\n data-testid={testId}\n />\n <CheckboxIndicator round={round} />\n </span>\n\n {typeof description === \"string\" ? (\n <div id={descriptionId} aria-live=\"polite\">\n {description}\n {isRequired && <span aria-hidden=\"true\"> *</span>}\n </div>\n ) : (\n description\n )}\n </div>\n </div>\n\n {typeof error === \"string\" ? (\n <div\n role=\"alert\"\n className={csx(\"proton-CheckboxInput__error\")}\n id={errorId}\n >\n {error}\n </div>\n ) : (\n error\n )}\n </div>\n );\n },\n);\n\nCheckboxInput.displayName = \"ProtonUICheckboxInput\";\n"],"names":["CheckboxInput","forwardRef","controlledChecked","defaultChecked","onChange","name","value","isDisabled","isRequired","id","testId","label","description","error","indeterminate","round","forwardedRef","checkboxRef","useRef","setRefs","useMergedRef","isControlled","idBase","useId","useEffect","handleChange","e","checkboxId","errorId","descriptionId","ariaDescribedBy","jsx","csx","jsxs","CheckboxIndicator"],"mappings":"oVAgFaA,EAAgBC,EAAAA,WAC3B,CACE,CACE,QAASC,EACT,eAAAC,EACA,SAAAC,EACA,KAAAC,EACA,MAAAC,EACA,WAAAC,EAAa,GACb,WAAAC,EAAa,GACb,GAAAC,EACA,cAAeC,EACf,MAAAC,EACA,YAAAC,EACA,MAAAC,EACA,cAAAC,EAAgB,GAChB,MAAAC,EAAQ,EAAA,EAEVC,IACG,CACH,MAAMC,EAAcC,EAAAA,OAAyB,IAAI,EAC3CC,EAAUC,EAAAA,aAAaH,EAAaD,CAAY,EAChDK,EAAenB,IAAsB,OACrCoB,EAASC,EAAAA,MAAA,EAGfC,EAAAA,UAAU,IAAM,CACVP,EAAY,UACdA,EAAY,QAAQ,cAAgBH,EAExC,EAAG,CAACA,CAAa,CAAC,EAElB,MAAMW,EAAgBC,GAAqC,CACzDtB,GAAA,MAAAA,EAAWsB,EAAE,OAAO,QACtB,EAEMC,EAAalB,GAAM,GAAGa,CAAM,YAC5BM,EAAU,OAAOf,GAAU,SAAW,GAAGS,CAAM,SAAW,OAC1DO,EACJ,OAAOjB,GAAgB,SAAW,GAAGU,CAAM,eAAiB,OACxDQ,EACJ,CAACF,EAASC,CAAa,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAK,OAExD,gCACG,MAAA,CACC,SAAA,CAAAE,wBAAC,MAAA,CAAI,UAAWC,EAAAA,IAAIzB,GAAc,gCAAgC,EAChE,SAAA0B,EAAAA,kBAAAA,KAAC,MAAA,CACC,UAAWD,EAAAA,IACT,kCACAjB,GAAS,wCAAA,EAGV,SAAA,CAAA,OAAOJ,GAAU,SAChBoB,EAAAA,kBAAAA,IAAC,QAAA,CACC,QAASJ,EACT,UAAU,8BAET,SAAAhB,CAAA,CAAA,EAGHA,EAGFsB,EAAAA,kBAAAA,KAAC,OAAA,CAAK,UAAU,4BACd,SAAA,CAAAF,EAAAA,kBAAAA,IAAC,QAAA,CACC,IAAKZ,EACL,GAAIQ,EACJ,KAAAtB,EACA,KAAK,WACJ,GAAIgB,EACD,CAAE,QAASnB,CAAA,EACX,CAAE,eAAAC,CAAA,EACN,MAAAG,EACA,SAAUC,EACV,SAAUC,EACV,SAAUiB,EACV,UAAWO,EAAAA,IACT,8BACAnB,GAAS,qCACTE,GAAS,oCAAA,EAEX,aAAaJ,EAAe,OAAPN,EACrB,eAAc,EAAQQ,EACtB,oBAAmBe,EACnB,mBAAkBE,EAClB,cAAapB,CAAA,CAAA,EAEfqB,wBAACG,EAAAA,mBAAkB,MAAAnB,CAAA,CAAc,CAAA,EACnC,EAEC,OAAOH,GAAgB,SACtBqB,EAAAA,kBAAAA,KAAC,OAAI,GAAIJ,EAAe,YAAU,SAC/B,SAAA,CAAAjB,EACAJ,GAAcuB,EAAAA,kBAAAA,IAAC,OAAA,CAAK,cAAY,OAAO,SAAA,IAAA,CAAO,CAAA,CAAA,CACjD,EAEAnB,CAAA,CAAA,CAAA,EAGN,EAEC,OAAOC,GAAU,SAChBkB,EAAAA,kBAAAA,IAAC,MAAA,CACC,KAAK,QACL,UAAWC,EAAAA,IAAI,6BAA6B,EAC5C,GAAIJ,EAEH,SAAAf,CAAA,CAAA,EAGHA,CAAA,EAEJ,CAEJ,CACF,EAEAb,EAAc,YAAc"}
|