@remix-run/ui 0.1.0 → 0.1.2

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 (200) hide show
  1. package/README.md +24 -3
  2. package/dist/animation/animate-layout-mixin.js +66 -66
  3. package/dist/animation/animate-layout-mixin.js.map +1 -1
  4. package/dist/components/accordion/accordion.d.ts +3 -3
  5. package/dist/components/accordion/accordion.js +0 -2
  6. package/dist/components/accordion/accordion.js.map +1 -1
  7. package/dist/components/accordion/demos/card.demo.d.ts +6 -0
  8. package/dist/components/accordion/demos/card.demo.js +58 -0
  9. package/dist/components/accordion/demos/card.demo.js.map +1 -0
  10. package/dist/components/accordion/demos/multiple.demo.d.ts +6 -0
  11. package/dist/components/accordion/demos/multiple.demo.js +19 -0
  12. package/dist/components/accordion/demos/multiple.demo.js.map +1 -0
  13. package/dist/components/accordion/demos/overview.demo.d.ts +6 -0
  14. package/dist/components/accordion/demos/overview.demo.js +19 -0
  15. package/dist/components/accordion/demos/overview.demo.js.map +1 -0
  16. package/dist/components/breadcrumbs/breadcrumbs.js +0 -2
  17. package/dist/components/breadcrumbs/breadcrumbs.js.map +1 -1
  18. package/dist/components/breadcrumbs/demos/basic.demo.d.ts +5 -0
  19. package/dist/components/breadcrumbs/demos/basic.demo.js +14 -0
  20. package/dist/components/breadcrumbs/demos/basic.demo.js.map +1 -0
  21. package/dist/components/breadcrumbs/demos/separator.demo.d.ts +5 -0
  22. package/dist/components/breadcrumbs/demos/separator.demo.js +14 -0
  23. package/dist/components/breadcrumbs/demos/separator.demo.js.map +1 -0
  24. package/dist/components/button/button.d.ts +82 -0
  25. package/dist/components/button/button.js +60 -2
  26. package/dist/components/button/button.js.map +1 -1
  27. package/dist/components/button/demos/aliases.demo.d.ts +6 -0
  28. package/dist/components/button/demos/aliases.demo.js +18 -0
  29. package/dist/components/button/demos/aliases.demo.js.map +1 -0
  30. package/dist/components/button/demos/basic.demo.d.ts +6 -0
  31. package/dist/components/button/demos/basic.demo.js +19 -0
  32. package/dist/components/button/demos/basic.demo.js.map +1 -0
  33. package/dist/components/button/demos/states.demo.d.ts +6 -0
  34. package/dist/components/button/demos/states.demo.js +29 -0
  35. package/dist/components/button/demos/states.demo.js.map +1 -0
  36. package/dist/components/combobox/combobox.d.ts +3 -3
  37. package/dist/components/combobox/combobox.js +0 -2
  38. package/dist/components/combobox/combobox.js.map +1 -1
  39. package/dist/components/combobox/demos/overview.demo.d.ts +6 -0
  40. package/dist/components/combobox/demos/overview.demo.js +153 -0
  41. package/dist/components/combobox/demos/overview.demo.js.map +1 -0
  42. package/dist/components/listbox/demos/overview.demo.d.ts +6 -0
  43. package/dist/components/listbox/demos/overview.demo.js +64 -0
  44. package/dist/components/listbox/demos/overview.demo.js.map +1 -0
  45. package/dist/components/listbox/listbox.d.ts +1 -6
  46. package/dist/components/listbox/listbox.js +21 -33
  47. package/dist/components/listbox/listbox.js.map +1 -1
  48. package/dist/components/menu/demos/bubbling.demo.d.ts +5 -0
  49. package/dist/components/menu/demos/bubbling.demo.js +15 -0
  50. package/dist/components/menu/demos/bubbling.demo.js.map +1 -0
  51. package/dist/components/menu/demos/overview.demo.d.ts +6 -0
  52. package/dist/components/menu/demos/overview.demo.js +32 -0
  53. package/dist/components/menu/demos/overview.demo.js.map +1 -0
  54. package/dist/components/menu/menu.d.ts +5 -14
  55. package/dist/components/menu/menu.js +23 -38
  56. package/dist/components/menu/menu.js.map +1 -1
  57. package/dist/components/popover/demos/overview.demo.d.ts +6 -0
  58. package/dist/components/popover/demos/overview.demo.js +64 -0
  59. package/dist/components/popover/demos/overview.demo.js.map +1 -0
  60. package/dist/components/select/demos/deconstructed.demo.d.ts +6 -0
  61. package/dist/components/select/demos/deconstructed.demo.js +53 -0
  62. package/dist/components/select/demos/deconstructed.demo.js.map +1 -0
  63. package/dist/components/select/demos/overview.demo.d.ts +5 -0
  64. package/dist/components/select/demos/overview.demo.js +27 -0
  65. package/dist/components/select/demos/overview.demo.js.map +1 -0
  66. package/dist/components/select/select.d.ts +3 -3
  67. package/dist/components/select/select.js +17 -26
  68. package/dist/components/select/select.js.map +1 -1
  69. package/dist/components/tabs/tabs.d.ts +3 -3
  70. package/dist/components/tabs/tabs.js +0 -2
  71. package/dist/components/tabs/tabs.js.map +1 -1
  72. package/dist/index.d.ts +1 -1
  73. package/dist/index.js.map +1 -1
  74. package/dist/runtime/component.d.ts +8 -5
  75. package/dist/runtime/component.js +84 -80
  76. package/dist/runtime/component.js.map +1 -1
  77. package/dist/runtime/core/attributes.d.ts +12 -0
  78. package/dist/runtime/core/attributes.js +85 -0
  79. package/dist/runtime/core/attributes.js.map +1 -0
  80. package/dist/runtime/core/children.d.ts +7 -0
  81. package/dist/runtime/core/children.js +30 -0
  82. package/dist/runtime/core/children.js.map +1 -0
  83. package/dist/runtime/core/props.d.ts +9 -0
  84. package/dist/runtime/core/props.js +169 -0
  85. package/dist/runtime/core/props.js.map +1 -0
  86. package/dist/runtime/core/vnode.d.ts +3 -0
  87. package/dist/runtime/core/vnode.js +39 -0
  88. package/dist/runtime/core/vnode.js.map +1 -0
  89. package/dist/runtime/create-element.js +2 -1
  90. package/dist/runtime/create-element.js.map +1 -1
  91. package/dist/runtime/diff-dom.js +47 -14
  92. package/dist/runtime/diff-dom.js.map +1 -1
  93. package/dist/runtime/diff-props.d.ts +1 -2
  94. package/dist/runtime/diff-props.js +2 -181
  95. package/dist/runtime/diff-props.js.map +1 -1
  96. package/dist/runtime/dom.d.ts +4 -0
  97. package/dist/runtime/frame.d.ts +23 -2
  98. package/dist/runtime/frame.js +51 -52
  99. package/dist/runtime/frame.js.map +1 -1
  100. package/dist/runtime/jsx.js +2 -27
  101. package/dist/runtime/jsx.js.map +1 -1
  102. package/dist/runtime/mixins/mixin.js +9 -4
  103. package/dist/runtime/mixins/mixin.js.map +1 -1
  104. package/dist/runtime/mixins/on-mixin.d.ts +15 -4
  105. package/dist/runtime/mixins/on-mixin.js +9 -2
  106. package/dist/runtime/mixins/on-mixin.js.map +1 -1
  107. package/dist/runtime/navigation.d.ts +6 -0
  108. package/dist/runtime/navigation.js +16 -3
  109. package/dist/runtime/navigation.js.map +1 -1
  110. package/dist/runtime/reconcile.js +444 -181
  111. package/dist/runtime/reconcile.js.map +1 -1
  112. package/dist/runtime/run.d.ts +17 -2
  113. package/dist/runtime/run.js.map +1 -1
  114. package/dist/runtime/scheduler.js +10 -0
  115. package/dist/runtime/scheduler.js.map +1 -1
  116. package/dist/runtime/stream-protocol.d.ts +8 -0
  117. package/dist/runtime/stream-protocol.js +20 -0
  118. package/dist/runtime/stream-protocol.js.map +1 -0
  119. package/dist/runtime/to-vnode.js +17 -18
  120. package/dist/runtime/to-vnode.js.map +1 -1
  121. package/dist/runtime/vnode.d.ts +5 -4
  122. package/dist/runtime/vnode.js +2 -3
  123. package/dist/runtime/vnode.js.map +1 -1
  124. package/dist/server/stream.js +80 -106
  125. package/dist/server/stream.js.map +1 -1
  126. package/dist/style/layers.d.ts +2 -0
  127. package/dist/style/layers.js +3 -0
  128. package/dist/style/layers.js.map +1 -0
  129. package/dist/style/stylesheet.d.ts +3 -1
  130. package/dist/style/stylesheet.js +69 -8
  131. package/dist/style/stylesheet.js.map +1 -1
  132. package/dist/theme/glyph-contract.d.ts +1 -1
  133. package/dist/theme/runtime.js +4 -1
  134. package/dist/theme/runtime.js.map +1 -1
  135. package/package.json +6 -7
  136. package/src/animation/README.md +314 -0
  137. package/src/animation/animate-layout-mixin.ts +79 -71
  138. package/src/components/accordion/README.md +166 -0
  139. package/src/components/accordion/accordion.tsx +8 -10
  140. package/src/components/accordion/demos/card.demo.tsx +113 -0
  141. package/src/components/accordion/demos/multiple.demo.tsx +56 -0
  142. package/src/components/accordion/demos/overview.demo.tsx +56 -0
  143. package/src/components/anchor/README.md +153 -0
  144. package/src/components/breadcrumbs/README.md +55 -0
  145. package/src/components/breadcrumbs/breadcrumbs.tsx +0 -2
  146. package/src/components/breadcrumbs/demos/basic.demo.tsx +17 -0
  147. package/src/components/breadcrumbs/demos/separator.demo.tsx +18 -0
  148. package/src/components/button/README.md +4 -4
  149. package/src/components/button/button.tsx +88 -2
  150. package/src/components/button/demos/aliases.demo.tsx +27 -0
  151. package/src/components/button/demos/basic.demo.tsx +30 -0
  152. package/src/components/button/demos/states.demo.tsx +52 -0
  153. package/src/components/combobox/combobox.tsx +8 -10
  154. package/src/components/combobox/demos/overview.demo.tsx +199 -0
  155. package/src/components/glyph/README.md +72 -0
  156. package/src/components/listbox/README.md +115 -0
  157. package/src/components/listbox/demos/overview.demo.tsx +101 -0
  158. package/src/components/listbox/listbox.ts +23 -32
  159. package/src/components/menu/README.md +96 -0
  160. package/src/components/menu/demos/bubbling.demo.tsx +34 -0
  161. package/src/components/menu/demos/overview.demo.tsx +76 -0
  162. package/src/components/menu/menu.tsx +35 -41
  163. package/src/components/popover/README.md +3 -3
  164. package/src/components/popover/demos/overview.demo.tsx +143 -0
  165. package/src/components/select/README.md +107 -0
  166. package/src/components/select/demos/deconstructed.demo.tsx +95 -0
  167. package/src/components/select/demos/overview.demo.tsx +51 -0
  168. package/src/components/select/select.tsx +28 -28
  169. package/src/components/tabs/tabs.tsx +10 -5
  170. package/src/index.ts +1 -1
  171. package/src/runtime/component.ts +94 -82
  172. package/src/runtime/core/attributes.ts +97 -0
  173. package/src/runtime/core/children.ts +42 -0
  174. package/src/runtime/core/props.ts +185 -0
  175. package/src/runtime/core/vnode.ts +48 -0
  176. package/src/runtime/create-element.ts +2 -1
  177. package/src/runtime/diff-dom.ts +59 -12
  178. package/src/runtime/diff-props.ts +2 -187
  179. package/src/runtime/dom.ts +4 -0
  180. package/src/runtime/frame.ts +84 -61
  181. package/src/runtime/jsx.ts +2 -30
  182. package/src/runtime/mixins/mixin.ts +9 -4
  183. package/src/runtime/mixins/on-mixin.ts +20 -12
  184. package/src/runtime/navigation.ts +24 -3
  185. package/src/runtime/reconcile.ts +552 -186
  186. package/src/runtime/run.ts +17 -1
  187. package/src/runtime/scheduler.ts +7 -0
  188. package/src/runtime/stream-protocol.ts +27 -0
  189. package/src/runtime/to-vnode.ts +15 -17
  190. package/src/runtime/vnode.ts +6 -9
  191. package/src/server/README.md +88 -0
  192. package/src/server/stream.ts +105 -117
  193. package/src/style/layers.ts +2 -0
  194. package/src/style/stylesheet.ts +75 -10
  195. package/src/test/README.md +107 -0
  196. package/src/test/utils.ts +3 -1
  197. package/src/theme/README.md +103 -0
  198. package/src/theme/runtime.ts +4 -1
  199. package/src/utils/scroll-lock/README.md +33 -0
  200. package/src/test/setup.ts +0 -7
