@linktr.ee/linkapp 0.0.48 → 0.0.49

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 (203) hide show
  1. package/README.md +1 -1
  2. package/dev-server/components/form/array-field.tsx +115 -0
  3. package/dev-server/components/form/file-field.tsx +48 -0
  4. package/dev-server/components/form/form-element.tsx +304 -0
  5. package/dev-server/components/form/link-behavior-field.tsx +68 -0
  6. package/dev-server/components/form/location-field.tsx +60 -0
  7. package/dev-server/components/settings-preview.tsx +138 -302
  8. package/dev-server/components/ui/checkbox.tsx +29 -0
  9. package/dev-server/components/ui/dialog.tsx +2 -10
  10. package/dev-server/components/ui/field.tsx +24 -49
  11. package/dev-server/components/ui/input.tsx +20 -21
  12. package/dev-server/components/ui/label.tsx +4 -4
  13. package/dev-server/components/ui/radio-group.tsx +37 -0
  14. package/dev-server/components/ui/select.tsx +153 -0
  15. package/dev-server/components/ui/switch.tsx +31 -0
  16. package/dev-server/components/ui/tabs.tsx +1 -1
  17. package/dev-server/components/ui/textarea.tsx +18 -19
  18. package/dev-server/env.d.ts +4 -1
  19. package/dev-server/expanded/main.tsx +20 -22
  20. package/dev-server/expanded.html +0 -1
  21. package/dev-server/featured/main.tsx +29 -36
  22. package/dev-server/featured-carousel.html +0 -1
  23. package/dev-server/featured.html +0 -1
  24. package/dev-server/index.html +1 -7
  25. package/dev-server/lib/utils.ts +3 -3
  26. package/dev-server/package.json +3 -3
  27. package/dev-server/postcss/tailwind-source-fallback.js +2 -7
  28. package/dev-server/postcss.config.mjs +2 -2
  29. package/dev-server/preview/Preview.tsx +310 -350
  30. package/dev-server/preview/main.tsx +8 -8
  31. package/dev-server/preview/preview.css +0 -1
  32. package/dev-server/public/site.webmanifest +1 -1
  33. package/dev-server/rsbuild.config.ts +1 -1
  34. package/dev-server/shared/dev-parent-simulator.ts +219 -0
  35. package/dev-server/shared/theme-presets.ts +71 -75
  36. package/dev-server/shared/theme-utils.ts +11 -11
  37. package/dist/cli.js +18 -12
  38. package/dist/cli.js.map +1 -1
  39. package/dist/commands/add.d.ts.map +1 -1
  40. package/dist/commands/add.js +27 -42
  41. package/dist/commands/add.js.map +1 -1
  42. package/dist/commands/build.d.ts.map +1 -1
  43. package/dist/commands/build.js +26 -16
  44. package/dist/commands/build.js.map +1 -1
  45. package/dist/commands/deploy.d.ts +1 -11
  46. package/dist/commands/deploy.d.ts.map +1 -1
  47. package/dist/commands/deploy.js +3 -13
  48. package/dist/commands/deploy.js.map +1 -1
  49. package/dist/commands/dev.d.ts.map +1 -1
  50. package/dist/commands/dev.js +132 -388
  51. package/dist/commands/dev.js.map +1 -1
  52. package/dist/commands/login.d.ts.map +1 -1
  53. package/dist/commands/login.js +17 -29
  54. package/dist/commands/login.js.map +1 -1
  55. package/dist/commands/logout.d.ts.map +1 -1
  56. package/dist/commands/logout.js +6 -11
  57. package/dist/commands/logout.js.map +1 -1
  58. package/dist/commands/rollback.d.ts +10 -0
  59. package/dist/commands/rollback.d.ts.map +1 -0
  60. package/dist/commands/rollback.js +148 -0
  61. package/dist/commands/rollback.js.map +1 -0
  62. package/dist/commands/status.d.ts +8 -0
  63. package/dist/commands/status.d.ts.map +1 -0
  64. package/dist/commands/status.js +96 -0
  65. package/dist/commands/status.js.map +1 -0
  66. package/dist/commands/test-url-match-rules.d.ts.map +1 -1
  67. package/dist/commands/test-url-match-rules.js +20 -26
  68. package/dist/commands/test-url-match-rules.js.map +1 -1
  69. package/dist/lib/auth/device-flow.d.ts +1 -1
  70. package/dist/lib/auth/device-flow.d.ts.map +1 -1
  71. package/dist/lib/auth/device-flow.js +3 -3
  72. package/dist/lib/auth/device-flow.js.map +1 -1
  73. package/dist/lib/auth/token-storage.d.ts.map +1 -1
  74. package/dist/lib/auth/token-storage.js +14 -37
  75. package/dist/lib/auth/token-storage.js.map +1 -1
  76. package/dist/lib/build/detect-layouts.d.ts.map +1 -1
  77. package/dist/lib/build/detect-layouts.js +27 -13
  78. package/dist/lib/build/detect-layouts.js.map +1 -1
  79. package/dist/lib/config/load-config.d.ts.map +1 -1
  80. package/dist/lib/config/load-config.js +0 -2
  81. package/dist/lib/config/load-config.js.map +1 -1
  82. package/dist/lib/deploy/deploy-output.d.ts +2 -1
  83. package/dist/lib/deploy/deploy-output.d.ts.map +1 -1
  84. package/dist/lib/deploy/deploy-output.js +9 -1
  85. package/dist/lib/deploy/deploy-output.js.map +1 -1
  86. package/dist/lib/deploy/deploy-phases.d.ts +2 -0
  87. package/dist/lib/deploy/deploy-phases.d.ts.map +1 -1
  88. package/dist/lib/deploy/deploy-phases.js +9 -23
  89. package/dist/lib/deploy/deploy-phases.js.map +1 -1
  90. package/dist/lib/deploy/deploy-utils.d.ts +15 -7
  91. package/dist/lib/deploy/deploy-utils.d.ts.map +1 -1
  92. package/dist/lib/deploy/deploy-utils.js +49 -36
  93. package/dist/lib/deploy/deploy-utils.js.map +1 -1
  94. package/dist/lib/deploy/generate-manifest-files.d.ts.map +1 -1
  95. package/dist/lib/deploy/generate-manifest-files.js +13 -39
  96. package/dist/lib/deploy/generate-manifest-files.js.map +1 -1
  97. package/dist/lib/deploy/pack-project.d.ts.map +1 -1
  98. package/dist/lib/deploy/pack-project.js +34 -20
  99. package/dist/lib/deploy/pack-project.js.map +1 -1
  100. package/dist/lib/deploy/slot-manager.d.ts +54 -0
  101. package/dist/lib/deploy/slot-manager.d.ts.map +1 -0
  102. package/dist/lib/deploy/slot-manager.js +72 -0
  103. package/dist/lib/deploy/slot-manager.js.map +1 -0
  104. package/dist/lib/deploy/test-url-match-rules.d.ts +10 -2
  105. package/dist/lib/deploy/test-url-match-rules.d.ts.map +1 -1
  106. package/dist/lib/deploy/test-url-match-rules.js +1 -1
  107. package/dist/lib/deploy/test-url-match-rules.js.map +1 -1
  108. package/dist/lib/deploy/upload.d.ts +1 -0
  109. package/dist/lib/deploy/upload.d.ts.map +1 -1
  110. package/dist/lib/deploy/upload.js +15 -24
  111. package/dist/lib/deploy/upload.js.map +1 -1
  112. package/dist/lib/deploy/validation.d.ts.map +1 -1
  113. package/dist/lib/deploy/validation.js +43 -48
  114. package/dist/lib/deploy/validation.js.map +1 -1
  115. package/dist/lib/rsbuild/config-factory.d.ts.map +1 -1
  116. package/dist/lib/rsbuild/config-factory.js +10 -17
  117. package/dist/lib/rsbuild/config-factory.js.map +1 -1
  118. package/dist/lib/rsbuild/plugins/asset-versioning.d.ts.map +1 -1
  119. package/dist/lib/rsbuild/plugins/asset-versioning.js +4 -14
  120. package/dist/lib/rsbuild/plugins/asset-versioning.js.map +1 -1
  121. package/dist/lib/rsbuild/plugins/brotli-compression.d.ts.map +1 -1
  122. package/dist/lib/rsbuild/plugins/brotli-compression.js +4 -4
  123. package/dist/lib/rsbuild/plugins/brotli-compression.js.map +1 -1
  124. package/dist/lib/rsbuild/plugins/copy-public.d.ts.map +1 -1
  125. package/dist/lib/rsbuild/plugins/copy-public.js.map +1 -1
  126. package/dist/lib/rsbuild/postcss/tailwind-source-fallback.d.ts.map +1 -1
  127. package/dist/lib/rsbuild/postcss/tailwind-source-fallback.js +1 -3
  128. package/dist/lib/rsbuild/postcss/tailwind-source-fallback.js.map +1 -1
  129. package/dist/lib/utils/console.d.ts +8 -0
  130. package/dist/lib/utils/console.d.ts.map +1 -0
  131. package/dist/lib/utils/console.js +10 -0
  132. package/dist/lib/utils/console.js.map +1 -0
  133. package/dist/lib/utils/filesystem.d.ts +9 -0
  134. package/dist/lib/utils/filesystem.d.ts.map +1 -0
  135. package/dist/lib/utils/filesystem.js +30 -0
  136. package/dist/lib/utils/filesystem.js.map +1 -0
  137. package/dist/lib/utils/formatters.d.ts +8 -0
  138. package/dist/lib/utils/formatters.d.ts.map +1 -0
  139. package/dist/lib/utils/formatters.js +22 -0
  140. package/dist/lib/utils/formatters.js.map +1 -0
  141. package/dist/lib/utils/index.d.ts +7 -0
  142. package/dist/lib/utils/index.d.ts.map +1 -0
  143. package/dist/lib/utils/index.js +7 -0
  144. package/dist/lib/utils/index.js.map +1 -0
  145. package/dist/lib/utils/setup-runtime.d.ts.map +1 -1
  146. package/dist/lib/utils/setup-runtime.js +22 -63
  147. package/dist/lib/utils/setup-runtime.js.map +1 -1
  148. package/dist/schema/config.schema.d.ts +9 -48
  149. package/dist/schema/config.schema.d.ts.map +1 -1
  150. package/dist/schema/config.schema.js +119 -120
  151. package/dist/schema/config.schema.js.map +1 -1
  152. package/dist/sdk/hooks/mocks.d.ts +9 -0
  153. package/dist/sdk/hooks/mocks.d.ts.map +1 -0
  154. package/dist/sdk/hooks/mocks.js +17 -0
  155. package/dist/sdk/hooks/mocks.js.map +1 -0
  156. package/dist/sdk/hooks/use-audience-manager.d.ts +44 -0
  157. package/dist/sdk/hooks/use-audience-manager.d.ts.map +1 -0
  158. package/dist/sdk/hooks/use-audience-manager.js +109 -0
  159. package/dist/sdk/hooks/use-audience-manager.js.map +1 -0
  160. package/dist/sdk/hooks/use-ip.d.ts +45 -0
  161. package/dist/sdk/hooks/use-ip.d.ts.map +1 -0
  162. package/dist/sdk/hooks/use-ip.js +46 -0
  163. package/dist/sdk/hooks/use-ip.js.map +1 -0
  164. package/dist/sdk/hooks/use-sdk-request.d.ts +46 -0
  165. package/dist/sdk/hooks/use-sdk-request.d.ts.map +1 -0
  166. package/dist/sdk/hooks/use-sdk-request.js +65 -0
  167. package/dist/sdk/hooks/use-sdk-request.js.map +1 -0
  168. package/dist/sdk/hooks/use-theme.d.ts +45 -0
  169. package/dist/sdk/hooks/use-theme.d.ts.map +1 -0
  170. package/dist/sdk/hooks/use-theme.js +97 -0
  171. package/dist/sdk/hooks/use-theme.js.map +1 -0
  172. package/dist/sdk/hooks/use-visitor.d.ts +41 -0
  173. package/dist/sdk/hooks/use-visitor.d.ts.map +1 -0
  174. package/dist/sdk/hooks/use-visitor.js +42 -0
  175. package/dist/sdk/hooks/use-visitor.js.map +1 -0
  176. package/dist/sdk/hooks/validation.d.ts +8 -0
  177. package/dist/sdk/hooks/validation.d.ts.map +1 -0
  178. package/dist/sdk/hooks/validation.js +13 -0
  179. package/dist/sdk/hooks/validation.js.map +1 -0
  180. package/dist/sdk/index.d.ts +17 -5
  181. package/dist/sdk/index.d.ts.map +1 -1
  182. package/dist/sdk/index.js +16 -5
  183. package/dist/sdk/index.js.map +1 -1
  184. package/dist/sdk/message-bus.d.ts +59 -0
  185. package/dist/sdk/message-bus.d.ts.map +1 -0
  186. package/dist/sdk/message-bus.js +152 -0
  187. package/dist/sdk/message-bus.js.map +1 -0
  188. package/dist/sdk/messages.d.ts +121 -0
  189. package/dist/sdk/messages.d.ts.map +1 -0
  190. package/dist/sdk/messages.js +9 -0
  191. package/dist/sdk/messages.js.map +1 -0
  192. package/dist/sdk/send-message.d.ts +1 -1
  193. package/dist/sdk/send-message.js +18 -18
  194. package/dist/sdk/send-message.js.map +1 -1
  195. package/dist/sdk/use-expand-link-app.d.ts +3 -3
  196. package/dist/sdk/use-expand-link-app.d.ts.map +1 -1
  197. package/dist/sdk/use-expand-link-app.js +9 -5
  198. package/dist/sdk/use-expand-link-app.js.map +1 -1
  199. package/dist/types.d.ts +235 -55
  200. package/dist/types.d.ts.map +1 -1
  201. package/dist/types.js +8 -3
  202. package/dist/types.js.map +1 -1
  203. package/package.json +3 -9
