@nswds/app 1.6.0 → 1.8.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/dist/index.cjs CHANGED
@@ -2,25 +2,55 @@
2
2
 
3
3
  var reactSlot = require('@radix-ui/react-slot')
4
4
  var classVarianceAuthority = require('class-variance-authority')
5
- var clsx2 = require('clsx')
5
+ var clsx5 = require('clsx')
6
6
  var tailwindMerge = require('tailwind-merge')
7
7
  var jsxRuntime = require('react/jsx-runtime')
8
8
  var react = require('react')
9
- var Link3 = require('next/link')
9
+ var Link4 = require('next/link')
10
10
  var navigation = require('next/navigation')
11
- var slugify = require('@sindresorhus/slugify')
12
11
  var nextThemes = require('next-themes')
12
+ var CollapsiblePrimitive = require('@radix-ui/react-collapsible')
13
+ var TabsPrimitive = require('@radix-ui/react-tabs')
14
+ var slugify = require('@sindresorhus/slugify')
13
15
 
14
16
  function _interopDefault(e) {
15
17
  return e && e.__esModule ? e : { default: e }
16
18
  }
17
19
 
18
- var clsx2__default = /*#__PURE__*/ _interopDefault(clsx2)
19
- var Link3__default = /*#__PURE__*/ _interopDefault(Link3)
20
+ function _interopNamespace(e) {
21
+ if (e && e.__esModule) return e
22
+ var n = Object.create(null)
23
+ if (e) {
24
+ Object.keys(e).forEach(function (k) {
25
+ if (k !== 'default') {
26
+ var d = Object.getOwnPropertyDescriptor(e, k)
27
+ Object.defineProperty(
28
+ n,
29
+ k,
30
+ d.get
31
+ ? d
32
+ : {
33
+ enumerable: true,
34
+ get: function () {
35
+ return e[k]
36
+ },
37
+ },
38
+ )
39
+ }
40
+ })
41
+ }
42
+ n.default = e
43
+ return Object.freeze(n)
44
+ }
45
+
46
+ var clsx5__default = /*#__PURE__*/ _interopDefault(clsx5)
47
+ var Link4__default = /*#__PURE__*/ _interopDefault(Link4)
48
+ var CollapsiblePrimitive__namespace = /*#__PURE__*/ _interopNamespace(CollapsiblePrimitive)
49
+ var TabsPrimitive__namespace = /*#__PURE__*/ _interopNamespace(TabsPrimitive)
20
50
 
21
51
  // src/components/Button.tsx
22
52
  function cn(...inputs) {
23
- return tailwindMerge.twMerge(clsx2.clsx(inputs))
53
+ return tailwindMerge.twMerge(clsx5.clsx(inputs))
24
54
  }
