@remix-run/ui 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -7
- package/dist/animation/demos/animation.demo.d.ts +5 -0
- package/dist/animation/demos/animation.demo.js +92 -0
- package/dist/animation/demos/animation.demo.js.map +1 -0
- package/dist/animation/demos/aspect-ratio.d.ts +2 -0
- package/dist/animation/demos/aspect-ratio.js +69 -0
- package/dist/animation/demos/aspect-ratio.js.map +1 -0
- package/dist/animation/demos/bouncy-switch.d.ts +2 -0
- package/dist/animation/demos/bouncy-switch.js +36 -0
- package/dist/animation/demos/bouncy-switch.js.map +1 -0
- package/dist/animation/demos/color-interpolation.d.ts +1 -0
- package/dist/animation/demos/color-interpolation.js +53 -0
- package/dist/animation/demos/color-interpolation.js.map +1 -0
- package/dist/animation/demos/cube.d.ts +2 -0
- package/dist/animation/demos/cube.js +86 -0
- package/dist/animation/demos/cube.js.map +1 -0
- package/dist/animation/demos/default-animate.d.ts +2 -0
- package/dist/animation/demos/default-animate.js +89 -0
- package/dist/animation/demos/default-animate.js.map +1 -0
- package/dist/animation/demos/drag-release.d.ts +24 -0
- package/dist/animation/demos/drag-release.js +96 -0
- package/dist/animation/demos/drag-release.js.map +1 -0
- package/dist/animation/demos/enter.d.ts +1 -0
- package/dist/animation/demos/enter.js +19 -0
- package/dist/animation/demos/enter.js.map +1 -0
- package/dist/animation/demos/exit.d.ts +2 -0
- package/dist/animation/demos/exit.js +58 -0
- package/dist/animation/demos/exit.js.map +1 -0
- package/dist/animation/demos/flip-toggle.d.ts +2 -0
- package/dist/animation/demos/flip-toggle.js +37 -0
- package/dist/animation/demos/flip-toggle.js.map +1 -0
- package/dist/animation/demos/hold-to-confirm.d.ts +13 -0
- package/dist/animation/demos/hold-to-confirm.js +211 -0
- package/dist/animation/demos/hold-to-confirm.js.map +1 -0
- package/dist/animation/demos/html-content.d.ts +2 -0
- package/dist/animation/demos/html-content.js +30 -0
- package/dist/animation/demos/html-content.js.map +1 -0
- package/dist/animation/demos/interruptible-keyframes.d.ts +1 -0
- package/dist/animation/demos/interruptible-keyframes.js +48 -0
- package/dist/animation/demos/interruptible-keyframes.js.map +1 -0
- package/dist/animation/demos/keyframes.d.ts +1 -0
- package/dist/animation/demos/keyframes.js +24 -0
- package/dist/animation/demos/keyframes.js.map +1 -0
- package/dist/animation/demos/material-ripple.d.ts +2 -0
- package/dist/animation/demos/material-ripple.js +127 -0
- package/dist/animation/demos/material-ripple.js.map +1 -0
- package/dist/animation/demos/mixin-presence-list.d.ts +2 -0
- package/dist/animation/demos/mixin-presence-list.js +88 -0
- package/dist/animation/demos/mixin-presence-list.js.map +1 -0
- package/dist/animation/demos/mixin-reclaim.d.ts +2 -0
- package/dist/animation/demos/mixin-reclaim.js +90 -0
- package/dist/animation/demos/mixin-reclaim.js.map +1 -0
- package/dist/animation/demos/multi-state-badge.d.ts +2 -0
- package/dist/animation/demos/multi-state-badge.js +231 -0
- package/dist/animation/demos/multi-state-badge.js.map +1 -0
- package/dist/animation/demos/press.d.ts +2 -0
- package/dist/animation/demos/press.js +63 -0
- package/dist/animation/demos/press.js.map +1 -0
- package/dist/animation/demos/reordering.d.ts +2 -0
- package/dist/animation/demos/reordering.js +50 -0
- package/dist/animation/demos/reordering.js.map +1 -0
- package/dist/animation/demos/rolling-square.d.ts +2 -0
- package/dist/animation/demos/rolling-square.js +42 -0
- package/dist/animation/demos/rolling-square.js.map +1 -0
- package/dist/animation/demos/rotate.d.ts +1 -0
- package/dist/animation/demos/rotate.js +18 -0
- package/dist/animation/demos/rotate.js.map +1 -0
- package/dist/animation/demos/shared-layout.d.ts +2 -0
- package/dist/animation/demos/shared-layout.js +114 -0
- package/dist/animation/demos/shared-layout.js.map +1 -0
- package/dist/animation/demos/spring.demo.d.ts +6 -0
- package/dist/animation/demos/spring.demo.js +304 -0
- package/dist/animation/demos/spring.demo.js.map +1 -0
- package/dist/animation/demos/transition-options.d.ts +1 -0
- package/dist/animation/demos/transition-options.js +21 -0
- package/dist/animation/demos/transition-options.js.map +1 -0
- package/dist/animation/spring.d.ts +24 -31
- package/dist/animation/spring.js +31 -8
- package/dist/animation/spring.js.map +1 -1
- package/dist/components/accordion/accordion.d.ts +6 -6
- package/dist/components/accordion/accordion.js.map +1 -1
- package/dist/components/accordion/demos/card.demo.d.ts +1 -0
- package/dist/components/accordion/demos/card.demo.js +1 -0
- package/dist/components/accordion/demos/card.demo.js.map +1 -1
- package/dist/components/accordion/demos/multiple.demo.d.ts +1 -0
- package/dist/components/accordion/demos/multiple.demo.js +1 -0
- package/dist/components/accordion/demos/multiple.demo.js.map +1 -1
- package/dist/components/accordion/demos/overview.demo.d.ts +1 -0
- package/dist/components/accordion/demos/overview.demo.js +1 -0
- package/dist/components/accordion/demos/overview.demo.js.map +1 -1
- package/dist/components/anchor/anchor.d.ts +8 -1
- package/dist/components/anchor/anchor.js +30 -11
- package/dist/components/anchor/anchor.js.map +1 -1
- package/dist/components/breadcrumbs/{demos/basic.demo.d.ts → basic.demo.d.ts} +1 -0
- package/dist/components/breadcrumbs/{demos/basic.demo.js → basic.demo.js} +1 -0
- package/dist/components/breadcrumbs/basic.demo.js.map +1 -0
- package/dist/components/breadcrumbs/breadcrumbs.d.ts +1 -1
- package/dist/components/breadcrumbs/{demos/separator.demo.d.ts → separator.demo.d.ts} +1 -0
- package/dist/components/breadcrumbs/{demos/separator.demo.js → separator.demo.js} +1 -0
- package/dist/components/breadcrumbs/separator.demo.js.map +1 -0
- package/dist/components/button/button.d.ts +4 -4
- package/dist/components/button/button.js +3 -1
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/button/demos/aliases.demo.d.ts +1 -0
- package/dist/components/button/demos/aliases.demo.js +1 -0
- package/dist/components/button/demos/aliases.demo.js.map +1 -1
- package/dist/components/button/demos/basic.demo.d.ts +1 -0
- package/dist/components/button/demos/basic.demo.js +1 -0
- package/dist/components/button/demos/basic.demo.js.map +1 -1
- package/dist/components/button/demos/states.demo.d.ts +1 -0
- package/dist/components/button/demos/states.demo.js +1 -0
- package/dist/components/button/demos/states.demo.js.map +1 -1
- package/dist/components/combobox/combobox.d.ts +10 -10
- package/dist/components/combobox/combobox.js.map +1 -1
- package/dist/components/combobox/{demos/overview.demo.d.ts → overview.demo.d.ts} +1 -0
- package/dist/components/combobox/{demos/overview.demo.js → overview.demo.js} +1 -0
- package/dist/components/combobox/overview.demo.js.map +1 -0
- package/dist/components/listbox/listbox.d.ts +3 -3
- package/dist/components/listbox/listbox.js.map +1 -1
- package/dist/components/listbox/{demos/overview.demo.d.ts → overview.demo.d.ts} +1 -0
- package/dist/components/listbox/{demos/overview.demo.js → overview.demo.js} +1 -0
- package/dist/components/listbox/overview.demo.js.map +1 -0
- package/dist/components/menu/demos/bubbling.demo.d.ts +1 -0
- package/dist/components/menu/demos/bubbling.demo.js +1 -0
- package/dist/components/menu/demos/bubbling.demo.js.map +1 -1
- package/dist/components/menu/demos/context-trigger.demo.d.ts +7 -0
- package/dist/components/menu/demos/context-trigger.demo.js +87 -0
- package/dist/components/menu/demos/context-trigger.demo.js.map +1 -0
- package/dist/components/menu/demos/overview.demo.d.ts +1 -0
- package/dist/components/menu/demos/overview.demo.js +1 -0
- package/dist/components/menu/demos/overview.demo.js.map +1 -1
- package/dist/components/menu/menu.d.ts +15 -12
- package/dist/components/menu/menu.js +55 -0
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/popover/{demos/overview.demo.d.ts → overview.demo.d.ts} +1 -0
- package/dist/components/popover/{demos/overview.demo.js → overview.demo.js} +1 -0
- package/dist/components/popover/overview.demo.js.map +1 -0
- package/dist/components/popover/popover.d.ts +7 -7
- package/dist/components/popover/popover.js +11 -4
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/select/{demos/deconstructed.demo.d.ts → deconstructed.demo.d.ts} +1 -0
- package/dist/components/select/{demos/deconstructed.demo.js → deconstructed.demo.js} +1 -0
- package/dist/components/select/deconstructed.demo.js.map +1 -0
- package/dist/components/select/{demos/overview.demo.d.ts → overview.demo.d.ts} +1 -0
- package/dist/components/select/{demos/overview.demo.js → overview.demo.js} +1 -0
- package/dist/components/select/overview.demo.js.map +1 -0
- package/dist/components/select/select.d.ts +10 -10
- package/dist/components/select/select.js +1 -1
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/tabs/tabs.d.ts +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interactions/keydown/keydown.d.ts +1 -1
- package/dist/interactions/outside-click/outside-click-mixin.d.ts +2 -1
- package/dist/interactions/typeahead/typeahead-mixin.d.ts +3 -1
- package/dist/runtime/client-entries.d.ts +1 -2
- package/dist/runtime/client-entries.js.map +1 -1
- package/dist/runtime/component.d.ts +20 -17
- package/dist/runtime/component.js +15 -6
- package/dist/runtime/component.js.map +1 -1
- package/dist/runtime/core/attributes.d.ts +3 -1
- package/dist/runtime/core/attributes.js +19 -1
- package/dist/runtime/core/attributes.js.map +1 -1
- package/dist/runtime/core/props.js +6 -5
- package/dist/runtime/core/props.js.map +1 -1
- package/dist/runtime/demos/basic.demo.d.ts +6 -0
- package/dist/runtime/demos/basic.demo.js +16 -0
- package/dist/runtime/demos/basic.demo.js.map +1 -0
- package/dist/runtime/demos/controlled-uncontrolled-values.demo.d.ts +6 -0
- package/dist/runtime/demos/controlled-uncontrolled-values.demo.js +77 -0
- package/dist/runtime/demos/controlled-uncontrolled-values.demo.js.map +1 -0
- package/dist/runtime/demos/keyed-list.demo.d.ts +6 -0
- package/dist/runtime/demos/keyed-list.demo.js +62 -0
- package/dist/runtime/demos/keyed-list.demo.js.map +1 -0
- package/dist/runtime/demos/readme.demo.d.ts +5 -0
- package/dist/runtime/demos/readme.demo.js +396 -0
- package/dist/runtime/demos/readme.demo.js.map +1 -0
- package/dist/runtime/diff-dom.js +194 -21
- package/dist/runtime/diff-dom.js.map +1 -1
- package/dist/runtime/dom.d.ts +16 -9
- package/dist/runtime/frame.d.ts +7 -0
- package/dist/runtime/frame.js +176 -41
- package/dist/runtime/frame.js.map +1 -1
- package/dist/runtime/jsx.d.ts +3 -4
- package/dist/runtime/jsx.js.map +1 -1
- package/dist/runtime/mixins/link-mixin.d.ts +5 -1
- package/dist/runtime/mixins/link-mixin.js.map +1 -1
- package/dist/runtime/mixins/mixin.d.ts +2 -1
- package/dist/runtime/mixins/mixin.js.map +1 -1
- package/dist/runtime/mixins/ref-mixin.d.ts +2 -1
- package/dist/runtime/mixins/ref-mixin.js.map +1 -1
- package/dist/runtime/reconcile.d.ts +1 -1
- package/dist/runtime/reconcile.js +19 -5
- package/dist/runtime/reconcile.js.map +1 -1
- package/dist/runtime/scheduler.d.ts +10 -10
- package/dist/runtime/scheduler.js +1 -1
- package/dist/runtime/scheduler.js.map +1 -1
- package/dist/runtime/svg-attributes.js +1 -0
- package/dist/runtime/svg-attributes.js.map +1 -1
- package/dist/runtime/to-vnode.js +2 -2
- package/dist/runtime/to-vnode.js.map +1 -1
- package/dist/runtime/vnode.d.ts +6 -1
- package/dist/runtime/vnode.js +4 -0
- package/dist/runtime/vnode.js.map +1 -1
- package/dist/server/stream.d.ts +2 -0
- package/dist/server/stream.js +82 -11
- package/dist/server/stream.js.map +1 -1
- package/dist/style/css-mixin.d.ts +2 -1
- package/dist/style/css-mixin.js.map +1 -1
- package/dist/style/index.d.ts +1 -1
- package/dist/style/style.js +27 -10
- package/dist/style/style.js.map +1 -1
- package/dist/style/stylesheet.d.ts +13 -13
- package/dist/style/stylesheet.js.map +1 -1
- package/dist/theme/contract.d.ts +24 -222
- package/dist/theme/contract.js +2 -2
- package/dist/theme/contract.js.map +1 -1
- package/dist/theme/glyph-contract.d.ts +1 -3
- package/dist/theme/glyph-contract.js.map +1 -1
- package/dist/theme/presets/rmx-01/index.d.ts +4 -2
- package/dist/theme/presets/rmx-01/index.js.map +1 -1
- package/dist/utils/scroll-lock.d.ts +3 -3
- package/dist/utils/scroll-lock.js.map +1 -1
- package/package.json +4 -4
- package/src/animation/README.md +7 -5
- package/src/animation/demos/animation.demo.tsx +194 -0
- package/src/animation/demos/aspect-ratio.tsx +120 -0
- package/src/animation/demos/bouncy-switch.tsx +47 -0
- package/src/animation/demos/color-interpolation.tsx +73 -0
- package/src/animation/demos/cube.tsx +116 -0
- package/src/animation/demos/default-animate.tsx +129 -0
- package/src/animation/demos/drag-release.ts +118 -0
- package/src/animation/demos/enter.tsx +22 -0
- package/src/animation/demos/exit.tsx +79 -0
- package/src/animation/demos/flip-toggle.tsx +46 -0
- package/src/animation/demos/hold-to-confirm.tsx +317 -0
- package/src/animation/demos/html-content.tsx +41 -0
- package/src/animation/demos/interruptible-keyframes.tsx +62 -0
- package/src/animation/demos/keyframes.tsx +29 -0
- package/src/animation/demos/material-ripple.tsx +158 -0
- package/src/animation/demos/mixin-presence-list.tsx +121 -0
- package/src/animation/demos/mixin-reclaim.tsx +125 -0
- package/src/animation/demos/multi-state-badge.tsx +426 -0
- package/src/animation/demos/press.tsx +67 -0
- package/src/animation/demos/reordering.tsx +65 -0
- package/src/animation/demos/rolling-square.tsx +57 -0
- package/src/animation/demos/rotate.tsx +21 -0
- package/src/animation/demos/shared-layout.tsx +211 -0
- package/src/animation/demos/spring.demo.tsx +385 -0
- package/src/animation/demos/transition-options.tsx +24 -0
- package/src/animation/spring.ts +43 -9
- package/src/components/accordion/accordion.tsx +7 -5
- package/src/components/accordion/demos/card.demo.tsx +1 -0
- package/src/components/accordion/demos/multiple.demo.tsx +1 -0
- package/src/components/accordion/demos/overview.demo.tsx +1 -0
- package/src/components/anchor/README.md +11 -3
- package/src/components/anchor/anchor.ts +54 -13
- package/src/components/breadcrumbs/{demos/basic.demo.tsx → basic.demo.tsx} +1 -0
- package/src/components/breadcrumbs/breadcrumbs.tsx +1 -1
- package/src/components/breadcrumbs/{demos/separator.demo.tsx → separator.demo.tsx} +1 -0
- package/src/components/button/button.tsx +30 -18
- package/src/components/button/demos/aliases.demo.tsx +1 -0
- package/src/components/button/demos/basic.demo.tsx +1 -0
- package/src/components/button/demos/states.demo.tsx +1 -0
- package/src/components/combobox/README.md +1 -1
- package/src/components/combobox/combobox.tsx +30 -12
- package/src/components/combobox/{demos/overview.demo.tsx → overview.demo.tsx} +1 -0
- package/src/components/glyph/glyph.tsx +2 -2
- package/src/components/listbox/listbox.ts +88 -83
- package/src/components/listbox/{demos/overview.demo.tsx → overview.demo.tsx} +1 -0
- package/src/components/menu/README.md +26 -2
- package/src/components/menu/demos/bubbling.demo.tsx +1 -0
- package/src/components/menu/demos/context-trigger.demo.tsx +133 -0
- package/src/components/menu/demos/overview.demo.tsx +1 -0
- package/src/components/menu/menu.tsx +100 -16
- package/src/components/popover/{demos/overview.demo.tsx → overview.demo.tsx} +1 -0
- package/src/components/popover/popover.ts +101 -81
- package/src/components/select/{demos/deconstructed.demo.tsx → deconstructed.demo.tsx} +1 -0
- package/src/components/select/{demos/overview.demo.tsx → overview.demo.tsx} +1 -0
- package/src/components/select/select.tsx +27 -10
- package/src/index.ts +1 -0
- package/src/runtime/client-entries.ts +1 -5
- package/src/runtime/component.ts +37 -15
- package/src/runtime/core/attributes.ts +21 -0
- package/src/runtime/core/props.ts +6 -4
- package/src/runtime/demos/basic.demo.tsx +21 -0
- package/src/runtime/demos/controlled-uncontrolled-values.demo.tsx +177 -0
- package/src/runtime/demos/keyed-list.demo.tsx +94 -0
- package/src/runtime/demos/readme.demo.tsx +702 -0
- package/src/runtime/diff-dom.ts +270 -20
- package/src/runtime/dom.ts +16 -9
- package/src/runtime/frame.ts +218 -41
- package/src/runtime/jsx.ts +7 -11
- package/src/runtime/mixins/link-mixin.ts +88 -86
- package/src/runtime/mixins/mixin.ts +9 -1
- package/src/runtime/mixins/ref-mixin.ts +4 -5
- package/src/runtime/reconcile.ts +23 -14
- package/src/runtime/scheduler.ts +20 -20
- package/src/runtime/svg-attributes.ts +1 -0
- package/src/runtime/to-vnode.ts +2 -2
- package/src/runtime/vnode.ts +10 -0
- package/src/server/README.md +4 -2
- package/src/server/stream.ts +84 -10
- package/src/style/css-mixin.ts +6 -1
- package/src/style/index.ts +1 -2
- package/src/style/style.ts +29 -10
- package/src/style/stylesheet.ts +14 -2
- package/src/theme/contract.ts +37 -5
- package/src/theme/glyph-contract.ts +3 -1
- package/src/theme/presets/rmx-01/index.ts +4 -2
- package/src/utils/scroll-lock.ts +7 -3
- package/dist/components/breadcrumbs/demos/basic.demo.js.map +0 -1
- package/dist/components/breadcrumbs/demos/separator.demo.js.map +0 -1
- package/dist/components/combobox/demos/overview.demo.js.map +0 -1
- package/dist/components/listbox/demos/overview.demo.js.map +0 -1
- package/dist/components/popover/demos/overview.demo.js.map +0 -1
- package/dist/components/select/demos/deconstructed.demo.js.map +0 -1
- package/dist/components/select/demos/overview.demo.js.map +0 -1
|
@@ -230,7 +230,7 @@ function isMultipleProps(props: AccordionProps | null): props is AccordionMultip
|
|
|
230
230
|
return props?.type === 'multiple'
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
function AccordionImpl(handle: Handle<AccordionProps, AccordionContext>) {
|
|
233
|
+
function AccordionImpl(handle: Handle<AccordionProps, AccordionContext>): () => RemixNode {
|
|
234
234
|
let rootNode: HTMLElement | null = null
|
|
235
235
|
let registeredItems: RegisteredItem[] = []
|
|
236
236
|
let uncontrolledSingleValue: string | null = null
|
|
@@ -418,13 +418,15 @@ function AccordionImpl(handle: Handle<AccordionProps, AccordionContext>) {
|
|
|
418
418
|
export function onAccordionChange<target extends HTMLElement>(
|
|
419
419
|
handler: AccordionChangeHandler<target>,
|
|
420
420
|
captureBoolean?: boolean,
|
|
421
|
-
) {
|
|
421
|
+
): ReturnType<typeof on<target, typeof ACCORDION_CHANGE_EVENT>> {
|
|
422
422
|
return on(ACCORDION_CHANGE_EVENT, handler, captureBoolean)
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
export const Accordion = AccordionImpl
|
|
426
426
|
|
|
427
|
-
export function AccordionItem(
|
|
427
|
+
export function AccordionItem(
|
|
428
|
+
handle: Handle<AccordionItemProps, AccordionItemContext>,
|
|
429
|
+
): () => RemixNode {
|
|
428
430
|
let triggerNode: HTMLButtonElement | null = null
|
|
429
431
|
let triggerId = `${handle.id}-trigger`
|
|
430
432
|
let panelId = `${handle.id}-panel`
|
|
@@ -468,7 +470,7 @@ export function AccordionItem(handle: Handle<AccordionItemProps, AccordionItemCo
|
|
|
468
470
|
}
|
|
469
471
|
}
|
|
470
472
|
|
|
471
|
-
export function AccordionTrigger(handle: Handle<AccordionTriggerProps>) {
|
|
473
|
+
export function AccordionTrigger(handle: Handle<AccordionTriggerProps>): () => RemixNode {
|
|
472
474
|
return () => {
|
|
473
475
|
let accordion = handle.context.get(Accordion)
|
|
474
476
|
let item = handle.context.get(AccordionItem)
|
|
@@ -539,7 +541,7 @@ export function AccordionTrigger(handle: Handle<AccordionTriggerProps>) {
|
|
|
539
541
|
}
|
|
540
542
|
}
|
|
541
543
|
|
|
542
|
-
export function AccordionContent(handle: Handle<AccordionContentProps>) {
|
|
544
|
+
export function AccordionContent(handle: Handle<AccordionContentProps>): () => RemixNode {
|
|
543
545
|
return () => {
|
|
544
546
|
let item = handle.context.get(AccordionItem)
|
|
545
547
|
let { children, mix, ...panelProps } = handle.props
|
|
@@ -10,6 +10,7 @@ import { theme } from '@remix-run/ui/theme'
|
|
|
10
10
|
/**
|
|
11
11
|
* @name Accordion in a Card
|
|
12
12
|
* @description The Accordion can sit inside a card when the surrounding surface needs stronger grouping.
|
|
13
|
+
* @layout center
|
|
13
14
|
* @order 3
|
|
14
15
|
*/
|
|
15
16
|
export default function Example() {
|
|
@@ -11,6 +11,7 @@ import { theme } from '@remix-run/ui/theme'
|
|
|
11
11
|
* @order 2
|
|
12
12
|
* @name Accordion Multiple Open
|
|
13
13
|
* @description Multiple mode allows several sections to stay open simultaneously, useful for operational checklists and dashboards.
|
|
14
|
+
* @layout center
|
|
14
15
|
*/
|
|
15
16
|
export default function Example() {
|
|
16
17
|
return () => (
|
|
@@ -10,6 +10,7 @@ import { theme } from '@remix-run/ui/theme'
|
|
|
10
10
|
/**
|
|
11
11
|
* @name Accordion Overview
|
|
12
12
|
* @description A single-open disclosure list that keeps settings, billing, or notification rules in one calm section.
|
|
13
|
+
* @layout center
|
|
13
14
|
* @order 1
|
|
14
15
|
*/
|
|
15
16
|
export default function Example() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# anchor
|
|
2
2
|
|
|
3
|
-
`anchor` positions a floating element against an anchor element and keeps it constrained to the viewport. Use it for custom floating surfaces that need placement, flipping, offsets, and optional relative alignment.
|
|
3
|
+
`anchor` positions a floating element against an anchor element or viewport coordinates and keeps it constrained to the viewport. Use it for custom floating surfaces that need placement, flipping, offsets, and optional relative alignment.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
@@ -49,11 +49,19 @@ popover.addEventListener('beforetoggle', (event) => {
|
|
|
49
49
|
})
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
Anchor to coordinates when the surface should open at a pointer location.
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
let cleanup = anchor(popover, { x: event.clientX, y: event.clientY }, { placement: 'bottom-start' })
|
|
56
|
+
```
|
|
57
|
+
|
|
52
58
|
## `anchor.*`
|
|
53
59
|
|
|
54
|
-
- `anchor(floatingElement,
|
|
60
|
+
- `anchor(floatingElement, anchorTarget, options)`: positions `floatingElement` against an element or coordinate target, starts animation-frame polling for geometry changes, and returns a cleanup function.
|
|
55
61
|
- `AnchorOptions`: placement, inset, relative alignment, and offset options.
|
|
62
|
+
- `AnchorPoint`: viewport coordinate target with `x`, `y`, and optional `width`/`height`.
|
|
56
63
|
- `AnchorPlacement`: exported placement names for the main sides and top/bottom start/end alignment.
|
|
64
|
+
- `AnchorTarget`: an `HTMLElement` or `AnchorPoint`.
|
|
57
65
|
|
|
58
66
|
## Placements
|
|
59
67
|
|
|
@@ -149,5 +157,5 @@ anchor(listbox, trigger, {
|
|
|
149
157
|
- Oversized inset surfaces with `relativeTo` preserve alignment by scrolling the nearest scrollable descendant when possible.
|
|
150
158
|
- `offset`, `offsetX`, and `offsetY` may be numbers or functions that receive the floating element.
|
|
151
159
|
- `relativeTo` lets a surface align to an inner element, which is useful for selected options inside popovers.
|
|
152
|
-
- `anchor` polls on animation frames for anchor or floating geometry changes and repositions when either changes.
|
|
160
|
+
- `anchor` polls on animation frames for anchor target or floating geometry changes and repositions when either changes.
|
|
153
161
|
- The returned cleanup function cancels animation-frame polling.
|
|
@@ -24,6 +24,15 @@ export type AnchorPlacement =
|
|
|
24
24
|
|
|
25
25
|
type AnchorOffsetValue = number | ((floating: HTMLElement) => number)
|
|
26
26
|
|
|
27
|
+
export interface AnchorPoint {
|
|
28
|
+
height?: number
|
|
29
|
+
width?: number
|
|
30
|
+
x: number
|
|
31
|
+
y: number
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type AnchorTarget = HTMLElement | AnchorPoint
|
|
35
|
+
|
|
27
36
|
export type AnchorOptions = {
|
|
28
37
|
placement?: ExtendedAnchorPlacement
|
|
29
38
|
inset?: boolean
|
|
@@ -125,6 +134,39 @@ function resolveOffsetValue(offset: AnchorOffsetValue | undefined, floating: HTM
|
|
|
125
134
|
return offset ?? 0
|
|
126
135
|
}
|
|
127
136
|
|
|
137
|
+
function isAnchorPoint(value: unknown): value is AnchorPoint {
|
|
138
|
+
if (typeof value !== 'object' || value === null) {
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!('x' in value) || !('y' in value)) {
|
|
143
|
+
return false
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
let width = 'width' in value ? value.width : undefined
|
|
147
|
+
let height = 'height' in value ? value.height : undefined
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
typeof value.x === 'number' &&
|
|
151
|
+
typeof value.y === 'number' &&
|
|
152
|
+
(width === undefined || typeof width === 'number') &&
|
|
153
|
+
(height === undefined || typeof height === 'number')
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function readAnchorRect(anchorTarget: AnchorTarget) {
|
|
158
|
+
if (anchorTarget instanceof HTMLElement) {
|
|
159
|
+
return anchorTarget.getBoundingClientRect()
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return new DOMRect(
|
|
163
|
+
anchorTarget.x,
|
|
164
|
+
anchorTarget.y,
|
|
165
|
+
anchorTarget.width ?? 0,
|
|
166
|
+
anchorTarget.height ?? 0,
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
128
170
|
function calculatePosition(
|
|
129
171
|
placement: ExtendedAnchorPlacement,
|
|
130
172
|
anchorRect: DOMRect,
|
|
@@ -468,7 +510,7 @@ function getFlippedPlacement(
|
|
|
468
510
|
placementHeight: number,
|
|
469
511
|
collisionWidth: number,
|
|
470
512
|
collisionHeight: number,
|
|
471
|
-
|
|
513
|
+
anchorIsAbsolutePositioned: boolean,
|
|
472
514
|
inset: boolean,
|
|
473
515
|
offset: number,
|
|
474
516
|
offsetX: number,
|
|
@@ -476,11 +518,9 @@ function getFlippedPlacement(
|
|
|
476
518
|
relativeOffsetX?: number | null,
|
|
477
519
|
relativeOffsetY?: number | null,
|
|
478
520
|
) {
|
|
479
|
-
let computedStyle = getComputedStyle(anchor)
|
|
480
|
-
let isAbsolutePositioned = computedStyle.position !== 'fixed'
|
|
481
521
|
let hasScroll = window.scrollY > 0
|
|
482
522
|
|
|
483
|
-
if (placement.startsWith('top') &&
|
|
523
|
+
if (placement.startsWith('top') && anchorIsAbsolutePositioned && hasScroll) {
|
|
484
524
|
if (anchorRect.top - placementHeight < 0) {
|
|
485
525
|
return placement
|
|
486
526
|
}
|
|
@@ -641,9 +681,9 @@ function solveRelativeAlignmentAxis(options: {
|
|
|
641
681
|
|
|
642
682
|
export function anchor(
|
|
643
683
|
floating: HTMLElement,
|
|
644
|
-
|
|
684
|
+
anchorTarget: AnchorTarget,
|
|
645
685
|
options: AnchorOptions = {},
|
|
646
|
-
) {
|
|
686
|
+
): () => void {
|
|
647
687
|
let lastAnchorRect: DOMRect
|
|
648
688
|
let lastFloatingDimensions: FloatingDimensions
|
|
649
689
|
|
|
@@ -651,8 +691,8 @@ export function anchor(
|
|
|
651
691
|
throw new TypeError('anchor() expected a floating HTMLElement')
|
|
652
692
|
}
|
|
653
693
|
|
|
654
|
-
if (!(
|
|
655
|
-
throw new TypeError('anchor() expected an anchor HTMLElement')
|
|
694
|
+
if (!(anchorTarget instanceof HTMLElement) && !isAnchorPoint(anchorTarget)) {
|
|
695
|
+
throw new TypeError('anchor() expected an anchor HTMLElement or coordinates')
|
|
656
696
|
}
|
|
657
697
|
|
|
658
698
|
let {
|
|
@@ -664,12 +704,13 @@ export function anchor(
|
|
|
664
704
|
offsetY: rawOffsetY = 0,
|
|
665
705
|
} = options
|
|
666
706
|
|
|
667
|
-
let
|
|
668
|
-
|
|
707
|
+
let anchorIsAbsolutePositioned =
|
|
708
|
+
anchorTarget instanceof HTMLElement && getComputedStyle(anchorTarget).position !== 'fixed'
|
|
709
|
+
let isFixed = floating.hasAttribute('popover') || !anchorIsAbsolutePositioned
|
|
669
710
|
let animationFrameId = 0
|
|
670
711
|
|
|
671
712
|
function updatePosition(
|
|
672
|
-
anchorRect =
|
|
713
|
+
anchorRect = readAnchorRect(anchorTarget),
|
|
673
714
|
naturalDimensions = getFloatingDimensions(floating, relativeTo, {
|
|
674
715
|
ignoreInlineMaxSize: true,
|
|
675
716
|
}),
|
|
@@ -695,7 +736,7 @@ export function anchor(
|
|
|
695
736
|
placementHeight,
|
|
696
737
|
naturalDimensions.width,
|
|
697
738
|
naturalDimensions.height,
|
|
698
|
-
|
|
739
|
+
anchorIsAbsolutePositioned,
|
|
699
740
|
inset,
|
|
700
741
|
offset,
|
|
701
742
|
offsetX,
|
|
@@ -872,7 +913,7 @@ export function anchor(
|
|
|
872
913
|
updatePosition()
|
|
873
914
|
|
|
874
915
|
function pollForPositionChanges() {
|
|
875
|
-
let currentRect =
|
|
916
|
+
let currentRect = readAnchorRect(anchorTarget)
|
|
876
917
|
let currentDimensions = getFloatingDimensions(floating, relativeTo)
|
|
877
918
|
if (
|
|
878
919
|
hasRectChanged(currentRect, lastAnchorRect) ||
|
|
@@ -72,7 +72,7 @@ const textCss = css({
|
|
|
72
72
|
whiteSpace: 'nowrap',
|
|
73
73
|
})
|
|
74
74
|
|
|
75
|
-
export function Breadcrumbs(handle: Handle<BreadcrumbsProps>) {
|
|
75
|
+
export function Breadcrumbs(handle: Handle<BreadcrumbsProps>): () => RemixNode {
|
|
76
76
|
return () => {
|
|
77
77
|
let { 'aria-label': ariaLabel, items, separator, mix, ...navProps } = handle.props
|
|
78
78
|
let currentIndex = items.findIndex((item) => item.current)
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { attrs, createElement, createMixin, css } from '@remix-run/ui'
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
CSSMixinDescriptor,
|
|
4
|
+
ElementProps,
|
|
5
|
+
Handle,
|
|
6
|
+
MixinDescriptor,
|
|
7
|
+
MixinFactory,
|
|
8
|
+
Props,
|
|
9
|
+
RemixNode,
|
|
10
|
+
} from '@remix-run/ui'
|
|
3
11
|
|
|
4
12
|
import { theme } from '../../theme/theme.ts'
|
|
5
13
|
|
|
@@ -74,22 +82,26 @@ const buttonIconCss: CSSMixinDescriptor = css({
|
|
|
74
82
|
},
|
|
75
83
|
})
|
|
76
84
|
|
|
77
|
-
const buttonIconAttrsCss = attrs({
|
|
85
|
+
const buttonIconAttrsCss: MixinDescriptor<Element, [Partial<ElementProps>], ElementProps> = attrs({
|
|
86
|
+
'aria-hidden': true,
|
|
87
|
+
})
|
|
78
88
|
|
|
79
|
-
const buttonDefaultsMixin
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
const buttonDefaultsMixin: MixinFactory<Element, [], ElementProps> = createMixin<
|
|
90
|
+
Element,
|
|
91
|
+
[],
|
|
92
|
+
ElementProps
|
|
93
|
+
>((handle, hostType) => (props) => {
|
|
94
|
+
if (hostType !== 'button' || props.type !== undefined) {
|
|
95
|
+
return handle.element
|
|
96
|
+
}
|
|
84
97
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
)
|
|
98
|
+
return createElement(handle.element as unknown as string, {
|
|
99
|
+
...props,
|
|
100
|
+
type: 'button',
|
|
101
|
+
})
|
|
102
|
+
})
|
|
91
103
|
|
|
92
|
-
const buttonDefaultsCss = buttonDefaultsMixin()
|
|
104
|
+
const buttonDefaultsCss: MixinDescriptor<Element, [], ElementProps> = buttonDefaultsMixin()
|
|
93
105
|
|
|
94
106
|
/**
|
|
95
107
|
* Base button styling with the default `type="button"` behavior for `<button>`
|
|
@@ -121,7 +133,7 @@ export const labelStyle = buttonLabelCss
|
|
|
121
133
|
*
|
|
122
134
|
* @category mixin
|
|
123
135
|
*/
|
|
124
|
-
export const primaryStyle = createButtonCss(theme.colors.action.primary)
|
|
136
|
+
export const primaryStyle: CSSMixinDescriptor = createButtonCss(theme.colors.action.primary)
|
|
125
137
|
|
|
126
138
|
/**
|
|
127
139
|
* Secondary visual treatment for buttons. Combine with {@link baseStyle} when
|
|
@@ -129,7 +141,7 @@ export const primaryStyle = createButtonCss(theme.colors.action.primary)
|
|
|
129
141
|
*
|
|
130
142
|
* @category mixin
|
|
131
143
|
*/
|
|
132
|
-
export const secondaryStyle = createButtonCss(theme.colors.action.secondary)
|
|
144
|
+
export const secondaryStyle: CSSMixinDescriptor = createButtonCss(theme.colors.action.secondary)
|
|
133
145
|
|
|
134
146
|
/**
|
|
135
147
|
* Ghost visual treatment for buttons — transparent background with a hover
|
|
@@ -146,7 +158,7 @@ export const ghostStyle = ghostButtonToneCss
|
|
|
146
158
|
*
|
|
147
159
|
* @category mixin
|
|
148
160
|
*/
|
|
149
|
-
export const dangerStyle = createButtonCss(theme.colors.action.danger)
|
|
161
|
+
export const dangerStyle: CSSMixinDescriptor = createButtonCss(theme.colors.action.danger)
|
|
150
162
|
|
|
151
163
|
const toneStyleByTone = {
|
|
152
164
|
primary: primaryStyle,
|
|
@@ -203,7 +215,7 @@ export type ButtonProps = Omit<Props<'button'>, 'children'> & {
|
|
|
203
215
|
* </Button>
|
|
204
216
|
* ```
|
|
205
217
|
*/
|
|
206
|
-
export function Button(handle: Handle<ButtonProps>) {
|
|
218
|
+
export function Button(handle: Handle<ButtonProps>): () => RemixNode {
|
|
207
219
|
return () => {
|
|
208
220
|
let { children, endIcon, mix, startIcon, tone = 'secondary', ...buttonProps } = handle.props
|
|
209
221
|
|
|
@@ -5,6 +5,7 @@ import { theme } from '@remix-run/ui/theme'
|
|
|
5
5
|
/**
|
|
6
6
|
* @name Button Component
|
|
7
7
|
* @description The Button component wraps the low-level style primitives and accepts a tone prop for quick theming.
|
|
8
|
+
* @layout center
|
|
8
9
|
* @order 2
|
|
9
10
|
*/
|
|
10
11
|
export default function Example() {
|
|
@@ -8,7 +8,7 @@ Use it when the user should type draft text, filter a popup list, and still comm
|
|
|
8
8
|
|
|
9
9
|
```tsx
|
|
10
10
|
import { css, type Handle } from 'remix/ui'
|
|
11
|
-
import { Combobox, ComboboxOption, onComboboxChange } from 'remix/ui'
|
|
11
|
+
import { Combobox, ComboboxOption, onComboboxChange } from 'remix/ui/combobox'
|
|
12
12
|
|
|
13
13
|
let airports = [
|
|
14
14
|
{
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type ElementProps,
|
|
11
11
|
type Handle,
|
|
12
12
|
type MixinHandle,
|
|
13
|
+
type MixinFactory,
|
|
13
14
|
type Props,
|
|
14
15
|
type RemixNode,
|
|
15
16
|
} from '@remix-run/ui'
|
|
@@ -213,7 +214,9 @@ function getOptionSearchValue(option: {
|
|
|
213
214
|
return option.searchValue ?? option.textValue ?? option.label
|
|
214
215
|
}
|
|
215
216
|
|
|
216
|
-
function ComboboxProvider(
|
|
217
|
+
function ComboboxProvider(
|
|
218
|
+
handle: Handle<ComboboxContextProps, ComboboxContextValue>,
|
|
219
|
+
): () => RemixNode {
|
|
217
220
|
let inputRef: HTMLInputElement | undefined
|
|
218
221
|
let listboxRef: listbox.ListboxRef | undefined
|
|
219
222
|
let surfaceRef: HTMLElement | undefined
|
|
@@ -807,7 +810,11 @@ function getComboboxContext(handle: Handle | MixinHandle) {
|
|
|
807
810
|
return handle.context.get(ComboboxProvider)
|
|
808
811
|
}
|
|
809
812
|
|
|
810
|
-
const inputMixin
|
|
813
|
+
const inputMixin: MixinFactory<HTMLInputElement, [], ElementProps> = createMixin<
|
|
814
|
+
HTMLInputElement,
|
|
815
|
+
[],
|
|
816
|
+
ElementProps
|
|
817
|
+
>((handle) => {
|
|
811
818
|
let context = getComboboxContext(handle)
|
|
812
819
|
|
|
813
820
|
return (props) => [
|
|
@@ -882,7 +889,11 @@ const inputMixin = createMixin<HTMLInputElement, [], ElementProps>((handle) => {
|
|
|
882
889
|
]
|
|
883
890
|
})
|
|
884
891
|
|
|
885
|
-
const popoverMixin
|
|
892
|
+
const popoverMixin: MixinFactory<HTMLElement, [], ElementProps> = createMixin<
|
|
893
|
+
HTMLElement,
|
|
894
|
+
[],
|
|
895
|
+
ElementProps
|
|
896
|
+
>((handle) => {
|
|
886
897
|
let context = getComboboxContext(handle)
|
|
887
898
|
|
|
888
899
|
return () => [
|
|
@@ -908,12 +919,20 @@ const popoverMixin = createMixin<HTMLElement, [], ElementProps>((handle) => {
|
|
|
908
919
|
]
|
|
909
920
|
})
|
|
910
921
|
|
|
911
|
-
const listMixin
|
|
922
|
+
const listMixin: MixinFactory<HTMLElement, [], ElementProps> = createMixin<
|
|
923
|
+
HTMLElement,
|
|
924
|
+
[],
|
|
925
|
+
ElementProps
|
|
926
|
+
>((handle) => {
|
|
912
927
|
let context = getComboboxContext(handle)
|
|
913
928
|
return () => [attrs({ id: context.listId }), listbox.list()]
|
|
914
929
|
})
|
|
915
930
|
|
|
916
|
-
const hiddenInputMixin
|
|
931
|
+
const hiddenInputMixin: MixinFactory<HTMLInputElement, [], ElementProps> = createMixin<
|
|
932
|
+
HTMLInputElement,
|
|
933
|
+
[],
|
|
934
|
+
ElementProps
|
|
935
|
+
>((handle) => {
|
|
917
936
|
let context = getComboboxContext(handle)
|
|
918
937
|
return () =>
|
|
919
938
|
attrs({
|
|
@@ -924,8 +943,8 @@ const hiddenInputMixin = createMixin<HTMLInputElement, [], ElementProps>((handle
|
|
|
924
943
|
})
|
|
925
944
|
})
|
|
926
945
|
|
|
927
|
-
const optionMixin
|
|
928
|
-
(handle) => {
|
|
946
|
+
const optionMixin: MixinFactory<HTMLElement, [options: ComboboxOptionOptions], ElementProps> =
|
|
947
|
+
createMixin<HTMLElement, [options: ComboboxOptionOptions], ElementProps>((handle) => {
|
|
929
948
|
let context = getComboboxContext(handle)
|
|
930
949
|
|
|
931
950
|
return (options) => {
|
|
@@ -946,8 +965,7 @@ const optionMixin = createMixin<HTMLElement, [options: ComboboxOptionOptions], E
|
|
|
946
965
|
}),
|
|
947
966
|
]
|
|
948
967
|
}
|
|
949
|
-
}
|
|
950
|
-
)
|
|
968
|
+
})
|
|
951
969
|
|
|
952
970
|
export const Context = ComboboxProvider
|
|
953
971
|
export const hiddenInput = hiddenInputMixin
|
|
@@ -968,11 +986,11 @@ const combobox = {
|
|
|
968
986
|
export function onComboboxChange<target extends HTMLElement>(
|
|
969
987
|
handler: ComboboxChangeHandler<target>,
|
|
970
988
|
captureBoolean?: boolean,
|
|
971
|
-
) {
|
|
989
|
+
): ReturnType<typeof on<target, typeof COMBOBOX_CHANGE_EVENT>> {
|
|
972
990
|
return on(COMBOBOX_CHANGE_EVENT, handler, captureBoolean)
|
|
973
991
|
}
|
|
974
992
|
|
|
975
|
-
export function Combobox(handle: Handle<ComboboxProps>) {
|
|
993
|
+
export function Combobox(handle: Handle<ComboboxProps>): () => RemixNode {
|
|
976
994
|
return () => {
|
|
977
995
|
let { children, defaultValue, disabled, inputId, name, placeholder, ...divProps } = handle.props
|
|
978
996
|
|
|
@@ -995,7 +1013,7 @@ export function Combobox(handle: Handle<ComboboxProps>) {
|
|
|
995
1013
|
}
|
|
996
1014
|
}
|
|
997
1015
|
|
|
998
|
-
export function ComboboxOption(handle: Handle<ComboboxOptionProps>) {
|
|
1016
|
+
export function ComboboxOption(handle: Handle<ComboboxOptionProps>): () => RemixNode {
|
|
999
1017
|
return () => {
|
|
1000
1018
|
let { children, disabled, label, mix, searchValue, value, ...divProps } = handle.props
|
|
1001
1019
|
|
|
@@ -5,6 +5,7 @@ import { theme } from '@remix-run/ui/theme'
|
|
|
5
5
|
/**
|
|
6
6
|
* @name Combobox Overview
|
|
7
7
|
* @description A searchable combobox with keyboard navigation. Try typing airport names or codes like ord, lax, or jfk.
|
|
8
|
+
* @layout center
|
|
8
9
|
*/
|
|
9
10
|
export default function Example(handle: Handle) {
|
|
10
11
|
let value: string | null = null
|
|
@@ -31,7 +31,7 @@ export function createGlyphSheet(values: GlyphValues): GlyphSheetComponent {
|
|
|
31
31
|
>,
|
|
32
32
|
)
|
|
33
33
|
|
|
34
|
-
function GlyphSheet(handle: Handle<GlyphSheetProps>) {
|
|
34
|
+
function GlyphSheet(handle: Handle<GlyphSheetProps>): () => RemixElement {
|
|
35
35
|
return () => {
|
|
36
36
|
let { style, ...svgProps } = handle.props
|
|
37
37
|
let hiddenStyle = {
|
|
@@ -70,7 +70,7 @@ export function createGlyphSheet(values: GlyphValues): GlyphSheetComponent {
|
|
|
70
70
|
})
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
export function Glyph(handle: Handle<GlyphProps>) {
|
|
73
|
+
export function Glyph(handle: Handle<GlyphProps>): () => RemixElement {
|
|
74
74
|
return () => {
|
|
75
75
|
let { fill, name, ...svgProps } = handle.props
|
|
76
76
|
let glyphId = glyphContract[name].id
|