@@ -1,25 +1,24 @@
1
- import * as React from "react"
1
+ import * as React from 'react'
2
2
 
3
- import { cn } from "../../lib/utils"
3
+ import { cn } from '../../lib/utils'
4
4
 
5
- const Input = React.forwardRef<
6
- HTMLInputElement,
7
- React.InputHTMLAttributes<HTMLInputElement>
8
- >(({ className, type, ...props }, ref) => (
9
- <input
10
- type={type}
11
- className={cn(
12
- "flex h-9 w-full rounded-md border border-gray-300 bg-white px-3 py-1 text-sm shadow-sm transition-colors",
13
- "file:border-0 file:bg-transparent file:text-sm file:font-medium",
14
- "placeholder:text-gray-400",
15
- "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-blue-500 focus-visible:border-blue-500",
16
- "disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500",
17
- className
18
- )}
19
- ref={ref}
20
- {...props}
21
- />
22
- ))
23
- Input.displayName = "Input"
5
+ const Input = React.forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(
6
+ ({ className, type, ...props }, ref) => (
7
+ <input
8
+ type={type}
9
+ className={cn(
10
+ 'flex h-9 w-full rounded-md border border-gray-300 bg-white px-3 py-1 text-sm shadow-sm transition-colors',
11
+ 'file:border-0 file:bg-transparent file:text-sm file:font-medium',
12
+ 'placeholder:text-gray-400',
13
+ 'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-blue-500 focus-visible:border-blue-500',
14
+ 'disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500',
15
+ className
16
+ )}
17
+ ref={ref}
18
+ {...props}
19
+ />
20
+ )
21
+ )
22
+ Input.displayName = 'Input'
24
23
 
