@wavv/ui 2.3.9 → 2.3.10

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.
@@ -0,0 +1,20 @@
1
+ import { type FileTriggerProps } from 'react-aria-components';
2
+ import type { IconType } from './helpers/getIcon';
3
+ import type { MarginPadding } from './types';
4
+ type Props = {
5
+ /** Size of the avatar in pixels */
6
+ size?: number;
7
+ /** URL of the avatar image */
8
+ url?: string;
9
+ /** Icon to display as fallback when no URL or initials are provided */
10
+ icon?: IconType;
11
+ /** Initials string to display as fallback when no URL is provided */
12
+ initials?: string;
13
+ /** File upload props - if provided, enables file upload functionality */
14
+ acceptedFileTypes?: FileTriggerProps['acceptedFileTypes'];
15
+ /** Callback when a file is selected */
16
+ onSelect?: FileTriggerProps['onSelect'];
17
+ onRemove?: () => void;
18
+ } & MarginPadding & Pick<FileTriggerProps, 'acceptedFileTypes' | 'onSelect'>;
19
+ declare const Avatar: ({ size, url, icon, initials, acceptedFileTypes, onSelect, onRemove, ...props }: Props) => import("react/jsx-runtime").JSX.Element;
20
+ export default Avatar;
@@ -0,0 +1,128 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import styled from "@emotion/styled";
3
+ import { FileTrigger } from "react-aria-components";
4
+ import Button from "./Button/index.js";
5
+ import getIcon from "./helpers/getIcon.js";
6
+ import { marginProps, paddingProps } from "./helpers/styledProps.js";
7
+ const Avatar = ({ size = 32, url, icon, initials, acceptedFileTypes, onSelect, onRemove, ...props })=>{
8
+ const imageSize = size - 4;
9
+ const hasUpload = !!acceptedFileTypes || !!onSelect;
10
+ const displayMode = url ? 'image' : initials ? 'initials' : icon ? 'icon' : 'placeholder';
11
+ const isInitials = 'initials' === displayMode;
12
+ const isImage = 'image' === displayMode;
13
+ const isPlaceholder = 'placeholder' === displayMode;
14
+ const isIcon = 'icon' === displayMode;
15
+ const iconSize = Math.max(12, Math.floor(0.5 * size));
16
+ const fontSize = Math.max(10, Math.floor(0.375 * size));
17
+ const hasRemove = !!(onRemove && url);
18
+ const content = /*#__PURE__*/ jsxs(AvatarContainer, {
19
+ size: size,
20
+ isImage: isImage,
21
+ isPlaceholder: isPlaceholder,
22
+ ...props,
23
+ children: [
24
+ isImage && url && /*#__PURE__*/ jsx(AvatarImg, {
25
+ url: url,
26
+ size: imageSize
27
+ }),
28
+ isInitials && /*#__PURE__*/ jsx(InitialText, {
29
+ fontSize: fontSize,
30
+ children: initials
31
+ }),
32
+ isIcon && icon && /*#__PURE__*/ jsx(IconWrapper, {
33
+ children: getIcon(icon, {
34
+ size: iconSize
35
+ })
36
+ }),
37
+ hasUpload && /*#__PURE__*/ jsxs(ButtonContainer, {
38
+ children: [
39
+ /*#__PURE__*/ jsx(FileTrigger, {
40
+ acceptedFileTypes: acceptedFileTypes,
41
+ onSelect: onSelect,
42
+ children: /*#__PURE__*/ jsx(Button, {
43
+ small: true,
44
+ outline: true,
45
+ icon: hasRemove ? 'cycle' : 'upload',
46
+ children: hasRemove ? 'Change' : 'Upload'
47
+ })
48
+ }),
49
+ hasRemove && /*#__PURE__*/ jsx(Button, {
50
+ small: true,
51
+ outline: true,
52
+ icon: "trash",
53
+ onClick: onRemove,
54
+ children: "Remove"
55
+ })
56
+ ]
57
+ })
58
+ ]
59
+ });
60
+ return content;
61
+ };
62
+ const ButtonContainer = styled.div(({ theme })=>({
63
+ display: 'flex',
64
+ flexDirection: 'column',
65
+ gap: 8,
66
+ alignItems: 'center',
67
+ justifyContent: 'center',
68
+ position: 'absolute',
69
+ top: 0,
70
+ left: 0,
71
+ width: '100%',
72
+ height: '100%',
73
+ backgroundColor: theme.color.grayscale9,
74
+ borderRadius: '50%',
75
+ opacity: 0,
76
+ visibility: 'hidden',
77
+ transition: 'opacity 0.2s ease, visibility 0.2s ease',
78
+ overflow: 'hidden'
79
+ }));
80
+ const AvatarContainer = styled.div(({ theme, size, isImage, isPlaceholder })=>{
81
+ const { scale2, scale4 } = theme;
82
+ return {
83
+ display: 'flex',
84
+ justifyContent: 'center',
85
+ alignItems: 'center',
86
+ height: size,
87
+ width: size,
88
+ border: `1px solid ${scale4}`,
89
+ borderRadius: '50%',
90
+ flexShrink: 0,
91
+ position: 'relative',
92
+ ...isPlaceholder && {
93
+ backgroundColor: scale2
94
+ },
95
+ ...isImage && {
96
+ backgroundColor: 'transparent'
97
+ },
98
+ '&:hover': {
99
+ [`${ButtonContainer}`]: {
100
+ opacity: 1,
101
+ visibility: 'visible'
102
+ }
103
+ }
104
+ };
105
+ }, marginProps, paddingProps);
106
+ const AvatarImg = styled.div(({ size, url })=>({
107
+ height: size,
108
+ width: size,
109
+ borderRadius: '50%',
110
+ backgroundImage: `url(${url})`,
111
+ backgroundRepeat: 'no-repeat',
112
+ backgroundSize: 'cover',
113
+ backgroundPosition: 'center',
114
+ flexShrink: 0
115
+ }));
116
+ const InitialText = styled.div(({ theme, fontSize })=>({
117
+ fontSize,
118
+ color: theme.scale10,
119
+ fontWeight: theme.font.weight.bold,
120
+ userSelect: 'none'
121
+ }));
122
+ const IconWrapper = styled.div({
123
+ display: 'flex',
124
+ alignItems: 'center',
125
+ justifyContent: 'center'
126
+ });
127
+ const components_Avatar = Avatar;
128
+ export { components_Avatar as default };
@@ -9,6 +9,7 @@ type ElAttributes = Omit<Attributes<HTMLButtonElement>, 'type' | 'size' | 'onCli
9
9
  } & AsProp & Omit<ButtonProps, 'isDisabled'>;
