@x33025/sveltely 0.0.57 → 0.1.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 (187) hide show
  1. package/dist/actions/tooltip.d.ts +10 -0
  2. package/dist/actions/tooltip.js +255 -0
  3. package/dist/components/{AnimatedNumber.demo.svelte → Library/AnimatedNumber/AnimatedNumber.demo.svelte} +6 -10
  4. package/dist/components/{AnimatedNumber.demo.svelte.d.ts → Library/AnimatedNumber/AnimatedNumber.demo.svelte.d.ts} +0 -1
  5. package/dist/components/Library/AnimatedNumber/AnimatedNumber.svelte +29 -0
  6. package/dist/components/Library/AnimatedNumber/AnimatedNumber.svelte.d.ts +9 -0
  7. package/dist/components/Library/AnimatedNumber/index.d.ts +1 -0
  8. package/dist/components/Library/AnimatedNumber/index.js +1 -0
  9. package/dist/components/{AsyncButton.demo.svelte → Library/AsyncButton/AsyncButton.demo.svelte} +0 -1
  10. package/dist/components/Library/AsyncButton/AsyncButton.svelte +178 -0
  11. package/dist/components/{AsyncButton.svelte.d.ts → Library/AsyncButton/AsyncButton.svelte.d.ts} +7 -2
  12. package/dist/components/Library/AsyncButton/index.d.ts +1 -0
  13. package/dist/components/Library/AsyncButton/index.js +1 -0
  14. package/dist/components/Library/Button/Button.demo.svelte +17 -0
  15. package/dist/components/Library/Button/Button.demo.svelte.d.ts +23 -0
  16. package/dist/components/Library/Button/Button.svelte +134 -0
  17. package/dist/components/Library/Button/Button.svelte.d.ts +17 -0
  18. package/dist/components/Library/Button/index.d.ts +1 -0
  19. package/dist/components/Library/Button/index.js +1 -0
  20. package/dist/components/Library/Calendar/Calendar.demo.svelte +30 -0
  21. package/dist/components/Library/Calendar/Calendar.demo.svelte.d.ts +10 -0
  22. package/dist/components/Library/Calendar/Calendar.svelte +310 -0
  23. package/dist/components/Library/Calendar/Calendar.svelte.d.ts +10 -0
  24. package/dist/components/Library/Calendar/index.d.ts +1 -0
  25. package/dist/components/Library/Calendar/index.js +1 -0
  26. package/dist/components/Library/Checkbox/Checkbox.demo.svelte +20 -0
  27. package/dist/components/Library/Checkbox/Checkbox.demo.svelte.d.ts +8 -0
  28. package/dist/components/Library/Checkbox/Checkbox.svelte +134 -0
  29. package/dist/components/Library/Checkbox/Checkbox.svelte.d.ts +11 -0
  30. package/dist/components/Library/Checkbox/index.d.ts +1 -0
  31. package/dist/components/Library/Checkbox/index.js +1 -0
  32. package/dist/components/{ChipInput.demo.svelte → Library/ChipInput/ChipInput.demo.svelte} +1 -2
  33. package/dist/components/{ChipInput.demo.svelte.d.ts → Library/ChipInput/ChipInput.demo.svelte.d.ts} +0 -1
  34. package/dist/components/{ChipInput.svelte → Library/ChipInput/ChipInput.svelte} +77 -3
  35. package/dist/components/{ChipInput.svelte.d.ts → Library/ChipInput/ChipInput.svelte.d.ts} +2 -1
  36. package/dist/components/Library/ChipInput/index.d.ts +1 -0
  37. package/dist/components/Library/ChipInput/index.js +1 -0
  38. package/dist/components/Library/Dropdown/Dropdown.demo.svelte +54 -0
  39. package/dist/components/Library/Dropdown/Dropdown.demo.svelte.d.ts +8 -0
  40. package/dist/components/Library/Dropdown/Dropdown.svelte +346 -0
  41. package/dist/components/Library/Dropdown/Dropdown.svelte.d.ts +40 -0
  42. package/dist/components/Library/Dropdown/index.d.ts +2 -0
  43. package/dist/components/Library/Dropdown/index.js +1 -0
  44. package/dist/components/Library/Dropdown/types.d.ts +27 -0
  45. package/dist/components/Library/Dropdown/types.js +1 -0
  46. package/dist/components/{Popover/Popover.svelte → Library/Floating/Floating.svelte} +155 -101
  47. package/dist/components/Library/Floating/Floating.svelte.d.ts +30 -0
  48. package/dist/components/Library/Floating/registry.svelte.d.ts +6 -0
  49. package/dist/components/{Popover → Library/Floating}/registry.svelte.js +2 -23
  50. package/dist/components/{GlowEffect.svelte → Library/GlowEffect/GlowEffect.svelte} +15 -6
  51. package/dist/components/{GlowEffect.svelte.d.ts → Library/GlowEffect/GlowEffect.svelte.d.ts} +3 -2
  52. package/dist/components/Library/GlowEffect/index.d.ts +1 -0
  53. package/dist/components/Library/GlowEffect/index.js +1 -0
  54. package/dist/components/Library/NavigationStack/NavigationStack.svelte +242 -0
  55. package/dist/components/Library/NavigationStack/NavigationStack.svelte.d.ts +15 -0
  56. package/dist/components/Library/NavigationStack/SidebarToggle.svelte +52 -0
  57. package/dist/components/Library/NavigationStack/SidebarToggle.svelte.d.ts +10 -0
  58. package/dist/components/Library/NavigationStack/Toolbar.svelte +59 -0
  59. package/dist/components/Library/NavigationStack/Toolbar.svelte.d.ts +11 -0
  60. package/dist/components/{Pagination.demo.svelte → Library/Pagination/Pagination.demo.svelte} +0 -1
  61. package/dist/components/{Pagination.demo.svelte.d.ts → Library/Pagination/Pagination.demo.svelte.d.ts} +0 -1
  62. package/dist/components/Library/Pagination/Pagination.svelte +227 -0
  63. package/dist/components/{Pagination.svelte.d.ts → Library/Pagination/Pagination.svelte.d.ts} +3 -3
  64. package/dist/components/Library/Pagination/index.d.ts +1 -0
  65. package/dist/components/Library/Pagination/index.js +1 -0
  66. package/dist/components/Library/Popover/Popover.demo.svelte +21 -0
  67. package/dist/components/Library/Popover/Popover.svelte +92 -0
  68. package/dist/components/Library/Popover/Popover.svelte.d.ts +14 -0
  69. package/dist/components/{Popover → Library/Popover}/PopoverDebugOverlay.svelte +1 -1
  70. package/dist/components/Library/Popover/index.d.ts +1 -0
  71. package/dist/components/Library/Popover/index.js +1 -0
  72. package/dist/components/Library/ScrollView/ScrollView.svelte +89 -0
  73. package/dist/components/Library/ScrollView/ScrollView.svelte.d.ts +12 -0
  74. package/dist/components/Library/ScrollView/index.d.ts +1 -0
  75. package/dist/components/Library/ScrollView/index.js +1 -0
  76. package/dist/components/{SearchInput.demo.svelte → Library/SearchInput/SearchInput.demo.svelte} +2 -3
  77. package/dist/components/{SearchInput.demo.svelte.d.ts → Library/SearchInput/SearchInput.demo.svelte.d.ts} +0 -1
  78. package/dist/components/Library/SearchInput/SearchInput.svelte +88 -0
  79. package/dist/components/{SearchInput.svelte.d.ts → Library/SearchInput/SearchInput.svelte.d.ts} +3 -3
  80. package/dist/components/Library/SearchInput/index.d.ts +1 -0
  81. package/dist/components/Library/SearchInput/index.js +1 -0
  82. package/dist/components/{SegmentedPicker.demo.svelte → Library/SegmentedPicker/SegmentedPicker.demo.svelte} +2 -3
  83. package/dist/components/{SegmentedPicker.demo.svelte.d.ts → Library/SegmentedPicker/SegmentedPicker.demo.svelte.d.ts} +0 -1
  84. package/dist/components/Library/SegmentedPicker/SegmentedPicker.svelte +106 -0
  85. package/dist/components/{SegmentedPicker.svelte.d.ts → Library/SegmentedPicker/SegmentedPicker.svelte.d.ts} +2 -2
  86. package/dist/components/Library/SegmentedPicker/index.d.ts +1 -0
  87. package/dist/components/Library/SegmentedPicker/index.js +1 -0
  88. package/dist/components/{Sheet → Library/Sheet}/Sheet.demo.svelte +4 -17
  89. package/dist/components/Library/Sheet/Sheet.demo.svelte.d.ts +23 -0
  90. package/dist/components/Library/Sheet/Sheet.svelte +113 -0
  91. package/dist/components/{Sheet → Library/Sheet}/Sheet.svelte.d.ts +4 -2
  92. package/dist/components/{Slider.demo.svelte → Library/Slider/Slider.demo.svelte} +2 -3
  93. package/dist/components/{Slider.demo.svelte.d.ts → Library/Slider/Slider.demo.svelte.d.ts} +0 -1
  94. package/dist/components/Library/Slider/Slider.svelte +122 -0
  95. package/dist/components/{Slider.svelte.d.ts → Library/Slider/Slider.svelte.d.ts} +2 -3
  96. package/dist/components/Library/Slider/index.d.ts +1 -0
  97. package/dist/components/Library/Slider/index.js +1 -0
  98. package/dist/components/{Spinner.demo.svelte → Library/Spinner/Spinner.demo.svelte} +3 -1
  99. package/dist/components/Library/Spinner/Spinner.svelte +32 -0
  100. package/dist/components/{Spinner.svelte.d.ts → Library/Spinner/Spinner.svelte.d.ts} +3 -2
  101. package/dist/components/Library/Spinner/index.d.ts +1 -0
  102. package/dist/components/Library/Spinner/index.js +1 -0
  103. package/dist/components/Library/Switch/Switch.demo.svelte +20 -0
  104. package/dist/components/Library/Switch/Switch.demo.svelte.d.ts +8 -0
  105. package/dist/components/Library/Switch/Switch.svelte +168 -0
  106. package/dist/components/Library/Switch/Switch.svelte.d.ts +11 -0
  107. package/dist/components/Library/Switch/index.d.ts +1 -0
  108. package/dist/components/Library/Switch/index.js +1 -0
  109. package/dist/components/Library/TextShimmer/TextShimmer.demo.svelte +14 -0
  110. package/dist/components/Library/TextShimmer/TextShimmer.demo.svelte.d.ts +23 -0
  111. package/dist/components/Library/TextShimmer/TextShimmer.svelte +88 -0
  112. package/dist/components/Library/TextShimmer/TextShimmer.svelte.d.ts +11 -0
  113. package/dist/components/Library/TextShimmer/index.d.ts +1 -0
  114. package/dist/components/Library/TextShimmer/index.js +1 -0
  115. package/dist/components/Library/TimePicker/TimePicker.demo.svelte +18 -0
  116. package/dist/components/Library/TimePicker/TimePicker.demo.svelte.d.ts +10 -0
  117. package/dist/components/Library/TimePicker/TimePicker.svelte +143 -0
  118. package/dist/components/Library/TimePicker/TimePicker.svelte.d.ts +13 -0
  119. package/dist/components/Library/TimePicker/index.d.ts +2 -0
  120. package/dist/components/Library/TimePicker/index.js +1 -0
  121. package/dist/components/Library/TokenSearchInput/TokenSearchInput.demo.svelte +19 -0
  122. package/dist/components/Library/TokenSearchInput/TokenSearchInput.demo.svelte.d.ts +9 -0
  123. package/dist/components/Library/TokenSearchInput/TokenSearchInput.svelte +230 -0
  124. package/dist/components/Library/TokenSearchInput/TokenSearchInput.svelte.d.ts +14 -0
  125. package/dist/components/Library/TokenSearchInput/index.d.ts +1 -0
  126. package/dist/components/Library/TokenSearchInput/index.js +1 -0
  127. package/dist/components/Library/Tooltip/Tooltip.demo.svelte +14 -0
  128. package/dist/components/{Tooltip.demo.svelte.d.ts → Library/Tooltip/Tooltip.demo.svelte.d.ts} +0 -1
  129. package/dist/components/Library/Tooltip/index.d.ts +2 -0
  130. package/dist/components/Library/Tooltip/index.js +1 -0
  131. package/dist/components/Library/WheelPicker/WheelColumn.svelte +302 -0
  132. package/dist/components/Library/WheelPicker/WheelColumn.svelte.d.ts +29 -0
  133. package/dist/components/Library/WheelPicker/WheelPicker.svelte +114 -0
  134. package/dist/components/Library/WheelPicker/WheelPicker.svelte.d.ts +9 -0
  135. package/dist/components/Library/WheelPicker/index.d.ts +2 -0
  136. package/dist/components/Library/WheelPicker/index.js +1 -0
  137. package/dist/components/Library/WheelPicker/types.d.ts +10 -0
  138. package/dist/components/Library/WheelPicker/types.js +1 -0
  139. package/dist/components/Local/ComponentGrid.svelte +7 -6
  140. package/dist/components/Local/ComponentGrid.svelte.d.ts +1 -1
  141. package/dist/components/Local/HeroCard.svelte +18 -8
  142. package/dist/components/Local/HeroCard.svelte.d.ts +1 -1
  143. package/dist/components/Local/StyleControls.svelte +119 -0
  144. package/dist/components/Local/StyleControls.svelte.d.ts +15 -0
  145. package/dist/index.d.ts +24 -14
  146. package/dist/index.js +23 -14
  147. package/dist/style/index.css +61 -280
  148. package/dist/style/surface.d.ts +17 -0
  149. package/dist/style/surface.js +54 -0
  150. package/dist/style.css +102 -523
  151. package/dist/utils/positioning.d.ts +3 -2
  152. package/dist/utils/positioning.js +9 -5
  153. package/package.json +2 -1
  154. package/dist/components/AnimatedNumber.svelte +0 -18
  155. package/dist/components/AnimatedNumber.svelte.d.ts +0 -8
  156. package/dist/components/AsyncButton.svelte +0 -93
  157. package/dist/components/NavigationStack/NavigationStack.svelte +0 -76
  158. package/dist/components/NavigationStack/NavigationStack.svelte.d.ts +0 -10
  159. package/dist/components/NavigationStack/SidebarToggle.svelte +0 -36
  160. package/dist/components/NavigationStack/SidebarToggle.svelte.d.ts +0 -9
  161. package/dist/components/NavigationStack/Toolbar.svelte +0 -25
  162. package/dist/components/NavigationStack/Toolbar.svelte.d.ts +0 -9
  163. package/dist/components/Pagination.svelte +0 -144
  164. package/dist/components/Popover/Popover.demo.svelte +0 -35
  165. package/dist/components/Popover/Popover.svelte.d.ts +0 -13
  166. package/dist/components/Popover/index.d.ts +0 -2
  167. package/dist/components/Popover/index.js +0 -2
  168. package/dist/components/Popover/registry.svelte.d.ts +0 -18
  169. package/dist/components/SearchInput.svelte +0 -39
  170. package/dist/components/SegmentedPicker.svelte +0 -51
  171. package/dist/components/Sheet/Sheet.demo.svelte.d.ts +0 -8
  172. package/dist/components/Sheet/Sheet.svelte +0 -60
  173. package/dist/components/Slider.svelte +0 -47
  174. package/dist/components/Spinner.svelte +0 -7
  175. package/dist/components/TextShimmer.svelte +0 -60
  176. package/dist/components/TextShimmer.svelte.d.ts +0 -10
  177. package/dist/components/Tooltip.demo.svelte +0 -16
  178. package/dist/components/Tooltip.svelte +0 -79
  179. package/dist/components/Tooltip.svelte.d.ts +0 -12
  180. /package/dist/components/{AsyncButton.demo.svelte.d.ts → Library/AsyncButton/AsyncButton.demo.svelte.d.ts} +0 -0
  181. /package/dist/components/{NavigationStack → Library/NavigationStack}/index.d.ts +0 -0
  182. /package/dist/components/{NavigationStack → Library/NavigationStack}/index.js +0 -0
  183. /package/dist/components/{Popover → Library/Popover}/Popover.demo.svelte.d.ts +0 -0
  184. /package/dist/components/{Popover → Library/Popover}/PopoverDebugOverlay.svelte.d.ts +0 -0
  185. /package/dist/components/{Sheet → Library/Sheet}/index.d.ts +0 -0
  186. /package/dist/components/{Sheet → Library/Sheet}/index.js +0 -0
  187. /package/dist/components/{Spinner.demo.svelte.d.ts → Library/Spinner/Spinner.demo.svelte.d.ts} +0 -0
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Shared positioning engine for floating UI elements (popovers, tooltips, dropdowns, etc.).
3
- * Handles anchor/align placement with automatic viewport-overflow flipping.
3
+ * Handles preferred side placement with contextual attachment and viewport-overflow flipping.
4
4
  */