25
24
  export { Input }
@@ -1,7 +1,7 @@
1
- import * as React from "react"
2
- import * as LabelPrimitive from "@radix-ui/react-label"
1
+ import * as LabelPrimitive from '@radix-ui/react-label'
2
+ import * as React from 'react'
3
3
 
4
- import { cn } from "../../lib/utils"
4
+ import { cn } from '../../lib/utils'
5
5
 
6
6
  const Label = React.forwardRef<
7
7
  React.ElementRef<typeof LabelPrimitive.Root>,
@@ -10,7 +10,7 @@ const Label = React.forwardRef<
10
10
  <LabelPrimitive.Root
11
11
  ref={ref}
12
12
  className={cn(
13
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
13
+ 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
14
14
  className
15
15
  )}
16
16
  {...props}
@@ -0,0 +1,37 @@
1
+ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group'
2
+ import { Circle } from 'lucide-react'
3
+ import * as React from 'react'
4
+
5
+ import { cn } from '../../lib/utils'
6
+
7
+ const RadioGroup = React.forwardRef<
8
+ React.ElementRef<typeof RadioGroupPrimitive.Root>,
9
+ React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
10
+ >(({ className, ...props }, ref) => (
11
+ <RadioGroupPrimitive.Root className={cn('grid gap-2', className)} {...props} ref={ref} />
12
+ ))
13
+ RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
14
+
15
+ const RadioGroupItem = React.forwardRef<
16
+ React.ElementRef<typeof RadioGroupPrimitive.Item>,
17
+ React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
18
+ >(({ className, ...props }, ref) => (
19
+ <RadioGroupPrimitive.Item
20
+ ref={ref}
21
+ className={cn(
22
+ 'aspect-square h-4 w-4 rounded-full border border-gray-300 shadow-sm',
23
+ 'focus:outline-none focus-visible:ring-1 focus-visible:ring-blue-500',
24
+ 'disabled:cursor-not-allowed disabled:opacity-50',
25
+ 'data-[state=checked]:border-blue-500',
26
+ className
27
+ )}
28
+ {...props}
29
+ >
30
+ <RadioGroupPrimitive.Indicator className="flex items-center justify-center">
31
+ <Circle className="h-2 w-2 fill-blue-500 text-blue-500" />
32
+ </RadioGroupPrimitive.Indicator>
33
+ </RadioGroupPrimitive.Item>
34
+ ))
35
+ RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
36
+
37
+ export { RadioGroup, RadioGroupItem }
@@ -0,0 +1,153 @@
1
+ import * as SelectPrimitive from '@radix-ui/react-select'
2
+ import { Check, ChevronDown, ChevronUp } from 'lucide-react'
3
+ import * as React from 'react'
4
+
5
+ import { cn } from '../../lib/utils'
6
+
7
+ const Select = SelectPrimitive.Root
8
+
9
+ const SelectGroup = SelectPrimitive.Group
10
+
11
+ const SelectValue = SelectPrimitive.Value
12
+
13
+ const SelectTrigger = React.forwardRef<
14
+ React.ElementRef<typeof SelectPrimitive.Trigger>,
15
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
16
+ >(({ className, children, ...props }, ref) => (
17
+ <SelectPrimitive.Trigger
18
+ ref={ref}
19
+ className={cn(
20
+ 'flex h-9 w-full items-center justify-between rounded-md border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm',
21
+ 'placeholder:text-gray-400',
22
+ 'focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500',
23
+ 'disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500',
24
+ '[&>span]:line-clamp-1',
25
+ className
26
+ )}
27
+ {...props}
28
+ >
29
+ {children}
30
+ <SelectPrimitive.Icon asChild>
31
+ <ChevronDown className="h-4 w-4 opacity-50" />
32
+ </SelectPrimitive.Icon>
33
+ </SelectPrimitive.Trigger>
34
+ ))
35
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
36
+
37
+ const SelectScrollUpButton = React.forwardRef<
38
+ React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
39
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
40
+ >(({ className, ...props }, ref) => (
41
+ <SelectPrimitive.ScrollUpButton
42
+ ref={ref}
43
+ className={cn('flex cursor-default items-center justify-center py-1', className)}
44
+ {...props}
45
+ >
46
+ <ChevronUp className="h-4 w-4" />
47
+ </SelectPrimitive.ScrollUpButton>
48
+ ))
49
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
50
+
51
+ const SelectScrollDownButton = React.forwardRef<
52
+ React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
53
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
54
+ >(({ className, ...props }, ref) => (
55
+ <SelectPrimitive.ScrollDownButton
56
+ ref={ref}
57
+ className={cn('flex cursor-default items-center justify-center py-1', className)}
58
+ {...props}
59
+ >
60
+ <ChevronDown className="h-4 w-4" />
61
+ </SelectPrimitive.ScrollDownButton>
62
+ ))
63
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName
64
+
65
+ const SelectContent = React.forwardRef<
66
+ React.ElementRef<typeof SelectPrimitive.Content>,
67
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
68
+ >(({ className, children, position = 'popper', ...props }, ref) => (
69
+ <SelectPrimitive.Portal>
70
+ <SelectPrimitive.Content
71
+ ref={ref}
72
+ className={cn(
73
+ 'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-gray-200 bg-white text-gray-900 shadow-md',
74
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out',
75
+ 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
76
+ 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
77
+ 'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',
78
+ 'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
79
+ position === 'popper' &&
80
+ 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
81
+ className
82
+ )}
83
+ position={position}
84
+ {...props}
85
+ >
86
+ <SelectScrollUpButton />
87
+ <SelectPrimitive.Viewport
88
+ className={cn(
89
+ 'p-1',
90
+ position === 'popper' &&
91
+ 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]'
92
+ )}
93
+ >
94
+ {children}
95
+ </SelectPrimitive.Viewport>
96
+ <SelectScrollDownButton />
97
+ </SelectPrimitive.Content>
98
+ </SelectPrimitive.Portal>
99
+ ))
100
+ SelectContent.displayName = SelectPrimitive.Content.displayName
101
+
102
+ const SelectLabel = React.forwardRef<
103
+ React.ElementRef<typeof SelectPrimitive.Label>,
104
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
105
+ >(({ className, ...props }, ref) => (
106
+ <SelectPrimitive.Label ref={ref} className={cn('px-2 py-1.5 text-sm font-semibold', className)} {...props} />
107
+ ))
108
+ SelectLabel.displayName = SelectPrimitive.Label.displayName
109
+
110
+ const SelectItem = React.forwardRef<
111
+ React.ElementRef<typeof SelectPrimitive.Item>,
112
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
113
+ >(({ className, children, ...props }, ref) => (
114
+ <SelectPrimitive.Item
115
+ ref={ref}
116
+ className={cn(
117
+ 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none',
118
+ 'focus:bg-gray-100 focus:text-gray-900',
119
+ 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
120
+ className
121
+ )}
122
+ {...props}
123
+ >
124
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
125
+ <SelectPrimitive.ItemIndicator>
126
+ <Check className="h-4 w-4" />
127
+ </SelectPrimitive.ItemIndicator>
128
+ </span>
129
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
130
+ </SelectPrimitive.Item>
131
+ ))
132
+ SelectItem.displayName = SelectPrimitive.Item.displayName
133
+
134
+ const SelectSeparator = React.forwardRef<
135
+ React.ElementRef<typeof SelectPrimitive.Separator>,
136
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
137
+ >(({ className, ...props }, ref) => (
138
+ <SelectPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-gray-100', className)} {...props} />
139
+ ))
140
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName
141
+
142
+ export {
143
+ Select,
144
+ SelectGroup,
145
+ SelectValue,
146
+ SelectTrigger,
147
+ SelectContent,
148
+ SelectLabel,
149
+ SelectItem,
150
+ SelectSeparator,
151
+ SelectScrollUpButton,
152
+ SelectScrollDownButton,
153
+ }
@@ -0,0 +1,31 @@
1
+ import * as SwitchPrimitives from '@radix-ui/react-switch'
2
+ import * as React from 'react'
3
+
4
+ import { cn } from '../../lib/utils'
5
+
6
+ const Switch = React.forwardRef<
7
+ React.ElementRef<typeof SwitchPrimitives.Root>,
8
+ React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
9
+ >(({ className, ...props }, ref) => (
10
+ <SwitchPrimitives.Root
11
+ className={cn(
12
+ 'peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors',
13
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white',
14
+ 'disabled:cursor-not-allowed disabled:opacity-50',
15
+ 'data-[state=checked]:bg-blue-500 data-[state=unchecked]:bg-gray-200',
16
+ className
17
+ )}
18
+ {...props}
19
+ ref={ref}
20
+ >
21
+ <SwitchPrimitives.Thumb
22
+ className={cn(
23
+ 'pointer-events-none block h-4 w-4 rounded-full bg-white shadow-lg ring-0 transition-transform',
24
+ 'data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0'
25
+ )}
26
+ />
27
+ </SwitchPrimitives.Root>
28
+ ))
29
+ Switch.displayName = SwitchPrimitives.Root.displayName
30
+
31
+ export { Switch }
@@ -1,5 +1,5 @@
1
- import * as React from 'react'
2
1
  import * as TabsPrimitive from '@radix-ui/react-tabs'