@@ -598,7 +598,6 @@ class MixinHandleImpl
598
598
  this.#activeScope = scope
599
599
  if (!scope) return
600
600
  if (this.#scopeTargets.has(scope)) return
601
- this.#scopeSignals.set(scope, new AbortController())
602
601
  this.#scopeTargets.set(scope, new TypedEventTarget<MixinHandleEventMap<Element>>())
603
602
  this.#scopePhaseCounts.set(scope, { beforeUpdate: 0, commit: 0 })
604
603
  }
@@ -616,8 +615,11 @@ class MixinHandleImpl
616
615
  this.#decrementGlobalPhaseCount('beforeUpdate', scopePhaseCounts.beforeUpdate)
617
616
  this.#decrementGlobalPhaseCount('commit', scopePhaseCounts.commit)
618
617
  }
619
- this.#scopeSignals.get(scope)?.abort()
620
- this.#scopeSignals.delete(scope)
618
+ let controller = this.#scopeSignals.get(scope)
619
+ if (controller) {
620
+ controller.abort()
621
+ this.#scopeSignals.delete(scope)
622
+ }
621
623
  this.#scopePhaseCounts.delete(scope)
622
624
  this.#scopeTargets.delete(scope)
623
625
  if (this.#activeScope === scope) {
@@ -646,7 +648,10 @@ class MixinHandleImpl
646
648
 
647
649
  #getScopeSignal(scope: symbol) {
648
650
  let controller = this.#scopeSignals.get(scope)
649
- invariant(controller)
651
+ if (!controller) {
652
+ controller = new AbortController()
653
+ this.#scopeSignals.set(scope, controller)
654
+ }
650
655
  return controller.signal
651
656
  }
