@uxf/ui 11.100.0 → 11.101.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/components.d.ts CHANGED
@@ -40,6 +40,7 @@ import * as lightboxStories from "./lightbox/lightbox.stories";
40
40
  import * as listItemStories from "./list-item/list-item.stories";
41
41
  import * as loaderStories from "./loader/loader.stories";
42
42
  import * as lozengeStories from "./lozenge/lozenge.stories";
43
+ import * as menuStories from "./menu/menu.stories";
43
44
  import * as messageStories from "./message/message.stories";
44
45
  import * as modalStories from "./modal/modal.stories";
45
46
  import * as modalDialogStories from "./modal-dialog/modal-dialog.stories";
@@ -48,6 +49,7 @@ import * as multiComboboxStories from "./multi-combobox/multi-combobox.stories";
48
49
  import * as multiSelectStories from "./multi-select/multi-select.stories";
49
50
  import * as paginationStories from "./pagination/pagination.stories";
50
51
  import * as paperStories from "./paper/paper.stories";
52
+ import * as popoverStories from "./popover/popover.stories";
51
53
  import * as radioStories from "./radio/radio.stories";
52
54
  import * as radioGroupStories from "./radio-group/radio-group.stories";
53
55
  import * as rasterImageStories from "./raster-image/raster-image.stories";
@@ -230,6 +232,10 @@ export declare const components: {
230
232
  readonly title: "Lozenge";
231
233
  readonly stories: typeof lozengeStories;
232
234
  };