2
+ import * as React from 'react'
3
3
  import { cn } from '../../lib/utils'
4
4
 
5
5
  const Tabs = TabsPrimitive.Root
@@ -1,23 +1,22 @@
1
- import * as React from "react"
1
+ import * as React from 'react'
2
2
 
3
- import { cn } from "../../lib/utils"
3
+ import { cn } from '../../lib/utils'
4
4
 
5
- const Textarea = React.forwardRef<
6
- HTMLTextAreaElement,
7
- React.TextareaHTMLAttributes<HTMLTextAreaElement>
8
- >(({ className, ...props }, ref) => (
9
- <textarea
10
- className={cn(
11
- "flex min-h-[80px] w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm transition-colors",
12
- "placeholder:text-gray-400",
13
- "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-blue-500 focus-visible:border-blue-500",
14
- "disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500 disabled:resize-none",
15
- className
16
- )}
17
- ref={ref}
18
- {...props}
19
- />
20
- ))
21
- Textarea.displayName = "Textarea"
5
+ const Textarea = React.forwardRef<HTMLTextAreaElement, React.TextareaHTMLAttributes<HTMLTextAreaElement>>(
6
+ ({ className, ...props }, ref) => (
7
+ <textarea
8
+ className={cn(
9
+ 'flex min-h-[80px] w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm transition-colors',
10
+ 'placeholder:text-gray-400',
11
+ 'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-blue-500 focus-visible:border-blue-500',
12
+ 'disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500 disabled:resize-none',
13
+ className
14
+ )}
15
+ ref={ref}
16
+ {...props}
17
+ />
18
+ )
19
+ )
20
+ Textarea.displayName = 'Textarea'
22
21
 