652
657
 
@@ -1,28 +1,28 @@
1
- import { createMixin } from './mixin.ts'
1
+ import { createMixin, type MixinType } from './mixin.ts'
2
2
  import type { ElementProps } from '../jsx.ts'
3
3
  import type { MixinDescriptor } from './mixin.ts'
4
- import type {
5
- EventType as AddEventType,
6
- ListenerFor as AddEventListenerFor,
7
- } from '../event-listeners.ts'
8
-
9
- export type { Dispatched } from '../event-listeners.ts'
4
+ import type { EnsureEvent, EventMap } from '../event-listeners.ts'
10
5
 
11
6
  type SignaledListener<event extends Event> = (
12
7
  event: event,
13
8
  signal: AbortSignal,
14
9
  ) => void | Promise<void>
15
10
 
16
- type EventType<target extends Element> = Extract<AddEventType<target>, string>
11
+ type EventType<target extends Element> = string & keyof EventMap<target>
12
+
17
13
  type ListenerFor<target extends Element, type extends EventType<target>> = SignaledListener<
18
- Parameters<AddEventListenerFor<target, type>>[0]
14
+ EnsureEvent<EventMap<target>[type], target>
19
15
  >
16
+ export type OnMixinDescriptor = {
17
+ type: typeof onMixinType
18
+ args: [type: string, handler: SignaledListener<Event>, captureBoolean?: boolean]
19
+ }
20
20
 
