@casinogate/ui 1.8.8 → 1.9.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.
Files changed (27) hide show
  1. package/dist/assets/css/root.css +75 -39
  2. package/dist/components/navigation/components/navigation.content.svelte +3 -4
  3. package/dist/components/navigation/components/navigation.item.svelte +19 -17
  4. package/dist/components/navigation/components/navigation.root.svelte +10 -12
  5. package/dist/components/navigation/components/navigation.sub-content.svelte +27 -28
  6. package/dist/components/navigation/components/navigation.sub-trigger.svelte +107 -0
  7. package/dist/components/navigation/components/navigation.sub-trigger.svelte.d.ts +4 -0
  8. package/dist/components/navigation/components/navigation.sub.svelte +55 -0
  9. package/dist/components/navigation/components/navigation.sub.svelte.d.ts +4 -0
  10. package/dist/components/navigation/components/navigation.svelte.d.ts +45 -15
  11. package/dist/components/navigation/components/navigation.svelte.js +68 -28
  12. package/dist/components/navigation/components/navigation.trigger.svelte +36 -80
  13. package/dist/components/navigation/exports-primitive.d.ts +2 -0
  14. package/dist/components/navigation/exports-primitive.js +2 -0
  15. package/dist/components/navigation/exports.d.ts +1 -1
  16. package/dist/components/navigation/exports.js +1 -1
  17. package/dist/components/navigation/index.d.ts +2 -1
  18. package/dist/components/navigation/index.js +1 -0
  19. package/dist/components/navigation/navigation.svelte +114 -29
  20. package/dist/components/navigation/navigation.svelte.d.ts +3 -0
  21. package/dist/components/navigation/styles.d.ts +19 -28
  22. package/dist/components/navigation/styles.js +45 -28
  23. package/dist/components/navigation/types.d.ts +59 -20
  24. package/dist/components/popover/popover.svelte +12 -3
  25. package/dist/components/popover/styles.js +1 -1
  26. package/dist/components/popover/types.d.ts +3 -1
  27. package/package.json +1 -1
@@ -226,6 +226,9 @@
226
226
  .cgui\:z-\(--cg-ui-z-index-dropdown\) {
227
227
  z-index: var(--cg-ui-z-index-dropdown);
228
228
  }
229
+ .cgui\:z-\(--cg-ui-z-index-popover\) {
230
+ z-index: var(--cg-ui-z-index-popover);
231
+ }
229
232
  .cgui\:z-\(--cg-ui-z-index-select\) {
230
233
  z-index: var(--cg-ui-z-index-select);
231
234
  }
@@ -291,6 +294,9 @@
291
294
  .cgui\:hidden {
292
295
  display: none;
293
296
  }
297
+ .cgui\:inline-block {
298
+ display: inline-block;
299
+ }
294
300
  .cgui\:inline-flex {
295
301
  display: inline-flex;
296
302
  }
@@ -431,9 +437,6 @@
431
437
  .cgui\:w-\(--app-shell-sidebar-width\) {
432
438
  width: var(--app-shell-sidebar-width);
433
439
  }
434
- .cgui\:w-0 {
435
- width: calc(var(--cgui-spacing) * 0);
436
- }
437
440
  .cgui\:w-1\.5 {
438
441
  width: calc(var(--cgui-spacing) * 1.5);
439
442
  }
@@ -536,6 +539,9 @@
536
539
  .cgui\:min-w-35 {
537
540
  min-width: calc(var(--cgui-spacing) * 35);
538
541
  }
542
+ .cgui\:min-w-40 {
543
+ min-width: calc(var(--cgui-spacing) * 40);
544
+ }
539
545
  .cgui\:min-w-42 {
540
546
  min-width: calc(var(--cgui-spacing) * 42);
541
547
  }
@@ -578,9 +584,6 @@
578
584
  --tw-scale-x: calc(1 * -1);
579
585
  scale: var(--tw-scale-x) var(--tw-scale-y);
580
586
  }
581
- .cgui\:rotate-180 {
582
- rotate: 180deg;
583
- }
584
587
  .cgui\:animate-pulse {
585
588
  animation: var(--cgui-animate-pulse);
586
589
  }