23
22
  export { Textarea }
@@ -1,8 +1,11 @@
1
1
  /// <reference types="@rsbuild/core/types" />
2
2
 
3
- import type { LinkAppSettings } from '../src/types'
3
+ import type { LinkAppManifest, LinkAppSettings } from '../src/types'
4
4
 
5
5
  declare global {
6
6
  const __PREVIEW_PROPS__: Record<string, unknown>
7
7
  const __SETTINGS_CONFIG__: LinkAppSettings
8
+ const __MANIFEST_CONFIG__: Partial<LinkAppManifest>
9
+ const __HAS_FEATURED__: boolean
10
+ const __HAS_FEATURED_CAROUSEL__: boolean
8
11
  }
@@ -1,9 +1,9 @@
1
- import Expanded from "@/app/expanded";
2
- import { StrictMode } from "react";
3
- import { createRoot } from "react-dom/client";
4
- import "@/app/globals.css";
5
- import { THEME_PRESETS } from "../shared/theme-presets";
6
- import { getThemeFromUrl, mergeThemeProps } from "../shared/theme-utils";
1
+ import Expanded from '@/app/expanded'
2
+ import { StrictMode } from 'react'
3
+ import { createRoot } from 'react-dom/client'
4
+ import '@/app/globals.css'
5
+ import { THEME_PRESETS } from '../shared/theme-presets'
6
+ import { getThemeFromUrl, mergeThemeProps } from '../shared/theme-utils'
7
7
 
