@protonradio/proton-ui 0.11.12 → 0.11.13-beta.1
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 +148 -148
- package/dist/components/ActionMenu/ActionMenu.cjs.js +1 -1
- package/dist/components/ActionMenu/ActionMenu.cjs.js.map +1 -1
- package/dist/components/ActionMenu/ActionMenu.es.js.map +1 -1
- package/dist/components/Badge/Badge.cjs.js.map +1 -1
- package/dist/components/Badge/Badge.es.js.map +1 -1
- package/dist/components/Banner/Banner.cjs.js +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 +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.map +1 -1
- package/dist/components/ButtonWithSelect/ButtonWithSelect.cjs.js.map +1 -1
- package/dist/components/ButtonWithSelect/ButtonWithSelect.es.js +13 -13
- package/dist/components/ButtonWithSelect/ButtonWithSelect.es.js.map +1 -1
- package/dist/components/DataTable/DataTable.cjs.js +1 -1
- package/dist/components/DataTable/DataTable.cjs.js.map +1 -1
- package/dist/components/DataTable/DataTable.es.js.map +1 -1
- package/dist/components/Dialog/Dialog.cjs.js +1 -1
- package/dist/components/Dialog/Dialog.cjs.js.map +1 -1
- package/dist/components/Dialog/Dialog.es.js.map +1 -1
- package/dist/components/Elevation/Elevation.cjs.js.map +1 -1
- package/dist/components/Elevation/Elevation.es.js.map +1 -1
- package/dist/components/Icon/Icon.cjs.js.map +1 -1
- package/dist/components/Icon/Icon.es.js.map +1 -1
- package/dist/components/ImageBackground/ImageBackground.cjs.js.map +1 -1
- package/dist/components/ImageBackground/ImageBackground.es.js.map +1 -1
- package/dist/components/Input/BaseInput/Input.cjs.js +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/CopyInput/CopyInput.cjs.js.map +1 -1
- package/dist/components/Input/CopyInput/CopyInput.es.js.map +1 -1
- package/dist/components/Input/SearchInput/SearchInput.cjs.js +1 -1
- package/dist/components/Input/SearchInput/SearchInput.cjs.js.map +1 -1
- package/dist/components/Input/SearchInput/SearchInput.es.js +1 -1
- package/dist/components/Input/SearchInput/SearchInput.es.js.map +1 -1
- package/dist/components/Menu/MenuTrigger.cjs.js +1 -1
- package/dist/components/Menu/MenuTrigger.cjs.js.map +1 -1
- package/dist/components/Menu/MenuTrigger.es.js.map +1 -1
- package/dist/components/Menu/PopoverMenu.cjs.js.map +1 -1
- package/dist/components/Menu/PopoverMenu.es.js.map +1 -1
- package/dist/components/Modal/Modal.cjs.js +1 -1
- package/dist/components/Modal/Modal.cjs.js.map +1 -1
- package/dist/components/Modal/Modal.es.js.map +1 -1
- package/dist/components/Popover/Popover.cjs.js.map +1 -1
- 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/Switch/Switch.cjs.js +1 -1
- package/dist/components/Switch/Switch.cjs.js.map +1 -1
- package/dist/components/Switch/Switch.es.js.map +1 -1
- package/dist/components/Table/Collection/CompoundComponents.cjs.js.map +1 -1
- package/dist/components/Table/Collection/CompoundComponents.es.js.map +1 -1
- package/dist/components/Table/Collection/collectionParser.cjs.js +1 -1
- package/dist/components/Table/Collection/collectionParser.cjs.js.map +1 -1
- package/dist/components/Table/Collection/collectionParser.es.js.map +1 -1
- package/dist/components/Table/Collection/useTableCollection.cjs.js +1 -1
- package/dist/components/Table/Collection/useTableCollection.cjs.js.map +1 -1
- package/dist/components/Table/Collection/useTableCollection.es.js.map +1 -1
- package/dist/components/Table/Table.cjs.js.map +1 -1
- package/dist/components/Table/Table.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/Text/TextEmphasis/TextEmphasis.cjs.js +1 -1
- package/dist/components/Text/TextEmphasis/TextEmphasis.cjs.js.map +1 -1
- package/dist/components/Text/TextEmphasis/TextEmphasis.es.js +15 -15
- package/dist/components/Text/TextEmphasis/TextEmphasis.es.js.map +1 -1
- package/dist/components/ThemeProvider.cjs.js +1 -1
- package/dist/components/ThemeProvider.cjs.js.map +1 -1
- package/dist/components/ThemeProvider.es.js.map +1 -1
- package/dist/components/Tombstone/Tombstone.cjs.js.map +1 -1
- package/dist/components/Tombstone/Tombstone.es.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.cjs.js +1 -1
- package/dist/components/Tooltip/Tooltip.cjs.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.es.js +71 -56
- package/dist/components/Tooltip/Tooltip.es.js.map +1 -1
- package/dist/components/Waveform/Waveform.cjs.js +1 -1
- package/dist/components/Waveform/Waveform.cjs.js.map +1 -1
- package/dist/components/Waveform/Waveform.es.js.map +1 -1
- package/dist/components/Waveform/WaveformBar.cjs.js.map +1 -1
- package/dist/components/Waveform/WaveformBar.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/placement.cjs.js.map +1 -1
- package/dist/constants/placement.es.js.map +1 -1
- package/dist/design/colors.cjs.js.map +1 -1
- package/dist/design/colors.es.js.map +1 -1
- package/dist/design/darkTheme/colors.cjs.js.map +1 -1
- package/dist/design/darkTheme/colors.es.js.map +1 -1
- package/dist/design/darkTheme/stylesheet.cjs.js.map +1 -1
- package/dist/design/darkTheme/stylesheet.es.js.map +1 -1
- package/dist/design/generateStylesheet.cjs.js.map +1 -1
- package/dist/design/generateStylesheet.es.js.map +1 -1
- package/dist/design/lightTheme/colors.cjs.js.map +1 -1
- package/dist/design/lightTheme/colors.es.js.map +1 -1
- package/dist/design/lightTheme/stylesheet.cjs.js.map +1 -1
- package/dist/design/lightTheme/stylesheet.es.js.map +1 -1
- package/dist/design/theme.cjs.js.map +1 -1
- package/dist/design/theme.es.js.map +1 -1
- package/dist/hooks/useBreakpoint.cjs.js +1 -1
- package/dist/hooks/useBreakpoint.cjs.js.map +1 -1
- package/dist/hooks/useBreakpoint.es.js.map +1 -1
- package/dist/hooks/useIsClosing.cjs.js +1 -1
- package/dist/hooks/useIsClosing.cjs.js.map +1 -1
- package/dist/hooks/useIsClosing.es.js.map +1 -1
- package/dist/hooks/useLockBodyScroll.cjs.js.map +1 -1
- package/dist/hooks/useLockBodyScroll.es.js.map +1 -1
- package/dist/hooks/usePalette.cjs.js.map +1 -1
- package/dist/hooks/usePalette.es.js.map +1 -1
- package/dist/icons.svg +10 -10
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +52 -25
- package/dist/index.es.js +6 -6
- package/dist/node_modules/@react-aria/focus/dist/FocusScope.cjs.js +1 -1
- package/dist/node_modules/@react-aria/form/dist/useFormValidation.cjs.js +1 -1
- package/dist/node_modules/@react-aria/i18n/dist/context.cjs.js +1 -1
- package/dist/node_modules/@react-aria/i18n/dist/context.es.js +3 -3
- package/dist/node_modules/@react-aria/interactions/dist/useFocusWithin.cjs.js +1 -1
- package/dist/node_modules/@react-aria/interactions/dist/useFocusable.cjs.js +1 -1
- package/dist/node_modules/@react-aria/interactions/dist/useFocusable.cjs.js.map +1 -1
- package/dist/node_modules/@react-aria/interactions/dist/useFocusable.es.js +20 -30
- package/dist/node_modules/@react-aria/interactions/dist/useFocusable.es.js.map +1 -1
- package/dist/node_modules/@react-aria/interactions/dist/usePress.cjs.js +2 -2
- package/dist/node_modules/@react-aria/overlays/dist/Overlay.cjs.js +1 -1
- package/dist/node_modules/@react-aria/ssr/dist/SSRProvider.es.js.map +1 -1
- package/dist/node_modules/@react-stately/form/dist/useFormValidationState.cjs.js +1 -1
- package/dist/node_modules/@react-stately/radio/dist/useRadioGroupState.cjs.js +1 -1
- package/dist/node_modules/@react-stately/utils/dist/useControlledState.cjs.js +1 -1
- package/dist/node_modules/react/cjs/react-jsx-runtime.development.cjs.js +5 -5
- package/dist/node_modules/react/cjs/react-jsx-runtime.development.es.js +14 -14
- package/dist/node_modules/react/cjs/react-jsx-runtime.production.min.es.js +2 -2
- package/dist/style.css +1 -1
- package/dist/utils/color2k.cjs.js.map +1 -1
- package/dist/utils/color2k.es.js.map +1 -1
- package/dist/utils/copy.cjs.js.map +1 -1
- package/dist/utils/copy.es.js.map +1 -1
- package/dist/utils/image.cjs.js.map +1 -1
- package/dist/utils/image.es.js.map +1 -1
- package/dist/utils/navigation.cjs.js.map +1 -1
- package/dist/utils/navigation.es.js.map +1 -1
- package/dist/utils/palette.cjs.js.map +1 -1
- package/dist/utils/palette.es.js.map +1 -1
- package/dist/utils/string.cjs.js.map +1 -1
- package/dist/utils/string.es.js.map +1 -1
- package/package.json +140 -140
- package/dist/node_modules/react-aria-components/dist/OverlayArrow.cjs.js +0 -2
- package/dist/node_modules/react-aria-components/dist/OverlayArrow.cjs.js.map +0 -1
- package/dist/node_modules/react-aria-components/dist/OverlayArrow.es.js +0 -37
- package/dist/node_modules/react-aria-components/dist/OverlayArrow.es.js.map +0 -1
- package/dist/node_modules/react-aria-components/dist/Tooltip.cjs.js +0 -2
- package/dist/node_modules/react-aria-components/dist/Tooltip.cjs.js.map +0 -1
- package/dist/node_modules/react-aria-components/dist/Tooltip.es.js +0 -98
- package/dist/node_modules/react-aria-components/dist/Tooltip.es.js.map +0 -1
- package/dist/node_modules/react-aria-components/dist/utils.cjs.js +0 -2
- package/dist/node_modules/react-aria-components/dist/utils.cjs.js.map +0 -1
- package/dist/node_modules/react-aria-components/dist/utils.es.js +0 -89
- package/dist/node_modules/react-aria-components/dist/utils.es.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
# ProtonUI
|
|
2
|
-
|
|
3
|
-