@@ -849,6 +852,9 @@
849
852
  .cgui\:bg-surface-darkest {
850
853
  background-color: var(--cg-ui-color-surface-darkest);
851
854
  }
855
+ .cgui\:bg-surface-hover {
856
+ background-color: var(--cg-ui-color-surface-hover);
857
+ }
852
858
  .cgui\:bg-surface-light {
853
859
  background-color: var(--cg-ui-color-surface-light);
854
860
  }
@@ -927,6 +933,9 @@
927
933
  .cgui\:p-4 {
928
934
  padding: calc(var(--cgui-spacing) * 4);
929
935
  }
936
+ .cgui\:px-1 {
937
+ padding-inline: calc(var(--cgui-spacing) * 1);
938
+ }
930
939
  .cgui\:px-1\.5 {
931
940
  padding-inline: calc(var(--cgui-spacing) * 1.5);
932
941
  }
@@ -1131,9 +1140,6 @@
1131
1140
  .cgui\:underline {
1132
1141
  text-decoration-line: underline;
1133
1142
  }
1134
- .cgui\:opacity-0 {
1135
- opacity: 0%;
1136
- }
1137
1143
  .cgui\:opacity-50 {
1138
1144
  opacity: 50%;
1139
1145
  }
@@ -1292,6 +1298,11 @@
1292
1298
  }
1293
1299
  }
1294
1300
  }
1301
+ .cgui\:group-data-\[compact\=true\]\/navigation\:justify-center {
1302
+ &:is(:where(.cgui\:group\/navigation)[data-compact="true"] *) {
1303
+ justify-content: center;
1304
+ }
1305
+ }
1295
1306
  .cgui\:group-data-\[compact\=true\]\/navigation\:py-3 {
1296
1307
  &:is(:where(.cgui\:group\/navigation)[data-compact="true"] *) {
1297
1308
  padding-block: calc(var(--cgui-spacing) * 3);
@@ -1376,6 +1387,11 @@
1376
1387
  content: var(--tw-content);
1377
1388
  }
1378
1389
  }
1390
+ .cgui\:empty\:hidden {
1391
+ &:empty {
1392
+ display: none;
1393
+ }
1394
+ }
1379
1395
  .cgui\:hover\:bg-primary-60 {
1380
1396
  &:hover {
1381
1397
  @media (hover: hover) {
@@ -1607,16 +1623,6 @@
1607
1623
  }
1608
1624
  }
1609
1625
  }
1610
- .cgui\:data-\[popover-content\]\:rounded-md {
1611
- &[data-popover-content] {
1612
- border-radius: calc(var(--cg-ui-number-md) * 1px);
1613
- }
1614
- }
1615
- .cgui\:data-\[popover-content\]\:bg-surface-darkest {
1616
- &[data-popover-content] {
1617
- background-color: var(--cg-ui-color-surface-darkest);
1618
- }
1619
- }
1620
1626
  .cgui\:data-\[selected\=\"\"\]\:border-stroke-primary {
1621
1627
  &[data-selected=""] {
1622
1628
  border-color: var(--cg-ui-color-stroke-primary);
@@ -1795,13 +1801,6 @@
1795
1801
  --tw-enter-scale: .95;
1796
1802
  }
1797
1803
  }
1798
- .cgui\:data-\[sub-content\=\"false\"\]\:group-data-\[compact\=true\]\/navigation\:justify-center {
1799
- &[data-sub-content="false"] {
1800
- &:is(:where(.cgui\:group\/navigation)[data-compact="true"] *) {
1801
- justify-content: center;
1802
- }
1803
- }
1804
- }
1805
1804
  .cgui\:scrollbar-hover\:scrollbar-thumb-surface-regular\/60 {
1806
1805
  &::-webkit-scrollbar-thumb:hover {
1807
1806
  --scrollbar-thumb: var(--cg-ui-color-surface-regular);
@@ -1810,10 +1809,39 @@
1810
1809
  }
1811
1810
  }
1812
1811
  }