8
8
  // Declare global window properties for theme and font application
9
9
  declare global {
@@ -18,42 +18,40 @@ declare global {
18
18
  }
19
19
 
20
20
  // Preview props injected by dev server via define
21
- declare const __PREVIEW_PROPS__: Record<string, unknown>;
21
+ declare const __PREVIEW_PROPS__: Record<string, unknown>
22
22
 
23
23
  // Extract just the variables from THEME_PRESETS for theme lookups
24
- const THEME_VARS = Object.fromEntries(
25
- Object.entries(THEME_PRESETS).map(([key, { variables }]) => [key, variables])
26
- );
24
+ const THEME_VARS = Object.fromEntries(Object.entries(THEME_PRESETS).map(([key, { variables }]) => [key, variables]))
27
25
 
28
26
  // Get theme variables from URL
29
- const themeVariables = getThemeFromUrl(THEME_VARS);
27
+ const themeVariables = getThemeFromUrl(THEME_VARS)
30
28
 
31
29
  // Get the selected theme key from URL or default to "default"
32
- const urlParams = new URLSearchParams(window.location.search);
33
- const themeKey = urlParams.get("theme") || "default";
34
- const selectedTheme = THEME_PRESETS[themeKey as keyof typeof THEME_PRESETS] || THEME_PRESETS.default;
30
+ const urlParams = new URLSearchParams(window.location.search)
31
+ const themeKey = urlParams.get('theme') || 'default'
32
+ const selectedTheme = THEME_PRESETS[themeKey as keyof typeof THEME_PRESETS] || THEME_PRESETS.default
35
33
 
36
34
  // Merge with preview props
37
- const previewProps = __PREVIEW_PROPS__ || {};
38
- const mergedProps = mergeThemeProps(themeVariables, previewProps);
35
+ const previewProps = __PREVIEW_PROPS__ || {}
36
+ const mergedProps = mergeThemeProps(themeVariables, previewProps)
39
37
 
40
38
  // Apply theme CSS variables on mount
41
39
  if (themeVariables && window.__linkapp_applyTheme) {
42
- window.__linkapp_applyTheme(themeVariables);
40
+ window.__linkapp_applyTheme(themeVariables)
43
41
  }
44
42
 
45
43
  // Apply font on mount
46
44
  if (selectedTheme.font && window.__linkapp_applyFont) {
47
- window.__linkapp_applyFont(selectedTheme.font);
45
+ window.__linkapp_applyFont(selectedTheme.font)
48
46
  }
49
47
 
50
- const rootElement = document.getElementById("root");
48
+ const rootElement = document.getElementById('root')
51
49
  if (!rootElement) {
52
- throw new Error("Root element not found");
50
+ throw new Error('Root element not found')
53
51
  }
54
52
 
55
53
  createRoot(rootElement).render(
56
54
  <StrictMode>
57
55
  <Expanded {...mergedProps} />
58
- </StrictMode>,
59
- );
56
+ </StrictMode>
57
+ )
@@ -3,7 +3,6 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Expanded - LinkApp</title>
7
6
 