|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
npm run storybook
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
## Installation
|
|
10
|
-
|
|
11
|
-
### Prerequisites
|
|
12
|
-
|
|
13
|
-
1. Ensure you have access to `@protonradio/proton-ui` [npm package](https://www.npmjs.com/package/@protonradio/proton-ui)
|
|
14
|
-
2. Login using `npm login`
|
|
15
|
-
|
|
16
|
-
### Install
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
npm install @protonradio/proton-ui --save
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### Project Structure
|
|
23
|
-
|
|
24
|
-
TODO: Explain project structure after treeshaking efforts have concluded
|
|
25
|
-
|
|
26
|
-
### Setup ThemeProvider
|
|
27
|
-
|
|
28
|
-
Wrap your application with the `ThemeProvider` to enable theming:
|
|
29
|
-
|
|
30
|
-
```jsx
|
|
31
|
-
import { ThemeProvider, THEMES } from "@protonradio/proton-ui";
|
|
32
|
-
|
|
33
|
-
function MyApp({ Component, pageProps }) {
|
|
34
|
-
return (
|
|
35
|
-
<ThemeProvider theme={THEMES.DARK}>
|
|
36
|
-
<Component {...pageProps} />
|
|
37
|
-
</ThemeProvider>
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Custom Color Palettes
|
|
43
|
-
|
|
44
|
-
Each theme has a `ProtonPalette` with colors tailored for UI design. Palettes are made up of `ProtonColorScale`s that have shades from super_light to super_dark:
|
|
45
|
-
|
|
46
|
-
- **Primary Scale**
|
|
47
|
-
- **Secondary Scale**
|
|
48
|
-
- **Brand Colors** [Partial ProtonColorScale]
|
|
49
|
-
- **Gray Scale**
|
|
50
|
-
- **Semantic Colors**
|
|
51
|
-
- Success
|
|
52
|
-
- Warning
|
|
53
|
-
- Error
|
|
54
|
-
|
|
55
|
-
When you pass a custom palette to the ThemeProvider, these five scales are updated with colors based on the background image you gave it. This is useful for designing UIs around individual releases, labels and artists. All generated scales are designed with accessibility in mind, ensuring proper contrast ratios and visual hierarchy.
|
|
56
|
-
|
|
57
|
-
To generate a new palette, use the `usePalette` hook:
|
|
58
|
-
|
|
59
|
-
```jsx
|
|
60
|
-
import { ThemeProvider, usePalette, THEMES } from "@protonradio/proton-ui";
|
|
61
|
-
|
|
62
|
-
function AppWithCustomPalette(props) {
|
|
63
|
-
const customPalette = usePalette(
|
|
64
|
-
`https://example.com/${props.imgUrl}.jpg`,
|
|
65
|
-
THEMES.DARK
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
return (
|
|
69
|
-
<ThemeProvider theme={THEMES.DARK} palette={customPalette}>
|
|
70
|
-
<YourApp />
|
|
71
|
-
</ThemeProvider>
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Best Styling Practices
|
|
77
|
-
|
|
78
|
-
Components use standardized _control_ variables defined in the theme config stylesheets for consistent styling across the design system:
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
export interface ProtonStyleSheet {
|
|
82
|
-
"--proton-control__background-color": string;
|
|
83
|
-
"--proton-control__background-color-light": string;
|
|
84
|
-
"--proton-control__text-color": string;
|
|
85
|
-
"--proton-control__title-color": string;
|
|
86
|
-
"--proton-control__border-color": string;
|
|
87
|
-
"--proton-control__shadow-color": string;
|
|
88
|
-
// ... etc
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
These control variables unify the styling system while powering theme-specific CSS customization, and follow the pattern `--proton-control__{style}-{property}`:
|
|
92
|
-
|
|
93
|
-
```css
|
|
94
|
-
.myComponent {
|
|
95
|
-
background-color: var(--proton-control__background-color);
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
For more advanced theme overrides we utilize the theme class names. The `ThemeProvider` applies the appropriate theme class to its container, making it available to all child components. Theme class names follow the pattern `proton-ui__theme--{themeName}`:
|
|
100
|
-
|
|
101
|
-
```css
|
|
102
|
-
.proton-ui__theme--dark .myComponent[active] {
|
|
103
|
-
background-color: var(--proton-control__interactive-color);
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Palettes can also be accessed in JSX via the `useTheme` hook for more advanced use cases:
|
|
108
|
-
|
|
109
|
-
```jsx
|
|
110
|
-
import { useTheme } from "@protonradio/proton-ui";
|
|
111
|
-
|
|
112
|
-
function MyComponent() {
|
|
113
|
-
const { palette } = useTheme();
|
|
114
|
-
|
|
115
|
-
// Prefer CSS selectors over programmatic styling
|
|
116
|
-
return <Icon color={palette.BRAND.PRIMARY} />;
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Publishing Updates to NPM
|
|
121
|
-
|
|
122
|
-
We follow semantic versioning and use automated CI/CD for releases:
|
|
123
|
-
|
|
124
|
-
**For Beta Releases (Testing):**
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
npm run build
|
|
128
|
-
npm run publish-beta # Automated versioning with beta tag
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**For Production Releases:**
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
npm run build
|
|
135
|
-
npm version <patch|minor|major> # Semantic versioning
|
|
136
|
-
npm publish
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
**Best Practices:**
|
|
140
|
-
|
|
141
|
-
- Always publish beta releases first for testing across platforms
|
|
142
|
-
- Test on all supported environments before production release
|
|
143
|
-
- Use semantic versioning (patch for bug fixes, minor for features, major for breaking changes)
|
|
144
|
-
- Our GitHub Actions [NPM Version](https://github.com/protonradio/proton-ui/actions/workflows/npm_release.yml) tool automatically handles versioning and deployment workflows
|
|
145
|
-
|
|
146
|
-
## Recommended Reading
|
|
147
|
-
|
|
148
|
-
- https://www.gabe.pizza/notes-on-component-libraries/
|
|
1
|
+
# ProtonUI
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
npm run storybook
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
### Prerequisites
|
|
12
|
+
|
|
13
|
+
1. Ensure you have access to `@protonradio/proton-ui` [npm package](https://www.npmjs.com/package/@protonradio/proton-ui)
|
|
14
|
+
2. Login using `npm login`
|
|
15
|
+
|
|
16
|
+
### Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @protonradio/proton-ui --save
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Project Structure
|
|
23
|
+
|
|
24
|
+
TODO: Explain project structure after treeshaking efforts have concluded
|
|
25
|
+
|
|
26
|
+
### Setup ThemeProvider
|
|
27
|
+
|
|
28
|
+
Wrap your application with the `ThemeProvider` to enable theming:
|
|
29
|
+
|
|
30
|
+
```jsx
|
|
31
|
+
import { ThemeProvider, THEMES } from "@protonradio/proton-ui";
|
|
32
|
+
|
|
33
|
+
function MyApp({ Component, pageProps }) {
|
|
34
|
+
return (
|
|
35
|
+
<ThemeProvider theme={THEMES.DARK}>
|
|
36
|
+
<Component {...pageProps} />
|
|
37
|
+
</ThemeProvider>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Custom Color Palettes
|
|
43
|
+
|
|
44
|
+
Each theme has a `ProtonPalette` with colors tailored for UI design. Palettes are made up of `ProtonColorScale`s that have shades from super_light to super_dark:
|
|
45
|
+
|
|
46
|
+
- **Primary Scale**
|
|
47
|
+
- **Secondary Scale**
|
|
48
|
+
- **Brand Colors** [Partial ProtonColorScale]
|
|
49
|
+
- **Gray Scale**
|
|
50
|
+
- **Semantic Colors**
|
|
51
|
+
- Success
|
|
52
|
+
- Warning
|
|
53
|
+
- Error
|
|
54
|
+
|
|
55
|
+
When you pass a custom palette to the ThemeProvider, these five scales are updated with colors based on the background image you gave it. This is useful for designing UIs around individual releases, labels and artists. All generated scales are designed with accessibility in mind, ensuring proper contrast ratios and visual hierarchy.
|
|
56
|
+
|
|
57
|
+
To generate a new palette, use the `usePalette` hook:
|
|
58
|
+
|
|
59
|
+
```jsx
|
|
60
|
+
import { ThemeProvider, usePalette, THEMES } from "@protonradio/proton-ui";
|
|
61
|
+
|
|
62
|
+
function AppWithCustomPalette(props) {
|
|
63
|
+
const customPalette = usePalette(
|
|
64
|
+
`https://example.com/${props.imgUrl}.jpg`,
|
|
65
|
+
THEMES.DARK
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<ThemeProvider theme={THEMES.DARK} palette={customPalette}>
|
|
70
|
+
<YourApp />
|
|
71
|
+
</ThemeProvider>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Best Styling Practices
|
|
77
|
+
|
|
78
|
+
Components use standardized _control_ variables defined in the theme config stylesheets for consistent styling across the design system:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
export interface ProtonStyleSheet {
|
|
82
|
+
"--proton-control__background-color": string;
|
|
83
|
+
"--proton-control__background-color-light": string;
|
|
84
|
+
"--proton-control__text-color": string;
|
|
85
|
+
"--proton-control__title-color": string;
|
|
86
|
+
"--proton-control__border-color": string;
|
|
87
|
+
"--proton-control__shadow-color": string;
|
|
88
|
+
// ... etc
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
These control variables unify the styling system while powering theme-specific CSS customization, and follow the pattern `--proton-control__{style}-{property}`:
|
|
92
|
+
|
|
93
|
+
```css
|
|
94
|
+
.myComponent {
|
|
95
|
+
background-color: var(--proton-control__background-color);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
For more advanced theme overrides we utilize the theme class names. The `ThemeProvider` applies the appropriate theme class to its container, making it available to all child components. Theme class names follow the pattern `proton-ui__theme--{themeName}`:
|
|
100
|
+
|
|
101
|
+
```css
|
|
102
|
+
.proton-ui__theme--dark .myComponent[active] {
|
|
103
|
+
background-color: var(--proton-control__interactive-color);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Palettes can also be accessed in JSX via the `useTheme` hook for more advanced use cases:
|
|
108
|
+
|
|
109
|
+
```jsx
|
|
110
|
+
import { useTheme } from "@protonradio/proton-ui";
|
|
111
|
+
|
|
112
|
+
function MyComponent() {
|
|
113
|
+
const { palette } = useTheme();
|
|
114
|
+
|
|
115
|
+
// Prefer CSS selectors over programmatic styling
|
|
116
|
+
return <Icon color={palette.BRAND.PRIMARY} />;
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Publishing Updates to NPM
|
|
121
|
+
|
|
122
|
+
We follow semantic versioning and use automated CI/CD for releases:
|
|
123
|
+
|
|
124
|
+
**For Beta Releases (Testing):**
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npm run build
|
|
128
|
+
npm run publish-beta # Automated versioning with beta tag
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**For Production Releases:**
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm run build
|
|
135
|
+
npm version <patch|minor|major> # Semantic versioning
|
|
136
|
+
npm publish
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Best Practices:**
|
|
140
|
+
|
|
141
|
+
- Always publish beta releases first for testing across platforms
|
|
142
|
+
- Test on all supported environments before production release
|
|
143
|
+
- Use semantic versioning (patch for bug fixes, minor for features, major for breaking changes)
|
|
144
|
+
- Our GitHub Actions [NPM Version](https://github.com/protonradio/proton-ui/actions/workflows/npm_release.yml) tool automatically handles versioning and deployment workflows
|
|
145
|
+
|
|
146
|
+
## Recommended Reading
|
|
147
|
+
|
|
148
|
+
- https://www.gabe.pizza/notes-on-component-libraries/
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("../../node_modules/react/jsx-runtime.cjs.js"),s=require("react"),H=require("../../hooks/useIsClosing.cjs.js"),P=require("../../hooks/useLockBodyScroll.cjs.js"),G=require("../Button/Button.cjs.js"),L=require("../ScreenOverlay/ScreenOverlay.cjs.js"),i=require("radix-ui"),N=require("../Icon/Icon.cjs.js");;/* empty css */const D=require("../../utils/navigation.cjs.js"),T=({isOpen:e,actions:a=[],children:o,showCancel:l=!0,cancelButtonText:m="Cancel",selectionMode:E="single",selectedKeys:x,disabledKeys:h=[],onSelectionChange:p,onClose:f,title:j,"data-testid":r})=>{var $;P.useLockBodyScroll(e);const[u,c]=s.useState(0),[t,d]=s.useState([]),[A,_]=s.useState({title:j,actions:a,key:null,previousKey:null}),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("../../node_modules/react/jsx-runtime.cjs.js"),s=require("react"),H=require("../../hooks/useIsClosing.cjs.js"),P=require("../../hooks/useLockBodyScroll.cjs.js"),G=require("../Button/Button.cjs.js"),L=require("../ScreenOverlay/ScreenOverlay.cjs.js"),i=require("radix-ui"),N=require("../Icon/Icon.cjs.js");;/* empty css */const D=require("../../utils/navigation.cjs.js"),T=({isOpen:e,actions:a=[],children:o,showCancel:l=!0,cancelButtonText:m="Cancel",selectionMode:E="single",selectedKeys:x,disabledKeys:h=[],onSelectionChange:p,onClose:f,title:j,"data-testid":r})=>{var $;P.useLockBodyScroll(e);const[u,c]=s.useState(0),[t,d]=s.useState([]),[A,_]=s.useState({title:j,actions:a,key:null,previousKey:null}),g=s.useRef(null),C=s.useRef(null),S=s.useRef(null),{isClosing:M,handleClose:b}=H.useIsClosing({onClose:f,overlayRef:S}),v=A.actions||[],w=v&&v.length>0,I=o||w||l,q=t.length>0;function B(R){const y=v.find(k=>k.key===R);if(!y){console.error(`Action with key ${R} not found`);return}d(k=>[...k,A]),_(k=>({title:y.label,actions:y.children,key:y.key,previousKey:k.key}))}function F(){if(t.length>0){const R=t[t.length-1];_(R),d(t.slice(0,-1))}}return s.useEffect(()=>{e&&requestAnimationFrame(()=>{g.current&&c(g.current.scrollHeight+12)})},[e,t,I]),s.useEffect(()=>{(!e||M)&&c(0)},[e,M]),!e&&!M?null:n.jsxRuntimeExports.jsx(L.ScreenOverlay,{fadeIn:!0,ref:S,children:n.jsxRuntimeExports.jsxs(i.DropdownMenu.Root,{modal:!0,open:e,onOpenChange:R=>{R||b()},children:[n.jsxRuntimeExports.jsx(i.DropdownMenu.Trigger,{asChild:!0,children:n.jsxRuntimeExports.jsx("div",{children:""})}),n.jsxRuntimeExports.jsx("div",{className:"proton-ActionMenu__background-wrapper",style:{opacity:M?0:1},children:n.jsxRuntimeExports.jsx("div",{"data-testid":r||"ActionMenu-wrapper",className:"proton-ActionMenu__wrapper",children:n.jsxRuntimeExports.jsx("div",{className:"proton-ActionMenu__card","data-testid":"ActionMenu-content",style:{height:`${u}px`},children:n.jsxRuntimeExports.jsx("div",{ref:C,className:"proton-ActionMenu__menu",children:n.jsxRuntimeExports.jsx(i.DropdownMenu.Content,{loop:!0,sideOffset:8,ref:g,children:I&&n.jsxRuntimeExports.jsxs(n.jsxRuntimeExports.Fragment,{children:[o&&n.jsxRuntimeExports.jsx("div",{className:"proton-ActionMenu__content",children:typeof o=="function"?o({close:b}):o}),w&&n.jsxRuntimeExports.jsx(z,{actions:v,selectionMode:E,selectedKeys:x,onSelectionChange:p,disabledKeys:h,handleSubmenuOpen:B,title:A.title,isInSubmenu:q,handleBack:F,previousMenuTitle:($=t[t.length-1])==null?void 0:$.title}),l&&n.jsxRuntimeExports.jsxs(n.jsxRuntimeExports.Fragment,{children:[n.jsxRuntimeExports.jsx(i.DropdownMenu.Separator,{}),n.jsxRuntimeExports.jsx(i.DropdownMenu.Item,{className:"proton-ActionMenu__cancel-button",children:n.jsxRuntimeExports.jsx(G.Button,{"data-testid":"ActionMenuItem-cancel",onPress:b,fullWidth:!0,variant:"secondary",children:m})})]})]})})})})})})]})})},z=({actions:e,selectionMode:a,selectedKeys:o=[],onSelectionChange:l,disabledKeys:m=[],handleSubmenuOpen:E,title:x,isInSubmenu:h=!1,handleBack:p,previousMenuTitle:f})=>{const j=()=>n.jsxRuntimeExports.jsxs(n.jsxRuntimeExports.Fragment,{children:[h&&p&&n.jsxRuntimeExports.jsxs("div",{className:"proton-ActionMenu__back-button-container",children:[n.jsxRuntimeExports.jsx(i.DropdownMenu.Item,{className:"proton-ActionMenu__back-button",onSelect:r=>{r.preventDefault(),p()},"aria-label":`Go back to ${f||"previous menu"}`,children:n.jsxRuntimeExports.jsx(N.Icon,{id:"chevron-left",size:16,"aria-hidden":"true"})}),n.jsxRuntimeExports.jsx("div",{className:"proton-ActionMenu__title",role:"banner","aria-label":h?`Submenu: ${x}`:`Menu: ${x}`,children:n.jsxRuntimeExports.jsx("span",{children:x})}),n.jsxRuntimeExports.jsx(i.DropdownMenu.Separator,{})]}),e.map((r,u)=>{var t;const c=e[u];return n.jsxRuntimeExports.jsx(U,{item:r,isSubmenu:!!((t=c.children)!=null&&t.length),selectionMode:a,onSelectionChange:l,selectedKeys:o,disabledKeys:m,handleSubmenuOpen:E},r.key)})]});return n.jsxRuntimeExports.jsx("div",{"aria-disabled":a==="none",className:"proton-ActionMenu__list",role:"menu","aria-label":x?`${h?"Submenu":"Menu"}: ${x}`:"Action menu","aria-orientation":"vertical",children:a==="single"?n.jsxRuntimeExports.jsx(i.DropdownMenu.RadioGroup,{value:(o==null?void 0:o[0])||"",onValueChange:r=>{var c;const u=e.find(t=>t.key===r);(c=u==null?void 0:u.children)!=null&&c.length||l&&l(new Set([r]))},children:n.jsxRuntimeExports.jsx(j,{})}):n.jsxRuntimeExports.jsx(i.DropdownMenu.Group,{children:n.jsxRuntimeExports.jsx(j,{})})})},U=({item:e,isSubmenu:a,selectionMode:o,onSelectionChange:l,selectedKeys:m=[],disabledKeys:E=[],handleSubmenuOpen:x})=>{const h=s.useRef(null),p=e.to&&D.isUrlExternal(e.to),f=E.includes(e.key),j=m.includes(e.key),r={className:"proton-ActionMenu__item","aria-label":e.label?`${e.label}${e.description?`, ${e.description}`:""}`:`ActionMenu-Item-${e.key}`,role:"menuitem",disabled:f,ref:h},u=t=>{var d;if((d=e==null?void 0:e.children)!=null&&d.length){t.preventDefault(),x(e.key);return}e.onAction&&e.onAction(e.key)},c=n.jsxRuntimeExports.jsxs(n.jsxRuntimeExports.Fragment,{children:[n.jsxRuntimeExports.jsxs("div",{className:"proton-ActionMenu__item-content",children:[n.jsxRuntimeExports.jsx("div",{className:"proton-ActionMenu__item-label",children:e.label}),e.description&&n.jsxRuntimeExports.jsx("div",{className:"proton-ActionMenu__description",children:e.description})]}),a&&n.jsxRuntimeExports.jsx(N.Icon,{id:"chevron-right",size:16,"aria-hidden":"true"})]});return e.to?s.createElement(i.DropdownMenu.Item,{...r,key:e.key,asChild:!0},n.jsxRuntimeExports.jsx("a",{"aria-label":e.label?`${e.label}${e.description?`, ${e.description}`:""}`:`ActionMenu-Item-${e.key}`,"aria-disabled":f,"aria-checked":j,"aria-expanded":a?!1:void 0,href:e.to,target:p?"_blank":void 0,rel:p?"noopener noreferrer":void 0,onClick:t=>{p||!e.to||D.handleInternalNavigation(t,e.to)},children:c})):o==="multiple"?s.createElement(i.DropdownMenu.CheckboxItem,{...r,key:e.key,checked:j,onSelect:u,onCheckedChange:t=>{if(!l)return;const d=new Set(m);t?d.add(e.key):d.delete(e.key),l(d)}},c):s.createElement(i.DropdownMenu.RadioItem,{...r,value:e.key,key:e.key,"aria-checked":j,"aria-expanded":a?!1:void 0,onSelect:u},c)};exports.ActionMenu=T;
|
|
2
2
|
//# sourceMappingURL=ActionMenu.cjs.js.map
|
|
@@ -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\";\nimport type { Selection } from \"@react-types/shared\";\n\nimport { useIsClosing } from \"../../hooks/useIsClosing\";\nimport { useLockBodyScroll } from \"../../hooks/useLockBodyScroll\";\nimport { handleInternalNavigation, isUrlExternal } from \"../../utils\";\n\nimport { Button } from \"../Button/Button\";\nimport { ScreenOverlay } from \"../ScreenOverlay/ScreenOverlay\";\nimport { DropdownMenu } from \"radix-ui\";\nimport { Icon } from \"../Icon/Icon\";\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\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 Selection}\n */\n onSelectionChange?: (keys: Selection) => 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 useLockBodyScroll(isOpen);\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 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: Selection) => 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 <Icon id=\"chevron-left\" size={16} aria-hidden=\"true\" />\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: Selection) => 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 && <Icon id=\"chevron-right\" size={16} aria-hidden=\"true\" />}\n </>\n );\n\n if (item.to) {\n return (\n <DropdownMenu.Item {...radixItemProps} key={item.key} asChild>\n <a\n aria-label={\n item.label\n ? `${item.label}${item.description ? `, ${item.description}` : \"\"}`\n : `ActionMenu-Item-${item.key}`\n }\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","useLockBodyScroll","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","Icon","i","itemProps","ActionMenuItem","value","item","isSubmenu","ref","isExternal","isUrlExternal","isDisabled","isSelected","radixItemProps","onSelect","content","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\";\r\n\r\nimport { ReactNode, useEffect, useRef, useState } from \"react\";\r\nimport type { Selection } from \"@react-types/shared\";\r\n\r\nimport { useIsClosing } from \"../../hooks/useIsClosing\";\r\nimport { useLockBodyScroll } from \"../../hooks/useLockBodyScroll\";\r\nimport { handleInternalNavigation, isUrlExternal } from \"../../utils\";\r\n\r\nimport { Button } from \"../Button/Button\";\r\nimport { ScreenOverlay } from \"../ScreenOverlay/ScreenOverlay\";\r\nimport { DropdownMenu } from \"radix-ui\";\r\nimport { Icon } from \"../Icon/Icon\";\r\n\r\nimport \"./ActionMenu.css\";\r\n\r\nexport interface ActionMenuAction {\r\n key: string;\r\n label?: ReactNode;\r\n description?: ReactNode;\r\n to?: string;\r\n onAction?: (key: string) => void;\r\n children?: ActionMenuAction[];\r\n}\r\n\r\nexport type ActionMenuSelectionMode = \"single\" | \"multiple\" | \"none\";\r\n\r\nexport interface ActionMenuProps {\r\n /** The actions of the menu\r\n * - type {@link ActionMenuAction}[]\r\n */\r\n actions?: ActionMenuAction[];\r\n\r\n /** The text of the cancel button */\r\n cancelButtonText?: string;\r\n\r\n /** The children of the menu */\r\n children?: ReactNode | ((props: { close: () => void }) => ReactNode);\r\n\r\n /** The test id of the menu */\r\n \"data-testid\"?: string;\r\n\r\n /** The keys of the disabled items\r\n * @default []\r\n */\r\n disabledKeys?: string[];\r\n\r\n /** Whether the menu is open\r\n * @default false\r\n */\r\n isOpen: boolean;\r\n\r\n /** The callback function to close the menu */\r\n onClose?: () => void;\r\n\r\n /** The callback function to change the selection\r\n * - type {@link Selection}\r\n */\r\n onSelectionChange?: (keys: Selection) => void;\r\n\r\n /** The selection mode of the menu\r\n * @default \"single\"\r\n */\r\n selectionMode?: ActionMenuSelectionMode;\r\n\r\n /** The keys of the selected items */\r\n selectedKeys?: string[];\r\n\r\n /** Whether to show the cancel button */\r\n showCancel?: boolean;\r\n\r\n /** The title of the menu */\r\n title?: string;\r\n}\r\n\r\ntype ActionStack = {\r\n title: ReactNode | null;\r\n actions: ActionMenuAction[];\r\n key: string | null;\r\n previousKey: string | null;\r\n};\r\n\r\n/**\r\n * A controlled ActionMenu to display a menu of actions.\r\n * Renders a list of actions as a focusable menu, or non-focusable children.\r\n *\r\n * API:\r\n * - {@link ActionMenuProps}\r\n */\r\nexport const ActionMenu = ({\r\n isOpen,\r\n actions = [],\r\n children,\r\n showCancel = true,\r\n cancelButtonText = \"Cancel\",\r\n selectionMode = \"single\",\r\n selectedKeys,\r\n disabledKeys = [],\r\n onSelectionChange,\r\n onClose,\r\n title,\r\n \"data-testid\": testId,\r\n}: ActionMenuProps) => {\r\n useLockBodyScroll(isOpen);\r\n const [contentHeight, setContentHeight] = useState<number>(0);\r\n const [stackHistory, setStackHistory] = useState<ActionStack[]>([]);\r\n const [currentActionStack, setCurrentActionStack] = useState<ActionStack>({\r\n title,\r\n actions,\r\n key: null,\r\n previousKey: null,\r\n });\r\n const contentRef = useRef<HTMLDivElement>(null);\r\n const menuRef = useRef<HTMLDivElement>(null);\r\n const overlayRef = useRef<HTMLDivElement>(null);\r\n const { isClosing, handleClose } = useIsClosing({ onClose, overlayRef });\r\n\r\n const currentActions = currentActionStack.actions || [];\r\n const hasActions = currentActions && currentActions.length > 0;\r\n const hasContent = children || hasActions || showCancel;\r\n const isInSubmenu = stackHistory.length > 0;\r\n\r\n function handleSubmenuOpen(key: string) {\r\n const action = currentActions.find((action) => action.key === key);\r\n if (!action) {\r\n console.error(`Action with key ${key} not found`);\r\n return;\r\n }\r\n\r\n setStackHistory((prevStackHistory) => [\r\n ...prevStackHistory,\r\n currentActionStack,\r\n ]);\r\n setCurrentActionStack((prevStack) => ({\r\n title: action.label,\r\n actions: action.children,\r\n key: action.key,\r\n previousKey: prevStack.key,\r\n }));\r\n }\r\n\r\n function handleBack() {\r\n if (stackHistory.length > 0) {\r\n const previousStack = stackHistory[stackHistory.length - 1];\r\n setCurrentActionStack(previousStack);\r\n setStackHistory(stackHistory.slice(0, -1));\r\n }\r\n }\r\n\r\n // Re-measure the open menu's content height when stack history changes\r\n useEffect(() => {\r\n if (!isOpen) return;\r\n\r\n requestAnimationFrame(() => {\r\n if (contentRef.current) {\r\n setContentHeight(contentRef.current.scrollHeight + 12);\r\n }\r\n });\r\n }, [isOpen, stackHistory, hasContent]);\r\n\r\n // Reset content height when menu closes or is closing\r\n useEffect(() => {\r\n if (!isOpen || isClosing) {\r\n setContentHeight(0);\r\n }\r\n }, [isOpen, isClosing]);\r\n\r\n if (!isOpen && !isClosing) return null;\r\n\r\n return (\r\n <ScreenOverlay fadeIn ref={overlayRef}>\r\n <DropdownMenu.Root\r\n modal\r\n open={isOpen}\r\n onOpenChange={(open) => {\r\n if (!open) handleClose();\r\n }}\r\n >\r\n <DropdownMenu.Trigger asChild>\r\n {/* No visible trigger, menu is controlled by isOpen */}\r\n <div>{\"\"}</div>\r\n </DropdownMenu.Trigger>\r\n\r\n <div\r\n className=\"proton-ActionMenu__background-wrapper\"\r\n style={{ opacity: isClosing ? 0 : 1 }}\r\n >\r\n <div\r\n data-testid={testId || \"ActionMenu-wrapper\"}\r\n className=\"proton-ActionMenu__wrapper\"\r\n >\r\n <div\r\n className=\"proton-ActionMenu__card\"\r\n data-testid=\"ActionMenu-content\"\r\n style={{ height: `${contentHeight}px` }}\r\n >\r\n <div ref={menuRef} className=\"proton-ActionMenu__menu\">\r\n <DropdownMenu.Content loop sideOffset={8} ref={contentRef}>\r\n {hasContent && (\r\n <>\r\n {children && (\r\n <div className=\"proton-ActionMenu__content\">\r\n {typeof children === \"function\"\r\n ? children({ close: handleClose })\r\n : children}\r\n </div>\r\n )}\r\n\r\n {hasActions && (\r\n <ActionMenuList\r\n actions={currentActions}\r\n selectionMode={selectionMode}\r\n selectedKeys={selectedKeys}\r\n onSelectionChange={onSelectionChange}\r\n disabledKeys={disabledKeys}\r\n handleSubmenuOpen={handleSubmenuOpen}\r\n title={currentActionStack.title}\r\n isInSubmenu={isInSubmenu}\r\n handleBack={handleBack}\r\n previousMenuTitle={\r\n stackHistory[stackHistory.length - 1]?.title\r\n }\r\n />\r\n )}\r\n\r\n {showCancel && (\r\n <>\r\n <DropdownMenu.Separator />\r\n <DropdownMenu.Item className=\"proton-ActionMenu__cancel-button\">\r\n <Button\r\n data-testid=\"ActionMenuItem-cancel\"\r\n onPress={handleClose}\r\n fullWidth\r\n variant=\"secondary\"\r\n >\r\n {cancelButtonText}\r\n </Button>\r\n </DropdownMenu.Item>\r\n </>\r\n )}\r\n </>\r\n )}\r\n </DropdownMenu.Content>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </DropdownMenu.Root>\r\n </ScreenOverlay>\r\n );\r\n};\r\n\r\ninterface ActionMenuListProps {\r\n actions: ActionMenuAction[];\r\n selectionMode: ActionMenuSelectionMode;\r\n selectedKeys?: string[];\r\n onSelectionChange?: (keys: Selection) => void;\r\n disabledKeys?: string[];\r\n handleSubmenuOpen: (key: string) => void;\r\n title?: ReactNode;\r\n isInSubmenu?: boolean;\r\n handleBack?: () => void;\r\n previousMenuTitle?: ReactNode;\r\n}\r\n\r\nconst ActionMenuList = ({\r\n actions,\r\n selectionMode,\r\n selectedKeys = [],\r\n onSelectionChange,\r\n disabledKeys = [],\r\n handleSubmenuOpen,\r\n title,\r\n isInSubmenu = false,\r\n handleBack,\r\n previousMenuTitle,\r\n}: ActionMenuListProps) => {\r\n const ActionMenuItemMap = () => (\r\n <>\r\n {isInSubmenu && handleBack && (\r\n <div className=\"proton-ActionMenu__back-button-container\">\r\n <DropdownMenu.Item\r\n className=\"proton-ActionMenu__back-button\"\r\n onSelect={(event) => {\r\n event.preventDefault();\r\n handleBack();\r\n }}\r\n aria-label={`Go back to ${previousMenuTitle || \"previous menu\"}`}\r\n >\r\n <Icon id=\"chevron-left\" size={16} aria-hidden=\"true\" />\r\n </DropdownMenu.Item>\r\n <div\r\n className=\"proton-ActionMenu__title\"\r\n role=\"banner\"\r\n aria-label={isInSubmenu ? `Submenu: ${title}` : `Menu: ${title}`}\r\n >\r\n <span>{title}</span>\r\n </div>\r\n <DropdownMenu.Separator />\r\n </div>\r\n )}\r\n\r\n {actions.map((action, i) => {\r\n const itemProps = actions[i];\r\n return (\r\n <ActionMenuItem\r\n key={action.key}\r\n item={action}\r\n isSubmenu={Boolean(itemProps.children?.length)}\r\n selectionMode={selectionMode}\r\n onSelectionChange={onSelectionChange}\r\n selectedKeys={selectedKeys}\r\n disabledKeys={disabledKeys}\r\n handleSubmenuOpen={handleSubmenuOpen}\r\n />\r\n );\r\n })}\r\n </>\r\n );\r\n\r\n return (\r\n <div\r\n aria-disabled={selectionMode === \"none\"}\r\n className=\"proton-ActionMenu__list\"\r\n role=\"menu\"\r\n aria-label={\r\n title ? `${isInSubmenu ? \"Submenu\" : \"Menu\"}: ${title}` : \"Action menu\"\r\n }\r\n aria-orientation=\"vertical\"\r\n >\r\n {selectionMode === \"single\" ? (\r\n <DropdownMenu.RadioGroup\r\n value={selectedKeys?.[0] || \"\"}\r\n onValueChange={(value) => {\r\n // Check if this is a submenu item - if so, don't trigger selection change\r\n const action = actions.find((action) => action.key === value);\r\n if (action?.children?.length) {\r\n return;\r\n }\r\n\r\n if (onSelectionChange) {\r\n onSelectionChange(new Set([value]));\r\n }\r\n }}\r\n >\r\n <ActionMenuItemMap />\r\n </DropdownMenu.RadioGroup>\r\n ) : (\r\n <DropdownMenu.Group>\r\n <ActionMenuItemMap />\r\n </DropdownMenu.Group>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\ninterface ActionMenuItemProps {\r\n to?: string;\r\n item: ActionMenuAction;\r\n isSubmenu?: boolean;\r\n selectionMode: ActionMenuSelectionMode;\r\n onSelectionChange?: (keys: Selection) => void;\r\n selectedKeys?: string[];\r\n disabledKeys?: string[];\r\n handleSubmenuOpen: (key: string) => void;\r\n}\r\n\r\nconst ActionMenuItem = ({\r\n item,\r\n isSubmenu,\r\n selectionMode,\r\n onSelectionChange,\r\n selectedKeys = [],\r\n disabledKeys = [],\r\n handleSubmenuOpen,\r\n}: ActionMenuItemProps) => {\r\n const ref = useRef(null);\r\n const isExternal = item.to && isUrlExternal(item.to);\r\n const isDisabled = disabledKeys.includes(item.key);\r\n const isSelected = selectedKeys.includes(item.key);\r\n\r\n const radixItemProps = {\r\n className: \"proton-ActionMenu__item\",\r\n \"aria-label\": item.label\r\n ? `${item.label}${item.description ? `, ${item.description}` : \"\"}`\r\n : `ActionMenu-Item-${item.key}`,\r\n role: \"menuitem\",\r\n disabled: isDisabled,\r\n ref,\r\n };\r\n\r\n const onSelect = (event: Event) => {\r\n if (item?.children?.length) {\r\n event.preventDefault();\r\n handleSubmenuOpen(item.key);\r\n return;\r\n }\r\n if (item.onAction) {\r\n item.onAction(item.key);\r\n }\r\n };\r\n\r\n const content = (\r\n <>\r\n <div className=\"proton-ActionMenu__item-content\">\r\n <div className=\"proton-ActionMenu__item-label\">{item.label}</div>\r\n {item.description && (\r\n <div className=\"proton-ActionMenu__description\">\r\n {item.description}\r\n </div>\r\n )}\r\n </div>\r\n {isSubmenu && <Icon id=\"chevron-right\" size={16} aria-hidden=\"true\" />}\r\n </>\r\n );\r\n\r\n if (item.to) {\r\n return (\r\n <DropdownMenu.Item {...radixItemProps} key={item.key} asChild>\r\n <a\r\n aria-label={\r\n item.label\r\n ? `${item.label}${item.description ? `, ${item.description}` : \"\"}`\r\n : `ActionMenu-Item-${item.key}`\r\n }\r\n aria-disabled={isDisabled}\r\n aria-checked={isSelected}\r\n aria-expanded={isSubmenu ? false : undefined}\r\n href={item.to}\r\n target={isExternal ? \"_blank\" : undefined}\r\n rel={isExternal ? \"noopener noreferrer\" : undefined}\r\n onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {\r\n if (isExternal || !item.to) {\r\n return;\r\n }\r\n handleInternalNavigation(e, item.to);\r\n }}\r\n >\r\n {content}\r\n </a>\r\n </DropdownMenu.Item>\r\n );\r\n }\r\n\r\n if (selectionMode === \"multiple\") {\r\n return (\r\n <DropdownMenu.CheckboxItem\r\n {...radixItemProps}\r\n key={item.key}\r\n checked={isSelected}\r\n onSelect={onSelect}\r\n onCheckedChange={(checked: boolean) => {\r\n if (!onSelectionChange) return;\r\n\r\n const currentKeys = new Set(selectedKeys);\r\n if (checked) {\r\n currentKeys.add(item.key);\r\n } else {\r\n currentKeys.delete(item.key);\r\n }\r\n onSelectionChange(currentKeys);\r\n }}\r\n >\r\n {content}\r\n </DropdownMenu.CheckboxItem>\r\n );\r\n }\r\n\r\n return (\r\n <DropdownMenu.RadioItem\r\n {...radixItemProps}\r\n value={item.key}\r\n key={item.key}\r\n aria-checked={isSelected}\r\n aria-expanded={isSubmenu ? false : undefined}\r\n onSelect={onSelect}\r\n >\r\n {content}\r\n </DropdownMenu.RadioItem>\r\n );\r\n};\r\n"],"names":["ActionMenu","isOpen","actions","children","showCancel","cancelButtonText","selectionMode","selectedKeys","disabledKeys","onSelectionChange","onClose","title","testId","useLockBodyScroll","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","Icon","i","itemProps","ActionMenuItem","value","item","isSubmenu","ref","isExternal","isUrlExternal","isDisabled","isSelected","radixItemProps","onSelect","content","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\";\nimport type { Selection } from \"@react-types/shared\";\n\nimport { useIsClosing } from \"../../hooks/useIsClosing\";\nimport { useLockBodyScroll } from \"../../hooks/useLockBodyScroll\";\nimport { handleInternalNavigation, isUrlExternal } from \"../../utils\";\n\nimport { Button } from \"../Button/Button\";\nimport { ScreenOverlay } from \"../ScreenOverlay/ScreenOverlay\";\nimport { DropdownMenu } from \"radix-ui\";\nimport { Icon } from \"../Icon/Icon\";\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\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 Selection}\n */\n onSelectionChange?: (keys: Selection) => 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 useLockBodyScroll(isOpen);\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 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: Selection) => 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 <Icon id=\"chevron-left\" size={16} aria-hidden=\"true\" />\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: Selection) => 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 && <Icon id=\"chevron-right\" size={16} aria-hidden=\"true\" />}\n </>\n );\n\n if (item.to) {\n return (\n <DropdownMenu.Item {...radixItemProps} key={item.key} asChild>\n <a\n aria-label={\n item.label\n ? `${item.label}${item.description ? `, ${item.description}` : \"\"}`\n : `ActionMenu-Item-${item.key}`\n }\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","useLockBodyScroll","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","Icon","i","itemProps","ActionMenuItem","value","item","isSubmenu","ref","isExternal","isUrlExternal","isDisabled","isSelected","radixItemProps","onSelect","content","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\";\r\n\r\nimport { ReactNode, useEffect, useRef, useState } from \"react\";\r\nimport type { Selection } from \"@react-types/shared\";\r\n\r\nimport { useIsClosing } from \"../../hooks/useIsClosing\";\r\nimport { useLockBodyScroll } from \"../../hooks/useLockBodyScroll\";\r\nimport { handleInternalNavigation, isUrlExternal } from \"../../utils\";\r\n\r\nimport { Button } from \"../Button/Button\";\r\nimport { ScreenOverlay } from \"../ScreenOverlay/ScreenOverlay\";\r\nimport { DropdownMenu } from \"radix-ui\";\r\nimport { Icon } from \"../Icon/Icon\";\r\n\r\nimport \"./ActionMenu.css\";\r\n\r\nexport interface ActionMenuAction {\r\n key: string;\r\n label?: ReactNode;\r\n description?: ReactNode;\r\n to?: string;\r\n onAction?: (key: string) => void;\r\n children?: ActionMenuAction[];\r\n}\r\n\r\nexport type ActionMenuSelectionMode = \"single\" | \"multiple\" | \"none\";\r\n\r\nexport interface ActionMenuProps {\r\n /** The actions of the menu\r\n * - type {@link ActionMenuAction}[]\r\n */\r\n actions?: ActionMenuAction[];\r\n\r\n /** The text of the cancel button */\r\n cancelButtonText?: string;\r\n\r\n /** The children of the menu */\r\n children?: ReactNode | ((props: { close: () => void }) => ReactNode);\r\n\r\n /** The test id of the menu */\r\n \"data-testid\"?: string;\r\n\r\n /** The keys of the disabled items\r\n * @default []\r\n */\r\n disabledKeys?: string[];\r\n\r\n /** Whether the menu is open\r\n * @default false\r\n */\r\n isOpen: boolean;\r\n\r\n /** The callback function to close the menu */\r\n onClose?: () => void;\r\n\r\n /** The callback function to change the selection\r\n * - type {@link Selection}\r\n */\r\n onSelectionChange?: (keys: Selection) => void;\r\n\r\n /** The selection mode of the menu\r\n * @default \"single\"\r\n */\r\n selectionMode?: ActionMenuSelectionMode;\r\n\r\n /** The keys of the selected items */\r\n selectedKeys?: string[];\r\n\r\n /** Whether to show the cancel button */\r\n showCancel?: boolean;\r\n\r\n /** The title of the menu */\r\n title?: string;\r\n}\r\n\r\ntype ActionStack = {\r\n title: ReactNode | null;\r\n actions: ActionMenuAction[];\r\n key: string | null;\r\n previousKey: string | null;\r\n};\r\n\r\n/**\r\n * A controlled ActionMenu to display a menu of actions.\r\n * Renders a list of actions as a focusable menu, or non-focusable children.\r\n *\r\n * API:\r\n * - {@link ActionMenuProps}\r\n */\r\nexport const ActionMenu = ({\r\n isOpen,\r\n actions = [],\r\n children,\r\n showCancel = true,\r\n cancelButtonText = \"Cancel\",\r\n selectionMode = \"single\",\r\n selectedKeys,\r\n disabledKeys = [],\r\n onSelectionChange,\r\n onClose,\r\n title,\r\n \"data-testid\": testId,\r\n}: ActionMenuProps) => {\r\n useLockBodyScroll(isOpen);\r\n const [contentHeight, setContentHeight] = useState<number>(0);\r\n const [stackHistory, setStackHistory] = useState<ActionStack[]>([]);\r\n const [currentActionStack, setCurrentActionStack] = useState<ActionStack>({\r\n title,\r\n actions,\r\n key: null,\r\n previousKey: null,\r\n });\r\n const contentRef = useRef<HTMLDivElement>(null);\r\n const menuRef = useRef<HTMLDivElement>(null);\r\n const overlayRef = useRef<HTMLDivElement>(null);\r\n const { isClosing, handleClose } = useIsClosing({ onClose, overlayRef });\r\n\r\n const currentActions = currentActionStack.actions || [];\r\n const hasActions = currentActions && currentActions.length > 0;\r\n const hasContent = children || hasActions || showCancel;\r\n const isInSubmenu = stackHistory.length > 0;\r\n\r\n function handleSubmenuOpen(key: string) {\r\n const action = currentActions.find((action) => action.key === key);\r\n if (!action) {\r\n console.error(`Action with key ${key} not found`);\r\n return;\r\n }\r\n\r\n setStackHistory((prevStackHistory) => [\r\n ...prevStackHistory,\r\n currentActionStack,\r\n ]);\r\n setCurrentActionStack((prevStack) => ({\r\n title: action.label,\r\n actions: action.children,\r\n key: action.key,\r\n previousKey: prevStack.key,\r\n }));\r\n }\r\n\r\n function handleBack() {\r\n if (stackHistory.length > 0) {\r\n const previousStack = stackHistory[stackHistory.length - 1];\r\n setCurrentActionStack(previousStack);\r\n setStackHistory(stackHistory.slice(0, -1));\r\n }\r\n }\r\n\r\n // Re-measure the open menu's content height when stack history changes\r\n useEffect(() => {\r\n if (!isOpen) return;\r\n\r\n requestAnimationFrame(() => {\r\n if (contentRef.current) {\r\n setContentHeight(contentRef.current.scrollHeight + 12);\r\n }\r\n });\r\n }, [isOpen, stackHistory, hasContent]);\r\n\r\n // Reset content height when menu closes or is closing\r\n useEffect(() => {\r\n if (!isOpen || isClosing) {\r\n setContentHeight(0);\r\n }\r\n }, [isOpen, isClosing]);\r\n\r\n if (!isOpen && !isClosing) return null;\r\n\r\n return (\r\n <ScreenOverlay fadeIn ref={overlayRef}>\r\n <DropdownMenu.Root\r\n modal\r\n open={isOpen}\r\n onOpenChange={(open) => {\r\n if (!open) handleClose();\r\n }}\r\n >\r\n <DropdownMenu.Trigger asChild>\r\n {/* No visible trigger, menu is controlled by isOpen */}\r\n <div>{\"\"}</div>\r\n </DropdownMenu.Trigger>\r\n\r\n <div\r\n className=\"proton-ActionMenu__background-wrapper\"\r\n style={{ opacity: isClosing ? 0 : 1 }}\r\n >\r\n <div\r\n data-testid={testId || \"ActionMenu-wrapper\"}\r\n className=\"proton-ActionMenu__wrapper\"\r\n >\r\n <div\r\n className=\"proton-ActionMenu__card\"\r\n data-testid=\"ActionMenu-content\"\r\n style={{ height: `${contentHeight}px` }}\r\n >\r\n <div ref={menuRef} className=\"proton-ActionMenu__menu\">\r\n <DropdownMenu.Content loop sideOffset={8} ref={contentRef}>\r\n {hasContent && (\r\n <>\r\n {children && (\r\n <div className=\"proton-ActionMenu__content\">\r\n {typeof children === \"function\"\r\n ? children({ close: handleClose })\r\n : children}\r\n </div>\r\n )}\r\n\r\n {hasActions && (\r\n <ActionMenuList\r\n actions={currentActions}\r\n selectionMode={selectionMode}\r\n selectedKeys={selectedKeys}\r\n onSelectionChange={onSelectionChange}\r\n disabledKeys={disabledKeys}\r\n handleSubmenuOpen={handleSubmenuOpen}\r\n title={currentActionStack.title}\r\n isInSubmenu={isInSubmenu}\r\n handleBack={handleBack}\r\n previousMenuTitle={\r\n stackHistory[stackHistory.length - 1]?.title\r\n }\r\n />\r\n )}\r\n\r\n {showCancel && (\r\n <>\r\n <DropdownMenu.Separator />\r\n <DropdownMenu.Item className=\"proton-ActionMenu__cancel-button\">\r\n <Button\r\n data-testid=\"ActionMenuItem-cancel\"\r\n onPress={handleClose}\r\n fullWidth\r\n variant=\"secondary\"\r\n >\r\n {cancelButtonText}\r\n </Button>\r\n </DropdownMenu.Item>\r\n </>\r\n )}\r\n </>\r\n )}\r\n </DropdownMenu.Content>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </DropdownMenu.Root>\r\n </ScreenOverlay>\r\n );\r\n};\r\n\r\ninterface ActionMenuListProps {\r\n actions: ActionMenuAction[];\r\n selectionMode: ActionMenuSelectionMode;\r\n selectedKeys?: string[];\r\n onSelectionChange?: (keys: Selection) => void;\r\n disabledKeys?: string[];\r\n handleSubmenuOpen: (key: string) => void;\r\n title?: ReactNode;\r\n isInSubmenu?: boolean;\r\n handleBack?: () => void;\r\n previousMenuTitle?: ReactNode;\r\n}\r\n\r\nconst ActionMenuList = ({\r\n actions,\r\n selectionMode,\r\n selectedKeys = [],\r\n onSelectionChange,\r\n disabledKeys = [],\r\n handleSubmenuOpen,\r\n title,\r\n isInSubmenu = false,\r\n handleBack,\r\n previousMenuTitle,\r\n}: ActionMenuListProps) => {\r\n const ActionMenuItemMap = () => (\r\n <>\r\n {isInSubmenu && handleBack && (\r\n <div className=\"proton-ActionMenu__back-button-container\">\r\n <DropdownMenu.Item\r\n className=\"proton-ActionMenu__back-button\"\r\n onSelect={(event) => {\r\n event.preventDefault();\r\n handleBack();\r\n }}\r\n aria-label={`Go back to ${previousMenuTitle || \"previous menu\"}`}\r\n >\r\n <Icon id=\"chevron-left\" size={16} aria-hidden=\"true\" />\r\n </DropdownMenu.Item>\r\n <div\r\n className=\"proton-ActionMenu__title\"\r\n role=\"banner\"\r\n aria-label={isInSubmenu ? `Submenu: ${title}` : `Menu: ${title}`}\r\n >\r\n <span>{title}</span>\r\n </div>\r\n <DropdownMenu.Separator />\r\n </div>\r\n )}\r\n\r\n {actions.map((action, i) => {\r\n const itemProps = actions[i];\r\n return (\r\n <ActionMenuItem\r\n key={action.key}\r\n item={action}\r\n isSubmenu={Boolean(itemProps.children?.length)}\r\n selectionMode={selectionMode}\r\n onSelectionChange={onSelectionChange}\r\n selectedKeys={selectedKeys}\r\n disabledKeys={disabledKeys}\r\n handleSubmenuOpen={handleSubmenuOpen}\r\n />\r\n );\r\n })}\r\n </>\r\n );\r\n\r\n return (\r\n <div\r\n aria-disabled={selectionMode === \"none\"}\r\n className=\"proton-ActionMenu__list\"\r\n role=\"menu\"\r\n aria-label={\r\n title ? `${isInSubmenu ? \"Submenu\" : \"Menu\"}: ${title}` : \"Action menu\"\r\n }\r\n aria-orientation=\"vertical\"\r\n >\r\n {selectionMode === \"single\" ? (\r\n <DropdownMenu.RadioGroup\r\n value={selectedKeys?.[0] || \"\"}\r\n onValueChange={(value) => {\r\n // Check if this is a submenu item - if so, don't trigger selection change\r\n const action = actions.find((action) => action.key === value);\r\n if (action?.children?.length) {\r\n return;\r\n }\r\n\r\n if (onSelectionChange) {\r\n onSelectionChange(new Set([value]));\r\n }\r\n }}\r\n >\r\n <ActionMenuItemMap />\r\n </DropdownMenu.RadioGroup>\r\n ) : (\r\n <DropdownMenu.Group>\r\n <ActionMenuItemMap />\r\n </DropdownMenu.Group>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\ninterface ActionMenuItemProps {\r\n to?: string;\r\n item: ActionMenuAction;\r\n isSubmenu?: boolean;\r\n selectionMode: ActionMenuSelectionMode;\r\n onSelectionChange?: (keys: Selection) => void;\r\n selectedKeys?: string[];\r\n disabledKeys?: string[];\r\n handleSubmenuOpen: (key: string) => void;\r\n}\r\n\r\nconst ActionMenuItem = ({\r\n item,\r\n isSubmenu,\r\n selectionMode,\r\n onSelectionChange,\r\n selectedKeys = [],\r\n disabledKeys = [],\r\n handleSubmenuOpen,\r\n}: ActionMenuItemProps) => {\r\n const ref = useRef(null);\r\n const isExternal = item.to && isUrlExternal(item.to);\r\n const isDisabled = disabledKeys.includes(item.key);\r\n const isSelected = selectedKeys.includes(item.key);\r\n\r\n const radixItemProps = {\r\n className: \"proton-ActionMenu__item\",\r\n \"aria-label\": item.label\r\n ? `${item.label}${item.description ? `, ${item.description}` : \"\"}`\r\n : `ActionMenu-Item-${item.key}`,\r\n role: \"menuitem\",\r\n disabled: isDisabled,\r\n ref,\r\n };\r\n\r\n const onSelect = (event: Event) => {\r\n if (item?.children?.length) {\r\n event.preventDefault();\r\n handleSubmenuOpen(item.key);\r\n return;\r\n }\r\n if (item.onAction) {\r\n item.onAction(item.key);\r\n }\r\n };\r\n\r\n const content = (\r\n <>\r\n <div className=\"proton-ActionMenu__item-content\">\r\n <div className=\"proton-ActionMenu__item-label\">{item.label}</div>\r\n {item.description && (\r\n <div className=\"proton-ActionMenu__description\">\r\n {item.description}\r\n </div>\r\n )}\r\n </div>\r\n {isSubmenu && <Icon id=\"chevron-right\" size={16} aria-hidden=\"true\" />}\r\n </>\r\n );\r\n\r\n if (item.to) {\r\n return (\r\n <DropdownMenu.Item {...radixItemProps} key={item.key} asChild>\r\n <a\r\n aria-label={\r\n item.label\r\n ? `${item.label}${item.description ? `, ${item.description}` : \"\"}`\r\n : `ActionMenu-Item-${item.key}`\r\n }\r\n aria-disabled={isDisabled}\r\n aria-checked={isSelected}\r\n aria-expanded={isSubmenu ? false : undefined}\r\n href={item.to}\r\n target={isExternal ? \"_blank\" : undefined}\r\n rel={isExternal ? \"noopener noreferrer\" : undefined}\r\n onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {\r\n if (isExternal || !item.to) {\r\n return;\r\n }\r\n handleInternalNavigation(e, item.to);\r\n }}\r\n >\r\n {content}\r\n </a>\r\n </DropdownMenu.Item>\r\n );\r\n }\r\n\r\n if (selectionMode === \"multiple\") {\r\n return (\r\n <DropdownMenu.CheckboxItem\r\n {...radixItemProps}\r\n key={item.key}\r\n checked={isSelected}\r\n onSelect={onSelect}\r\n onCheckedChange={(checked: boolean) => {\r\n if (!onSelectionChange) return;\r\n\r\n const currentKeys = new Set(selectedKeys);\r\n if (checked) {\r\n currentKeys.add(item.key);\r\n } else {\r\n currentKeys.delete(item.key);\r\n }\r\n onSelectionChange(currentKeys);\r\n }}\r\n >\r\n {content}\r\n </DropdownMenu.CheckboxItem>\r\n );\r\n }\r\n\r\n return (\r\n <DropdownMenu.RadioItem\r\n {...radixItemProps}\r\n value={item.key}\r\n key={item.key}\r\n aria-checked={isSelected}\r\n aria-expanded={isSubmenu ? false : undefined}\r\n onSelect={onSelect}\r\n >\r\n {content}\r\n </DropdownMenu.RadioItem>\r\n );\r\n};\r\n"],"names":["ActionMenu","isOpen","actions","children","showCancel","cancelButtonText","selectionMode","selectedKeys","disabledKeys","onSelectionChange","onClose","title","testId","useLockBodyScroll","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","Icon","i","itemProps","ActionMenuItem","value","item","isSubmenu","ref","isExternal","isUrlExternal","isDisabled","isSelected","radixItemProps","onSelect","content","createElement","e","handleInternalNavigation","checked","currentKeys"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.cjs.js","sources":["../../../src/components/Badge/Badge.tsx"],"sourcesContent":["\"use client\";\n\nimport { ReactNode } from \"react\";\nimport { csx } from \"../../utils\";\n\nimport \"./Badge.css\";\n\nexport type BadgeVariant =\n | \"primary\"\n | \"secondary\"\n | \"transparent\"\n | \"success\"\n | \"warning\"\n | \"danger\";\n\nexport const BadgeVariants: Record<BadgeVariant, BadgeVariant> = {\n primary: \"primary\",\n secondary: \"secondary\",\n transparent: \"transparent\",\n success: \"success\",\n warning: \"warning\",\n danger: \"danger\",\n};\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The content to display within the badge.\n */\n children: ReactNode;\n /**\n * The badge's visual aesthetic.\n * - type {@link BadgeVariant}\n */\n variant?: BadgeVariant;\n}\n\n/**\n * A badge component for displaying status, categories, or counts with various visual styles.\n *\n * API:\n * - {@link BadgeProps}\n * - extends {@link React.HTMLAttributes}\n */\nexport const Badge = ({ variant, children, ...props }: BadgeProps) => {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n data-testid={props[\"data-testid\"]}\n className={csx(\"proton-Badge\", variant && `proton-Badge--${variant}`)}\n >\n {children}\n </div>\n );\n};\n"],"names":["BadgeVariants","Badge","variant","children","props","jsx","csx"],"mappings":"0NAeaA,EAAoD,CAC/D,QAAS,UACT,UAAW,YACX,YAAa,cACb,QAAS,UACT,QAAS,UACT,OAAQ,QACV,EAqBaC,EAAQ,CAAC,CAAE,QAAAC,EAAS,SAAAC,EAAU,GAAGC,KAE1CC,EAAA,kBAAA,IAAC,MAAA,CACC,KAAK,SACL,YAAU,SACV,cAAaD,EAAM,aAAa,EAChC,UAAWE,EAAI,IAAA,eAAgBJ,GAAW,iBAAiBA,CAAO,EAAE,EAEnE,SAAAC,CAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"Badge.cjs.js","sources":["../../../src/components/Badge/Badge.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { ReactNode } from \"react\";\r\nimport { csx } from \"../../utils\";\r\n\r\nimport \"./Badge.css\";\r\n\r\nexport type BadgeVariant =\r\n | \"primary\"\r\n | \"secondary\"\r\n | \"transparent\"\r\n | \"success\"\r\n | \"warning\"\r\n | \"danger\";\r\n\r\nexport const BadgeVariants: Record<BadgeVariant, BadgeVariant> = {\r\n primary: \"primary\",\r\n secondary: \"secondary\",\r\n transparent: \"transparent\",\r\n success: \"success\",\r\n warning: \"warning\",\r\n danger: \"danger\",\r\n};\r\n\r\nexport interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {\r\n /**\r\n * The content to display within the badge.\r\n */\r\n children: ReactNode;\r\n /**\r\n * The badge's visual aesthetic.\r\n * - type {@link BadgeVariant}\r\n */\r\n variant?: BadgeVariant;\r\n}\r\n\r\n/**\r\n * A badge component for displaying status, categories, or counts with various visual styles.\r\n *\r\n * API:\r\n * - {@link BadgeProps}\r\n * - extends {@link React.HTMLAttributes}\r\n */\r\nexport const Badge = ({ variant, children, ...props }: BadgeProps) => {\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n data-testid={props[\"data-testid\"]}\r\n className={csx(\"proton-Badge\", variant && `proton-Badge--${variant}`)}\r\n >\r\n {children}\r\n </div>\r\n );\r\n};\r\n"],"names":["BadgeVariants","Badge","variant","children","props","jsx","csx"],"mappings":"0NAeaA,EAAoD,CAC/D,QAAS,UACT,UAAW,YACX,YAAa,cACb,QAAS,UACT,QAAS,UACT,OAAQ,QACV,EAqBaC,EAAQ,CAAC,CAAE,QAAAC,EAAS,SAAAC,EAAU,GAAGC,KAE1CC,EAAA,kBAAA,IAAC,MAAA,CACC,KAAK,SACL,YAAU,SACV,cAAaD,EAAM,aAAa,EAChC,UAAWE,EAAI,IAAA,eAAgBJ,GAAW,iBAAiBA,CAAO,EAAE,EAEnE,SAAAC,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.es.js","sources":["../../../src/components/Badge/Badge.tsx"],"sourcesContent":["\"use client\";\n\nimport { ReactNode } from \"react\";\nimport { csx } from \"../../utils\";\n\nimport \"./Badge.css\";\n\nexport type BadgeVariant =\n | \"primary\"\n | \"secondary\"\n | \"transparent\"\n | \"success\"\n | \"warning\"\n | \"danger\";\n\nexport const BadgeVariants: Record<BadgeVariant, BadgeVariant> = {\n primary: \"primary\",\n secondary: \"secondary\",\n transparent: \"transparent\",\n success: \"success\",\n warning: \"warning\",\n danger: \"danger\",\n};\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The content to display within the badge.\n */\n children: ReactNode;\n /**\n * The badge's visual aesthetic.\n * - type {@link BadgeVariant}\n */\n variant?: BadgeVariant;\n}\n\n/**\n * A badge component for displaying status, categories, or counts with various visual styles.\n *\n * API:\n * - {@link BadgeProps}\n * - extends {@link React.HTMLAttributes}\n */\nexport const Badge = ({ variant, children, ...props }: BadgeProps) => {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n data-testid={props[\"data-testid\"]}\n className={csx(\"proton-Badge\", variant && `proton-Badge--${variant}`)}\n >\n {children}\n </div>\n );\n};\n"],"names":["BadgeVariants","Badge","variant","children","props","jsx","csx"],"mappings":";;;AAeO,MAAMA,IAAoD;AAAA,EAC/D,SAAS;AAAA,EACT,WAAW;AAAA,EACX,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AACV,GAqBaC,IAAQ,CAAC,EAAE,SAAAC,GAAS,UAAAC,GAAU,GAAGC,QAE1CC,gBAAAA,EAAA;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,MAAK;AAAA,IACL,aAAU;AAAA,IACV,eAAaD,EAAM,aAAa;AAAA,IAChC,WAAWE,EAAI,gBAAgBJ,KAAW,iBAAiBA,CAAO,EAAE;AAAA,IAEnE,UAAAC;AAAA,EAAA;AAAA;"}
|
|
1
|
+
{"version":3,"file":"Badge.es.js","sources":["../../../src/components/Badge/Badge.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { ReactNode } from \"react\";\r\nimport { csx } from \"../../utils\";\r\n\r\nimport \"./Badge.css\";\r\n\r\nexport type BadgeVariant =\r\n | \"primary\"\r\n | \"secondary\"\r\n | \"transparent\"\r\n | \"success\"\r\n | \"warning\"\r\n | \"danger\";\r\n\r\nexport const BadgeVariants: Record<BadgeVariant, BadgeVariant> = {\r\n primary: \"primary\",\r\n secondary: \"secondary\",\r\n transparent: \"transparent\",\r\n success: \"success\",\r\n warning: \"warning\",\r\n danger: \"danger\",\r\n};\r\n\r\nexport interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {\r\n /**\r\n * The content to display within the badge.\r\n */\r\n children: ReactNode;\r\n /**\r\n * The badge's visual aesthetic.\r\n * - type {@link BadgeVariant}\r\n */\r\n variant?: BadgeVariant;\r\n}\r\n\r\n/**\r\n * A badge component for displaying status, categories, or counts with various visual styles.\r\n *\r\n * API:\r\n * - {@link BadgeProps}\r\n * - extends {@link React.HTMLAttributes}\r\n */\r\nexport const Badge = ({ variant, children, ...props }: BadgeProps) => {\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n data-testid={props[\"data-testid\"]}\r\n className={csx(\"proton-Badge\", variant && `proton-Badge--${variant}`)}\r\n >\r\n {children}\r\n </div>\r\n );\r\n};\r\n"],"names":["BadgeVariants","Badge","variant","children","props","jsx","csx"],"mappings":";;;AAeO,MAAMA,IAAoD;AAAA,EAC/D,SAAS;AAAA,EACT,WAAW;AAAA,EACX,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AACV,GAqBaC,IAAQ,CAAC,EAAE,SAAAC,GAAS,UAAAC,GAAU,GAAGC,QAE1CC,gBAAAA,EAAA;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,MAAK;AAAA,IACL,aAAU;AAAA,IACV,eAAaD,EAAM,aAAa;AAAA,IAChC,WAAWE,EAAI,gBAAgBJ,KAAW,iBAAiBA,CAAO,EAAE;AAAA,IAEnE,UAAAC;AAAA,EAAA;AAAA;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("../../node_modules/react/jsx-runtime.cjs.js"),o=require("react"),h=require("../Button/Button.cjs.js");;/* empty css */const a=require("../../utils/string.cjs.js"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("../../node_modules/react/jsx-runtime.cjs.js"),o=require("react"),h=require("../Button/Button.cjs.js");;/* empty css */const a=require("../../utils/string.cjs.js"),x={success:n.jsxRuntimeExports.jsx("svg",{viewBox:"0 0 20 20",height:"18",width:"18",children:n.jsxRuntimeExports.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"})}),warning:n.jsxRuntimeExports.jsx("svg",{viewBox:"0 0 56 56",height:"17",width:"17",children:n.jsxRuntimeExports.jsx("path",{d:"M9.59 50.207h36.82c3.516 0 5.719-2.531 5.719-5.719a5.56 5.56 0 0 0-.75-2.812l-18.445-33c-1.055-1.899-2.977-2.883-4.922-2.883c-1.922 0-3.89.984-4.946 2.883L4.645 41.699c-.516.89-.774 1.828-.774 2.79c0 3.187 2.227 5.718 5.719 5.718m18.422-16.055c-1.242 0-1.922-.703-1.969-1.968l-.328-11.578c-.047-1.266.937-2.204 2.273-2.204c1.313 0 2.344.961 2.297 2.227l-.351 11.555c-.047 1.289-.727 1.968-1.922 1.968m0 8.649c-1.36 0-2.625-1.078-2.625-2.532s1.242-2.53 2.625-2.53s2.625 1.054 2.625 2.53c0 1.477-1.266 2.532-2.625 2.532"})}),danger:n.jsxRuntimeExports.jsx("svg",{viewBox:"0 0 20 20",height:"18",width:"18",children:n.jsxRuntimeExports.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z"})})},N={default:"default",success:"success",warning:"warning",danger:"danger"},c=o.createContext(void 0),s=({variant:t="default",rounded:e=!0,icon:r=!1,compact:i=!0,children:m,"data-testid":j})=>n.jsxRuntimeExports.jsx(c.Provider,{value:t,children:n.jsxRuntimeExports.jsx("div",{role:"status","aria-live":"polite",className:a.csx("proton-Banner",`proton-Banner--${t}`,e&&"proton-Banner--rounded"),"data-testid":j,children:n.jsxRuntimeExports.jsxs("div",{className:a.csx("proton-Banner__wrapper",i&&"proton-Banner__wrapper--compact"),children:[n.jsxRuntimeExports.jsx(s.Icon,{icon:r}),n.jsxRuntimeExports.jsx("div",{className:"proton-Banner__content-wrapper",children:n.jsxRuntimeExports.jsx("div",{className:"proton-Banner__container",children:m})})]})})});s.displayName="Banner";const d=({children:t,"data-testid":e})=>{const r=o.useContext(c);if(!r)throw new Error("BannerTitle must be used within a Banner");return n.jsxRuntimeExports.jsx("h3",{className:a.csx("proton-Banner__title",`proton-Banner--${r}__title`),"data-testid":e,children:t})};d.displayName="Banner.Title";const u=({children:t,"data-testid":e})=>{const r=o.useContext(c);if(!r)throw new Error("BannerContent must be used within a Banner");return n.jsxRuntimeExports.jsx("p",{className:a.csx("proton-Banner__content",`proton-Banner--${r}__content`),"data-testid":e,children:t})};u.displayName="Banner.Content";function R(t,e){return o.isValidElement(t)?t:t?x[e]:null}const l=({icon:t,"data-testid":e})=>{const r=o.useContext(c);if(!r)throw new Error("BannerIcon must be used within a Banner");const i=R(t,r);return i?n.jsxRuntimeExports.jsx("div",{"aria-hidden":"true","data-testid":e,className:a.csx("proton-Banner__icon",`proton-Banner--${r}__icon`),children:i}):null};l.displayName="Banner.Icon";const p=({children:t,...e})=>n.jsxRuntimeExports.jsx(h.Button,{...e,children:t});p.displayName="Banner.Action";const B=({children:t})=>n.jsxRuntimeExports.jsx("div",{className:"proton-Banner__actions",children:t});B.displayName="Banner.Actions";s.Title=d;s.Content=u;s.Icon=l;s.Action=p;s.Actions=B;exports.BANNER_ICONS=x;exports.BANNER_VARIANTS=N;exports.Banner=s;
|
|
2
2
|
//# sourceMappingURL=Banner.cjs.js.map
|