25
55
  function truncate(text, maxLength) {
26
56
  if (text.length <= maxLength) {
@@ -38,21 +68,18 @@ function camelCase(str) {
38
68
  return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase())
39
69
  }
40
70
  var buttonVariants = classVarianceAuthority.cva(
41
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-zinc-950 focus-visible:ring-zinc-950/50 focus-visible:ring-[3px] aria-invalid:ring-red-500/20 dark:aria-invalid:ring-red-500/40 aria-invalid:border-red-500 dark:focus-visible:border-zinc-300 dark:focus-visible:ring-zinc-300/50 dark:aria-invalid:ring-red-900/20 dark:dark:aria-invalid:ring-red-900/40 dark:aria-invalid:border-red-900",
71
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
42
72
  {
43
73
  variants: {
44
74
  variant: {
45
- default:
46
- 'bg-zinc-900 text-zinc-50 shadow-xs hover:bg-zinc-900/90 dark:bg-zinc-50 dark:text-zinc-900 dark:hover:bg-zinc-50/90',
75
+ default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
47
76
  destructive:
48
- 'bg-red-500 text-white shadow-xs hover:bg-red-500/90 focus-visible:ring-red-500/20 dark:focus-visible:ring-red-500/40 dark:bg-red-500/60 dark:bg-red-900 dark:hover:bg-red-900/90 dark:focus-visible:ring-red-900/20 dark:dark:focus-visible:ring-red-900/40 dark:dark:bg-red-900/60',
77
+ 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
49
78
  outline:
50
- 'border bg-white shadow-xs hover:bg-zinc-100 hover:text-zinc-900 dark:bg-zinc-200/30 dark:border-zinc-200 dark:hover:bg-zinc-200/50 dark:bg-zinc-950 dark:hover:bg-zinc-800 dark:hover:text-zinc-50 dark:dark:bg-zinc-800/30 dark:dark:border-zinc-800 dark:dark:hover:bg-zinc-800/50',
51
- secondary:
52
- 'bg-zinc-100 text-zinc-900 shadow-xs hover:bg-zinc-100/80 dark:bg-zinc-800 dark:text-zinc-50 dark:hover:bg-zinc-800/80',
53
- ghost:
54
- 'hover:bg-zinc-100 hover:text-zinc-900 dark:hover:bg-zinc-100/50 dark:hover:bg-zinc-800 dark:hover:text-zinc-50 dark:dark:hover:bg-zinc-800/50',
55
- link: 'text-zinc-900 underline-offset-4 hover:underline dark:text-zinc-50',
79
+ 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
80
+ secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
81
+ ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
82
+ link: 'text-primary underline-offset-4 hover:underline',
56
83
  },
57
84
  size: {
58
85
  default: 'h-9 px-4 py-2 has-[>svg]:px-3',
@@ -612,7 +639,7 @@ var Icons = {
612
639
  }),
613
640
  }
614
641
  function SocialLink({ href, icon: Icon, children }) {
615
- return /* @__PURE__ */ jsxRuntime.jsxs(Link3__default.default, {
642
+ return /* @__PURE__ */ jsxRuntime.jsxs(Link4__default.default, {
616
643
  href,
617
644
  className: 'group',
618
645
  children: [
@@ -654,66 +681,13 @@ function Footer() {
654
681
  children: /* @__PURE__ */ jsxRuntime.jsx(SmallPrint, {}),
655
682
  })
656
683
  }
657
- function getNodeText(node) {
658
- let text = ''
659
- for (const child of node.children ?? []) {
660
- if ('type' in child && child.type === 'text') {
661
- text += child.attributes?.content ?? ''
662
- } else if (child instanceof HTMLElement) {
663
- text += getNodeText(child)
664
- }
665
- }
666
- return text
667
- }
668
- function domToSimple(node) {
669
- if (node.nodeType === Node.TEXT_NODE) {
670
- return {
671
- type: 'text',
672
- attributes: {
673
- content: node.textContent ?? void 0,
674
- },
675
- }
676
- }
677
- if (node.nodeType === Node.ELEMENT_NODE) {
678
- return {
679
- type: node.nodeName.toLowerCase(),
680
- attributes: {},
681
- children: Array.from(node.childNodes).map(domToSimple),
682
- }
683
- }
684
- throw new Error('Unsupported node type')
685
- }
686
- function getHeadings(slugify$1 = slugify.slugifyWithCounter()) {
687
- const content = document.querySelector('article')
688
- if (!content) {
689
- return []
690
- }
691
- const headings = Array.from(content.querySelectorAll('h2, h3, h4, h5, h6'))
692
- const result = []
693
- const stack = []
694
- headings.forEach((el) => {
695
- const simplifiedNode = domToSimple(el)
696
- const title = getNodeText(simplifiedNode).trim()
697
- const slugifiedTitle = slugify$1(title)
698
- const id = el.id || slugifiedTitle
699
- const level = parseInt(el.tagName[1])
700
- const node = { level, id, title, children: [] }
701
- if (!el.id) el.id = id
702
- if (level === 2) {
703
- result.push(node)
704
- stack.length = 0
705
- stack.push(node)
706
- } else {
707
- while (stack.length && stack[stack.length - 1].level >= level) {
708
- stack.pop()
709
- }
710
- if (stack.length) {
711
- stack[stack.length - 1].children.push(node)
712
- }
713
- stack.push(node)
714
- }
684
+ function Logo(props) {
685
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
686
+ children: [
687
+ /* @__PURE__ */ jsxRuntime.jsx('span', { className: 'sr-only', children: 'NSW Government' }),
688
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.logo, { ...props }),
689
+ ],
715
690
  })
716
- return result
717
691
  }
718
692
  function Masthead() {
719
693
  return /* @__PURE__ */ jsxRuntime.jsx('div', {
@@ -730,18 +704,10 @@ function Masthead() {
730
704
  }),
731
705
  })
732
706
  }
733
- function Logo(props) {
734
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
735
- children: [
736
- /* @__PURE__ */ jsxRuntime.jsx('span', { className: 'sr-only', children: 'NSW Government' }),
737
- /* @__PURE__ */ jsxRuntime.jsx(Icons.logo, { ...props }),
738
- ],
739
- })
740
- }
741
707
  function Navigation({ className, onLinkClick, navigation: navigation$1 }) {
742
708
  const pathname = navigation.usePathname()
743
709
  return /* @__PURE__ */ jsxRuntime.jsx('nav', {
744
- className: clsx2__default.default('text-base lg:text-sm', className),
710
+ className: clsx5__default.default('text-base lg:text-sm', className),
745
711
  children: /* @__PURE__ */ jsxRuntime.jsx('ul', {
746
712
  role: 'list',
747
713
  className: 'flex flex-col gap-9',
@@ -763,10 +729,10 @@ function Navigation({ className, onLinkClick, navigation: navigation$1 }) {
763
729
  'li',
764
730
  {
765
731
  className: '-ml-px flex flex-col items-start gap-2',
766
- children: /* @__PURE__ */ jsxRuntime.jsx(Link3__default.default, {
732
+ children: /* @__PURE__ */ jsxRuntime.jsx(Link4__default.default, {
767
733
  href: link.href,
768
734
  onClick: onLinkClick,
769
- className: clsx2__default.default(
735
+ className: clsx5__default.default(
770
736
  'text-foreground inline-block border-l pl-5 text-base/8 sm:pl-4 sm:text-sm/6',
771
737
  'hover:border-nsw-grey-950 hover:text-nsw-gray-950 hover:font-semibold',
772
738
  'dark:text-nsw-grey-400',
@@ -789,39 +755,65 @@ function Navigation({ className, onLinkClick, navigation: navigation$1 }) {
789
755
  }),
790
756
  })
791
757
  }
792
- function ThemeSwitcher() {
793
- const { resolvedTheme, setTheme } = nextThemes.useTheme()
794
- const [mounted, setMounted] = react.useState(false)
795
- const classes = 'fill-nsw-grey-600 dark:fill-nsw-grey-100 size-6'
796
- react.useEffect(() => {
797
- setMounted(true)
798
- }, [])
799
- if (!mounted) {
800
- return /* @__PURE__ */ jsxRuntime.jsx(Button, {
801
- variant: 'ghost',
802
- size: 'icon',
803
- className: 'h-10 w-10',
804
- disabled: true,
805
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.light_mode, { className: classes }),
806
- })
807
- }
808
- return /* @__PURE__ */ jsxRuntime.jsxs(Button, {
809
- variant: 'outline',
810
- size: 'icon',
811
- className: 'h-10 w-10 cursor-pointer',
812
- onClick: () => setTheme(resolvedTheme === 'dark' ? 'light' : 'dark'),
813
- 'aria-label': `Switch to ${resolvedTheme === 'dark' ? 'light' : 'dark'} theme`,
758
+ function ArrowIcon(props) {
759
+ return /* @__PURE__ */ jsxRuntime.jsx('svg', {
760
+ viewBox: '0 0 16 16',
761
+ 'aria-hidden': 'true',
762
+ ...props,
763
+ children: /* @__PURE__ */ jsxRuntime.jsx('path', {
764
+ d: 'm9.182 13.423-1.17-1.16 3.505-3.505H3V7.065h8.517l-3.506-3.5L9.181 2.4l5.512 5.511-5.511 5.512Z',
765
+ }),
766
+ })
767
+ }
768
+ function PageLink({ title, href, dir = 'next', ...props }) {
769
+ return /* @__PURE__ */ jsxRuntime.jsxs('div', {
770
+ ...props,
814
771
  children: [
815
- resolvedTheme === 'dark'
816
- ? /* @__PURE__ */ jsxRuntime.jsx(Icons.light_mode, { className: classes })
817
- : /* @__PURE__ */ jsxRuntime.jsx(Icons.dark_mode, { className: classes }),
818
- /* @__PURE__ */ jsxRuntime.jsx('span', {
819
- className: 'sr-only',
820
- children: resolvedTheme === 'dark' ? 'Switch to light theme' : 'Switch to dark theme',
772
+ /* @__PURE__ */ jsxRuntime.jsx('dt', {
773
+ className: 'font-display text-sm font-medium text-slate-900 dark:text-white',
774
+ children: dir === 'next' ? 'Next' : 'Previous',
775
+ }),
776
+ /* @__PURE__ */ jsxRuntime.jsx('dd', {
777
+ className: 'mt-1',
778
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Link4__default.default, {
779
+ href,
780
+ className: clsx5__default.default(
781
+ 'flex items-center gap-x-1 text-base font-semibold text-slate-500 hover:text-slate-600 dark:text-slate-400 dark:hover:text-slate-300',
782
+ dir === 'previous' && 'flex-row-reverse',
783
+ ),
784
+ children: [
785
+ title,
786
+ /* @__PURE__ */ jsxRuntime.jsx(ArrowIcon, {
787
+ className: clsx5__default.default(
788
+ 'h-4 w-4 flex-none fill-current',
789
+ dir === 'previous' && '-scale-x-100',
790
+ ),
791
+ }),
792
+ ],
793
+ }),
821
794
  }),
822
795
  ],
823
796
  })
824
797
  }
798
+ function PrevNextLinks({ navigation: navigation$1 }) {
799
+ const pathname = navigation.usePathname()
800
+ const allLinks = navigation$1.flatMap((section) => section.links)
801
+ const linkIndex = allLinks.findIndex((link) => link.href === pathname)
802
+ const previousPage = linkIndex > -1 ? allLinks[linkIndex - 1] : null
803
+ const nextPage = linkIndex > -1 ? allLinks[linkIndex + 1] : null
804
+ if (!nextPage && !previousPage) {
805
+ return null
806
+ }
807
+ return /* @__PURE__ */ jsxRuntime.jsxs('dl', {
808
+ className: 'mt-12 flex border-t border-slate-200 pt-6 dark:border-slate-800',
809
+ children: [
810
+ previousPage &&
811
+ /* @__PURE__ */ jsxRuntime.jsx(PageLink, { dir: 'previous', ...previousPage }),
812
+ nextPage &&
813
+ /* @__PURE__ */ jsxRuntime.jsx(PageLink, { className: 'ml-auto text-right', ...nextPage }),
814
+ ],
815
+ })
816
+ }
825
817
  function TableOfContents({ tableOfContents }) {
826
818
  const [currentSection, setCurrentSection] = react.useState(tableOfContents[0]?.id)
827
819
  const getHeadings2 = react.useCallback((tableOfContents2) => {
@@ -891,9 +883,9 @@ function TableOfContents({ tableOfContents }) {
891
883
  {
892
884
  children: [
893
885
  /* @__PURE__ */ jsxRuntime.jsx('h3', {
894
- children: /* @__PURE__ */ jsxRuntime.jsx(Link3__default.default, {
886
+ children: /* @__PURE__ */ jsxRuntime.jsx(Link4__default.default, {
895
887
  href: `#${section.id}`,
896
- className: clsx2__default.default(
888
+ className: clsx5__default.default(
897
889
  isActive(section)
898
890
  ? 'text-primary font-semibold'
899
891
  : 'font-normal text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-300',
@@ -909,7 +901,7 @@ function TableOfContents({ tableOfContents }) {
909
901
  /* @__PURE__ */ jsxRuntime.jsx(
910
902
  'li',
911
903
  {
912
- children: /* @__PURE__ */ jsxRuntime.jsx(Link3__default.default, {
904
+ children: /* @__PURE__ */ jsxRuntime.jsx(Link4__default.default, {
913
905
  href: `#${subSection.id}`,
914
906
  className: isActive(subSection)
915
907
  ? 'text-primary-light font-semibold'
@@ -932,225 +924,297 @@ function TableOfContents({ tableOfContents }) {
932
924
  }),
933
925
  })
934
926
  }
935
- function ArrowIcon(props) {
936
- return /* @__PURE__ */ jsxRuntime.jsx('svg', {
937
- viewBox: '0 0 16 16',
938
- 'aria-hidden': 'true',
939
- ...props,
940
- children: /* @__PURE__ */ jsxRuntime.jsx('path', {
941
- d: 'm9.182 13.423-1.17-1.16 3.505-3.505H3V7.065h8.517l-3.506-3.5L9.181 2.4l5.512 5.511-5.511 5.512Z',
942
- }),
943
- })
944
- }
945
- function PageLink({ title, href, dir = 'next', ...props }) {
946
- return /* @__PURE__ */ jsxRuntime.jsxs('div', {
947
- ...props,
927
+ function ThemeSwitcher() {
928
+ const { resolvedTheme, setTheme } = nextThemes.useTheme()
929
+ const [mounted, setMounted] = react.useState(false)
930
+ const classes = 'fill-nsw-grey-600 dark:fill-nsw-grey-100 size-6'
931
+ react.useEffect(() => {
932
+ setMounted(true)
933
+ }, [])
934
+ if (!mounted) {
935
+ return /* @__PURE__ */ jsxRuntime.jsx(Button, {
936
+ variant: 'ghost',
937
+ size: 'icon',
938
+ className: 'h-10 w-10',
939
+ disabled: true,
940
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.light_mode, { className: classes }),
941
+ })
942
+ }
943
+ return /* @__PURE__ */ jsxRuntime.jsxs(Button, {
944
+ variant: 'outline',
945
+ size: 'icon',
946
+ className: 'h-10 w-10 cursor-pointer',
947
+ onClick: () => setTheme(resolvedTheme === 'dark' ? 'light' : 'dark'),
948
+ 'aria-label': `Switch to ${resolvedTheme === 'dark' ? 'light' : 'dark'} theme`,
948
949
  children: [
949
- /* @__PURE__ */ jsxRuntime.jsx('dt', {
950
- className: 'font-display text-sm font-medium text-slate-900 dark:text-white',
951
- children: dir === 'next' ? 'Next' : 'Previous',
952
- }),
953
- /* @__PURE__ */ jsxRuntime.jsx('dd', {
954
- className: 'mt-1',
955
- children: /* @__PURE__ */ jsxRuntime.jsxs(Link3__default.default, {
956
- href,
957
- className: clsx2__default.default(
958
- 'flex items-center gap-x-1 text-base font-semibold text-slate-500 hover:text-slate-600 dark:text-slate-400 dark:hover:text-slate-300',
959
- dir === 'previous' && 'flex-row-reverse',
960
- ),
961
- children: [
962
- title,
963
- /* @__PURE__ */ jsxRuntime.jsx(ArrowIcon, {
964
- className: clsx2__default.default(
965
- 'h-4 w-4 flex-none fill-current',
966
- dir === 'previous' && '-scale-x-100',
967
- ),
968
- }),
969
- ],
970
- }),
950
+ resolvedTheme === 'dark'
951
+ ? /* @__PURE__ */ jsxRuntime.jsx(Icons.light_mode, { className: classes })
952
+ : /* @__PURE__ */ jsxRuntime.jsx(Icons.dark_mode, { className: classes }),
953
+ /* @__PURE__ */ jsxRuntime.jsx('span', {
954
+ className: 'sr-only',
955
+ children: resolvedTheme === 'dark' ? 'Switch to light theme' : 'Switch to dark theme',
971
956
  }),
972
957
  ],
973
958
  })
974
959
  }
975
- function PrevNextLinks({ navigation: navigation$1 }) {
976
- const pathname = navigation.usePathname()
977
- const allLinks = navigation$1.flatMap((section) => section.links)
978
- const linkIndex = allLinks.findIndex((link) => link.href === pathname)
979
- const previousPage = linkIndex > -1 ? allLinks[linkIndex - 1] : null
980
- const nextPage = linkIndex > -1 ? allLinks[linkIndex + 1] : null
981
- if (!nextPage && !previousPage) {
982
- return null
983
- }
984
- return /* @__PURE__ */ jsxRuntime.jsxs('dl', {
985
- className: 'mt-12 flex border-t border-slate-200 pt-6 dark:border-slate-800',
986
- children: [
987
- previousPage &&
988
- /* @__PURE__ */ jsxRuntime.jsx(PageLink, { dir: 'previous', ...previousPage }),
989
- nextPage &&
990
- /* @__PURE__ */ jsxRuntime.jsx(PageLink, { className: 'ml-auto text-right', ...nextPage }),
991
- ],
960
+ function Collapsible({ ...props }) {
961
+ return /* @__PURE__ */ jsxRuntime.jsx(CollapsiblePrimitive__namespace.Root, {
962
+ 'data-slot': 'collapsible',
963
+ ...props,
992
964
  })
993
965
  }
994
- var defaultNavigation = [
995
- {
996
- title: 'Getting Started',
997
- links: [
998
- { title: 'Introduction', href: '/' },
999
- { title: 'Installation', href: '/installation' },
1000
- ],
1001
- },
1002
- {
1003
- title: 'Components',
1004
- links: [
1005
- { title: 'Button', href: '/components/button' },
1006
- { title: 'Layout', href: '/components/layout' },
1007
- { title: 'Navigation', href: '/components/navigation' },
1008
- ],
1009
- },
1010
- ]
1011
- function usePageHeadings() {
1012
- const [headings, setHeadings] = react.useState([])
1013
- react.useEffect(() => {
1014
- const result = getHeadings()
1015
- setHeadings(result)
1016
- }, [])
1017
- return headings
966
+ function CollapsibleTrigger2({ ...props }) {
967
+ return /* @__PURE__ */ jsxRuntime.jsx(CollapsiblePrimitive__namespace.CollapsibleTrigger, {
968
+ 'data-slot': 'collapsible-trigger',
969
+ ...props,
970
+ })
1018
971
  }
1019
- function Header({ sitename } = {}) {
1020
- const [isScrolled, setIsScrolled] = react.useState(false)
1021
- react.useEffect(() => {
1022
- function onScroll() {
1023
- setIsScrolled(window.scrollY > 0)
1024
- }
1025
- onScroll()
1026
- window.addEventListener('scroll', onScroll, { passive: true })
1027
- return () => {
1028
- window.removeEventListener('scroll', onScroll)
1029
- }
1030
- }, [])
1031
- return /* @__PURE__ */ jsxRuntime.jsxs('header', {
1032
- className: clsx2__default.default(
1033
- 'sticky top-0 z-50 flex flex-none flex-wrap items-center justify-between bg-white px-4 py-5 shadow-md shadow-slate-900/5 transition duration-500 sm:px-6 lg:px-8 dark:shadow-none',
1034
- isScrolled
1035
- ? 'dark:bg-slate-900/95 dark:backdrop-blur-sm dark:[@supports(backdrop-filter:blur(0))]:bg-slate-900/75'
1036
- : 'dark:bg-transparent',
1037
- ),
1038
- children: [
1039
- /* @__PURE__ */ jsxRuntime.jsx('div', { className: 'mr-6 flex lg:hidden' }),
1040
- /* @__PURE__ */ jsxRuntime.jsx('div', {
1041
- className: 'relative flex grow basis-0 items-center',
1042
- children: /* @__PURE__ */ jsxRuntime.jsxs(Link3__default.default, {
1043
- href: '/',
1044
- 'aria-label': 'Home page',
1045
- className: 'flex items-center justify-between',
1046
- children: [
1047
- /* @__PURE__ */ jsxRuntime.jsx(Logo, { className: 'h-12 w-auto lg:h-14' }),
1048
- /* @__PURE__ */ jsxRuntime.jsx('h2', {
1049
- className: 'text-primary ml-6 text-2xl font-semibold dark:text-white',
1050
- children: sitename,
1051
- }),
1052
- ],
1053
- }),
1054
- }),
1055
- /* @__PURE__ */ jsxRuntime.jsx('div', { className: '-my-5 mr-6 sm:mr-8 md:mr-0' }),
1056
- /* @__PURE__ */ jsxRuntime.jsxs('div', {
1057
- className: 'relative flex basis-0 justify-end gap-2 sm:gap-4 md:grow',
1058
- children: [
1059
- /* @__PURE__ */ jsxRuntime.jsx(ThemeSwitcher, {}),
1060
- /* @__PURE__ */ jsxRuntime.jsx(Button, {
1061
- variant: 'outline',
1062
- size: 'icon',
1063
- className: 'h-10 w-10',
1064
- asChild: true,
1065
- children: /* @__PURE__ */ jsxRuntime.jsx(Link3__default.default, {
1066
- href: 'https://github.com',
1067
- className: 'group',
1068
- 'aria-label': 'GitHub',
1069
- children: /* @__PURE__ */ jsxRuntime.jsx(Icons.github, {
1070
- className: 'fill-nsw-grey-600 dark:fill-nsw-grey-100 size-6',
1071
- }),
1072
- }),
1073
- }),
1074
- ],
1075
- }),
1076
- ],
972
+ function CollapsibleContent2({ ...props }) {
973
+ return /* @__PURE__ */ jsxRuntime.jsx(CollapsiblePrimitive__namespace.CollapsibleContent, {
974
+ 'data-slot': 'collapsible-content',
975
+ ...props,
1077
976
  })
1078
977
  }
1079
- function Layout({ children, sitename, navigation: navigation$1 = defaultNavigation }) {
978
+ function SidebarNavigation({ className, onLinkClick, navigation: navigation$1 }) {
1080
979
  const pathname = navigation.usePathname()
1081
- const isHomePage = pathname === '/'
1082
- const tableOfContents = usePageHeadings()
1083
- return /* @__PURE__ */ jsxRuntime.jsxs('div', {
1084
- className: 'flex w-full flex-col',
1085
- children: [
1086
- /* @__PURE__ */ jsxRuntime.jsx(Masthead, {}),
1087
- /* @__PURE__ */ jsxRuntime.jsx(Header, { sitename }),
1088
- isHomePage && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {}),
1089
- /* @__PURE__ */ jsxRuntime.jsxs('div', {
1090
- className:
1091
- 'max-w-8xl relative mx-auto flex w-full flex-auto justify-center sm:px-2 lg:px-8 xl:px-12',
1092
- children: [
1093
- /* @__PURE__ */ jsxRuntime.jsxs('div', {
1094
- className: 'hidden lg:relative lg:block lg:flex-none',
980
+ return /* @__PURE__ */ jsxRuntime.jsx('nav', {
981
+ className: clsx5__default.default('text-base lg:text-sm', className),
982
+ children: /* @__PURE__ */ jsxRuntime.jsx('ul', {
983
+ role: 'list',
984
+ className: 'flex flex-col gap-9',
985
+ children: navigation$1.map((section, sectionIndex) =>
986
+ /* @__PURE__ */ jsxRuntime.jsxs(
987
+ 'li',
988
+ {
1095
989
  children: [
1096
- /* @__PURE__ */ jsxRuntime.jsx('div', {
1097
- className: 'bg-nsw-grey-50 absolute inset-y-0 right-0 w-[50vw] dark:hidden',
1098
- }),
1099
- /* @__PURE__ */ jsxRuntime.jsx('div', {
1100
- className:
1101
- 'from-nsw-grey-600 absolute top-16 right-0 bottom-0 hidden h-12 w-px bg-linear-to-t dark:block',
1102
- }),
1103
- /* @__PURE__ */ jsxRuntime.jsx('div', {
1104
- className:
1105
- 'bg-nsw-grey-600 absolute top-28 right-0 bottom-0 hidden w-px dark:block',
990
+ /* @__PURE__ */ jsxRuntime.jsx('h2', {
991
+ className: 'font-display text-foreground font-medium dark:text-white',
992
+ children: section.title,
1106
993
  }),
1107
- /* @__PURE__ */ jsxRuntime.jsx('div', {
994
+ /* @__PURE__ */ jsxRuntime.jsx('ul', {
995
+ role: 'list',
1108
996
  className:
1109
- 'sticky top-[4.75rem] -ml-0.5 h-[calc(100vh-4.75rem)] w-64 overflow-x-hidden overflow-y-auto py-16 pr-8 pl-0.5 xl:w-72 xl:pr-16',
1110
- children: /* @__PURE__ */ jsxRuntime.jsx(Navigation, { navigation: navigation$1 }),
997
+ 'border-nsw-grey-400 dark:border-nsw-grey-200/15 mt-2 flex flex-col gap-2 border-l lg:mt-4',
998
+ children: section.links.map((link) =>
999
+ /* @__PURE__ */ jsxRuntime.jsx(
1000
+ SidebarLink,
1001
+ {
1002
+ link,
1003
+ pathname,
1004
+ onLinkClick: onLinkClick || (() => {}),
1005
+ depth: 1,
1006
+ },
1007
+ link.href,
1008
+ ),
1009
+ ),
1111
1010
  }),
1112
1011
  ],
1113
- }),
1114
- /* @__PURE__ */ jsxRuntime.jsxs('div', {
1115
- className: 'flex flex-1 flex-col',
1116
- children: [
1117
- /* @__PURE__ */ jsxRuntime.jsxs('div', {
1118
- className: 'flex flex-1',
1012
+ },
1013
+ sectionIndex,
1014
+ ),
1015
+ ),
1016
+ }),
1017
+ })
1018
+ }
1019
+ function SidebarLink({ link, pathname, onLinkClick, depth }) {
1020
+ const hasChildren = Array.isArray(link.links) && link.links.length > 0
1021
+ const isActive = pathname === link.href
1022
+ const baseLinkClasses = clsx5__default.default(
1023
+ 'border-l pl-4 pr-2 text-base/8 sm:text-sm/6 w-full text-left py-1 rounded-r-md cursor-pointer',
1024
+ 'hover:border-nsw-grey-950 hover:text-nsw-gray-950 hover:font-semibold hover:bg-primary/10',
1025
+ 'dark:text-nsw-grey-400 dark:hover:border-nsw-grey-400 dark:hover:text-white',
1026
+ isActive &&
1027
+ 'border-primary text-primary font-bold dark:border-white bg-nsw-sky-100 dark:bg-nsw-sky-900/20',
1028
+ )
1029
+ return /* @__PURE__ */ jsxRuntime.jsx('li', {
1030
+ className: '-ml-px flex flex-col items-start gap-1',
1031
+ children: hasChildren
1032
+ ? /* @__PURE__ */ jsxRuntime.jsxs(Collapsible, {
1033
+ className: 'w-full',
1034
+ defaultOpen: isActive,
1035
+ children: [
1036
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleTrigger2, {
1037
+ asChild: true,
1038
+ children: /* @__PURE__ */ jsxRuntime.jsxs('button', {
1039
+ className: clsx5__default.default(
1040
+ baseLinkClasses,
1041
+ 'group flex items-center justify-between gap-1',
1042
+ ),
1119
1043
  children: [
1120
- /* @__PURE__ */ jsxRuntime.jsxs('div', {
1121
- className:
1122
- 'max-w-2xl min-w-0 flex-auto px-4 py-16 lg:max-w-none lg:pr-0 lg:pl-8 xl:px-16',
1123
- children: [
1124
- /* @__PURE__ */ jsxRuntime.jsx('article', { children }),
1125
- /* @__PURE__ */ jsxRuntime.jsx(PrevNextLinks, { navigation: navigation$1 }),
1126
- ],
1044
+ /* @__PURE__ */ jsxRuntime.jsx('span', { children: link.title }),
1045
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.chevron_right, {
1046
+ className: clsx5__default.default(
1047
+ 'ml-2 size-5 transition-transform duration-200',
1048
+ 'group-data-[state=open]:rotate-90',
1049
+ ),
1127
1050
  }),
1128
- /* @__PURE__ */ jsxRuntime.jsx(TableOfContents, { tableOfContents }),
1129
1051
  ],
1130
1052
  }),
1131
- /* @__PURE__ */ jsxRuntime.jsx(Footer, {}),
1132
- ],
1133
- }),
1134
- ],
1135
- }),
1136
- ],
1053
+ }),
1054
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent2, {
1055
+ children: /* @__PURE__ */ jsxRuntime.jsx('ul', {
1056
+ className: clsx5__default.default(
1057
+ 'border-nsw-grey-400 dark:border-nsw-grey-200/15 mt-2 ml-5 flex flex-col gap-1 border-l pl-0',
1058
+ ),
1059
+ children:
1060
+ link.links &&
1061
+ link.links.map((childLink) =>
1062
+ /* @__PURE__ */ jsxRuntime.jsx(
1063
+ SidebarLink,
1064
+ {
1065
+ link: childLink,
1066
+ pathname,
1067
+ onLinkClick,
1068
+ depth: depth + 1,
1069
+ },
1070
+ childLink.href,
1071
+ ),
1072
+ ),
1073
+ }),
1074
+ }),
1075
+ ],
1076
+ })
1077
+ : /* @__PURE__ */ jsxRuntime.jsx(Link4__default.default, {
1078
+ href: link.href,
1079
+ onClick: onLinkClick,
1080
+ className: baseLinkClasses,
1081
+ children: link.title,
1082
+ }),
1083
+ })
1084
+ }
1085
+ function Tabs({ className, ...props }) {
1086
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive__namespace.Root, {
1087
+ 'data-slot': 'tabs',
1088
+ className: cn('flex flex-col gap-2', className),
1089
+ ...props,
1090
+ })
1091
+ }
1092
+ function TabsList({ className, ...props }) {
1093
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive__namespace.List, {
1094
+ 'data-slot': 'tabs-list',
1095
+ className: cn(
1096
+ 'bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]',
1097
+ className,
1098
+ ),
1099
+ ...props,
1100
+ })
1101
+ }
1102
+ function TabsTrigger({ className, ...props }) {
1103
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive__namespace.Trigger, {
1104
+ 'data-slot': 'tabs-trigger',
1105
+ className: cn(
1106
+ "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1107
+ className,
1108
+ ),
1109
+ ...props,
1110
+ })
1111
+ }
1112
+ function TabsContent({ className, ...props }) {
1113
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive__namespace.Content, {
1114
+ 'data-slot': 'tabs-content',
1115
+ className: cn('flex-1 outline-none', className),
1116
+ ...props,
1117
+ })
1118
+ }
1119
+ function ThemeProvider({ children, ...props }) {
1120
+ return /* @__PURE__ */ jsxRuntime.jsx(nextThemes.ThemeProvider, { ...props, children })
1121
+ }
1122
+ var TocContext = react.createContext({
1123
+ toc: true,
1124
+ setToc: () => {},
1125
+ })
1126
+ function TocProvider({ children }) {
1127
+ const [toc, setToc] = react.useState(true)
1128
+ return /* @__PURE__ */ jsxRuntime.jsx(TocContext.Provider, { value: { toc, setToc }, children })
1129
+ }
1130
+ function getNodeText(node) {
1131
+ let text = ''
1132
+ for (const child of node.children ?? []) {
1133
+ if ('type' in child && child.type === 'text') {
1134
+ text += child.attributes?.content ?? ''
1135
+ } else if (child instanceof HTMLElement) {
1136
+ text += getNodeText(child)
1137
+ }
1138
+ }
1139
+ return text
1140
+ }
1141
+ function domToSimple(node) {
1142
+ if (node.nodeType === Node.TEXT_NODE) {
1143
+ return {
1144
+ type: 'text',
1145
+ attributes: {
1146
+ content: node.textContent ?? void 0,
1147
+ },
1148
+ }
1149
+ }
1150
+ if (node.nodeType === Node.ELEMENT_NODE) {
1151
+ return {
1152
+ type: node.nodeName.toLowerCase(),
1153
+ attributes: {},
1154
+ children: Array.from(node.childNodes).map(domToSimple),
1155
+ }
1156
+ }
1157
+ if (node.nodeType === Node.COMMENT_NODE) {
1158
+ return {
1159
+ type: 'comment',
1160
+ attributes: {},
1161
+ }
1162
+ }
1163
+ throw new Error('Unsupported node type')
1164
+ }
1165
+ function getHeadings(slugify$1 = slugify.slugifyWithCounter()) {
1166
+ const content = document.querySelector('article')
1167
+ if (!content) {
1168
+ return []
1169
+ }
1170
+ const headings = Array.from(content.querySelectorAll('h2, h3, h4, h5, h6'))
1171
+ const result = []
1172
+ const stack = []
1173
+ headings.forEach((el) => {
1174
+ const simplifiedNode = domToSimple(el)
1175
+ const title = getNodeText(simplifiedNode).trim()
1176
+ const slugifiedTitle = slugify$1(title)
1177
+ const id = el.id || slugifiedTitle
1178
+ const level = parseInt(el.tagName[1])
1179
+ const node = { level, id, title, children: [] }
1180
+ if (!el.id) el.id = id
1181
+ if (level === 2) {
1182
+ result.push(node)
1183
+ stack.length = 0
1184
+ stack.push(node)
1185
+ } else {
1186
+ while (stack.length && stack[stack.length - 1].level >= level) {
1187
+ stack.pop()
1188
+ }
1189
+ if (stack.length) {
1190
+ stack[stack.length - 1].children.push(node)
1191
+ }
1192
+ stack.push(node)
1193
+ }
1137
1194
  })
1195
+ return result
1138
1196
  }
1139
1197
 
1140
1198
  exports.Button = Button
1199
+ exports.Collapsible = Collapsible
1141
1200
  exports.DynamicFavicon = DynamicFavicon
1142
1201
  exports.Footer = Footer
1143
1202
  exports.Icons = Icons
1144
- exports.Layout = Layout
1145
1203
  exports.Logo = Logo
1146
1204
  exports.Masthead = Masthead
1147
1205
  exports.Navigation = Navigation
1148
1206
  exports.PrevNextLinks = PrevNextLinks
1207
+ exports.SidebarNavigation = SidebarNavigation
1149
1208
  exports.TableOfContents = TableOfContents
1209
+ exports.Tabs = Tabs
1210
+ exports.TabsContent = TabsContent
1211
+ exports.TabsList = TabsList
1212
+ exports.TabsTrigger = TabsTrigger
1213
+ exports.ThemeProvider = ThemeProvider
1150
1214
  exports.ThemeSwitcher = ThemeSwitcher
1215
+ exports.TocProvider = TocProvider
1151
1216
  exports.camelCase = camelCase
1152
1217
  exports.cn = cn
1153
- exports.defaultNavigation = defaultNavigation
1154
1218
  exports.domToSimple = domToSimple
1155
1219
  exports.getHeadings = getHeadings
1156
1220
  exports.getNodeText = getNodeText