8
7
  <!-- iframe-resizer: Required for iframe height auto-adjustment -->
9
8
  <script crossorigin src="https://unpkg.com/iframe-resizer@4.3.2/js/iframeResizer.contentWindow.js"></script>
@@ -1,14 +1,14 @@
1
- import Featured from "@/app/featured";
2
- import { StrictMode } from "react";
3
- import { createRoot } from "react-dom/client";
4
- import "@/app/globals.css";
5
- import { THEME_PRESETS } from "../shared/theme-presets";
6
- import { getThemeFromUrl, mergeThemeProps } from "../shared/theme-utils";
1
+ import Featured from '@/app/featured'
2
+ import { StrictMode } from 'react'
3
+ import { createRoot } from 'react-dom/client'
4
+ import '@/app/globals.css'
5
+ import { THEME_PRESETS } from '../shared/theme-presets'
6
+ import { getThemeFromUrl, mergeThemeProps } from '../shared/theme-utils'
7
7
 
8
8
  // Try to import FeaturedCarousel if it exists
9
- let FeaturedCarousel: React.ComponentType<any> | null = null;
9
+ let FeaturedCarousel: React.ComponentType<any> | null = null
10
10
  try {
11
- FeaturedCarousel = require("@/app/featured-carousel").default;
11
+ FeaturedCarousel = require('@/app/featured-carousel').default
12
12
  } catch (e) {
13
13
  // featured-carousel.tsx doesn't exist, that's ok
14
14
  }
@@ -16,63 +16,56 @@ try {
16
16
  // Declare global window properties for theme and font application
17
17
  declare global {
18
18
  interface Window {
19
- __linkapp_applyTheme?: (variables: Record<string, string>) => void;
19
+ __linkapp_applyTheme?: (variables: Record<string, string>) => void
20
20
  __linkapp_applyFont?: (fontData: {
21
- fontFamily: string;
22
- fontStyle?: string;
23
- cssUrl?: string;
24
- }) => void;
21
+ fontFamily: string
22
+ fontStyle?: string
23
+ cssUrl?: string
24
+ }) => void
25
25
  }
26
26
  }
27
27
 
28
28
  // Preview props injected by dev server via define
29
- declare const __PREVIEW_PROPS__: Record<string, unknown>;
29
+ declare const __PREVIEW_PROPS__: Record<string, unknown>
30
30
 
31
31
  // Extract just the variables from THEME_PRESETS for theme lookups
32
- const THEME_VARS = Object.fromEntries(
33
- Object.entries(THEME_PRESETS).map(([key, { variables }]) => [key, variables]),
34
- );
32
+ const THEME_VARS = Object.fromEntries(Object.entries(THEME_PRESETS).map(([key, { variables }]) => [key, variables]))
35
33
 
36
34
  // Get theme variables and groupLayoutOption from URL
37
- const params = new URLSearchParams(window.location.search);
38
- const groupLayoutOptionParam = params.get("groupLayoutOption");
39
- const themeVariables = getThemeFromUrl(THEME_VARS);
35
+ const params = new URLSearchParams(window.location.search)
36
+ const groupLayoutOptionParam = params.get('groupLayoutOption')
37
+ const themeVariables = getThemeFromUrl(THEME_VARS)
40
38
 
41
39
  // Get the selected theme for font application
42
- const themeKey = params.get("theme") || "default";
43
- const selectedTheme =
44
- THEME_PRESETS[themeKey as keyof typeof THEME_PRESETS] ||
45
- THEME_PRESETS.default;
40
+ const themeKey = params.get('theme') || 'default'
41
+ const selectedTheme = THEME_PRESETS[themeKey as keyof typeof THEME_PRESETS] || THEME_PRESETS.default
46
42
 
47
43
  // Merge with preview props and add groupLayoutOption
48
- const previewProps = __PREVIEW_PROPS__ || {};
44
+ const previewProps = __PREVIEW_PROPS__ || {}
49
45
  const mergedProps = mergeThemeProps(themeVariables, previewProps, {
50
46
  groupLayoutOption: groupLayoutOptionParam || undefined,
51
- });
47
+ })
52
48
 
53
49
  // Apply theme CSS variables on mount
54
50
  if (themeVariables && window.__linkapp_applyTheme) {
55
- window.__linkapp_applyTheme(themeVariables);
51
+ window.__linkapp_applyTheme(themeVariables)
56
52
  }
57
53
 
58
54
  // Apply font on mount
59
55
  if (selectedTheme.font && window.__linkapp_applyFont) {
60
- window.__linkapp_applyFont(selectedTheme.font);
56
+ window.__linkapp_applyFont(selectedTheme.font)
61
57
  }
62
58
 
63
- const rootElement = document.getElementById("root");
59
+ const rootElement = document.getElementById('root')
64
60
  if (!rootElement) {
65
- throw new Error("Root element not found");
61
+ throw new Error('Root element not found')
66
62
  }
67
63
 