235
+ readonly menu: {
236
+ readonly title: "Menu";
237
+ readonly stories: typeof menuStories;
238
+ };
233
239
  readonly message: {
234
240
  readonly title: "Message";
235
241
  readonly stories: typeof messageStories;
@@ -262,6 +268,10 @@ export declare const components: {
262
268
  readonly title: "Paper";
263
269
  readonly stories: typeof paperStories;
264
270
  };
271
+ readonly popover: {
272
+ readonly title: "Popover";
273
+ readonly stories: typeof popoverStories;
274
+ };
265
275
  readonly radio: {
266
276
  readonly title: "Radio";
267
277
  readonly stories: typeof radioStories;
package/components.js CHANGED
@@ -77,6 +77,7 @@ const lightboxStories = __importStar(require("./lightbox/lightbox.stories"));
77
77
  const listItemStories = __importStar(require("./list-item/list-item.stories"));
78
78
  const loaderStories = __importStar(require("./loader/loader.stories"));
79
79
  const lozengeStories = __importStar(require("./lozenge/lozenge.stories"));
80
+ const menuStories = __importStar(require("./menu/menu.stories"));
80
81
  const messageStories = __importStar(require("./message/message.stories"));
81
82
  const modalStories = __importStar(require("./modal/modal.stories"));
82
83
  const modalDialogStories = __importStar(require("./modal-dialog/modal-dialog.stories"));
@@ -85,6 +86,7 @@ const multiComboboxStories = __importStar(require("./multi-combobox/multi-combob
85
86
  const multiSelectStories = __importStar(require("./multi-select/multi-select.stories"));
86
87
  const paginationStories = __importStar(require("./pagination/pagination.stories"));
87
88
  const paperStories = __importStar(require("./paper/paper.stories"));
89
+ const popoverStories = __importStar(require("./popover/popover.stories"));
88
90
  const radioStories = __importStar(require("./radio/radio.stories"));
89
91
  const radioGroupStories = __importStar(require("./radio-group/radio-group.stories"));
90
92
  const rasterImageStories = __importStar(require("./raster-image/raster-image.stories"));
@@ -267,6 +269,10 @@ exports.components = {
267
269
  title: "Lozenge",
268
270
  stories: lozengeStories
269
271
  },
272
+ "menu": {
273
+ title: "Menu",
274
+ stories: menuStories
275
+ },
270
276
  "message": {
271
277
  title: "Message",
272
278
  stories: messageStories
@@ -299,6 +305,10 @@ exports.components = {
299
305
  title: "Paper",
300
306
  stories: paperStories
301
307
  },
308
+ "popover": {
309
+ title: "Popover",
310
+ stories: popoverStories
311
+ },
302
312
  "radio": {
303
313
  title: "Radio",
304
314
  stories: radioStories
package/css/badge.css CHANGED
@@ -1,16 +1,34 @@
1
+ :root {
2
+ --uxf-badge-size: theme("space.8");
3
+ --uxf-badge-font-size: theme("fontSize.base");
4
+ }
5
+
1
6
  .uxf-badge {
2
7
  @apply bg-primary inline-flex shrink-0 items-center justify-center font-bold text-white;
3
8
 
9
+ font-size: var(--uxf-badge-font-size);
10
+ height: var(--uxf-badge-size);
11
+ min-width: var(--uxf-badge-size);
12
+
4
13
  &--size-small {
5
- @apply h-6 min-w-[24px] rounded-[12px] px-1.5 text-sm;
14
+ --uxf-badge-size: theme("space.6");
15
+ --uxf-badge-font-size: theme("fontSize.sm");
16
+
17
+ @apply rounded-[12px] px-1.5;
6
18
  }
7
19
 
8
20
  &--size-medium {
9
- @apply h-8 min-w-[32px] rounded-[16px] px-2 text-base;
21
+ --uxf-badge-size: theme("space.8");
22
+ --uxf-badge-font-size: theme("fontSize.base");
23
+
24
+ @apply rounded-[16px] px-2;
10
25
  }
11
26
 
12
27
  &--size-large {
13
- @apply h-10 min-w-[40px] rounded-[20px] px-2 text-lg;
28
+ --uxf-badge-size: theme("space.10");
29
+ --uxf-badge-font-size: theme("fontSize.lg");
30
+
31
+ @apply rounded-[20px] px-2;
14
32
  }
15
33
 
16
34
  :root .dark & {
package/css/menu.css ADDED
@@ -0,0 +1,113 @@
1
+ :root {
2
+ --uxf-menu-item-background-color: inherit;
3
+ --uxf-menu-icon-size: 16px;
4
+ --uxf-menu-item-gap: 12px;
5
+ --uxf-menu-item-px: 12px;
6
+ --uxf-menu-item-border-radius: 8px;
7
+ }
8
+
9
+ .uxf-menu {
10
+ font-size: theme("fontSize.sm");
11
+ padding: 4px;
12
+ }
13
+
14
+ .uxf-menu-item {
15
+ align-items: center;
16
+ background-color: var(--uxf-menu-item-background-color);
17
+ border-radius: var(--uxf-menu-item-border-radius);
18
+ color: black;
19
+ cursor: pointer;
20
+ display: flex;
21
+ flex-direction: row;
22
+ gap: var(--uxf-menu-item-gap);
23
+ height: 44px;
24
+ margin-bottom: 2px;
25
+ padding: 4px var(--uxf-menu-item-px);
26
+ width: 100%;
27
+
28
+ &:hover {
29
+ --uxf-menu-item-background-color: var(--uxf-color-base-surface-main-hover);
30
+ }
31
+
32
+ &.is-active:not(.uxf-menu-item--level-1),
33
+ &.is-active.has-no-children {
34
+ --uxf-menu-item-background-color: #e5e7eb;
35
+
36
+ font-weight: 500;
37
+ }
38
+ }
39
+
40
+ .uxf-menu-item__right-element {
41
+ align-items: center;
42
+ display: flex;
43
+
44
+ .uxf-badge {
45
+ --uxf-badge-size: 16px;
46
+ --uxf-badge-font-size: 12px;
47
+
48
+ font-weight: normal;
49
+ padding: 0 4px;
50
+ }
51
+ }
52
+
53
+ .uxf-menu-item__icon {
54
+ height: var(--uxf-menu-icon-size);
55
+ width: var(--uxf-menu-icon-size);
56
+ }
57
+
58
+ .uxf-menu-item__label {
59
+ flex-grow: 1;
60
+ text-align: left;
61
+
62
+ @apply truncate;
63
+ }
64
+
65
+ .uxf-menu-item__open-icon {
66
+ @apply transition-transform duration-200;
67
+
68
+ height: 20px;
69
+ width: 20px;
70
+
71
+ &.is-close {
72
+ transform: rotate(-90deg);
73
+ }
74
+ }
75
+
76
+ .uxf-menu__submenu {
77
+ padding-left: calc(var(--uxf-menu-item-gap) + var(--uxf-menu-icon-size));
78
+ position: relative;
79
+
80
+ &::before {
81
+ background-color: #e5e7eb;
82
+ bottom: 0;
83
+ content: "";
84
+ left: calc(var(--uxf-menu-item-px) + var(--uxf-menu-icon-size) / 2);
85
+ position: absolute;
86
+ top: 0;
87
+ width: 1px;
88
+ }
89
+
90
+ .uxf-menu-item {
91
+ position: relative;
92
+
93
+ &:hover {
94
+ &::before {
95
+ background-color: #0f1012;
96
+ bottom: 0;
97
+ content: "";
98
+ left: calc(-1 * (var(--uxf-menu-icon-size) / 2));
99
+ position: absolute;
100
+ top: 0;
101
+ width: 2px;
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ .uxf-menu__popover {
108
+ background-color: var(--uxf-color-base-surface-main);
109
+ border: 1px solid var(--uxf-color-base-border-border);
110
+ border-radius: 8px;
111
+ box-shadow: theme("boxShadow.sm");
112
+ padding: 4px;
113
+ }
package/menu/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Menu
2
+
3
+ ## CSS dependencies
4
+
5
+ ```css
6
+ @import url("@uxf/ui/css/menu.css");
7
+ ```
8
+
9
+ ## How to use active item
10
+
11
+ ```tsx
12
+ // app directory
13
+ import { usePathname } from "next/navigation";
14
+ import { usePageParams } from "@app-routes";
15
+
16
+ const pathname = usePathname();
17
+ const pathParams = usePageParams();
18
+
19
+ <Menu configuration={...} router={{pathname, pathParams}}/>
20
+ ```
21
+
22
+ ```tsx
23
+ // pages directory
24
+ import { useRouter } from "next/router";
25
+
26
+ const router = useRouter();
27
+
28
+ <Menu configuration={...} router={router}
29
+ ```
@@ -0,0 +1,17 @@
1
+ import { ReactElement } from "react";
2
+ import { IconName } from "../../icon/types";
3
+ import { NextLink } from "../../utils/next-link";
4
+ interface MenuItemButtonProps {
5
+ icon?: IconName;
6
+ label: string;
7
+ hasChildren?: boolean;
8
+ LinkComponent?: NextLink | "a";
9
+ href?: string;
10
+ onClick?: () => void;
11
+ isOpen?: boolean;
12
+ level?: number;
13
+ isActive?: boolean;
14
+ badge?: ReactElement;
15
+ }
16
+ export declare function MenuItemButton(props: MenuItemButtonProps): ReactElement;
17
+ export {};
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MenuItemButton = MenuItemButton;
7
+ const cx_1 = require("@uxf/core/utils/cx");
8
+ const is_nil_1 = require("@uxf/core/utils/is-nil");
9
+ const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
10
+ const icon_1 = require("@uxf/ui/icon");
11
+ const react_1 = __importDefault(require("react"));
12
+ function MenuItemButton(props) {
13
+ var _a;
14
+ const LinkComponent = (_a = props.LinkComponent) !== null && _a !== void 0 ? _a : "a";
15
+ const className = (0, cx_1.cx)(`uxf-menu-item uxf-menu-item--level-${props.level}`, props.isOpen ? "is-open" : "is-close", props.isActive && "is-active", props.hasChildren ? "has-children" : "has-no-children", (0, is_nil_1.isNil)(props.icon) && "uxf-menu-item--no-icon");
16
+ const content = (react_1.default.createElement(react_1.default.Fragment, null,
17
+ (0, is_not_nil_1.isNotNil)(props.icon) && (react_1.default.createElement("div", { className: "uxf-menu-item__icon-wrapper" },
18
+ react_1.default.createElement(icon_1.Icon, { className: "uxf-menu-item__icon", name: props.icon }))),
19
+ react_1.default.createElement("div", { className: "uxf-menu-item__label" }, props.label),
20
+ react_1.default.createElement("div", { className: "uxf-menu-item__right-element" },
21
+ (0, is_not_nil_1.isNotNil)(props.badge) && props.badge,
22
+ props.hasChildren && (react_1.default.createElement(icon_1.Icon, { className: (0, cx_1.cx)("uxf-menu-item__open-icon", props.isOpen ? "is-open" : "is-close", props.isActive && "is-active"), name: "caretDown" })))));
23
+ if ((0, is_not_nil_1.isNotNil)(props.href)) {
24
+ return (react_1.default.createElement(LinkComponent, { className: className, href: props.href, onClick: props.onClick, title: props.label }, content));
25
+ }
26
+ return (react_1.default.createElement("button", { className: className, onClick: props.onClick, title: props.label }, content));
27
+ }
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import { NextLink } from "../../utils/next-link";
3
+ import { ActiveTreeNode, MenuItemConfiguration } from "../types";
4
+ interface Props {
5
+ item: MenuItemConfiguration;
6
+ activeTree: ActiveTreeNode;
7
+ LinkComponent?: NextLink | "a";
8
+ level: number;
9
+ isPopoverEnabled?: boolean;
10
+ }
11
+ export declare function MenuItem(props: Props): React.JSX.Element;
12
+ export {};
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MenuItem = MenuItem;
37
+ const is_empty_1 = require("@uxf/core/utils/is-empty");
38
+ const is_nil_1 = require("@uxf/core/utils/is-nil");
39
+ const is_not_empty_1 = require("@uxf/core/utils/is-not-empty");
40
+ const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
41
+ const throw_error_1 = require("@uxf/core/utils/throw-error");
42
+ const react_1 = __importStar(require("react"));
43
+ const popover_1 = require("../../popover/popover");
44
+ const menu_item_button_1 = require("./menu-item-button");
45
+ function MenuItem(props) {
46
+ var _a, _b;
47
+ const [isOpen, setIsOpen] = (0, react_1.useState)(props.activeTree.isActive);
48
+ const button = (react_1.default.createElement(menu_item_button_1.MenuItemButton, { LinkComponent: (_b = (_a = props.item.as) !== null && _a !== void 0 ? _a : props.LinkComponent) !== null && _b !== void 0 ? _b : "a", badge: props.item.badge, hasChildren: (0, is_not_nil_1.isNotNil)(props.item.children) && (0, is_not_empty_1.isNotEmpty)(props.item.children), href: props.item.href, icon: props.item.icon, isActive: props.activeTree.isActive, isOpen: isOpen, label: props.item.label, level: props.level, onClick: () => setIsOpen((prev) => !prev) }));
49
+ if ((0, is_nil_1.isNil)(props.item.children) || (0, is_empty_1.isEmpty)(props.item.children)) {
50
+ return button;
51
+ }
52
+ const children = props.item.children.map((item, index) => {
53
+ var _a, _b;
54
+ return (react_1.default.createElement(MenuItem, { LinkComponent: props.LinkComponent, activeTree: (_b = (_a = props.activeTree.children) === null || _a === void 0 ? void 0 : _a.at(index)) !== null && _b !== void 0 ? _b : (0, throw_error_1.throwError)("Active tree is not defined"), isPopoverEnabled: props.isPopoverEnabled, item: item, key: item.label, level: props.level + 1 }));
55
+ });
56
+ if (!props.isPopoverEnabled) {
57
+ return (react_1.default.createElement("div", null,
58
+ button,
59
+ react_1.default.createElement("div", { className: "uxf-menu__submenu" }, isOpen && children)));
60
+ }
61
+ return (react_1.default.createElement(popover_1.Popover, { placement: "right-start", trigger: "hover" },
62
+ react_1.default.createElement(popover_1.Popover.Trigger, null,
63
+ react_1.default.createElement("div", null,
64
+ button,
65
+ isOpen && react_1.default.createElement("div", { className: "uxf-menu__submenu" }, children))),
66
+ !isOpen && react_1.default.createElement(popover_1.Popover.Content, { className: "uxf-menu__popover" }, children)));
67
+ }
@@ -0,0 +1,2 @@
1
+ export { Menu } from "./menu";
2
+ export type { MenuProps } from "./menu";
package/menu/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Menu = void 0;
4
+ var menu_1 = require("./menu");
5
+ Object.defineProperty(exports, "Menu", { enumerable: true, get: function () { return menu_1.Menu; } });
package/menu/menu.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import { RouterPathParams } from "../types/path-params";
3
+ import { MenuItemConfiguration } from "./types";
4
+ export type MenuConfiguration = MenuItemConfiguration[];
5
+ export type SimpleRouter = {
6
+ pathname: string | null;
7
+ pathParams?: RouterPathParams | null;
8
+ };
9
+ export interface MenuProps {
10
+ configuration: MenuConfiguration;
11
+ router: SimpleRouter;
12
+ className?: string;
13
+ isPopoverEnabled?: boolean;
14
+ }
15
+ export declare function Menu(props: MenuProps): React.JSX.Element;
package/menu/menu.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Menu = Menu;
7
+ const react_1 = __importDefault(require("react"));
8
+ const menu_item_1 = require("./components/menu-item");
9
+ function createActiveTree(menuItem, router) {
10
+ var _a, _b, _c, _d;
11
+ const children = (_a = menuItem.children) === null || _a === void 0 ? void 0 : _a.map((child) => createActiveTree(child, router));
12
+ return {
13
+ isActive: (children === null || children === void 0 ? void 0 : children.some((child) => child.isActive)) ||
14
+ ((_b = menuItem.routeMatcher) === null || _b === void 0 ? void 0 : _b.call(menuItem, (_c = router.pathname) !== null && _c !== void 0 ? _c : "", (_d = router.pathParams) !== null && _d !== void 0 ? _d : {})) ||
15
+ false,
16
+ children,
17
+ };
18
+ }
19
+ function Menu(props) {
20
+ var _a;
21
+ const activeTree = props.configuration.map((item) => createActiveTree(item, props.router));
22
+ return (react_1.default.createElement("div", { className: `uxf-menu ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}` }, props.configuration.map((item, index) => (react_1.default.createElement(menu_item_1.MenuItem, { activeTree: activeTree[index], isPopoverEnabled: props.isPopoverEnabled, item: item, key: item.label, level: 1 })))));
23
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const snap_test_1 = require("../utils/snap-test");
8
+ const menu_stories_1 = require("./menu.stories");
9
+ (0, snap_test_1.snapTest)("render stories", react_1.default.createElement(menu_stories_1.Default, null));
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export declare function Default(): React.JSX.Element;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Default = Default;
7
+ const react_1 = __importDefault(require("react"));
8
+ const badge_1 = require("../badge");
9
+ const menu_1 = require("./menu");
10
+ const CONFIGURATION = [
11
+ {
12
+ label: "UXF Web",
13
+ href: "https://www.uxf.cz",
14
+ icon: "eye",
15
+ },
16
+ {
17
+ label: "Link without children",
18
+ href: "/examples/ui/menu/Default",
19
+ icon: "camera",
20
+ badge: react_1.default.createElement("div", { className: "text-xs font-semibold text-neutral-500" }, "12"),
21
+ },
22
+ {
23
+ label: "Link with children",
24
+ icon: "file",
25
+ badge: react_1.default.createElement(badge_1.Badge, null, "5"),
26
+ children: [
27
+ { label: "Link 1", icon: "bars" },
28
+ { label: "Link 2", href: "/examples", icon: "copy" },
29
+ { label: "Link with very very long text", href: "/examples", icon: "copy" },
30
+ ],
31
+ },
32
+ {
33
+ label: "Link with very very long text",
34
+ icon: "file",
35
+ badge: react_1.default.createElement(badge_1.Badge, null, "5"),
36
+ },
37
+ ];
38
+ function Default() {
39
+ return (react_1.default.createElement("div", { className: "fixed inset-y-0 left-0 w-60 bg-white p-1" },
40
+ react_1.default.createElement(menu_1.Menu, { configuration: CONFIGURATION, router: { pathname: "", pathParams: {} } })));
41
+ }
@@ -0,0 +1,18 @@
1
+ import { ReactElement } from "react";
2
+ import { IconName } from "../icon/types";
3
+ import { RouterPathParams } from "../types/path-params";
4
+ import { NextLink } from "../utils/next-link";
5
+ export type ActiveTreeNode = {
6
+ isActive: boolean;
7
+ children?: ActiveTreeNode[];
8
+ };
9
+ export interface MenuItemConfiguration {
10
+ as?: NextLink | "a";
11
+ href?: string;
12
+ onClick?: () => void;
13
+ icon?: IconName;
14
+ label: string;
15
+ children?: MenuItemConfiguration[];
16
+ routeMatcher?: (pathname: string, pathParams?: RouterPathParams) => boolean;
17
+ badge?: ReactElement;
18
+ }
package/menu/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/ui",
3
- "version": "11.100.0",
3
+ "version": "11.101.0",
4
4
  "description": "",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -25,7 +25,7 @@
25
25
  "@headlessui/react": "1.7.19",
26
26
  "@uxf/core": "11.100.0",
27
27
  "@uxf/core-react": "11.100.0",
28
- "@uxf/datepicker": "11.99.1",
28
+ "@uxf/datepicker": "11.100.1",
29
29
  "@uxf/localize": "11.92.1",
30
30
  "@uxf/styles": "11.100.0",
31
31
  "color2k": "2.0.3",
@@ -0,0 +1,10 @@
1
+ # Popover
2
+
3
+ ## Basic usage
4
+
5
+ ```tsx
6
+ <Popover placement="right-start" trigger="hover">
7
+ <Popover.Trigger>Trigger button</Popover.Trigger>
8
+ <Popover.Content>Content</Popover.Content>
9
+ </Popover>
10
+ ```
@@ -0,0 +1,71 @@
1
+ import { Placement } from "@floating-ui/react";
2
+ import React, { HTMLAttributes, ReactNode } from "react";
3
+ interface PopoverOptions {
4
+ trigger?: "hover" | "click";
5
+ placement?: Placement;
6
+ }
7
+ export declare const usePopoverContext: () => {
8
+ labelId: string | undefined;
9
+ descriptionId: string | undefined;
10
+ setLabelId: React.Dispatch<React.SetStateAction<string | undefined>>;
11
+ setDescriptionId: React.Dispatch<React.SetStateAction<string | undefined>>;
12
+ placement: Placement;
13
+ strategy: import("@floating-ui/utils").Strategy;
14
+ middlewareData: import("@floating-ui/core").MiddlewareData;
15
+ x: number;
16
+ y: number;
17
+ isPositioned: boolean;
18
+ update: () => void;
19
+ floatingStyles: React.CSSProperties;
20
+ refs: {
21
+ reference: React.MutableRefObject<import("@floating-ui/react-dom").ReferenceType | null>;
22
+ floating: React.MutableRefObject<HTMLElement | null>;
23
+ setReference: (node: import("@floating-ui/react-dom").ReferenceType | null) => void;
24
+ setFloating: (node: HTMLElement | null) => void;
25
+ } & import("@floating-ui/react").ExtendedRefs<import("@floating-ui/react").ReferenceType>;
26
+ elements: {
27
+ reference: import("@floating-ui/react-dom").ReferenceType | null;
28
+ floating: HTMLElement | null;
29
+ } & import("@floating-ui/react").ExtendedElements<import("@floating-ui/react").ReferenceType>;
30
+ context: {
31
+ x: number;
32
+ y: number;
33
+ placement: Placement;
34
+ strategy: import("@floating-ui/utils").Strategy;
35
+ middlewareData: import("@floating-ui/core").MiddlewareData;
36
+ isPositioned: boolean;
37
+ update: () => void;
38
+ floatingStyles: React.CSSProperties;
39
+ open: boolean;
40
+ onOpenChange: (open: boolean, event?: Event, reason?: import("@floating-ui/react").OpenChangeReason) => void;
41
+ events: import("@floating-ui/react").FloatingEvents;
42
+ dataRef: React.MutableRefObject<import("@floating-ui/react").ContextData>;
43
+ nodeId: string | undefined;
44
+ floatingId: string | undefined;
45
+ refs: import("@floating-ui/react").ExtendedRefs<import("@floating-ui/react").ReferenceType>;
46
+ elements: import("@floating-ui/react").ExtendedElements<import("@floating-ui/react").ReferenceType>;
47
+ };
48
+ getReferenceProps: (userProps?: React.HTMLProps<Element>) => Record<string, unknown>;
49
+ getFloatingProps: (userProps?: React.HTMLProps<HTMLElement>) => Record<string, unknown>;
50
+ getItemProps: (userProps?: Omit<React.HTMLProps<HTMLElement>, "selected" | "active"> & {
51
+ active?: boolean;
52
+ selected?: boolean;
53
+ }) => Record<string, unknown>;
54
+ open: boolean;
55
+ setOpen: React.Dispatch<React.SetStateAction<boolean>>;
56
+ } & {
57
+ setLabelId: React.Dispatch<React.SetStateAction<string | undefined>>;
58
+ setDescriptionId: React.Dispatch<React.SetStateAction<string | undefined>>;
59
+ };
60
+ declare function PopoverBase(props: {
61
+ children: React.ReactNode;
62
+ } & PopoverOptions): React.JSX.Element;
63
+ interface PopoverTriggerProps extends HTMLAttributes<HTMLElement> {
64
+ children: ReactNode;
65
+ asChild?: boolean;
66
+ }
67
+ export declare const Popover: typeof PopoverBase & {
68
+ Trigger: React.ForwardRefExoticComponent<PopoverTriggerProps & React.RefAttributes<HTMLElement>>;
69
+ Content: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
70
+ };
71
+ export {};
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ "use client";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.Popover = exports.usePopoverContext = void 0;
38
+ const react_1 = require("@floating-ui/react");
39
+ const react_2 = __importStar(require("react"));
40
+ function usePopover(options = {}) {
41
+ var _a;
42
+ const [isOpen, setIsOpen] = (0, react_2.useState)(false);
43
+ const [labelId, setLabelId] = (0, react_2.useState)();
44
+ const [descriptionId, setDescriptionId] = (0, react_2.useState)();
45
+ const placement = (_a = options.placement) !== null && _a !== void 0 ? _a : "bottom";
46
+ const data = (0, react_1.useFloating)({
47
+ placement,
48
+ open: isOpen,
49
+ onOpenChange: setIsOpen,
50
+ whileElementsMounted: react_1.autoUpdate,
51
+ middleware: [
52
+ (0, react_1.offset)(12),
53
+ (0, react_1.flip)({
54
+ crossAxis: placement.includes("-"),
55
+ fallbackAxisSideDirection: "end",
56
+ padding: 5,
57
+ }),
58
+ (0, react_1.shift)({ padding: 12 }),
59
+ ],
60
+ });
61
+ const context = data.context;
62
+ const click = (0, react_1.useClick)(context, {
63
+ enabled: options.trigger === "click",
64
+ });
65
+ const hover = (0, react_1.useHover)(context, {
66
+ enabled: options.trigger === "hover",
67
+ handleClose: (0, react_1.safePolygon)(),
68
+ });
69
+ const dismiss = (0, react_1.useDismiss)(context);
70
+ const role = (0, react_1.useRole)(context);
71
+ const interactions = (0, react_1.useInteractions)([click, hover, dismiss, role]);
72
+ return (0, react_2.useMemo)(() => ({
73
+ open: isOpen,
74
+ setOpen: setIsOpen,
75
+ ...interactions,
76
+ ...data,
77
+ labelId,
78
+ descriptionId,
79
+ setLabelId,
80
+ setDescriptionId,
81
+ }), [isOpen, setIsOpen, interactions, data, labelId, descriptionId]);
82
+ }
83
+ const PopoverContext = (0, react_2.createContext)(null);
84
+ const usePopoverContext = () => {
85
+ const context = (0, react_2.useContext)(PopoverContext);
86
+ if (!context) {
87
+ throw new Error("Popover components must be wrapped in <Popover />");
88
+ }
89
+ return context;
90
+ };
91
+ exports.usePopoverContext = usePopoverContext;
92
+ function PopoverBase(props) {
93
+ // This can accept any props as options, e.g. `placement`,
94
+ // or other positioning options.
95
+ const popover = usePopover(props); // TODO
96
+ return react_2.default.createElement(PopoverContext.Provider, { value: popover }, props.children);
97
+ }
98
+ const PopoverTrigger = (0, react_2.forwardRef)(function PopoverTrigger(props, propRef) {
99
+ const context = (0, exports.usePopoverContext)();
100
+ const childrenRef = props.children.ref;
101
+ const ref = (0, react_1.useMergeRefs)([context.refs.setReference, propRef, childrenRef]);
102
+ // `asChild` allows the user to pass any element as the anchor
103
+ if (props.asChild && (0, react_2.isValidElement)(props.children)) {
104
+ return (0, react_2.cloneElement)(props.children, context.getReferenceProps({
105
+ ref,
106
+ ...props,
107
+ ...props.children.props,
108
+ "data-state": context.open ? "open" : "closed",
109
+ }));
110
+ }
111
+ return (react_2.default.createElement("button", { "data-state": context.open ? "open" : "closed", ref: ref, ...context.getReferenceProps(props) }, props.children));
112
+ });
113
+ const PopoverContent = (0, react_2.forwardRef)(function PopoverContent(props, propRef) {
114
+ const popoverContext = (0, exports.usePopoverContext)();
115
+ const ref = (0, react_1.useMergeRefs)([popoverContext.refs.setFloating, propRef]);
116
+ if (!popoverContext.context.open) {
117
+ return null;
118
+ }
119
+ return (react_2.default.createElement(react_1.FloatingPortal, null,
120
+ react_2.default.createElement(react_1.FloatingFocusManager, { context: popoverContext.context, modal: false },
121
+ react_2.default.createElement("div", { "aria-describedby": popoverContext.descriptionId, "aria-labelledby": popoverContext.labelId, ref: ref, style: { ...popoverContext.floatingStyles, ...props.style }, ...popoverContext.getFloatingProps(props) }, props.children))));
122
+ });
123
+ exports.Popover = Object.assign(PopoverBase, { Trigger: PopoverTrigger, Content: PopoverContent });
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export declare function Default(): React.JSX.Element;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Default = Default;
7
+ const react_1 = __importDefault(require("react"));
8
+ const popover_1 = require("./popover");
9
+ function Default() {
10
+ return (react_1.default.createElement("div", { className: "p-4" },
11
+ react_1.default.createElement("div", { className: "max-w-[400px]" },
12
+ react_1.default.createElement(popover_1.Popover, { placement: "right-start", trigger: "click" },
13
+ react_1.default.createElement(popover_1.Popover.Trigger, null, "Trigger"),
14
+ react_1.default.createElement(popover_1.Popover.Content, null, "Popover content")))));
15
+ }
package/readmes.d.ts CHANGED
@@ -42,6 +42,7 @@ export declare const readmes: {
42
42
  readonly "list-item": typeof accordionReadme;
43
43
  readonly loader: typeof accordionReadme;
44
44
  readonly lozenge: typeof accordionReadme;
45
+ readonly menu: typeof accordionReadme;
45
46
  readonly message: typeof accordionReadme;
46
47
  readonly modal: typeof accordionReadme;
47
48
  readonly "modal-dialog": typeof accordionReadme;
@@ -50,6 +51,7 @@ export declare const readmes: {
50
51
  readonly "multi-select": typeof accordionReadme;
51
52
  readonly pagination: typeof accordionReadme;
52
53
  readonly paper: typeof accordionReadme;
54
+ readonly popover: typeof accordionReadme;
53
55
  readonly radio: typeof accordionReadme;
54
56
  readonly "radio-group": typeof accordionReadme;
55
57
  readonly "raster-image": typeof accordionReadme;
package/readmes.js CHANGED
@@ -47,27 +47,29 @@ const README_md_39 = __importDefault(require("./lightbox/README.md"));
47
47
  const README_md_40 = __importDefault(require("./list-item/README.md"));
48
48
  const README_md_41 = __importDefault(require("./loader/README.md"));
49
49
  const README_md_42 = __importDefault(require("./lozenge/README.md"));
50
- const README_md_43 = __importDefault(require("./message/README.md"));
51
- const README_md_44 = __importDefault(require("./modal/README.md"));
52
- const README_md_45 = __importDefault(require("./modal-dialog/README.md"));
53
- const README_md_46 = __importDefault(require("./modal-header/README.md"));
54
- const README_md_47 = __importDefault(require("./multi-combobox/README.md"));
55
- const README_md_48 = __importDefault(require("./multi-select/README.md"));
56
- const README_md_49 = __importDefault(require("./pagination/README.md"));
57
- const README_md_50 = __importDefault(require("./paper/README.md"));
58
- const README_md_51 = __importDefault(require("./radio/README.md"));
59
- const README_md_52 = __importDefault(require("./radio-group/README.md"));
60
- const README_md_53 = __importDefault(require("./raster-image/README.md"));
61
- const README_md_54 = __importDefault(require("./select/README.md"));
62
- const README_md_55 = __importDefault(require("./tabs/README.md"));
63
- const README_md_56 = __importDefault(require("./text-input/README.md"));
64
- const README_md_57 = __importDefault(require("./text-link/README.md"));
65
- const README_md_58 = __importDefault(require("./textarea/README.md"));
66
- const README_md_59 = __importDefault(require("./time-picker/README.md"));
67
- const README_md_60 = __importDefault(require("./time-picker-input/README.md"));
68
- const README_md_61 = __importDefault(require("./toggle/README.md"));
69
- const README_md_62 = __importDefault(require("./tooltip/README.md"));
70
- const README_md_63 = __importDefault(require("./typography/README.md"));
50
+ const README_md_43 = __importDefault(require("./menu/README.md"));
51
+ const README_md_44 = __importDefault(require("./message/README.md"));
52
+ const README_md_45 = __importDefault(require("./modal/README.md"));
53
+ const README_md_46 = __importDefault(require("./modal-dialog/README.md"));
54
+ const README_md_47 = __importDefault(require("./modal-header/README.md"));
55
+ const README_md_48 = __importDefault(require("./multi-combobox/README.md"));
56
+ const README_md_49 = __importDefault(require("./multi-select/README.md"));
57
+ const README_md_50 = __importDefault(require("./pagination/README.md"));
58
+ const README_md_51 = __importDefault(require("./paper/README.md"));
59
+ const README_md_52 = __importDefault(require("./popover/README.md"));
60
+ const README_md_53 = __importDefault(require("./radio/README.md"));
61
+ const README_md_54 = __importDefault(require("./radio-group/README.md"));
62
+ const README_md_55 = __importDefault(require("./raster-image/README.md"));
63
+ const README_md_56 = __importDefault(require("./select/README.md"));
64
+ const README_md_57 = __importDefault(require("./tabs/README.md"));
65
+ const README_md_58 = __importDefault(require("./text-input/README.md"));
66
+ const README_md_59 = __importDefault(require("./text-link/README.md"));
67
+ const README_md_60 = __importDefault(require("./textarea/README.md"));
68
+ const README_md_61 = __importDefault(require("./time-picker/README.md"));
69
+ const README_md_62 = __importDefault(require("./time-picker-input/README.md"));
70
+ const README_md_63 = __importDefault(require("./toggle/README.md"));
71
+ const README_md_64 = __importDefault(require("./tooltip/README.md"));
72
+ const README_md_65 = __importDefault(require("./typography/README.md"));
71
73
  exports.readmes = {
72
74
  "accordion": README_md_1.default,
73
75
  "alert-bubble": README_md_2.default,
@@ -111,25 +113,27 @@ exports.readmes = {
111
113
  "list-item": README_md_40.default,
112
114
  "loader": README_md_41.default,
113
115
  "lozenge": README_md_42.default,
114
- "message": README_md_43.default,
115
- "modal": README_md_44.default,
116
- "modal-dialog": README_md_45.default,
117
- "modal-header": README_md_46.default,
118
- "multi-combobox": README_md_47.default,
119
- "multi-select": README_md_48.default,
120
- "pagination": README_md_49.default,
121
- "paper": README_md_50.default,
122
- "radio": README_md_51.default,
123
- "radio-group": README_md_52.default,
124
- "raster-image": README_md_53.default,
125
- "select": README_md_54.default,
126
- "tabs": README_md_55.default,
127
- "text-input": README_md_56.default,
128
- "text-link": README_md_57.default,
129
- "textarea": README_md_58.default,
130
- "time-picker": README_md_59.default,
131
- "time-picker-input": README_md_60.default,
132
- "toggle": README_md_61.default,
133
- "tooltip": README_md_62.default,
134
- "typography": README_md_63.default,
116
+ "menu": README_md_43.default,
117
+ "message": README_md_44.default,
118
+ "modal": README_md_45.default,
119
+ "modal-dialog": README_md_46.default,
120
+ "modal-header": README_md_47.default,
121
+ "multi-combobox": README_md_48.default,
122
+ "multi-select": README_md_49.default,
123
+ "pagination": README_md_50.default,
124
+ "paper": README_md_51.default,
125
+ "popover": README_md_52.default,
126
+ "radio": README_md_53.default,
127
+ "radio-group": README_md_54.default,
128
+ "raster-image": README_md_55.default,
129
+ "select": README_md_56.default,
130
+ "tabs": README_md_57.default,
131
+ "text-input": README_md_58.default,
132
+ "text-link": README_md_59.default,
133
+ "textarea": README_md_60.default,
134
+ "time-picker": README_md_61.default,
135
+ "time-picker-input": README_md_62.default,
136
+ "toggle": README_md_63.default,
137
+ "tooltip": README_md_64.default,
138
+ "typography": README_md_65.default,
135
139
  };
@@ -351,6 +351,11 @@ export declare const twColors: {
351
351
  DEFAULT: string;
352
352
  };
353
353
  test: string;
354
+ sidebar: {
355
+ background: string;
356
+ highlight: string;
357
+ hover: string;
358
+ };
354
359
  base_border_border: string;
355
360
  base_border_input: string;
356
361
  base_border_inverted_border: string;
@@ -355,6 +355,11 @@ exports.twColors = {
355
355
  "DEFAULT": "#ef4444"
356
356
  },
357
357
  "test": "#ff00ff",
358
+ "sidebar": {
359
+ "background": "#1F2937",
360
+ "highlight": "#111827",
361
+ "hover": "#111827"
362
+ },
358
363
  "base_border_border": "var(--uxf-color-base-border-border)",
359
364
  "base_border_input": "var(--uxf-color-base-border-input)",
360
365
  "base_border_inverted_border": "var(--uxf-color-base-border-inverted-border)",
@@ -0,0 +1 @@
1
+ export type RouterPathParams = Partial<Record<string, string | string[]>>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -97,6 +97,11 @@ module.exports = {
97
97
  900: "#7f1d1d",
98
98
  },
99
99
  test: "#ff00ff",
100
+ sidebar: {
101
+ background: "#1F2937",
102
+ highlight: "#111827",
103
+ hover: "#111827",
104
+ },
100
105
  // generated color-tokens from figma
101
106
  ...figmaColors,
102
107
  },