@opengovsg/oui 0.0.27 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/cjs/badge/badge.cjs +4 -4
  2. package/dist/cjs/badge/use-badge.cjs +6 -6
  3. package/dist/cjs/banner/banner.cjs +3 -3
  4. package/dist/cjs/button/button.cjs +3 -3
  5. package/dist/cjs/calendar/calendar-bottom-content.cjs +3 -3
  6. package/dist/cjs/calendar/calendar-header.cjs +2 -2
  7. package/dist/cjs/calendar/calendar-month-day-selector.cjs +2 -2
  8. package/dist/cjs/calendar/calendar.cjs +4 -4
  9. package/dist/cjs/calendar/hooks/use-calendar-selectors.cjs +4 -4
  10. package/dist/cjs/calendar/utils.cjs +3 -3
  11. package/dist/cjs/combo-box/combo-box-fuzzy.cjs +6 -6
  12. package/dist/cjs/combo-box/combo-box-item.cjs +2 -2
  13. package/dist/cjs/combo-box/combo-box.cjs +3 -3
  14. package/dist/cjs/date-field/date-field.cjs +3 -3
  15. package/dist/cjs/date-picker/date-picker.cjs +2 -2
  16. package/dist/cjs/date-range-picker/date-range-picker.cjs +3 -3
  17. package/dist/cjs/field/field.cjs +2 -2
  18. package/dist/cjs/file-dropzone/file-dropzone.cjs +10 -10
  19. package/dist/cjs/file-dropzone/file-info.cjs +3 -3
  20. package/dist/cjs/govt-banner/govt-banner.cjs +3 -3
  21. package/dist/cjs/hooks/use-callback-ref.cjs +4 -4
  22. package/dist/cjs/hooks/use-controllable-state.cjs +2 -2
  23. package/dist/cjs/hooks/use-draggable.cjs +8 -8
  24. package/dist/cjs/index.cjs +30 -11
  25. package/dist/cjs/input/input.cjs +2 -2
  26. package/dist/cjs/menu/menu.cjs +7 -7
  27. package/dist/cjs/modal/modal-body.cjs +2 -2
  28. package/dist/cjs/modal/modal-content.cjs +3 -3
  29. package/dist/cjs/modal/modal-footer.cjs +2 -2
  30. package/dist/cjs/modal/modal-header.cjs +2 -2
  31. package/dist/cjs/modal/modal.cjs +3 -3
  32. package/dist/cjs/navbar/index.cjs +25 -0
  33. package/dist/cjs/navbar/navbar-brand.cjs +28 -0
  34. package/dist/cjs/navbar/navbar-content.cjs +33 -0
  35. package/dist/cjs/navbar/navbar-context.cjs +14 -0
  36. package/dist/cjs/navbar/navbar-item.cjs +29 -0
  37. package/dist/cjs/navbar/navbar-menu/i18n.cjs +23 -0
  38. package/dist/cjs/navbar/navbar-menu/item.cjs +44 -0
  39. package/dist/cjs/navbar/navbar-menu/menu.cjs +62 -0
  40. package/dist/cjs/navbar/navbar-menu/toggle.cjs +94 -0
  41. package/dist/cjs/navbar/navbar.cjs +26 -0
  42. package/dist/cjs/navbar/use-navbar.cjs +116 -0
  43. package/dist/cjs/node_modules/.pnpm/@react-aria_overlays@3.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@react-aria/overlays/dist/Overlay.cjs +55 -0
  44. package/dist/cjs/node_modules/.pnpm/@react-aria_overlays@3.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@react-aria/overlays/dist/PortalProvider.cjs +23 -0
  45. package/dist/cjs/node_modules/.pnpm/@react-aria_overlays@3.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@react-aria/overlays/dist/usePreventScroll.cjs +208 -0
  46. package/dist/cjs/node_modules/.pnpm/@react-aria_ssr@3.9.10_react@19.2.3/node_modules/@react-aria/ssr/dist/SSRProvider.cjs +104 -0
  47. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/Icon.cjs +4 -4
  48. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/createLucideIcon.cjs +3 -3
  49. package/dist/cjs/number-field/number-field.cjs +1 -1
  50. package/dist/cjs/pagination/hooks/use-pagination.cjs +7 -7
  51. package/dist/cjs/pagination/pagination.cjs +6 -6
  52. package/dist/cjs/pagination/use-pagination-item.cjs +3 -3
  53. package/dist/cjs/pagination/use-pagination.cjs +8 -8
  54. package/dist/cjs/range-calendar/range-calendar.cjs +6 -6
  55. package/dist/cjs/ripple/use-ripple.cjs +4 -4
  56. package/dist/cjs/select/select.cjs +2 -2
  57. package/dist/cjs/spinner/use-spinner.cjs +3 -3
  58. package/dist/cjs/system/react-utils/children.cjs +26 -0
  59. package/dist/cjs/system/react-utils/context.cjs +3 -3
  60. package/dist/cjs/system/react-utils/refs.cjs +3 -3
  61. package/dist/cjs/system/utils.cjs +2 -2
  62. package/dist/cjs/tabs/tabs.cjs +2 -2
  63. package/dist/cjs/tag-field/tag-field-item.cjs +2 -2
  64. package/dist/cjs/tag-field/tag-field-list.cjs +4 -4
  65. package/dist/cjs/tag-field/tag-field-root.cjs +14 -14
  66. package/dist/cjs/tag-field/tag-field-state-context.cjs +2 -2
  67. package/dist/cjs/tag-field/tag-field-tag-list.cjs +3 -3
  68. package/dist/cjs/tag-field/tag-field-trigger.cjs +2 -2
  69. package/dist/cjs/tag-field/tag-field.cjs +3 -3
  70. package/dist/cjs/tag-field/use-tag-field-state.cjs +6 -6
  71. package/dist/cjs/tag-field/use-tag-field.cjs +4 -4
  72. package/dist/cjs/text-area/text-area.cjs +2 -2
  73. package/dist/cjs/toast/toast.cjs +1 -0
  74. package/dist/cjs/toggle/toggle.cjs +3 -3
  75. package/dist/esm/index.js +14 -5
  76. package/dist/esm/menu/menu.js +1 -1
  77. package/dist/esm/navbar/index.js +10 -0
  78. package/dist/esm/navbar/navbar-brand.js +26 -0
  79. package/dist/esm/navbar/navbar-content.js +31 -0
  80. package/dist/esm/navbar/navbar-context.js +11 -0
  81. package/dist/esm/navbar/navbar-item.js +27 -0
  82. package/dist/esm/navbar/navbar-menu/i18n.js +21 -0
  83. package/dist/esm/navbar/navbar-menu/item.js +42 -0
  84. package/dist/esm/navbar/navbar-menu/menu.js +60 -0
  85. package/dist/esm/navbar/navbar-menu/toggle.js +92 -0
  86. package/dist/esm/navbar/navbar.js +24 -0
  87. package/dist/esm/navbar/use-navbar.js +114 -0
  88. package/dist/esm/node_modules/.pnpm/@react-aria_overlays@3.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@react-aria/overlays/dist/Overlay.js +52 -0
  89. package/dist/esm/node_modules/.pnpm/@react-aria_overlays@3.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@react-aria/overlays/dist/PortalProvider.js +20 -0
  90. package/dist/esm/node_modules/.pnpm/@react-aria_overlays@3.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@react-aria/overlays/dist/usePreventScroll.js +206 -0
  91. package/dist/esm/node_modules/.pnpm/@react-aria_ssr@3.9.10_react@19.2.3/node_modules/@react-aria/ssr/dist/SSRProvider.js +102 -0
  92. package/dist/esm/number-field/number-field.js +1 -1
  93. package/dist/esm/pagination/use-pagination-item.js +1 -1
  94. package/dist/esm/system/react-utils/children.js +23 -0
  95. package/dist/esm/tag-field/tag-field.js +1 -1
  96. package/dist/esm/toast/toast.js +1 -0
  97. package/dist/types/index.d.mts +1 -0
  98. package/dist/types/index.d.ts +1 -0
  99. package/dist/types/index.d.ts.map +1 -1
  100. package/dist/types/navbar/index.d.ts +17 -0
  101. package/dist/types/navbar/index.d.ts.map +1 -0
  102. package/dist/types/navbar/navbar-brand.d.ts +6 -0
  103. package/dist/types/navbar/navbar-brand.d.ts.map +1 -0
  104. package/dist/types/navbar/navbar-content.d.ts +14 -0
  105. package/dist/types/navbar/navbar-content.d.ts.map +1 -0
  106. package/dist/types/navbar/navbar-context.d.ts +174 -0
  107. package/dist/types/navbar/navbar-context.d.ts.map +1 -0
  108. package/dist/types/navbar/navbar-item.d.ts +11 -0
  109. package/dist/types/navbar/navbar-item.d.ts.map +1 -0
  110. package/dist/types/navbar/navbar-menu/i18n.d.ts +3 -0
  111. package/dist/types/navbar/navbar-menu/i18n.d.ts.map +1 -0
  112. package/dist/types/navbar/navbar-menu/item.d.ts +16 -0
  113. package/dist/types/navbar/navbar-menu/item.d.ts.map +1 -0
  114. package/dist/types/navbar/navbar-menu/menu.d.ts +11 -0
  115. package/dist/types/navbar/navbar-menu/menu.d.ts.map +1 -0
  116. package/dist/types/navbar/navbar-menu/toggle.d.ts +12 -0
  117. package/dist/types/navbar/navbar-menu/toggle.d.ts.map +1 -0
  118. package/dist/types/navbar/navbar.d.ts +6 -0
  119. package/dist/types/navbar/navbar.d.ts.map +1 -0
  120. package/dist/types/navbar/use-navbar.d.ts +131 -0
  121. package/dist/types/navbar/use-navbar.d.ts.map +1 -0
  122. package/dist/types/system/react-utils/children.d.ts +10 -0
  123. package/dist/types/system/react-utils/children.d.ts.map +1 -0
  124. package/dist/types/system/react-utils/index.d.ts +5 -3
  125. package/dist/types/system/react-utils/index.d.ts.map +1 -1
  126. package/dist/types/toast/index.d.ts +2 -1
  127. package/dist/types/toast/index.d.ts.map +1 -1
  128. package/dist/types/toast/toast.d.ts.map +1 -1
  129. package/package.json +3 -3
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  'use strict';
3
3
 