5
- export type Anchor = 'top' | 'bottom' | 'leading' | 'trailing';
5
+ export type Anchor = 'top' | 'bottom' | 'left' | 'right';
6
6
  export type Align = 'left' | 'center' | 'right';
7
7
  export type Transform = 'none' | 'translateX(-50%)' | 'translateX(-100%)' | 'translateY(-100%)' | 'translate(-50%, -100%)' | 'translate(-100%, -100%)';
8
8
  export interface Placement {
@@ -16,6 +16,7 @@ export interface PositionResult extends Placement {
16
16
  }
17
17
  export declare function oppositeAnchor(value: Anchor): Anchor;
18
18
  export declare function flippedAlign(value: Align): Align;
19
+ export declare function autoAlignForViewport(rect: DOMRect): Align;
19
20
  export declare function getPlacement(rect: DOMRect, nextAnchor: Anchor, nextAlign: Align): Placement;
20
21
  export declare function getViewportRect(placement: Placement, width: number, height: number): {
21
22
  left: number;
@@ -1,21 +1,25 @@
1
1
  /**
2
2
  * Shared positioning engine for floating UI elements (popovers, tooltips, dropdowns, etc.).
3
- * Handles anchor/align placement with automatic viewport-overflow flipping.
3
+ * Handles preferred side placement with contextual attachment and viewport-overflow flipping.
4
4
  */
5
5
  export function oppositeAnchor(value) {
6
6
  if (value === 'top')
7
7
  return 'bottom';
8
8
  if (value === 'bottom')
9
9
  return 'top';
10
- if (value === 'leading')
11
- return 'trailing';
12
- return 'leading';
10
+ if (value === 'left')
11
+ return 'right';
12
+ return 'left';
13
13
  }
14
14
  export function flippedAlign(value) {
15
15
  if (value === 'center')
16
16
  return 'center';
17
17
  return value === 'left' ? 'right' : 'left';
18
18
  }
19
+ export function autoAlignForViewport(rect) {
20
+ const triggerCenter = rect.left + rect.width / 2;
21
+ return triggerCenter <= window.innerWidth / 2 ? 'left' : 'right';
22
+ }
19
23
  export function getPlacement(rect, nextAnchor, nextAlign) {
20
24
  if (nextAnchor === 'top' || nextAnchor === 'bottom') {
21
25
  const left = nextAlign === 'left'
@@ -41,7 +45,7 @@ export function getPlacement(rect, nextAnchor, nextAlign) {
41
45
  }
42
46
  return { top, left, transform: 'none' };
43
47
  }
44
- if (nextAnchor === 'leading') {
48
+ if (nextAnchor === 'left') {
45
49
  return {
46
50
  top: rect.top + window.scrollY,
47
51
  left: rect.left + window.scrollX,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x33025/sveltely",
3
- "version": "0.0.57",
3
+ "version": "0.1.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",
@@ -39,6 +39,7 @@
39
39
  "./style.css": "./dist/style.css"
40
40
  },
41
41
  "peerDependencies": {
42
+ "@sveltejs/kit": "^2.50.1",
42
43
  "svelte": "^5.0.0"
43
44
  },
44
45
  "devDependencies": {
@@ -1,18 +0,0 @@
1
- <script lang="ts">
2
- import { Spring } from 'svelte/motion';
3
-
4
- interface Props {
5
- value: number;
6
- class?: string;
7
- as?: keyof HTMLElementTagNameMap;
8
- }
9
-
10
- let { value, class: className = '', as = 'span' }: Props = $props();
11
-
12
- const spring = Spring.of(() => value);
13
- const display = $derived(Math.round(spring.current).toLocaleString());
14
- </script>
15
-
16
- <svelte:element this={as} class="tabular-nums {className}">
17
- {display}
18
- </svelte:element>
@@ -1,8 +0,0 @@
1
- interface Props {
2
- value: number;
3
- class?: string;
4
- as?: keyof HTMLElementTagNameMap;
5
- }
6
- declare const AnimatedNumber: import("svelte").Component<Props, {}, "">;
7
- type AnimatedNumber = ReturnType<typeof AnimatedNumber>;
8
- export default AnimatedNumber;
@@ -1,93 +0,0 @@
1
- <script lang="ts">
2
- import { CircleAlertIcon } from '@lucide/svelte';
3
- import type { Component } from 'svelte';
4
- import type { HTMLButtonAttributes } from 'svelte/elements';
5
- import Spinner from './Spinner.svelte';
6
- import Tooltip from './Tooltip.svelte';
7
-
8
- type Props = {
9
- icon?: Component<{ class?: string }>;
10
- label: string;
11
- action: () => void | Promise<void>;
12
- error?: unknown | null;
13
- loading?: boolean;
14
- disableWhileLoading?: boolean;
15
- style?: 'iconAndLabel' | 'iconOnly';
16
- } & Omit<HTMLButtonAttributes, 'children' | 'onclick'>;
17
-
18
- let {
19
- icon,
20
- label,
21
- action,
22
- error = $bindable<unknown | null>(null),
23
- loading = undefined,
24
- disableWhileLoading = true,
25
- style: styleMode = 'iconAndLabel',
26
- disabled = false,
27
- class: className = '',
28
- type = 'button',
29
- ...props
30
- }: Props = $props();
31
-
32
- let internalLoading = $state(false);
33
-
34
- const isControlledLoading = $derived(loading !== undefined);
35
- const effectiveLoading = $derived(isControlledLoading ? loading : internalLoading);
36
- const effectiveDisabled = $derived(disabled || (disableWhileLoading && effectiveLoading));
37
-
38
- const handleClick = async () => {
39
- if (effectiveDisabled) return;
40
- error = null;
41
- if (isControlledLoading) {
42
- try {
43
- await action();
44
- } catch (caught) {
45
- error = caught;
46
- }
47
- return;
48
- }
49
-
50
- internalLoading = true;
51
- try {
52
- await action();
53
- } catch (caught) {
54
- error = caught;
55
- } finally {
56
- internalLoading = false;
57
- }
58
- };
59
-
60
- const errorLabel = $derived.by(() => {
61
- if (!error) return null;
62
- if (typeof error === 'string' && error.trim().length > 0) return error;
63
- if (error instanceof Error && error.message.trim().length > 0) return error.message;
64
- return 'Something went wrong';
65
- });
66
- </script>
67
-
68
- <Tooltip label={errorLabel ?? ''} disabled={!errorLabel}>
69
- <button
70
- {type}
71
- class="inline-flex items-center gap-2 disabled:cursor-not-allowed disabled:opacity-50 {className}"
72
- disabled={effectiveDisabled}
73
- aria-busy={effectiveLoading}
74
- aria-label={styleMode === 'iconOnly' ? label : undefined}
75
- data-error={error ? 'true' : 'false'}
76
- {...props}
77
- onclick={handleClick}
78
- >
79
- <span class="inline-grid size-4 shrink-0 place-items-center">
80
- {#if effectiveLoading}
81
- <Spinner class="async-button-icon size-4" />
82
- {:else if error}
83
- <CircleAlertIcon class="async-button-icon size-4 text-red-600" />
84
- {:else if icon}
85
- {@const Icon = icon}
86
- <Icon class="async-button-icon size-4" />
87
- {/if}
88
- </span>
89
- {#if styleMode === 'iconAndLabel'}
90
- <span class="async-button-text">{label}</span>
91
- {/if}
92
- </button>
93
- </Tooltip>
@@ -1,76 +0,0 @@
1
- <script lang="ts">
2
- import { setContext, getContext } from 'svelte';
3
- import type { Snippet } from 'svelte';
4
-
5
- interface Props {
6
- left?: Snippet;
7
- right?: Snippet;
8
- children?: Snippet;
9
- chrome?: boolean;
10
- }
11
-
12
- let { left, right, children, chrome = true }: Props = $props();
13
-
14
- const existingContext = getContext<{
15
- leftOpen?: boolean;
16
- rightOpen?: boolean;
17
- }>('navigationStack');
18
-
19
- let leftOpen = $state(existingContext?.leftOpen ?? true);
20
- let rightOpen = $state(existingContext?.rightOpen ?? true);
21
-
22
- function toggleLeft() {
23
- leftOpen = !leftOpen;
24
- }
25
-
26
- function toggleRight() {
27
- rightOpen = !rightOpen;
28
- }
29
-
30
- setContext('navigationStack', {
31
- get leftOpen() {
32
- return leftOpen;
33
- },
34
- get rightOpen() {
35
- return rightOpen;
36
- },
37
- toggleLeft,
38
- toggleRight
39
- });
40
- </script>
41
-
42
- <div class="navigation-stack hstack size-full" data-chrome={chrome ? 'true' : 'false'}>
43
- {#if left}
44
- <div
45
- class="navigation-stack-sidebar navigation-stack-sidebar-left h-full overflow-hidden transition-all duration-300 ease-in-out"
46
- style="width: {leftOpen ? 'var(--navigation-stack-sidebar-width)' : '0'}"
47
- >
48
- <div
49
- class="navigation-stack-sidebar-inner vstack h-full overflow-auto p-4"
50
- style="width: var(--navigation-stack-sidebar-width);"
51
- >
52
- {@render left()}
53
- </div>
54
- </div>
55
- {/if}
56
-
57
- <div class="navigation-stack-content vstack flex-1">
58
- {#if children}
59
- {@render children()}
60
- {/if}
61
- </div>
62
-
63
- {#if right}
64
- <div
65
- class="navigation-stack-sidebar navigation-stack-sidebar-right h-full overflow-hidden transition-all duration-300 ease-in-out"
66
- style="width: {rightOpen ? 'var(--navigation-stack-sidebar-width)' : '0'}"
67
- >
68
- <div
69
- class="navigation-stack-sidebar-inner vstack h-full overflow-auto p-4"
70
- style="width: var(--navigation-stack-sidebar-width);"
71
- >
72
- {@render right()}
73
- </div>
74
- </div>
75
- {/if}
76
- </div>
@@ -1,10 +0,0 @@
1
- import type { Snippet } from 'svelte';
2
- interface Props {
3
- left?: Snippet;
4
- right?: Snippet;
5
- children?: Snippet;
6
- chrome?: boolean;
7
- }
8
- declare const NavigationStack: import("svelte").Component<Props, {}, "">;
9
- type NavigationStack = ReturnType<typeof NavigationStack>;
10
- export default NavigationStack;
@@ -1,36 +0,0 @@
1
- <script lang="ts">
2
- import { getContext } from 'svelte';
3
- import type { Snippet } from 'svelte';
4
- import { PanelLeft, PanelRight } from '@lucide/svelte';
5
-
6
- interface Props {
7
- side: 'left' | 'right';
8
- children?: Snippet;
9
- class?: string;
10
- }
11
-
12
- let { side, children, class: className = '' }: Props = $props();
13
-
14
- const ctx = getContext<{
15
- toggleLeft: () => void;
16
- toggleRight: () => void;
17
- }>('navigationStack');
18
-
19
- function handleClick() {
20
- if (side === 'left') {
21
- ctx?.toggleLeft();
22
- } else {
23
- ctx?.toggleRight();
24
- }
25
- }
26
- </script>
27
-
28
- <button onclick={handleClick} class="sidebar-toggle {className}" title="Toggle {side} sidebar">
29
- {#if children}
30
- {@render children()}
31
- {:else if side === 'left'}
32
- <PanelLeft class="h-5 w-5" />
33
- {:else}
34
- <PanelRight class="h-5 w-5" />
35
- {/if}
36
- </button>
@@ -1,9 +0,0 @@
1
- import type { Snippet } from 'svelte';
2
- interface Props {
3
- side: 'left' | 'right';
4
- children?: Snippet;
5
- class?: string;
6
- }
7
- declare const SidebarToggle: import("svelte").Component<Props, {}, "">;
8
- type SidebarToggle = ReturnType<typeof SidebarToggle>;
9
- export default SidebarToggle;
@@ -1,25 +0,0 @@
1
- <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
-
4
- interface Props {
5
- header?: Snippet;
6
- children?: Snippet;
7
- chrome?: boolean;
8
- }
9
-
10
- let { header, children, chrome = true }: Props = $props();
11
- </script>
12
-
13
- <div class="navigation-stack-toolbar-shell vstack h-full" data-chrome={chrome ? 'true' : 'false'}>
14
- {#if header}
15
- <div class="navigation-stack-toolbar flex items-center gap-2 p-2">
16
- {@render header()}
17
- </div>
18
- {/if}
19
-
20
- <div class="navigation-stack-toolbar-content vstack h-full">
21
- {#if children}
22
- {@render children()}
23
- {/if}
24
- </div>
25
- </div>
@@ -1,9 +0,0 @@
1
- import type { Snippet } from 'svelte';
2
- interface Props {
3
- header?: Snippet;
4
- children?: Snippet;
5
- chrome?: boolean;
6
- }
7
- declare const Toolbar: import("svelte").Component<Props, {}, "">;
8
- type Toolbar = ReturnType<typeof Toolbar>;
9
- export default Toolbar;
@@ -1,144 +0,0 @@
1
- <script lang="ts">
2
- import { goto } from '$app/navigation';
3
- import {
4
- ChevronLeftIcon,
5
- ChevronRightIcon,
6
- ChevronsLeftIcon,
7
- ChevronsRightIcon
8
- } from '@lucide/svelte';
9
-
10
- type PaginationData = {
11
- view: string;
12
- page: number;
13
- totalPages: number;
14
- hasNext?: boolean;
15
- };
16
-
17
- let {
18
- data,
19
- onPageChange,
20
- showFirstLast = false,
21
- style: styleMode = 'label',
22
- class: className = ''
23
- }: {
24
- data: PaginationData;
25
- onPageChange?: (page: number, href: string) => void | Promise<void>;
26
- showFirstLast?: boolean;
27
- style?: 'icon' | 'label';
28
- class?: string;
29
- } = $props();
30
-
31
- const clampedPage = (targetPage: number) => Math.min(Math.max(targetPage, 1), maxPage());
32
-
33
- const toQuery = (targetPage: number) => {
34
- const params = new URLSearchParams({
35
- view: data.view,
36
- page: String(clampedPage(targetPage))
37
- });
38
- return `?${params.toString()}`;
39
- };
40
-
41
- const maxPage = () => Math.max(1, data.totalPages);
42
- const safePage = () => Math.min(Math.max(data.page, 1), maxPage());
43
- const hasNext = () => (typeof data.hasNext === 'boolean' ? data.hasNext : safePage() < maxPage());
44
- const hasPrevious = () => safePage() > 1;
45
- const buttonClass = () =>
46
- `pagination-button action disabled:bg-zinc-200 disabled:text-zinc-500 inline-flex items-center justify-center leading-none ${
47
- styleMode === 'icon' ? 'h-8 w-8 p-0' : 'padding-sm'
48
- }`;
49
-
50
- const goToPage = (targetPage: number) => {
51
- const clamped = clampedPage(targetPage);
52
- const href = toQuery(clamped);
53
- if (onPageChange) {
54
- void onPageChange(clamped, href);
55
- return;
56
- }
57
- void goto(href);
58
- };
59
-
60
- const handleSubmit = (event: SubmitEvent) => {
61
- event.preventDefault();
62
- const form = event.currentTarget as HTMLFormElement;
63
- const input = form.elements.namedItem('page') as HTMLInputElement | null;
64
- if (!input) return;
65
-
66
- const parsed = Number.parseInt(input.value, 10);
67
- const fallback = safePage();
68
- const next = Number.isFinite(parsed) ? parsed : fallback;
69
- const clamped = Math.min(Math.max(next, 1), maxPage());
70
- input.value = String(clamped);
71
- goToPage(clamped);
72
- };
73
- </script>
74
-
75
- <div class={`pagination hstack items-center ${className}`}>
76
- {#if showFirstLast}
77
- <button
78
- type="button"
79
- class={buttonClass()}
80
- onclick={() => goToPage(1)}
81
- aria-label="First page"
82
- disabled={!hasPrevious()}
83
- >
84
- {#if styleMode === 'icon'}
85
- <ChevronsLeftIcon class="size-4 -translate-x-px" />
86
- {:else}
87
- First
88
- {/if}
89
- </button>
90
- {/if}
91
-
92
- <button
93
- type="button"
94
- class={buttonClass()}
95
- onclick={() => goToPage(safePage() - 1)}
96
- aria-label="Previous page"
97
- disabled={!hasPrevious()}
98
- >
99
- {#if styleMode === 'icon'}
100
- <ChevronLeftIcon class="size-4 -translate-x-px" />
101
- {:else}
102
- Previous
103
- {/if}
104
- </button>
105
-
106
- <span>Page</span>
107
-
108
- <form method="GET" style="display: inline;" novalidate onsubmit={handleSubmit}>
109
- <input type="hidden" name="view" value={data.view} />
110
- <input id="page" name="page" type="number" class="pagination-input" value={safePage()} />
111
- </form>
112
-
113
- <span>of {maxPage()}</span>
114
-
115
- <button
116
- type="button"
117
- class={buttonClass()}
118
- onclick={() => goToPage(safePage() + 1)}
119
- aria-label="Next page"
120
- disabled={!hasNext()}
121
- >
122
- {#if styleMode === 'icon'}
123
- <ChevronRightIcon class="size-4 translate-x-px" />
124
- {:else}
125
- Next
126
- {/if}
127
- </button>
128
-
129
- {#if showFirstLast}
130
- <button
131
- type="button"
132
- class={buttonClass()}
133
- onclick={() => goToPage(maxPage())}
134
- aria-label="Last page"
135
- disabled={!hasNext()}
136
- >
137
- {#if styleMode === 'icon'}
138
- <ChevronsRightIcon class="size-4 translate-x-px" />
139
- {:else}
140
- Last
141
- {/if}
142
- </button>
143
- {/if}
144
- </div>
@@ -1,35 +0,0 @@
1
- <script module lang="ts">
2
- export const demo = {
3
- name: 'Popover',
4
- description: 'Composable popover with trigger and content snippets.'
5
- };
6
- </script>
7
-
8
- <script lang="ts">
9
- import Popover from './Popover.svelte';
10
- import SearchInput from '../SearchInput.svelte';
11
-
12
- let search = $state('');
13
- </script>
14
-
15
- <Popover align="center">
16
- {#snippet trigger()}
17
- <button
18
- type="button"
19
- class="rounded-full border border-zinc-300 px-3 py-2 text-sm text-zinc-800"
20
- >
21
- Open popover
22
- </button>
23
- {/snippet}
24
-
25
- <div class="vstack gap-2">
26
- <label for="popover-demo-search" class="text-sm font-medium text-zinc-700">Search</label>
27
- <SearchInput
28
- id="popover-demo-search"
29
- bind:value={search}
30
- placeholder="Type to search..."
31
- confirmText="Enter"
32
- class="w-64"
33
- />
34
- </div>
35
- </Popover>
@@ -1,13 +0,0 @@
1
- import type { Snippet } from 'svelte';
2
- import { type Anchor, type Align } from '../../utils/positioning';
3
- interface Props {
4
- trigger: Snippet;
5
- children: Snippet;
6
- open?: boolean;
7
- class?: string;
8
- align?: Align;
9
- anchor?: Anchor;
10
- }
11
- declare const Popover: import("svelte").Component<Props, {}, "open">;
12
- type Popover = ReturnType<typeof Popover>;
13
- export default Popover;
@@ -1,2 +0,0 @@
1
- export { default } from './Popover.svelte';
2
- export { default as PopoverDebugOverlay } from './PopoverDebugOverlay.svelte';
@@ -1,2 +0,0 @@
1
- export { default } from './Popover.svelte';
2
- export { default as PopoverDebugOverlay } from './PopoverDebugOverlay.svelte';
@@ -1,18 +0,0 @@
1
- export declare function registerPopover(id: string): void;
2
- export declare function unregisterPopover(id: string): void;
3
- export declare function setParentId(id: string, parentId: string | null): void;
4
- export declare function setOpen(id: string, open: boolean): void;
5
- export declare function getParentId(id: string): string | null;
6
- /**
7
- * Returns true if any registered popover lists `parentId` as its parent and is currently open.
8
- */
9
- export declare function hasOpenChild(parentId: string): boolean;
10
- /**
11
- * Walk the parent chain from `candidateId` upward.
12
- * Returns true if `ancestorId` is found in the chain.
13
- */
14
- export declare function isAncestor(candidateId: string | null, ancestorId: string): boolean;
15
- /**
16
- * Returns the IDs of all currently open popovers.
17
- */
18
- export declare function getOpenPopoverIds(): string[];
@@ -1,39 +0,0 @@
1
- <script lang="ts">
2
- import { SearchIcon } from '@lucide/svelte';
3
- import type { HTMLInputAttributes } from 'svelte/elements';
4
-
5
- type Props = {
6
- value?: string;
7
- confirmText?: string | null;
8
- inputClass?: string;
9
- } & Omit<HTMLInputAttributes, 'children' | 'type' | 'value'>;
10
-
11
- let {
12
- value = $bindable(''),
13
- confirmText = null,
14
- inputClass = '',
15
- class: className = '',
16
- disabled = false,
17
- placeholder = 'Search',
18
- ...props
19
- }: Props = $props();
20
- </script>
21
-
22
- <label class="search-input {className}" data-disabled={disabled ? 'true' : 'false'}>
23
- <span class="search-input-icon" aria-hidden="true">
24
- <SearchIcon class="size-4" />
25
- </span>
26
- <input
27
- type="search"
28
- bind:value
29
- {disabled}
30
- {placeholder}
31
- class="search-input-field {inputClass}"
32
- {...props}
33
- />
34
- {#if confirmText}
35
- <span class="search-input-confirm">
36
- {confirmText}
37
- </span>
38
- {/if}
39
- </label>
@@ -1,51 +0,0 @@
1
- <script lang="ts">
2
- type Option = {
3
- label: string;
4
- value: string;
5
- disabled?: boolean;
6
- };
7
-
8
- let {
9
- options,
10
- value = $bindable(''),
11
- disabled = false,
12
- class: className = ''
13
- }: {
14
- options: Option[];
15
- value: string;
16
- disabled?: boolean;
17
- class?: string;
18
- } = $props();
19
- </script>
20
-
21
- <div
22
- class={`segmented-picker hstack w-fit ${className}`}
23
- class:segmented-picker-disabled={disabled}
24
- >
25
- {#each options as option}
26
- {#if option.disabled}
27
- <span
28
- class={`segmented-picker-button segmented-picker-button-disabled ${
29
- option.value === value ? 'segmented-picker-button-disabled-selected' : ''
30
- }`}
31
- aria-disabled="true"
32
- >
33
- {option.label}
34
- </span>
35
- {:else if option.value === value}
36
- <span class="segmented-picker-button segmented-picker-button-active">{option.label}</span>
37
- {:else}
38
- <button
39
- type="button"
40
- {disabled}
41
- class="segmented-picker-button"
42
- onclick={() => {
43
- if (disabled) return;
44
- value = option.value;
45
- }}
46
- >
47
- {option.label}
48
- </button>
49
- {/if}
50
- {/each}
51
- </div>