21
- const onMixin = createMixin<
21
+ const onMixinType: MixinType<
22
22
  Element,
23
23
  [type: string, handler: SignaledListener<Event>, captureBoolean?: boolean],
24
24
  ElementProps
25
- >((handle) => {
25
+ > = (handle) => {
26
26
  let currentHandler: SignaledListener<Event> = () => {}
27
27
  let currentType = ''
28
28
  let currentCapture = false
@@ -61,7 +61,15 @@ const onMixin = createMixin<
61
61
 
62
62
  return handle.element
63
63
  }
64
- })
64
+ }
65
+
66
+ const onMixin = createMixin(onMixinType)
67
+
68
+ export function isOnMixinDescriptor(descriptor: unknown): descriptor is OnMixinDescriptor {
69
+ if (!descriptor || typeof descriptor !== 'object') return false
70
+ let candidate = descriptor as { type?: unknown; args?: unknown }
71
+ return candidate.type === onMixinType && Array.isArray(candidate.args)
72
+ }
65
73
 
66
74
  /**
67
75
  * Attaches a typed DOM event handler through the mixin system.
@@ -42,8 +42,20 @@ export async function navigate(href: string, options?: NavigationOptions) {
42
42
  * Starts listening for Navigation API transitions and routes them through frame reloads.
43
43
  *
44
44
  * @param signal Abort signal used to remove the listener.
45
+ * @returns void
45
46
  */