68
64
  // Select the appropriate component based on groupLayoutOption parameter
69
- const LayoutComponent =
70
- groupLayoutOptionParam === "carousel" && FeaturedCarousel
71
- ? FeaturedCarousel
72
- : Featured;
65
+ const LayoutComponent = groupLayoutOptionParam === 'carousel' && FeaturedCarousel ? FeaturedCarousel : Featured
73
66
 
74
67
  createRoot(rootElement).render(
75
68
  <StrictMode>
76
69
  <LayoutComponent {...mergedProps} />
77
- </StrictMode>,
78
- );
70
+ </StrictMode>
71
+ )
@@ -3,7 +3,6 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Featured Carousel - LinkApp</title>
7
6
 
8
7
  <!-- iframe-resizer: Required for iframe height auto-adjustment -->
9
8
  <script crossorigin src="https://unpkg.com/iframe-resizer@4.3.2/js/iframeResizer.contentWindow.js"></script>
@@ -3,7 +3,6 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Featured - LinkApp</title>
7
6
 
8
7
  <!-- iframe-resizer: Required for iframe height auto-adjustment -->
9
8
  <script crossorigin src="https://unpkg.com/iframe-resizer@4.3.2/js/iframeResizer.contentWindow.js"></script>
@@ -3,14 +3,8 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Preview - LinkApp</title>
7
6
 
8
- <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
9
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
10
- <link rel="shortcut icon" href="/favicon.ico" />
11
- <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
12
- <meta name="apple-mobile-web-app-title" content="Linktree" />
13
- <link rel="manifest" href="/site.webmanifest" />
7
+ <link rel="icon" type="image/svg+xml" href="/app-icon.svg" />
14
8
 
15
9
  <!-- iframe-resizer: Required for LinkApps to communicate with Linktree parent frame -->
16
10
  <script crossorigin src="https://unpkg.com/iframe-resizer@4.3.2/js/iframeResizer.contentWindow.js"></script>
@@ -1,4 +1,4 @@
1
- import { clsx, type ClassValue } from 'clsx'
1
+ import { type ClassValue, clsx } from 'clsx'
2
2
  import { twMerge } from 'tailwind-merge'
3
3
 
4
4
  export function cn(...inputs: ClassValue[]) {
@@ -6,7 +6,7 @@ export function cn(...inputs: ClassValue[]) {
6
6
  }
7
7
 
8
8
  export const renderCssVariables = (vars: Record<string, string>): string => {
9
- return Object.entries(vars)
9
+ return `${Object.entries(vars)
10
10
  .map((entry) => entry.join(': '))
11
- .join('; ') + ';'
11
+ .join('; ')};`
12
12
  }
@@ -16,15 +16,15 @@
16
16
  "iframe-resizer-react": "^1.1.0",
17
17
  "lucide-react": "^0.545.0",
18
18
  "postcss": "^8.5.6",
19
- "react": "^19.1.0",
20
- "react-dom": "^19.1.0",
19
+ "react": "^19.2.1",
20
+ "react-dom": "^19.2.1",
21
21
  "tailwind-merge": "^3.3.1"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@rsbuild/core": "^1.1.14",
25
25
  "@rsbuild/plugin-react": "^1.1.0",
26
26
  "@types/react": "^19.2.2",
27
- "@types/react-dom": "^19",
27
+ "@types/react-dom": "^19.2.2",
28
28
  "tailwindcss": "^4",
29
29
  "tw-animate-css": "^1.4.0",
30
30
  "typescript": "^5"
@@ -36,9 +36,7 @@ export function createTailwindSourceFallback(options = {}) {
36
36
  }
37
37
 
38
38
  const normalizedSourceFile = toPosixPath(sourceFile)
39
- const normalizedProjectRoot = toPosixPath(
40
- projectRoot.endsWith('/') ? projectRoot : `${projectRoot}/`
41
- )
39
+ const normalizedProjectRoot = toPosixPath(projectRoot.endsWith('/') ? projectRoot : `${projectRoot}/`)
42
40
 
43
41
  if (!normalizedSourceFile.startsWith(normalizedProjectRoot)) {
44
42
  return
@@ -60,10 +58,7 @@ export function createTailwindSourceFallback(options = {}) {
60
58
  const normalizedBase = toPosixPath(baseSegment)
61
59
  const trimmedBase = normalizedBase.replace(/\/$/, '')
62
60
 
63
- const sourcePath =
64
- trimmedBase === '.' || trimmedBase === ''
65
- ? `./${glob}`
66
- : `${trimmedBase}/${glob}`
61
+ const sourcePath = trimmedBase === '.' || trimmedBase === '' ? `./${glob}` : `${trimmedBase}/${glob}`
67
62
 
68
63
  const atRule = postcss.atRule({
69
64
  name: 'source',
@@ -1,5 +1,5 @@
1
- import { fileURLToPath } from 'url'
2
- import { dirname, resolve } from 'path'
1
+ import { dirname, resolve } from 'node:path'
2
+ import { fileURLToPath } from 'node:url'
3
3
  import tailwindcss from '@tailwindcss/postcss'
4
4
  import { createTailwindSourceFallback } from './postcss/tailwind-source-fallback.js'
5
5