4
- var react = require('react');
4
+ var $670gB$react = require('react');
5
5
  var form = require('@react-stately/form');
6
6
  var utils = require('@react-stately/utils');
7
7
  var useControllableState = require('../hooks/use-controllable-state.cjs');
8
8
 
9
9
  function useTagFieldState(props) {
10
10
  const { itemToText, itemToKey, defaultFilter } = props;
11
- const itemsByKey = react.useMemo(() => {
11
+ const itemsByKey = $670gB$react.useMemo(() => {
12
12
  const items = props.items ?? props.defaultItems ?? [];
13
13
  return items.reduce(
14
14
  (acc, item) => {
@@ -18,7 +18,7 @@ function useTagFieldState(props) {
18
18
  {}
19
19
  ) ?? {};
20
20
  }, [itemToKey, props.defaultItems, props.items]);
21
- const getSelectedItemsByKey = react.useCallback(
21
+ const getSelectedItemsByKey = $670gB$react.useCallback(
22
22
  (keys) => {
23
23
  if (!keys) return;
24
24
  return [...keys].map((key) => itemsByKey[key]);
@@ -36,13 +36,13 @@ function useTagFieldState(props) {
36
36
  defaultInputValue,
37
37
  props.onInputChange
38
38
  );
39
- const controlledSelectedKeys = react.useMemo(
39
+ const controlledSelectedKeys = $670gB$react.useMemo(
40
40
  () => new Set(selectedItems.map(itemToKey)),
41
41
  [itemToKey, selectedItems]
42
42
  );
43
43
  const validation = form.useFormValidationState({
44
44
  ...props,
45
- value: react.useMemo(
45
+ value: $670gB$react.useMemo(
46
46
  () => ({
47
47
  inputValue,
48
48
  selectedKeys: controlledSelectedKeys
@@ -50,7 +50,7 @@ function useTagFieldState(props) {
50
50
  [controlledSelectedKeys, inputValue]
51
51
  )
52
52
  });
53
- const filteredItems = react.useMemo(
53
+ const filteredItems = $670gB$react.useMemo(
54
54
  () => (
55
55
  // No default filter if items are controlled.
56
56
  !!props.items || !defaultFilter ? props.items ?? [] : filterItems({
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  'use strict';
3
3
 
4
- var react = require('react');
4
+ var $670gB$react = require('react');
5
5
  var utils = require('@react-aria/utils');
6
6
  var reactVirtual = require('@tanstack/react-virtual');
7
7
  var downshift = require('downshift');
@@ -23,7 +23,7 @@ function useTagField(props, state) {
23
23
  label,
24
24
  virtualRowHeight = 40
25
25
  } = props;
26
- const backupBtnRef = react.useRef(null);
26
+ const backupBtnRef = $670gB$react.useRef(null);
27
27
  buttonRef = buttonRef ?? backupBtnRef;
28
28
  const {
29
29
  selectedItems,
@@ -48,14 +48,14 @@ function useTagField(props, state) {
48
48
  }
49
49
  }
50
50
  });
51
- const disabledKeysSet = react.useMemo(() => {
51
+ const disabledKeysSet = $670gB$react.useMemo(() => {
52
52
  return new Set(disabledKeys);
53
53
  }, [disabledKeys]);
54
54
  const rowVirtualizer = reactVirtual.useVirtualizer({
55
55
  count: items.length,
56
56
  getScrollElement: () => listBoxRef.current,
57
57
  estimateSize: () => virtualRowHeight,
58
- getItemKey: react.useCallback(
58
+ getItemKey: $670gB$react.useCallback(
59
59
  (index) => itemToKey(items[index]),
60
60
  [itemToKey, items]
61
61
  ),
@@ -3,11 +3,11 @@
3
3
  'use strict';
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
- var react = require('react');
6
+ var $670gB$react = require('react');
7
7
  var reactAriaComponents = require('react-aria-components');
8
8
  var ouiTheme = require('@opengovsg/oui-theme');
9
9
 
10
- const TextArea = react.forwardRef(
10
+ const TextArea = $670gB$react.forwardRef(
11
11
  ({ size, variant, isDisabled, ...props }, ref) => {
12
12
  return /* @__PURE__ */ jsxRuntime.jsx(
13
13
  reactAriaComponents.TextArea,
@@ -18,6 +18,7 @@ function Toaster(originalProps) {
18
18
  className: styles.base({
19
19
  className: props.className ?? props.classNames?.base
20
20
  }),
21
+ position: "top-center",
21
22
  icons: {
22
23
  loading: /* @__PURE__ */ jsxRuntime.jsx(spinner.Spinner, { size: "xs" }),
23
24
  close: /* @__PURE__ */ jsxRuntime.jsx(x.default, {})
@@ -3,7 +3,7 @@
3
3
  'use strict';
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
- var react = require('react');
6
+ var $670gB$react = require('react');
7
7
  var reactAria = require('react-aria');
8
8
  var reactAriaComponents = require('react-aria-components');
9
9
  var ouiTheme = require('@opengovsg/oui-theme');
@@ -21,12 +21,12 @@ const Toggle = ({
21
21
  ouiTheme.toggleStyles.variantKeys
22
22
  );
23
23
  const slots = ouiTheme.toggleStyles(variantProps);
24
- const clonedThumbIcon = react.useCallback(
24
+ const clonedThumbIcon = $670gB$react.useCallback(
25
25
  (renderProps) => {
26
26
  const baseProps = {
27
27
  className: slots.thumbIcon({ className: classNames?.thumbIcon })
28
28
  };
29
- return typeof thumbIcon === "function" ? thumbIcon(reactAria.mergeProps(baseProps, renderProps)) : thumbIcon && react.cloneElement(thumbIcon, baseProps);
29
+ return typeof thumbIcon === "function" ? thumbIcon(reactAria.mergeProps(baseProps, renderProps)) : thumbIcon && $670gB$react.cloneElement(thumbIcon, baseProps);
30
30
  },
31
31
  [classNames?.thumbIcon, slots, thumbIcon]
32
32
  );
package/dist/esm/index.js CHANGED
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  export { useControllableState } from './hooks/use-controllable-state.js';
3
3
  export { useDraggable } from './hooks/use-draggable.js';
4
+ export { GovtBanner } from './govt-banner/govt-banner.js';
4
5
  export { Ripple } from './ripple/ripple.js';
5
6
  export { useRipple } from './ripple/use-ripple.js';
6
7
  export { Spinner } from './spinner/spinner.js';
7
8
  export { useSpinner } from './spinner/use-spinner.js';
8
9
  export { Toggle } from './toggle/toggle.js';
9
10
  export { SkipNavLink } from './skip-nav-link/skip-nav-link.js';
11
+ export { Input } from './input/input.js';
10
12
  export { TextField } from './text-field/text-field.js';
11
13
  export { TextArea } from './text-area/text-area.js';
12
14
  export { TextAreaField } from './text-area-field/text-area-field.js';
@@ -24,6 +26,9 @@ export { PaginationCursor } from './pagination/pagination-cursor.js';
24
26
  export { PaginationItem } from './pagination/pagination-item.js';
25
27
  export { PaginationItemType } from './pagination/hooks/use-pagination.js';
26
28
  export { CURSOR_TRANSITION_TIMEOUT, usePagination } from './pagination/use-pagination.js';
29
+ export { FileDropzone } from './file-dropzone/file-dropzone.js';
30
+ export { FileInfo } from './file-dropzone/file-info.js';
31
+ export { formatBytes, formatErrorMessage } from './file-dropzone/utils.js';
27
32
  export { NumberField } from './number-field/number-field.js';
28
33
  export { Modal } from './modal/modal.js';
29
34
  export { ModalContent } from './modal/modal-content.js';
@@ -32,9 +37,16 @@ export { ModalBody } from './modal/modal-body.js';
32
37
  export { ModalHeader } from './modal/modal-header.js';
33
38
  export { ModalVariantContext, useModalVariantContext } from './modal/modal-variant-context.js';
34
39
  export { Toaster } from './toast/toast.js';
40
+ export { Navbar } from './navbar/navbar.js';
41
+ export { NavbarBrand } from './navbar/navbar-brand.js';
42
+ export { NavbarContent } from './navbar/navbar-content.js';
43
+ export { NavbarMenu } from './navbar/navbar-menu/menu.js';
44
+ export { NavbarMenuItem } from './navbar/navbar-menu/item.js';
45
+ export { NavbarMenuToggle } from './navbar/navbar-menu/toggle.js';
46
+ export { NavbarItem } from './navbar/navbar-item.js';
47
+ export { useNavbar } from './navbar/use-navbar.js';
48
+ export { NavbarProvider, useNavbarContext } from './navbar/navbar-context.js';
35
49
  export { Button } from './button/button.js';
36
- export { GovtBanner } from './govt-banner/govt-banner.js';
37
- export { Input } from './input/input.js';
38
50
  export { Description, FieldError, FieldErrorIcon, FieldGroup, Label } from './field/field.js';
39
51
  export { ComboBox, ComboBoxEmptyState } from './combo-box/combo-box.js';
40
52
  export { ComboBoxFuzzy } from './combo-box/combo-box-fuzzy.js';
@@ -51,7 +63,4 @@ export { DatePicker } from './date-picker/date-picker.js';
51
63
  export { DateRangePicker } from './date-range-picker/date-range-picker.js';
52
64
  export { Checkbox, CheckboxGroup } from './checkbox/checkbox.js';
53
65
  export { CheckboxGroupStyleContext, useCheckboxGroupStyleContext } from './checkbox/checkbox-group-style-context.js';
54
- export { FileDropzone } from './file-dropzone/file-dropzone.js';
55
- export { FileInfo } from './file-dropzone/file-info.js';
56
- export { formatBytes, formatErrorMessage } from './file-dropzone/utils.js';
57
66
  export { toast } from 'sonner';
@@ -6,9 +6,9 @@ import { useContextProps, MenuItem as MenuItem$1, composeRenderProps, Provider,
6
6
  import { listBoxItemStyles, menuItemStyles, menuStyles, menuSectionStyles, menuDividerStyles } from '@opengovsg/oui-theme';
7
7
  import { Popover } from '../popover/popover.js';
8
8
  import { forwardRefGeneric, mapPropsVariants } from '../system/utils.js';
9
+ import { createContext } from '../system/react-utils/context.js';
9
10
  import Check from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/check.js';
10
11
  import ChevronRight from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-right.js';
11
- import { createContext } from '../system/react-utils/context.js';
12
12
 
13
13
  const [MenuVariantContext, useMenuVariantContext] = createContext({
14
14
  name: "MenuVariantContext",
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ export { Navbar } from './navbar.js';
3
+ export { NavbarBrand } from './navbar-brand.js';
4
+ export { NavbarContent } from './navbar-content.js';
5
+ export { NavbarMenu } from './navbar-menu/menu.js';
6
+ export { NavbarMenuItem } from './navbar-menu/item.js';
7
+ export { NavbarMenuToggle } from './navbar-menu/toggle.js';
8
+ export { NavbarItem } from './navbar-item.js';
9
+ export { useNavbar } from './use-navbar.js';
10
+ export { NavbarProvider, useNavbarContext } from './navbar-context.js';
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { cn } from '@opengovsg/oui-theme';
5
+ import { forwardRef } from '../system/utils.js';
6
+ import { useNavbarContext } from './navbar-context.js';
7
+ import { useDomRef } from '../system/react-utils/refs.js';
8
+
9
+ const NavbarBrand = forwardRef((props, ref) => {
10
+ const { as, className, children, ...otherProps } = props;
11
+ const Component = as || "div";
12
+ const domRef = useDomRef(ref);
13
+ const { slots, classNames } = useNavbarContext();
14
+ return /* @__PURE__ */ jsx(
15
+ Component,
16
+ {
17
+ ref: domRef,
18
+ className: slots.brand?.({ className: cn(classNames?.brand, className) }),
19
+ ...otherProps,
20
+ children
21
+ }
22
+ );
23
+ });
24
+ NavbarBrand.displayName = "NavbarBrand";
25
+
26
+ export { NavbarBrand };
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { cn } from '@opengovsg/oui-theme';
5
+ import { forwardRef } from '../system/utils.js';
6
+ import { useNavbarContext } from './navbar-context.js';
7
+ import { useDomRef } from '../system/react-utils/refs.js';
8
+
9
+ const NavbarContent = forwardRef(
10
+ (props, ref) => {
11
+ const { as, className, children, justify = "start", ...otherProps } = props;
12
+ const Component = as || "div";
13
+ const domRef = useDomRef(ref);
14
+ const { slots, classNames } = useNavbarContext();
15
+ return /* @__PURE__ */ jsx(
16
+ Component,
17
+ {
18
+ ref: domRef,
19
+ className: slots.content?.({
20
+ className: cn(classNames?.content, className)
21
+ }),
22
+ "data-justify": justify,
23
+ ...otherProps,
24
+ children
25
+ }
26
+ );
27
+ }
28
+ );
29
+ NavbarContent.displayName = "NavbarContent";
30
+
31
+ export { NavbarContent };
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ "use client";
3
+ import { createContext } from '../system/react-utils/context.js';
4
+
5
+ const [NavbarProvider, useNavbarContext] = createContext({
6
+ name: "NavbarContext",
7
+ strict: true,
8
+ errorMessage: "useNavbarContext: `context` is undefined. Seems you forgot to wrap component within <Navbar />"
9
+ });
10
+
11
+ export { NavbarProvider, useNavbarContext };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { dataAttr, cn } from '@opengovsg/oui-theme';
5
+ import { forwardRef } from '../system/utils.js';
6
+ import { useNavbarContext } from './navbar-context.js';
7
+ import { useDomRef } from '../system/react-utils/refs.js';
8
+
9
+ const NavbarItem = forwardRef((props, ref) => {
10
+ const { as, className, children, isActive, ...otherProps } = props;
11
+ const Component = as || "div";
12
+ const domRef = useDomRef(ref);
13
+ const { slots, classNames } = useNavbarContext();
14
+ return /* @__PURE__ */ jsx(
15
+ Component,
16
+ {
17
+ ref: domRef,
18
+ className: slots.item({ className: cn(classNames?.item, className) }),
19
+ "data-active": dataAttr(isActive),
20
+ ...otherProps,
21
+ children
22
+ }
23
+ );
24
+ });
25
+ NavbarItem.displayName = "NavbarItem";
26
+
27
+ export { NavbarItem };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ const i18nStrings = {
3
+ "en-SG": {
4
+ openMenu: "Open navigation menu",
5
+ closeMenu: "Close navigation menu"
6
+ },
7
+ "zh-SG": {
8
+ openMenu: "\u6253\u5F00\u5BFC\u822A\u83DC\u5355",
9
+ closeMenu: "\u5173\u95ED\u5BFC\u822A\u83DC\u5355"
10
+ },
11
+ "ms-SG": {
12
+ openMenu: "Buka menu navigasi",
13
+ closeMenu: "Tutup menu navigasi"
14
+ },
15
+ "ta-SG": {
16
+ openMenu: "\u0BA8\u0BC7\u0BB5\u0BBF\u0B95\u0BC7\u0BB7\u0BA9\u0BCD \u0BAE\u0BC6\u0BA9\u0BC1\u0BB5\u0BC8\u0BA4\u0BCD \u0BA4\u0BBF\u0BB1",
17
+ closeMenu: "\u0BA8\u0BC7\u0BB5\u0BBF\u0B95\u0BC7\u0BB7\u0BA9\u0BCD \u0BAE\u0BC6\u0BA9\u0BC1\u0BB5\u0BC8 \u0BAE\u0BC2\u0B9F\u0BC1"
18
+ }
19
+ };
20
+
21
+ export { i18nStrings };
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { useRenderProps, composeRenderProps } from 'react-aria-components';
5
+ import { navbarMenuItemStyles, cn, dataAttr } from '@opengovsg/oui-theme';
6
+ import { forwardRef } from '../../system/utils.js';
7
+ import { useNavbarContext } from '../navbar-context.js';
8
+ import { useDomRef } from '../../system/react-utils/refs.js';
9
+
10
+ const NavbarMenuItem = forwardRef(
11
+ (props, ref) => {
12
+ const { className, children, isActive, ...otherProps } = props;
13
+ const domRef = useDomRef(ref);
14
+ const { isMenuOpen, classNames } = useNavbarContext();
15
+ const renderProps = useRenderProps({
16
+ className: composeRenderProps(
17
+ className,
18
+ (className2, renderProps2) => navbarMenuItemStyles({
19
+ className: cn(classNames?.menuItem, className2),
20
+ ...renderProps2
21
+ })
22
+ ),
23
+ values: {
24
+ isActive: !!isActive
25
+ }
26
+ });
27
+ return /* @__PURE__ */ jsx(
28
+ "li",
29
+ {
30
+ ref: domRef,
31
+ className: renderProps.className,
32
+ "data-active": dataAttr(isActive),
33
+ "data-open": dataAttr(isMenuOpen),
34
+ ...otherProps,
35
+ children
36
+ }
37
+ );
38
+ }
39
+ );
40
+ NavbarMenuItem.displayName = "NavbarMenuItem";
41
+
42
+ export { NavbarMenuItem };
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { Overlay as $337b884510726a0d$export$c6fdb837b070b4ff } from '../../node_modules/.pnpm/@react-aria_overlays@3.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@react-aria/overlays/dist/Overlay.js';
5
+ import { chain } from 'react-aria';
6
+ import { dataAttr, cn } from '@opengovsg/oui-theme';
7
+ import { forwardRef } from '../../system/utils.js';
8
+ import { useNavbarContext } from '../navbar-context.js';
9
+ import { useDomRef } from '../../system/react-utils/refs.js';
10
+
11
+ const NavbarMenu = forwardRef(
12
+ ({ className, children, portalContainer, style, onKeyDown, ...props }, ref) => {
13
+ const domRef = useDomRef(ref);
14
+ const {
15
+ slots,
16
+ isMenuOpen,
17
+ height,
18
+ classNames,
19
+ setIsMenuOpen,
20
+ domRef: parentRef,
21
+ menuRef
22
+ } = useNavbarContext();
23
+ const handleKeyDown = (e) => {
24
+ if (e.key === "Escape") {
25
+ e.stopPropagation();
26
+ setIsMenuOpen(false);
27
+ menuRef.current?.focus();
28
+ }
29
+ };
30
+ if (!isMenuOpen) return null;
31
+ return /* @__PURE__ */ jsx(
32
+ $337b884510726a0d$export$c6fdb837b070b4ff,
33
+ {
34
+ disableFocusManagement: true,
35
+ portalContainer: portalContainer ?? parentRef.current ?? void 0,
36
+ children: /* @__PURE__ */ jsx(
37
+ "ul",
38
+ {
39
+ ref: domRef,
40
+ className: slots.menu?.({
41
+ className: cn(classNames?.menu, className)
42
+ }),
43
+ "data-open": dataAttr(isMenuOpen),
44
+ style: {
45
+ ...style,
46
+ // @ts-expect-error due to not having any type declaration for CSS variables in React style prop
47
+ "--navbar-height": typeof height === "number" ? `${height}px` : height
48
+ },
49
+ onKeyDown: chain(handleKeyDown, onKeyDown),
50
+ ...props,
51
+ children
52
+ }
53
+ )
54
+ }
55
+ );
56
+ }
57
+ );
58
+ NavbarMenu.displayName = "NavbarMenu";
59
+
60
+ export { NavbarMenu };
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { useMemo } from 'react';
5
+ import { useMessageFormatter, chain } from 'react-aria';
6
+ import { ToggleButton } from 'react-aria-components';
7
+ import { buttonStyles, cn, dataAttr } from '@opengovsg/oui-theme';
8
+ import { useNavbarContext } from '../navbar-context.js';
9
+ import { i18nStrings } from './i18n.js';
10
+
11
+ const NavbarMenuToggle = ({
12
+ icon,
13
+ className,
14
+ onChange,
15
+ classNames,
16
+ size = "sm",
17
+ radius,
18
+ isIconOnly = true,
19
+ ...props
20
+ }) => {
21
+ const {
22
+ slots,
23
+ classNames: contextClassNames,
24
+ isMenuOpen,
25
+ setIsMenuOpen,
26
+ menuRef,
27
+ position
28
+ } = useNavbarContext();
29
+ const shouldScrollToTop = (isMenuOpen2) => {
30
+ if (!isMenuOpen2 || position === "sticky" || typeof window === "undefined") {
31
+ return;
32
+ }
33
+ window.scrollTo({ top: 0, behavior: "instant" });
34
+ };
35
+ const formatMessage = useMessageFormatter(i18nStrings);
36
+ const toggleStyles = useMemo(() => {
37
+ return buttonStyles({
38
+ variant: "unstyled",
39
+ size,
40
+ radius,
41
+ isIconOnly,
42
+ className: slots.toggle({
43
+ className: cn(
44
+ contextClassNames?.toggle,
45
+ className ?? classNames?.toggle
46
+ )
47
+ })
48
+ });
49
+ }, [
50
+ className,
51
+ classNames?.toggle,
52
+ contextClassNames?.toggle,
53
+ isIconOnly,
54
+ radius,
55
+ size,
56
+ slots
57
+ ]);
58
+ const child = useMemo(() => {
59
+ if (typeof icon === "function") {
60
+ return icon(isMenuOpen ?? false);
61
+ }
62
+ return icon || /* @__PURE__ */ jsx(
63
+ "span",
64
+ {
65
+ className: slots.toggleIcon({
66
+ class: cn(contextClassNames?.toggleIcon, classNames?.toggleIcon)
67
+ })
68
+ }
69
+ );
70
+ }, [
71
+ icon,
72
+ slots,
73
+ classNames?.toggleIcon,
74
+ contextClassNames?.toggleIcon,
75
+ isMenuOpen
76
+ ]);
77
+ return /* @__PURE__ */ jsx(
78
+ ToggleButton,
79
+ {
80
+ "aria-label": isMenuOpen ? formatMessage("closeMenu") : formatMessage("openMenu"),
81
+ ref: menuRef,
82
+ "data-open": dataAttr(isMenuOpen),
83
+ className: toggleStyles,
84
+ isSelected: isMenuOpen,
85
+ onChange: chain(onChange, shouldScrollToTop, setIsMenuOpen),
86
+ ...props,
87
+ children: child
88
+ }
89
+ );
90
+ };
91
+
92
+ export { NavbarMenuToggle };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
4
+ import { FocusScope } from 'react-aria';
5
+ import { pickChildren } from '../system/react-utils/children.js';
6
+ import { forwardRef } from '../system/utils.js';
7
+ import { NavbarProvider } from './navbar-context.js';
8
+ import { NavbarMenu } from './navbar-menu/menu.js';
9
+ import { useNavbar } from './use-navbar.js';
10
+
11
+ const Navbar = forwardRef((props, ref) => {
12
+ const { children, ...otherProps } = props;
13
+ const context = useNavbar({ ...otherProps, ref });
14
+ const Component = context.Component;
15
+ const [childrenWithoutMenu, menu] = pickChildren(children, NavbarMenu);
16
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
17
+ /* @__PURE__ */ jsx("header", { ...context.getWrapperProps(), children: childrenWithoutMenu }),
18
+ menu
19
+ ] });
20
+ return /* @__PURE__ */ jsx(NavbarProvider, { value: context, children: /* @__PURE__ */ jsx(FocusScope, { contain: context.isMenuOpen, children: /* @__PURE__ */ jsx(Component, { ...context.getBaseProps(), children: content }) }) });
21
+ });
22
+ Navbar.displayName = "Navbar";
23
+
24
+ export { Navbar };
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ "use client";
3
+ import { useRef, useCallback, useEffect } from 'react';
4
+ import { usePreventScroll as $49c51c25361d4cd2$export$ee0f7cc6afcd1c18 } from '../node_modules/.pnpm/@react-aria_overlays@3.30.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@react-aria/overlays/dist/usePreventScroll.js';
5
+ import { useResizeObserver, mergeProps } from '@react-aria/utils';
6
+ import { useControlledState } from '@react-stately/utils';
7
+ import { useDeepCompareMemo } from 'use-deep-compare';
8
+ import { navbarStyles, cn, dataAttr } from '@opengovsg/oui-theme';
9
+ import { mapPropsVariants } from '../system/utils.js';
10
+ import { useDomRef } from '../system/react-utils/refs.js';
11
+
12
+ function useNavbar(originalProps) {
13
+ const [
14
+ {
15
+ ref,
16
+ as,
17
+ height = "4rem",
18
+ shouldBlockScroll = true,
19
+ isMenuOpen: isMenuOpenProp,
20
+ isMenuDefaultOpen,
21
+ onMenuOpenChange = () => {
22
+ },
23
+ className,
24
+ classNames,
25
+ ...otherProps
26
+ },
27
+ variantProps
28
+ ] = mapPropsVariants(originalProps, navbarStyles.variantKeys);
29
+ const Component = as || "nav";
30
+ const domRef = useDomRef(ref);
31
+ const menuRef = useRef(null);
32
+ const prevWidth = useRef(0);
33
+ const navHeight = useRef(0);
34
+ const handleMenuOpenChange = useCallback(
35
+ (isOpen) => {
36
+ onMenuOpenChange(isOpen || false);
37
+ },
38
+ [onMenuOpenChange]
39
+ );
40
+ const [isMenuOpen, setIsMenuOpen] = useControlledState(
41
+ isMenuOpenProp,
42
+ isMenuDefaultOpen ?? false,
43
+ handleMenuOpenChange
44
+ );
45
+ const updateWidth = useCallback(() => {
46
+ if (domRef.current) {
47
+ const width = domRef.current.offsetWidth;
48
+ if (width !== prevWidth.current) {
49
+ prevWidth.current = width;
50
+ }
51
+ }
52
+ }, [domRef]);
53
+ $49c51c25361d4cd2$export$ee0f7cc6afcd1c18({
54
+ isDisabled: !(shouldBlockScroll && isMenuOpen)
55
+ });
56
+ useResizeObserver({
57
+ ref: domRef,
58
+ onResize: () => {
59
+ const currentWidth = domRef.current?.offsetWidth;
60
+ const scrollWidth = window.innerWidth - document.documentElement.clientWidth;
61
+ if (currentWidth && currentWidth + scrollWidth == prevWidth.current) {
62
+ return;
63
+ }
64
+ if (currentWidth !== prevWidth.current) {
65
+ updateWidth();
66
+ setIsMenuOpen(false);
67
+ }
68
+ }
69
+ });
70
+ useEffect(() => {
71
+ updateWidth();
72
+ navHeight.current = domRef.current?.offsetHeight || 0;
73
+ }, [domRef, updateWidth]);
74
+ const slots = useDeepCompareMemo(
75
+ () => navbarStyles({
76
+ ...variantProps
77
+ }),
78
+ [variantProps]
79
+ );
80
+ const baseStyles = cn(classNames?.base, className);
81
+ const getBaseProps = (props = {}) => ({
82
+ ...mergeProps(otherProps, props),
83
+ "data-menu-open": dataAttr(isMenuOpen),
84
+ ref: domRef,
85
+ className: slots.base({ class: cn(baseStyles, props?.className) }),
86
+ style: {
87
+ "--navbar-height": typeof height === "number" ? `${height}px` : height,
88
+ ...otherProps?.style,
89
+ ...props?.style
90
+ }
91
+ });
92
+ const getWrapperProps = (props = {}) => ({
93
+ ...props,
94
+ "data-menu-open": dataAttr(isMenuOpen),
95
+ className: slots.wrapper({
96
+ class: cn(classNames?.wrapper, props?.className)
97
+ })
98
+ });
99
+ return {
100
+ Component,
101
+ slots,
102
+ domRef,
103
+ height,
104
+ isMenuOpen,
105
+ classNames,
106
+ setIsMenuOpen,
107
+ menuRef,
108
+ getBaseProps,
109
+ getWrapperProps,
110
+ position: variantProps.position ?? "sticky"
111
+ };
112
+ }
113
+
114
+ export { useNavbar };