46
47
  export function startNavigationListener(signal: AbortSignal) {
48
+ return startNavigationListenerImpl(signal, { getTopFrame, getNamedFrame })
49
+ }
50
+
51
+ // Internal version used by unit tests so we can inject stub frames
52
+ export function startNavigationListenerImpl(
53
+ signal: AbortSignal,
54
+ options: {
55
+ getTopFrame: typeof getTopFrame
56
+ getNamedFrame: typeof getNamedFrame
57
+ },
58
+ ) {
47
59
  let navigation = window.navigation
48
60
 
49
61
  navigation.updateCurrentEntry({
@@ -53,13 +65,17 @@ export function startNavigationListener(signal: AbortSignal) {
53
65
  navigation.addEventListener(
54
66
  'navigate',
55
67
  (event) => {
56
- if (!event.canIntercept) return
68
+ // Safari seems to incorrectly set canIntercept to true for sub-domain navigations, so
69
+ // we do a host check ourselves/. The spec is clear that a different host should prevent
70
+ // interception so this is likely a bug in Safari:
71
+ // https://html.spec.whatwg.org/multipage/nav-history-apis.html#can-have-its-url-rewritten
72
+ if (!event.canIntercept || isCrossOriginDestination(event)) return
57
73
 
58
74
  let state = getRuntimeNavigationState(event)
59
75
  if (!state) return
60
76
 
61
- let topFrame = getTopFrame()
62
- let namedFrame = state.target ? getNamedFrame(state.target) : undefined
77
+ let topFrame = options.getTopFrame()
78
+ let namedFrame = state.target ? options.getNamedFrame(state.target) : undefined
63
79
  let frame = namedFrame ?? topFrame
64
80
 
65
81
  event.intercept({
@@ -86,6 +102,11 @@ function isRuntimeNavigation(info: unknown): info is NavigationState {
86
102
  return typeof info === 'object' && info != null && '$rmx' in info
87
103
  }
88
104
 
105
+ function isCrossOriginDestination(event: NavigateEvent): boolean {
106
+ let destination = new URL(event.destination.url)
107
+ return destination.origin !== window.location.origin
108
+ }
109
+
89
110
  function getRuntimeNavigationState(event: NavigateEvent): NavigationState | undefined {
90
111
  if (event.navigationType === 'traverse') {
91
112
  return getTraverseNavigationState(event)