1813
- .cgui\:\[\&_\[data-slot\=\"icon\"\]\]\:size-6 {
1812
+ .cgui\:group-data-\[compact\=false\]\/navigation\:data-\[state\=open\]\:\[\&_\[data-slot\=\"chevron\"\]\]\:rotate-180 {
1813
+ &:is(:where(.cgui\:group\/navigation)[data-compact="false"] *) {
1814
+ &[data-state="open"] {
1815
+ & [data-slot="chevron"] {
1816
+ rotate: 180deg;
1817
+ }
1818
+ }
1819
+ }
1820
+ }
1821
+ .cgui\:\[\&_\[data-slot\=\"icon\"\]\]\:me-auto {
1814
1822
  & [data-slot="icon"] {
1815
- width: calc(var(--cgui-spacing) * 6);
1816
- height: calc(var(--cgui-spacing) * 6);
1823
+ margin-inline-end: auto;
1824
+ }
1825
+ }
1826
+ .cgui\:\[\&_\[data-slot\=\"trigger\"\]\]\:rounded-sm {
1827
+ & [data-slot="trigger"] {
1828
+ border-radius: calc(var(--cg-ui-number-sm) * 1px);
1829
+ }
1830
+ }
1831
+ .cgui\:\[\&_\[data-slot\=\"trigger\"\]\]\:px-2 {
1832
+ & [data-slot="trigger"] {
1833
+ padding-inline: calc(var(--cgui-spacing) * 2);
1834
+ }
1835
+ }
1836
+ .cgui\:\[\&_\[data-slot\=\"trigger\"\]\]\:py-2 {
1837
+ & [data-slot="trigger"] {
1838
+ padding-block: calc(var(--cgui-spacing) * 2);
1839
+ }
1840
+ }
1841
+ .cgui\:\[\&_\[data-slot\=\"trigger\"\]\]\:text-sm {
1842
+ & [data-slot="trigger"] {
1843
+ font-size: var(--cgui-text-sm);
1844
+ line-height: var(--tw-leading, var(--cgui-text-sm--line-height));
1817
1845
  }
1818
1846
  }
1819
1847
  .cgui\:data-\[compact\=false\]\:\[\&_\[data-slot\=\"trigger\"\]\]\:pl-0 {
@@ -1823,6 +1851,12 @@
1823
1851
  }
1824
1852
  }
1825
1853
  }
1854
+ .cgui\:\[\&_\[data-slot\=\"trigger\"\]_\[data-slot\=\"icon\"\]\]\:size-4 {
1855
+ & [data-slot="trigger"] [data-slot="icon"] {
1856
+ width: calc(var(--cgui-spacing) * 4);
1857
+ height: calc(var(--cgui-spacing) * 4);
1858
+ }
1859
+ }
1826
1860
  .cgui\:hover\:\[\&_\[data-slot\=icon\]\]\:text-icon-focus {
1827
1861
  &:hover {
1828
1862
  @media (hover: hover) {
@@ -1889,6 +1923,18 @@
1889
1923
  pointer-events: none;
1890
1924
  }
1891
1925
  }
1926
+ .cgui\:\[\&_svg\]\:size-4 {
1927
+ & svg {
1928
+ width: calc(var(--cgui-spacing) * 4);
1929
+ height: calc(var(--cgui-spacing) * 4);
1930
+ }
1931
+ }
1932
+ .cgui\:\[\&_svg\]\:size-6 {
1933
+ & svg {
1934
+ width: calc(var(--cgui-spacing) * 6);
1935
+ height: calc(var(--cgui-spacing) * 6);
1936
+ }
1937
+ }
1892
1938
  .cgui\:\[\&_svg\]\:shrink-0 {
1893
1939
  & svg {
1894
1940
  flex-shrink: 0;
@@ -1922,16 +1968,6 @@
1922
1968
  border-width: 0px;
1923
1969
  }
1924
1970
  }
1925
- .cgui\:\[data-disabled\]\:cursor-not-allowed {
1926
- &:is(data-disabled) {
1927
- cursor: not-allowed;
1928
- }
1929
- }
1930
- .cgui\:\[data-disabled\]\:opacity-50 {
1931
- &:is(data-disabled) {
1932
- opacity: 50%;
1933
- }
1934
- }
1935
1971
  .cgui\:\[\&\>\*\]\:focus-visible\:relative {
1936
1972
  &>* {
1937
1973
  &:focus-visible {
@@ -1,8 +1,7 @@
1
1
  <script lang="ts">
2
- import { boxWith, mergeProps } from 'svelte-toolbelt';
3
-
4
- import { NavigationStylesContext } from '../styles.js';
5
2
  import { cn, useId } from '../../../internal/utils/common.js';
3
+ import { boxWith, mergeProps } from 'svelte-toolbelt';
4
+ import { navigationContentStyles } from '../styles.js';
6
5
  import type { NavigationContentProps } from '../types.js';
7
6
  import { NavigationContentState } from './navigation.svelte.js';
8
7
 
@@ -26,7 +25,7 @@
26
25
  });
27
26
 
28
27
  const mergedProps = $derived(
29
- mergeProps(restProps, contentState.props, { class: cn(NavigationStylesContext.get().current.content(), className) })
28
+ mergeProps(restProps, contentState.props, { class: cn(navigationContentStyles(), className) })
30
29
  );
31
30
  </script>
32
31
 
@@ -1,11 +1,10 @@
1
1
  <script lang="ts">
2
- import { CollapsiblePrimitive } from '../../collapsible/index.js';
3
- import { NavigationStylesContext } from '../styles.js';
4
- import { PopoverPrimitive } from '../../popover/index.js';
2
+ import { DropdownPrimitive } from '../../dropdown/index.js';
5
3
  import { cn, useId } from '../../../internal/utils/common.js';
6
4
  import { boxWith, mergeProps } from 'svelte-toolbelt';
5
+ import { navigationItemStyles } from '../styles.js';
7
6
  import type { NavigationItemProps } from '../types.js';
8
- import { NavigationItemState } from './navigation.svelte.js';
7
+ import { NavigationItemState, NavigationSubStateCtx } from './navigation.svelte.js';
9
8
 
10
9
  const uid = $props.id();
11
10
 
@@ -18,6 +17,10 @@
18
17
  ...restProps
19
18
  }: NavigationItemProps = $props();
20
19
 
20
+ // Check if we're inside a Sub (SubContent context)
21
+ const subState = NavigationSubStateCtx.getOr(null);
22
+ const isInsideSub = $derived(subState !== null);
23
+
21
24
  const itemState = NavigationItemState.create({
22
25
  ref: boxWith(
23
26
  () => ref,
@@ -27,24 +30,23 @@
27
30
  });
28
31
 
29
32
  const mergedProps = $derived(
30
- mergeProps(restProps, itemState.props, { class: cn(NavigationStylesContext.get().current.item(), className) })
33
+ mergeProps(restProps, itemState.props, { class: cn(navigationItemStyles(), className) })
31
34
  );
35
+
36
+ // Should use dropdown item when inside Sub in compact mode
37
+ const useDropdownItem = $derived(isInsideSub && itemState.root.isCompact);
32
38
  </script>
33
39
 
34
40
  {#if child}
35
41
  {@render child({ props: mergedProps })}
36
- {:else if itemState.root.isCompact}
42
+ {:else if useDropdownItem}
43
+ <!-- Inside SubContent in compact mode: use Dropdown.Item -->
44
+ <DropdownPrimitive.Item {...mergedProps}>
45
+ {@render children?.()}
46
+ </DropdownPrimitive.Item>
47
+ {:else}
48
+ <!-- Regular list item -->
37
49
  <li {...mergedProps}>
38
- <PopoverPrimitive.Root>
39
- {@render children?.()}
40
- </PopoverPrimitive.Root>
50
+ {@render children?.()}
41
51
  </li>
42
- {:else}
43
- <CollapsiblePrimitive.Root variant="clean">
44
- {#snippet child({ props: childProps })}
45
- <li {...mergedProps} {...childProps}>
46
- {@render children?.()}
47
- </li>
48
- {/snippet}
49
- </CollapsiblePrimitive.Root>
50
52
  {/if}
@@ -1,11 +1,11 @@
1
1
  <script lang="ts">
2
- import { NavigationStylesContext, navigationVariants } from '../styles.js';
2
+ import { navigationRootStyles } from '../styles.js';
3
3
  import type { NavigationRootProps } from '../types.js';
4
4
 
5
5
  import { NavigationRootState } from './navigation.svelte.js';
6
6
 
7
7
  import { cn, useId } from '../../../internal/utils/common.js';
8
- import { box, mergeProps } from 'svelte-toolbelt';
8
+ import { boxWith, mergeProps } from 'svelte-toolbelt';
9
9
 
10
10
  const uid = $props.id();
11
11
 
@@ -16,25 +16,23 @@
16
16
  children,
17
17
  child,
18
18
  class: className,
19
- popoverProps,
19
+ dropdownProps,
20
20
  ...restProps
21
21
  }: NavigationRootProps = $props();
22
22
 
23
23
  const rootState = NavigationRootState.create({
24
- ref: box.with(
24
+ ref: boxWith(
25
25
  () => ref,
26
26
  (v) => (ref = v)
27
27
  ),
28
- id: box.with(() => id),
29
- compact: box.with(() => compact),
30
- popoverProps: box.with(() => popoverProps),
28
+ id: boxWith(() => id),
29
+ compact: boxWith(() => compact),
30
+ dropdownProps: boxWith(() => dropdownProps),
31
31
  });
32
32
 
33
- const variants = $derived(navigationVariants({ compact }));
34
-
35
- NavigationStylesContext.set(box.with(() => variants));
36
-
37
- const mergedProps = $derived(mergeProps(restProps, rootState.props, { class: cn(variants.root(), className) }));
33
+ const mergedProps = $derived(
34
+ mergeProps(restProps, rootState.props, { class: cn(navigationRootStyles({ compact }), className) })
35
+ );
38
36
  </script>
39
37
 
40
38
  {#if child}
@@ -1,12 +1,11 @@
1
1
  <script lang="ts">
2
- import { boxWith, mergeProps } from 'svelte-toolbelt';
3
-
4
2
  import { CollapsiblePrimitive } from '../../collapsible/index.js';
5
- import { NavigationStylesContext } from '../styles.js';
6
- import { PopoverPrimitive } from '../../popover/index.js';
3
+ import { DropdownPrimitive } from '../../dropdown/index.js';
7
4
  import { cn, useId } from '../../../internal/utils/common.js';
5
+ import { boxWith, mergeProps } from 'svelte-toolbelt';
8
6
  import { cubicInOut } from 'svelte/easing';
9
- import { fade, fly } from 'svelte/transition';
7
+ import { fade } from 'svelte/transition';
8
+ import { navigationDropdownContentStyles, navigationSubContentStyles } from '../styles.js';
10
9
  import type { NavigationSubContentProps } from '../types.js';
11
10
  import { NavigationSubContentState } from './navigation.svelte.js';
12
11
 
@@ -31,39 +30,39 @@
31
30
 
32
31
  const mergedProps = $derived(
33
32
  mergeProps(restProps, subContentState.props, {
34
- class: cn(NavigationStylesContext.get().current.subContent(), className),
33
+ class: cn(navigationSubContentStyles(), className),
35
34
  })
36
35
  );
36
+
37
+ // Safe access to dropdownProps
38
+ const dropdownProps = $derived(subContentState.root.opts.dropdownProps?.current);
37
39
  </script>
38
40
 
39
41
  {#if child}
40
42
  {@render child({ props: mergedProps, compact: subContentState.root.isCompact })}
41
43
  {:else if subContentState.root.isCompact}
42
- <PopoverPrimitive.Portal>
43
- <PopoverPrimitive.Content
44
- side={subContentState.root.opts.popoverProps.current?.side ?? 'right'}
45
- sideOffset={subContentState.root.opts.popoverProps.current?.sideOffset ?? 8}
46
- alignOffset={subContentState.root.opts.popoverProps.current?.alignOffset ?? 0}
47
- forceMount
44
+ <!-- Compact mode: Dropdown with Portal -->
45
+ <DropdownPrimitive.Portal>
46
+ <DropdownPrimitive.Content
47
+ side={dropdownProps?.side ?? 'right'}
48
+ sideOffset={dropdownProps?.sideOffset ?? 8}
49
+ alignOffset={dropdownProps?.alignOffset ?? 0}
50
+ variant="clean"
51
+ w="auto"
52
+ gap="clean"
53
+ rounded="clean"
54
+ class={cn(navigationDropdownContentStyles())}
48
55
  >
49
- {#snippet child({ props: childProps, wrapperProps, open })}
50
- {@const popoverProps = mergeProps(childProps, mergedProps)}
51
- {#if open}
52
- <div {...wrapperProps}>
53
- <ol {...popoverProps} transition:fly={{ duration: 250, easing: cubicInOut, x: 10 }}>
54
- {@render children?.({ compact: subContentState.root.isCompact })}
55
- </ol>
56
- </div>
57
- {/if}
58
- {/snippet}
59
- </PopoverPrimitive.Content>
60
- </PopoverPrimitive.Portal>
56
+ <ol {...mergedProps}>
57
+ {@render children?.({ compact: subContentState.root.isCompact })}
58
+ </ol>
59
+ </DropdownPrimitive.Content>
60
+ </DropdownPrimitive.Portal>
61
61
  {:else}
62
- <CollapsiblePrimitive.Content {...mergedProps}>
63
- {#snippet child({ props: childProps, open })}
64
- {@const collapsibleProps = mergeProps(childProps, mergedProps)}
62
+ <CollapsiblePrimitive.Content>
63
+ {#snippet child({ props: collapsibleProps, open })}
65
64
  {#if open}
66
- <ol {...collapsibleProps} transition:fade={{ duration: 250, easing: cubicInOut }}>
65
+ <ol {...collapsibleProps} {...mergedProps} transition:fade={{ duration: 250, easing: cubicInOut }}>
67
66
  {@render children?.({ compact: subContentState.root.isCompact })}
68
67
  </ol>
69
68
  {/if}
@@ -0,0 +1,107 @@
1
+ <script lang="ts">
2
+ import { CollapsiblePrimitive } from '../../collapsible/index.js';
3
+ import { DropdownPrimitive } from '../../dropdown/index.js';
4
+ import ChevronDown from '../../icons/chevron-down.svelte';
5
+ import { cn, useId } from '../../../internal/utils/common.js';
6
+ import { boxWith, mergeProps } from 'svelte-toolbelt';
7
+ import { cubicInOut } from 'svelte/easing';
8
+ import { slide } from 'svelte/transition';
9
+ import { navigationSubTriggerStyles } from '../styles.js';
10
+ import type { NavigationSubTriggerProps } from '../types.js';
11
+ import { NavigationSubTriggerState } from './navigation.svelte.js';
12
+
13
+ const uid = $props.id();
14
+
15
+ let {
16
+ ref = $bindable(null),
17
+ id = useId(uid),
18
+ child,
19
+ icon,
20
+ label,
21
+ class: className,
22
+ disabled = false,
23
+ ...restProps
24
+ }: NavigationSubTriggerProps = $props();
25
+
26
+ const subTriggerState = NavigationSubTriggerState.create({
27
+ ref: boxWith(
28
+ () => ref,
29
+ (v) => (ref = v)
30
+ ),
31
+ id: boxWith(() => id),
32
+ disabled: boxWith(() => disabled),
33
+ });
34
+
35
+ const mergedProps = $derived(
36
+ mergeProps(restProps, subTriggerState.props, {
37
+ class: cn(navigationSubTriggerStyles(), className),
38
+ })
39
+ );
40
+
41
+ const attrs = $derived({
42
+ compact: subTriggerState.root.isCompact,
43
+ open: subTriggerState.sub.isOpen,
44
+ });
45
+ </script>
46
+
47
+ {#snippet content()}
48
+ {#if icon}
49
+ <span
50
+ data-slot="icon"
51
+ class={cn('cgui:inline-flex cgui:items-center cgui:justify-center cgui:shrink-0 cgui:empty:hidden')}
52
+ >
53
+ {@render icon?.()}
54
+ </span>
55
+ {/if}
56
+
57
+ {#if label}
58
+ {#if typeof label === 'string'}
59
+ {#if !subTriggerState.root.isCompact}
60
+ <span
61
+ data-slot="label"
62
+ class="cgui:min-w-0 cgui:text-left cgui:whitespace-nowrap cgui:overflow-hidden cgui:flex-1"
63
+ transition:slide={{ axis: 'x', duration: 250, easing: cubicInOut }}
64
+ >
65
+ <span class="cgui:inline-block" transition:slide={{ axis: 'x', duration: 150, easing: cubicInOut }}>
66
+ {label}
67
+ </span>
68
+ </span>
69
+ {/if}
70
+ {:else}
71
+ {@render label?.({ props: { 'data-slot': 'label' } })}
72
+ {/if}
73
+ {/if}
74
+ {/snippet}
75
+
76
+ {#snippet chevron()}
77
+ <span
78
+ data-slot="chevron"
79
+ class={cn(
80
+ 'cgui:flex cgui:items-center cgui:justify-center cgui:shrink-0',
81
+ 'cgui:transition-transform cgui:duration-250 cgui:ease-in-out'
82
+ )}
83
+ >
84
+ <ChevronDown width={24} height={24} />
85
+ </span>
86
+ {/snippet}
87
+
88
+ {#if child}
89
+ {@render child({ props: mergedProps, ...attrs })}
90
+ {:else if subTriggerState.root.isCompact}
91
+ <DropdownPrimitive.Trigger>
92
+ {#snippet child({ props: dropdownProps })}
93
+ <button {...dropdownProps} {...mergedProps}>
94
+ {@render content?.()}
95
+ </button>
96
+ {/snippet}
97
+ </DropdownPrimitive.Trigger>
98
+ {:else}
99
+ <CollapsiblePrimitive.Trigger>
100
+ {#snippet child({ props: collapsibleProps })}
101
+ <button {...collapsibleProps} {...mergedProps}>
102
+ {@render content?.()}
103
+ {@render chevron()}
104
+ </button>
105
+ {/snippet}
106
+ </CollapsiblePrimitive.Trigger>
107
+ {/if}
@@ -0,0 +1,4 @@
1
+ import type { NavigationSubTriggerProps } from '../types.js';
2
+ declare const Navigation: import("svelte").Component<NavigationSubTriggerProps, {}, "ref">;
3
+ type Navigation = ReturnType<typeof Navigation>;
4
+ export default Navigation;
@@ -0,0 +1,55 @@
1
+ <script lang="ts">
2
+ import { CollapsiblePrimitive } from '../../collapsible/index.js';
3
+ import { DropdownPrimitive } from '../../dropdown/index.js';
4
+ import { cn, useId } from '../../../internal/utils/common.js';
5
+ import { boxWith, mergeProps } from 'svelte-toolbelt';
6
+ import { navigationSubStyles } from '../styles.js';
7
+ import type { NavigationSubProps } from '../types.js';
8
+ import { NavigationSubState } from './navigation.svelte.js';
9
+
10
+ const uid = $props.id();
11
+
12
+ let {
13
+ ref = $bindable(null),
14
+ id = useId(uid),
15
+ open = $bindable(false),
16
+ children,
17
+ child,
18
+ class: className,
19
+ ...restProps
20
+ }: NavigationSubProps = $props();
21
+
22
+ const subState = NavigationSubState.create({
23
+ ref: boxWith(
24
+ () => ref,
25
+ (v) => (ref = v)
26
+ ),
27
+ id: boxWith(() => id),
28
+ open: boxWith(
29
+ () => open,
30
+ (v) => (open = v)
31
+ ),
32
+ });
33
+
34
+ const mergedProps = $derived(mergeProps(restProps, subState.props, { class: cn(navigationSubStyles(), className) }));
35
+ </script>
36
+
37
+ {#if child}
38
+ {@render child({ props: mergedProps, open })}
39
+ {:else if subState.root.isCompact}
40
+ <!-- Compact mode: use Dropdown -->
41
+ <DropdownPrimitive.Root bind:open>
42
+ <li {...mergedProps}>
43
+ {@render children?.({ open })}
44
+ </li>
45
+ </DropdownPrimitive.Root>
46
+ {:else}
47
+ <!-- Expanded mode: use Collapsible -->
48
+ <CollapsiblePrimitive.Root bind:open variant="clean">
49
+ {#snippet child({ props: collapsibleProps })}
50
+ <li {...mergedProps} {...collapsibleProps}>
51
+ {@render children?.({ open })}
52
+ </li>
53
+ {/snippet}
54
+ </CollapsiblePrimitive.Root>
55
+ {/if}
@@ -0,0 +1,4 @@
1
+ import type { NavigationSubProps } from '../types.js';
2
+ declare const Navigation: import("svelte").Component<NavigationSubProps, {}, "ref" | "open">;
3
+ type Navigation = ReturnType<typeof Navigation>;
4
+ export default Navigation;