10
10
  type ButtonBaseProps = {
11
11
  children?: ReactNode;
12
+ /** Controls how buttons are joined together in a group (left, right, or middle) */
12
13
  joined?: 'left' | 'right' | 'middle';
13
14
  hideJoinedBorder?: boolean;
14
15
  joinedPadding?: number;
@@ -142,6 +143,5 @@ export type ButtonDropdownProps = {
142
143
  export type ButtonComponentProps = {
143
144
  /** Sets the text of the button */
144
145
  content?: string;
145
- joined?: never;
146
146
  } & BasicButtonProps & DropdownProps & Margin;
147
147
  export {};
@@ -25,6 +25,8 @@ type ModalProps = {
25
25
  overflow?: CSSProperties['overflow'];
26
26
  /** Removes the overlay background, and allows the modal to be positioned anywhere on the page */
27
27
  noOverlay?: boolean;
28
+ /** Removes the background color of the modal container */
29
+ noBackground?: boolean;
28
30
  /** Prevents the modal from being interacted with */
29
31
  inert?: boolean;
30
32
  /** Renders the Modal as a full-height sliding drawer */
@@ -53,7 +55,7 @@ type ModalProps = {
53
55
  'aria-label'?: string;
54
56
  } & WidthHeight & MaxWidthHeight & MinWidthHeight & Padding & DivAttributes;
55
57
  declare const Modal: {
56
- ({ children, visible, width, height, onClose, closeIcon, preventOverlayClose, overlayBlur, overlayColor, backgroundColor, noOverlay, inert, drawer, drawerDirection, scopeRef, centerX, centerY, position, top, bottom, right, left, zIndex, ...props }: ModalProps): import("react/jsx-runtime").JSX.Element;
58
+ ({ children, visible, width, height, onClose, closeIcon, preventOverlayClose, overlayBlur, overlayColor, backgroundColor, noOverlay, noBackground, inert, drawer, drawerDirection, scopeRef, centerX, centerY, position, top, bottom, right, left, zIndex, ...props }: ModalProps): import("react/jsx-runtime").JSX.Element;
57
59
  Header: {
58
60
  ({ children, ...props }: HeaderProps): import("react/jsx-runtime").JSX.Element;
59
61
  displayName: string;
@@ -5,7 +5,7 @@ import { Dialog, Heading, Modal, ModalOverlay } from "react-aria-components";
5
5
  import { marginProps, maxWidthHeightProps, minWidthHeightProps, paddingProps } from "./helpers/styledProps.js";
6
6
  import Icon from "./Icon/index.js";
7
7
  import PortalScope from "./PortalScope.js";
8
- const Modal_Modal = ({ children, visible, width, height, onClose, closeIcon, preventOverlayClose, overlayBlur = true, overlayColor, backgroundColor, noOverlay, inert, drawer, drawerDirection = 'right', scopeRef, centerX, centerY, position, top, bottom, right, left, zIndex, ...props })=>{
8
+ const Modal_Modal = ({ children, visible, width, height, onClose, closeIcon, preventOverlayClose, overlayBlur = true, overlayColor, backgroundColor, noOverlay, noBackground, inert, drawer, drawerDirection = 'right', scopeRef, centerX, centerY, position, top, bottom, right, left, zIndex, ...props })=>{
9
9
  const { 'aria-label': ariaLabel, ...rest } = props;
10
10
  const handleOpenChange = (open)=>{
11
11
  if (!open) onClose();
@@ -41,6 +41,7 @@ const Modal_Modal = ({ children, visible, width, height, onClose, closeIcon, pre
41
41
  width: width,
42
42
  height: height,
43
43
  backgroundColor: backgroundColor,
44
+ noBackground: noBackground,
44
45
  noOverlay: noOverlay,
45
46
  drawer: drawer,
46
47
  drawerDirection: drawerDirection,
@@ -114,15 +115,19 @@ const ModalFooter = styled.div(({ justify = 'end', gap })=>{
114
115
  gap
115
116
  };
116
117
  }, marginProps);
117
- const ModalContainer = styled.div(({ theme, width, height, backgroundColor, borderRadius, overflow, drawer, drawerDirection })=>({
118
+ const ModalContainer = styled.div(({ theme, width, height, backgroundColor, borderRadius, overflow, drawer, drawerDirection, noBackground })=>({
118
119
  display: 'flex',
119
120
  flexDirection: 'column',
120
- backgroundColor: backgroundColor || theme.modal.background,
121
+ backgroundColor: noBackground ? 'transparent' : backgroundColor || theme.modal.background,
121
122
  color: theme.scale10,
122
- boxShadow: drawer ? 'left' === drawerDirection ? '8px 0 20px rgba(0, 0, 0, 0.2)' : '-8px 0 20px rgba(0, 0, 0, 0.2)' : theme.elevation3,
123
+ boxShadow: noBackground ? void 0 : drawer ? 'left' === drawerDirection ? '8px 0 20px rgba(0, 0, 0, 0.2)' : '-8px 0 20px rgba(0, 0, 0, 0.2)' : theme.elevation3,
123
124
  width: width || 'max-content',
124
125
  height: drawer ? height || '100%' : height || 'max-content',
125
126
  borderRadius: drawer ? 0 : borderRadius || theme.size.sm,
127
+ borderTopLeftRadius: drawer && 'right' === drawerDirection ? borderRadius || theme.size.sm : void 0,
128
+ borderBottomLeftRadius: drawer && 'right' === drawerDirection ? borderRadius || theme.size.sm : void 0,
129
+ borderTopRightRadius: drawer && 'left' === drawerDirection ? borderRadius || theme.size.sm : void 0,
130
+ borderBottomRightRadius: drawer && 'left' === drawerDirection ? borderRadius || theme.size.sm : void 0,
126
131
  padding: theme.size.lg,
127
132
  overflow: overflow || 'hidden'
128
133
  }), ({ noOverlay, drawer })=>!noOverlay && !drawer && {
package/build/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { default as Accordion } from './components/Accordion';
2
+ export { default as Avatar } from './components/Avatar';
2
3
  export { default as Audio } from './components/Audio';
3
4
  export { default as BarChart } from './components/BarChart';
4
5
  export { default as Button } from './components/Button';
package/build/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import Accordion from "./components/Accordion/index.js";
2
+ import Avatar from "./components/Avatar.js";
2
3
  import Audio from "./components/Audio.js";
3
4
  import BarChart from "./components/BarChart.js";
4
5
  import Button from "./components/Button/index.js";
@@ -80,4 +81,4 @@ import formatDate from "./utils/formatDate.js";
80
81
  import formatNumber from "./utils/formatNumber.js";
81
82
  import numberWithCommas from "./utils/numberWithCommas.js";
82
83
  import matchesFileTypes from "./utils/matchesFileTypes.js";
83
- export { Accordion, Audio, BarChart, Button, Calendar, Checkbox, Code, ComboBox, CommandMenu, DatePicker, DateRangePicker, DateRangeSelect, DocTable, Dot, DraftEditor, DropZone, Dropdown, DropdownMenu, DropdownSelect, Editor, Ellipsis, FileTrigger, Form, Grid, Icon, ImageViewer, InlineCode, InlineInput, InputHelpers as InputUtils, Label, LineChart, Menu, Message, MessageHr, Modal, MultiSelect, NumberInput, Pagination, PhoneInput, PieChart, Popover, PortalScope, Progress, Radio, RangeCalendar, ResetStyles, ScrollbarStyles, SearchInput, Select, Slider, Spinner, Table, Tabs, Tag, TextArea, TextInput, TimeInput, ToastStyles, Toggle, ToggleButton, ToggleButtonGroup, Tooltip, TransferList, Tree, UnstyledButton, colors, copyToClipboard, createEditorContent, darkScale, editorContentToText, formatDate, formatNumber, lightScale, marginProps, matchesFileTypes, numberWithCommas, paddingProps, positionProps, theme, themeClasses, themeOptions, useConfirm, useCopy, useElementObserver, useEventListener, useOnClickOutside, usePrevious, useSelectAll, useWindowSize, widthHeightProps };
84
+ export { Accordion, Audio, Avatar, BarChart, Button, Calendar, Checkbox, Code, ComboBox, CommandMenu, DatePicker, DateRangePicker, DateRangeSelect, DocTable, Dot, DraftEditor, DropZone, Dropdown, DropdownMenu, DropdownSelect, Editor, Ellipsis, FileTrigger, Form, Grid, Icon, ImageViewer, InlineCode, InlineInput, InputHelpers as InputUtils, Label, LineChart, Menu, Message, MessageHr, Modal, MultiSelect, NumberInput, Pagination, PhoneInput, PieChart, Popover, PortalScope, Progress, Radio, RangeCalendar, ResetStyles, ScrollbarStyles, SearchInput, Select, Slider, Spinner, Table, Tabs, Tag, TextArea, TextInput, TimeInput, ToastStyles, Toggle, ToggleButton, ToggleButtonGroup, Tooltip, TransferList, Tree, UnstyledButton, colors, copyToClipboard, createEditorContent, darkScale, editorContentToText, formatDate, formatNumber, lightScale, marginProps, matchesFileTypes, numberWithCommas, paddingProps, positionProps, theme, themeClasses, themeOptions, useConfirm, useCopy, useElementObserver, useEventListener, useOnClickOutside, usePrevious, useSelectAll, useWindowSize, widthHeightProps };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wavv/ui",
3
- "version": "2.3.9",
3
+ "version": "2.3.10",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -44,16 +44,16 @@
44
44
  "cmdk": "^1.1.1",
45
45
  "date-fns": "^4.1.0",
46
46
  "draft-js": "^0.11.7",
47
- "es-toolkit": "^1.42.0",
47
+ "es-toolkit": "^1.43.0",
48
48
  "libphonenumber-js": "^1.12.31",
49
- "lucide-react": "^0.556.0",
49
+ "lucide-react": "^0.561.0",
50
50
  "polished": "^4.1.4",
51
51
  "prism-react-renderer": "^2.4.1",
52
52
  "react-aria": "3.44.0",
53
53
  "react-aria-components": "1.13.0",
54
54
  "react-keyed-flatten-children": "^5.1.1",
55
55
  "react-phone-input-auto-format": "^0.1.0",
56
- "recharts": "^3.5.1",
56
+ "recharts": "^3.6.0",
57
57
  "sanitize.css": "^13.0.0",
58
58
  "webfontloader": "^1.6.28"
59
59
  },
@@ -61,17 +61,17 @@
61
61
  "@babel/core": "^7.28.5",
62
62
  "@babel/preset-env": "^7.28.5",
63
63
  "@babel/preset-typescript": "^7.28.5",
64
- "@biomejs/biome": "2.3.8",
64
+ "@biomejs/biome": "2.3.9",
65
65
  "@chromatic-com/storybook": "^4.1.3",
66
66
  "@emotion/babel-plugin": "^11.13.5",
67
67
  "@emotion/react": "^11.14.0",
68
- "@rsbuild/core": "1.6.12",
68
+ "@rsbuild/core": "1.6.14",
69
69
  "@rsbuild/plugin-react": "^1.4.2",
70
- "@rsbuild/plugin-svgr": "^1.2.2",
71
- "@rslib/core": "^0.18.3",
72
- "@storybook/addon-docs": "^10.1.4",
73
- "@storybook/addon-links": "^10.1.4",
74
- "@storybook/addon-themes": "^10.1.4",
70
+ "@rsbuild/plugin-svgr": "^1.2.3",
71
+ "@rslib/core": "^0.18.4",
72
+ "@storybook/addon-docs": "^10.1.9",
73
+ "@storybook/addon-links": "^10.1.9",
74
+ "@storybook/addon-themes": "^10.1.9",
75
75
  "@storybook/test-runner": "^0.24.2",
76
76
  "@svgr/core": "^8.1.0",
77
77
  "@svgr/plugin-jsx": "^8.1.0",
@@ -80,7 +80,7 @@
80
80
  "@types/draft-js": "^0.11.20",
81
81
  "@types/jest": "^30.0.0",
82
82
  "@types/ncp": "^2.0.8",
83
- "@types/node": "^24.10.1",
83
+ "@types/node": "^25.0.2",
84
84
  "@types/prompts": "^2.4.9",
85
85
  "@types/randomcolor": "^0.5.9",
86
86
  "@types/react": "^19.2.7",
@@ -91,20 +91,20 @@
91
91
  "change-case": "^5.4.4",
92
92
  "chromatic": "^13.3.4",
93
93
  "jest": "^30.2.0",
94
- "lefthook": "^2.0.8",
94
+ "lefthook": "^2.0.12",
95
95
  "ncp": "^2.0.0",
96
96
  "path": "^0.12.7",
97
- "phone": "^3.1.67",
97
+ "phone": "^3.1.68",
98
98
  "playwright": "^1.57.0",
99
99
  "postcss": "^8.5.6",
100
100
  "prettier": "^3.7.4",
101
101
  "prompts": "^2.4.2",
102
102
  "randomcolor": "^0.6.2",
103
- "react": "^19.2.1",
104
- "react-dom": "^19.2.1",
103
+ "react": "^19.2.3",
104
+ "react-dom": "^19.2.3",
105
105
  "replace": "^1.2.2",
106
106
  "signale": "^1.4.0",
107
- "storybook": "^10.1.4",
107
+ "storybook": "^10.1.9",
108
108
  "storybook-react-rsbuild": "^3.1.0",
109
109
  "tsc-files": "^1.1.4",
110
110
  "tslib": "^2.8.1",