@octanejs/aria 0.0.3 → 0.0.5
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/package.json +7 -5
- package/src/autocomplete/useAutocomplete.ts +656 -0
- package/src/collections/BaseCollection.ts +374 -0
- package/src/collections/CollectionBuilder.ts +343 -0
- package/src/collections/Document.ts +451 -0
- package/src/collections/Hidden.ts +84 -0
- package/src/collections/useCachedChildren.ts +103 -0
- package/src/components/Autocomplete.ts +124 -0
- package/src/components/Breadcrumbs.ts +170 -0
- package/src/components/Button.ts +209 -0
- package/src/components/Checkbox.ts +593 -0
- package/src/components/Collection.ts +301 -0
- package/src/components/ComboBox.ts +477 -0
- package/src/components/Dialog.ts +195 -0
- package/src/components/Disclosure.ts +322 -0
- package/src/components/DragAndDrop.ts +177 -0
- package/src/components/FieldError.ts +79 -0
- package/src/components/Form.ts +65 -0
- package/src/components/GridList.ts +1099 -0
- package/src/components/Group.ts +146 -0
- package/src/components/Header.ts +32 -0
- package/src/components/Heading.ts +45 -0
- package/src/components/Input.ts +139 -0
- package/src/components/Keyboard.ts +23 -0
- package/src/components/Label.ts +30 -0
- package/src/components/Link.ts +137 -0
- package/src/components/ListBox.ts +886 -0
- package/src/components/Menu.ts +685 -0
- package/src/components/Meter.ts +100 -0
- package/src/components/Modal.ts +352 -0
- package/src/components/NumberField.ts +221 -0
- package/src/components/OverlayArrow.ts +117 -0
- package/src/components/Popover.ts +385 -0
- package/src/components/ProgressBar.ts +112 -0
- package/src/components/RadioGroup.ts +542 -0
- package/src/components/SearchField.ts +208 -0
- package/src/components/Select.ts +505 -0
- package/src/components/SelectionIndicator.ts +52 -0
- package/src/components/Separator.ts +97 -0
- package/src/components/SharedElementTransition.ts +209 -0
- package/src/components/Slider.ts +472 -0
- package/src/components/Switch.ts +449 -0
- package/src/components/Tabs.ts +675 -0
- package/src/components/TagGroup.ts +443 -0
- package/src/components/Text.ts +27 -0
- package/src/components/TextArea.ts +92 -0
- package/src/components/TextField.ts +200 -0
- package/src/components/ToggleButton.ts +147 -0
- package/src/components/ToggleButtonGroup.ts +106 -0
- package/src/components/Toolbar.ts +74 -0
- package/src/components/Tooltip.ts +249 -0
- package/src/components/index.ts +302 -0
- package/src/components/useDragAndDrop.ts +164 -0
- package/src/components/utils.ts +521 -0
- package/src/intl/autocomplete/ar-AE.json +3 -0
- package/src/intl/autocomplete/bg-BG.json +3 -0
- package/src/intl/autocomplete/cs-CZ.json +3 -0
- package/src/intl/autocomplete/da-DK.json +3 -0
- package/src/intl/autocomplete/de-DE.json +3 -0
- package/src/intl/autocomplete/el-GR.json +3 -0
- package/src/intl/autocomplete/en-US.json +3 -0
- package/src/intl/autocomplete/es-ES.json +3 -0
- package/src/intl/autocomplete/et-EE.json +3 -0
- package/src/intl/autocomplete/fi-FI.json +3 -0
- package/src/intl/autocomplete/fr-FR.json +3 -0
- package/src/intl/autocomplete/he-IL.json +3 -0
- package/src/intl/autocomplete/hr-HR.json +3 -0
- package/src/intl/autocomplete/hu-HU.json +3 -0
- package/src/intl/autocomplete/index.ts +75 -0
- package/src/intl/autocomplete/it-IT.json +3 -0
- package/src/intl/autocomplete/ja-JP.json +3 -0
- package/src/intl/autocomplete/ko-KR.json +3 -0
- package/src/intl/autocomplete/lt-LT.json +3 -0
- package/src/intl/autocomplete/lv-LV.json +3 -0
- package/src/intl/autocomplete/nb-NO.json +3 -0
- package/src/intl/autocomplete/nl-NL.json +3 -0
- package/src/intl/autocomplete/pl-PL.json +3 -0
- package/src/intl/autocomplete/pt-BR.json +3 -0
- package/src/intl/autocomplete/pt-PT.json +3 -0
- package/src/intl/autocomplete/ro-RO.json +3 -0
- package/src/intl/autocomplete/ru-RU.json +3 -0
- package/src/intl/autocomplete/sk-SK.json +3 -0
- package/src/intl/autocomplete/sl-SI.json +3 -0
- package/src/intl/autocomplete/sr-SP.json +3 -0
- package/src/intl/autocomplete/sv-SE.json +3 -0
- package/src/intl/autocomplete/tr-TR.json +3 -0
- package/src/intl/autocomplete/uk-UA.json +3 -0
- package/src/intl/autocomplete/zh-CN.json +3 -0
- package/src/intl/autocomplete/zh-TW.json +3 -0
- package/src/stately/autocomplete/useAutocompleteState.ts +85 -0
- package/src/utils/animation.ts +149 -0
- package/src/utils/useLoadMoreSentinel.ts +78 -0
- package/src/utils/useViewportSize.ts +123 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/Group.tsx).
|
|
2
|
+
// octane adaptations: `.tsx` → `.ts`, JSX → `createElement`; NO forwardRef — the forwarded ref
|
|
3
|
+
// is `props.ref`, passed into `useContextProps` explicitly and re-applied as the merged object
|
|
4
|
+
// ref; the plain-`.ts` component uses the S()/subSlot component-slot convention; React's
|
|
5
|
+
// HTMLAttributes prop bag → a structural record.
|
|
6
|
+
import type { AriaLabelingProps, DOMProps } from '@react-types/shared';
|
|
7
|
+
import { createContext, createElement } from 'octane';
|
|
8
|
+
|
|
9
|
+
import { useFocusRing } from '../focus/useFocusRing';
|
|
10
|
+
import { type HoverProps, useHover } from '../interactions/useHover';
|
|
11
|
+
import { S, subSlot } from '../internal';
|
|
12
|
+
import { mergeProps } from '../utils/mergeProps';
|
|
13
|
+
import {
|
|
14
|
+
type ClassNameOrFunction,
|
|
15
|
+
type ContextValue,
|
|
16
|
+
dom,
|
|
17
|
+
type RenderProps,
|
|
18
|
+
type SlotProps,
|
|
19
|
+
useContextProps,
|
|
20
|
+
useRenderProps,
|
|
21
|
+
} from './utils';
|
|
22
|
+
|
|
23
|
+
// octane adaptation: structural prop bag (upstream extends React's HTMLAttributes).
|
|
24
|
+
type HTMLAttributes = Record<string, any>;
|
|
25
|
+
|
|
26
|
+
export interface GroupRenderProps {
|
|
27
|
+
/**
|
|
28
|
+
* Whether the group is currently hovered with a mouse.
|
|
29
|
+
*
|
|
30
|
+
* @selector [data-hovered]
|
|
31
|
+
*/
|
|
32
|
+
isHovered: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Whether an element within the group is focused, either via a mouse or keyboard.
|
|
35
|
+
*
|
|
36
|
+
* @selector [data-focus-within]
|
|
37
|
+
*/
|
|
38
|
+
isFocusWithin: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Whether an element within the group is keyboard focused.
|
|
41
|
+
*
|
|
42
|
+
* @selector [data-focus-visible]
|
|
43
|
+
*/
|
|
44
|
+
isFocusVisible: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether the group is disabled.
|
|
47
|
+
*
|
|
48
|
+
* @selector [data-disabled]
|
|
49
|
+
*/
|
|
50
|
+
isDisabled: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Whether the group is invalid.
|
|
53
|
+
*
|
|
54
|
+
* @selector [data-invalid]
|
|
55
|
+
*/
|
|
56
|
+
isInvalid: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface GroupProps
|
|
60
|
+
extends
|
|
61
|
+
AriaLabelingProps,
|
|
62
|
+
Omit<HTMLAttributes, 'children' | 'className' | 'style' | 'render' | 'role' | 'slot'>,
|
|
63
|
+
DOMProps,
|
|
64
|
+
HoverProps,
|
|
65
|
+
RenderProps<GroupRenderProps>,
|
|
66
|
+
SlotProps {
|
|
67
|
+
/**
|
|
68
|
+
* The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
|
|
69
|
+
* element. A function may be provided to compute the class based on component state.
|
|
70
|
+
*
|
|
71
|
+
* @default 'react-aria-Group'
|
|
72
|
+
*/
|
|
73
|
+
className?: ClassNameOrFunction<GroupRenderProps>;
|
|
74
|
+
/** Whether the group is disabled. */
|
|
75
|
+
isDisabled?: boolean;
|
|
76
|
+
/** Whether the group is invalid. */
|
|
77
|
+
isInvalid?: boolean;
|
|
78
|
+
/** Whether the group is read only. */
|
|
79
|
+
isReadOnly?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* An accessibility role for the group. By default, this is set to `'group'`.
|
|
82
|
+
* Use `'region'` when the contents of the group is important enough to be
|
|
83
|
+
* included in the page table of contents. Use `'presentation'` if the group
|
|
84
|
+
* is visual only and does not represent a semantic grouping of controls.
|
|
85
|
+
*
|
|
86
|
+
* @default 'group'
|
|
87
|
+
*/
|
|
88
|
+
role?: 'group' | 'region' | 'presentation';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const GroupContext = createContext<ContextValue<GroupProps, HTMLDivElement>>({});
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* A group represents a set of related UI controls, and supports interactive states for styling.
|
|
95
|
+
*/
|
|
96
|
+
export function Group(props: GroupProps): any {
|
|
97
|
+
const slot = S('Group');
|
|
98
|
+
let ref: any;
|
|
99
|
+
[props, ref] = useContextProps(props, props.ref, GroupContext, subSlot(slot, 'ctx'));
|
|
100
|
+
let {
|
|
101
|
+
isDisabled,
|
|
102
|
+
isInvalid,
|
|
103
|
+
isReadOnly,
|
|
104
|
+
onHoverStart,
|
|
105
|
+
onHoverChange,
|
|
106
|
+
onHoverEnd,
|
|
107
|
+
...otherProps
|
|
108
|
+
} = props;
|
|
109
|
+
isDisabled ??= !!props['aria-disabled'] && props['aria-disabled'] !== 'false';
|
|
110
|
+
isInvalid ??= !!props['aria-invalid'] && props['aria-invalid'] !== 'false';
|
|
111
|
+
|
|
112
|
+
let { hoverProps, isHovered } = useHover(
|
|
113
|
+
{ onHoverStart, onHoverChange, onHoverEnd, isDisabled },
|
|
114
|
+
subSlot(slot, 'hover'),
|
|
115
|
+
);
|
|
116
|
+
let { isFocused, isFocusVisible, focusProps } = useFocusRing(
|
|
117
|
+
{
|
|
118
|
+
within: true,
|
|
119
|
+
},
|
|
120
|
+
subSlot(slot, 'focusRing'),
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
let renderProps = useRenderProps(
|
|
124
|
+
{
|
|
125
|
+
...props,
|
|
126
|
+
values: { isHovered, isFocusWithin: isFocused, isFocusVisible, isDisabled, isInvalid },
|
|
127
|
+
defaultClassName: 'react-aria-Group',
|
|
128
|
+
},
|
|
129
|
+
subSlot(slot, 'render'),
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
return createElement(dom.div, {
|
|
133
|
+
...mergeProps(otherProps, focusProps, hoverProps),
|
|
134
|
+
...renderProps,
|
|
135
|
+
ref,
|
|
136
|
+
role: props.role ?? 'group',
|
|
137
|
+
slot: props.slot ?? undefined,
|
|
138
|
+
'data-focus-within': isFocused || undefined,
|
|
139
|
+
'data-hovered': isHovered || undefined,
|
|
140
|
+
'data-focus-visible': isFocusVisible || undefined,
|
|
141
|
+
'data-disabled': isDisabled || undefined,
|
|
142
|
+
'data-invalid': isInvalid || undefined,
|
|
143
|
+
'data-readonly': isReadOnly || undefined,
|
|
144
|
+
children: renderProps.children,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/Header.tsx).
|
|
2
|
+
// octane adaptations: `.tsx` → `.ts`, JSX → `createElement`; NO forwardRef — the forwarded ref
|
|
3
|
+
// arrives positionally from `createLeafComponent` (which forwards `props.ref`); the
|
|
4
|
+
// plain-`.ts` component uses the S()/subSlot component-slot convention; React's
|
|
5
|
+
// HTMLAttributes prop bag → a structural record.
|
|
6
|
+
import { createContext, createElement } from 'octane';
|
|
7
|
+
|
|
8
|
+
import { HeaderNode } from '../collections/BaseCollection';
|
|
9
|
+
import { createLeafComponent } from '../collections/CollectionBuilder';
|
|
10
|
+
import { S, subSlot } from '../internal';
|
|
11
|
+
import { type ContextValue, dom, type DOMRenderProps, useContextProps } from './utils';
|
|
12
|
+
|
|
13
|
+
// octane adaptation: structural prop bag (upstream extends React's HTMLAttributes).
|
|
14
|
+
type HTMLAttributes = Record<string, any>;
|
|
15
|
+
|
|
16
|
+
export interface HeaderProps extends HTMLAttributes, DOMRenderProps<'header', undefined> {}
|
|
17
|
+
|
|
18
|
+
export const HeaderContext = createContext<ContextValue<HeaderProps, HTMLElement>>({});
|
|
19
|
+
|
|
20
|
+
export const Header = /*#__PURE__*/ createLeafComponent(
|
|
21
|
+
HeaderNode,
|
|
22
|
+
function Header(props: HeaderProps, ref: any) {
|
|
23
|
+
const slot = S('Header');
|
|
24
|
+
[props, ref] = useContextProps(props, ref, HeaderContext, subSlot(slot, 'ctx'));
|
|
25
|
+
return createElement(dom.header, {
|
|
26
|
+
className: 'react-aria-Header',
|
|
27
|
+
...props,
|
|
28
|
+
ref,
|
|
29
|
+
children: props.children,
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/Heading.tsx).
|
|
2
|
+
// octane adaptations: `.tsx` → `.ts`, JSX → `createElement`; NO forwardRef — the forwarded ref
|
|
3
|
+
// is `props.ref`, passed into `useContextProps` explicitly and re-applied as the merged object
|
|
4
|
+
// ref; the plain-`.ts` component uses the S()/subSlot component-slot convention; React's
|
|
5
|
+
// HTMLAttributes prop bag → a structural record.
|
|
6
|
+
import { createContext, createElement } from 'octane';
|
|
7
|
+
|
|
8
|
+
import { S, subSlot } from '../internal';
|
|
9
|
+
import { type ContextValue, dom, type DOMRenderProps, useContextProps } from './utils';
|
|
10
|
+
|
|
11
|
+
// octane adaptation: structural prop bag (upstream extends React's HTMLAttributes).
|
|
12
|
+
type HTMLAttributes = Record<string, any>;
|
|
13
|
+
|
|
14
|
+
export interface HeadingProps extends HTMLAttributes, DOMRenderProps<'h1', undefined> {
|
|
15
|
+
/**
|
|
16
|
+
* The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
|
|
17
|
+
* element.
|
|
18
|
+
*
|
|
19
|
+
* @default 'react-aria-Heading'
|
|
20
|
+
*/
|
|
21
|
+
className?: string;
|
|
22
|
+
/**
|
|
23
|
+
* The heading level.
|
|
24
|
+
*
|
|
25
|
+
* @default 3
|
|
26
|
+
*/
|
|
27
|
+
level?: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const HeadingContext = createContext<ContextValue<HeadingProps, HTMLHeadingElement>>({});
|
|
31
|
+
|
|
32
|
+
export function Heading(props: HeadingProps): any {
|
|
33
|
+
const slot = S('Heading');
|
|
34
|
+
let ref: any;
|
|
35
|
+
[props, ref] = useContextProps(props, props.ref, HeadingContext, subSlot(slot, 'ctx'));
|
|
36
|
+
let { children, level = 3, className, ...domProps } = props;
|
|
37
|
+
let Element = dom[`h${level}`];
|
|
38
|
+
|
|
39
|
+
return createElement(Element, {
|
|
40
|
+
...domProps,
|
|
41
|
+
ref,
|
|
42
|
+
className: className ?? 'react-aria-Heading',
|
|
43
|
+
children,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/Input.tsx).
|
|
2
|
+
// octane adaptations: `.tsx` → `.ts`, JSX → `createElement`; NO forwardRef — the forwarded ref
|
|
3
|
+
// arrives positionally from `createHideableComponent` (which forwards `props.ref`); the
|
|
4
|
+
// plain-`.ts` component uses the S()/subSlot component-slot convention; React's
|
|
5
|
+
// InputHTMLAttributes prop bag → a structural record. NATIVE EVENTS: this is a text control —
|
|
6
|
+
// per-keystroke wiring rides octane's native `onInput` (props produced by useTextField et al.
|
|
7
|
+
// pass through unchanged); no synthetic `onChange` is added.
|
|
8
|
+
import type { HoverEvents } from '@react-types/shared';
|
|
9
|
+
import { createContext, createElement } from 'octane';
|
|
10
|
+
|
|
11
|
+
import { createHideableComponent } from '../collections/Hidden';
|
|
12
|
+
import { useFocusRing } from '../focus/useFocusRing';
|
|
13
|
+
import { useHover } from '../interactions/useHover';
|
|
14
|
+
import { S, subSlot } from '../internal';
|
|
15
|
+
import { mergeProps } from '../utils/mergeProps';
|
|
16
|
+
import {
|
|
17
|
+
type ClassNameOrFunction,
|
|
18
|
+
type ContextValue,
|
|
19
|
+
dom,
|
|
20
|
+
type StyleRenderProps,
|
|
21
|
+
useContextProps,
|
|
22
|
+
useRenderProps,
|
|
23
|
+
} from './utils';
|
|
24
|
+
|
|
25
|
+
// octane adaptation: structural prop bag (upstream extends React's InputHTMLAttributes).
|
|
26
|
+
type InputHTMLAttributes = Record<string, any>;
|
|
27
|
+
|
|
28
|
+
export interface InputRenderProps {
|
|
29
|
+
/**
|
|
30
|
+
* Whether the input is currently hovered with a mouse.
|
|
31
|
+
*
|
|
32
|
+
* @selector [data-hovered]
|
|
33
|
+
*/
|
|
34
|
+
isHovered: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Whether the input is focused, either via a mouse or keyboard.
|
|
37
|
+
*
|
|
38
|
+
* @selector [data-focused]
|
|
39
|
+
*/
|
|
40
|
+
isFocused: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Whether the input is keyboard focused.
|
|
43
|
+
*
|
|
44
|
+
* @selector [data-focus-visible]
|
|
45
|
+
*/
|
|
46
|
+
isFocusVisible: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Whether the input is disabled.
|
|
49
|
+
*
|
|
50
|
+
* @selector [data-disabled]
|
|
51
|
+
*/
|
|
52
|
+
isDisabled: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Whether the input is invalid.
|
|
55
|
+
*
|
|
56
|
+
* @selector [data-invalid]
|
|
57
|
+
*/
|
|
58
|
+
isInvalid: boolean;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface InputProps
|
|
62
|
+
extends
|
|
63
|
+
Omit<InputHTMLAttributes, 'className' | 'style'>,
|
|
64
|
+
HoverEvents,
|
|
65
|
+
StyleRenderProps<InputRenderProps, 'input'> {
|
|
66
|
+
/**
|
|
67
|
+
* The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
|
|
68
|
+
* element. A function may be provided to compute the class based on component state.
|
|
69
|
+
*
|
|
70
|
+
* @default 'react-aria-Input'
|
|
71
|
+
*/
|
|
72
|
+
className?: ClassNameOrFunction<InputRenderProps>;
|
|
73
|
+
/**
|
|
74
|
+
* Temporary text that occupies the text input when it is empty.
|
|
75
|
+
* See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/placeholder).
|
|
76
|
+
*/
|
|
77
|
+
placeholder?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const InputContext = createContext<ContextValue<InputProps, HTMLInputElement>>({});
|
|
81
|
+
|
|
82
|
+
let filterHoverProps = (props: InputProps) => {
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
84
|
+
let { onHoverStart, onHoverChange, onHoverEnd, ...otherProps } = props;
|
|
85
|
+
return otherProps;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* An input allows a user to input text.
|
|
90
|
+
*/
|
|
91
|
+
export const Input = /*#__PURE__*/ createHideableComponent(function Input(
|
|
92
|
+
props: InputProps,
|
|
93
|
+
ref: any,
|
|
94
|
+
) {
|
|
95
|
+
const slot = S('Input');
|
|
96
|
+
[props, ref] = useContextProps(props, ref, InputContext, subSlot(slot, 'ctx'));
|
|
97
|
+
|
|
98
|
+
let { hoverProps, isHovered } = useHover(
|
|
99
|
+
{
|
|
100
|
+
...props,
|
|
101
|
+
isDisabled: props.disabled,
|
|
102
|
+
},
|
|
103
|
+
subSlot(slot, 'hover'),
|
|
104
|
+
);
|
|
105
|
+
let { isFocused, isFocusVisible, focusProps } = useFocusRing(
|
|
106
|
+
{
|
|
107
|
+
isTextInput: true,
|
|
108
|
+
autoFocus: props.autoFocus,
|
|
109
|
+
},
|
|
110
|
+
subSlot(slot, 'focusRing'),
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
let isInvalid = !!props['aria-invalid'] && props['aria-invalid'] !== 'false';
|
|
114
|
+
let renderProps = useRenderProps(
|
|
115
|
+
{
|
|
116
|
+
...props,
|
|
117
|
+
values: {
|
|
118
|
+
isHovered,
|
|
119
|
+
isFocused,
|
|
120
|
+
isFocusVisible,
|
|
121
|
+
isDisabled: props.disabled || false,
|
|
122
|
+
isInvalid,
|
|
123
|
+
},
|
|
124
|
+
defaultClassName: 'react-aria-Input',
|
|
125
|
+
},
|
|
126
|
+
subSlot(slot, 'render'),
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
return createElement(dom.input, {
|
|
130
|
+
...mergeProps(filterHoverProps(props), focusProps, hoverProps),
|
|
131
|
+
...renderProps,
|
|
132
|
+
ref,
|
|
133
|
+
'data-focused': isFocused || undefined,
|
|
134
|
+
'data-disabled': props.disabled || undefined,
|
|
135
|
+
'data-hovered': isHovered || undefined,
|
|
136
|
+
'data-focus-visible': isFocusVisible || undefined,
|
|
137
|
+
'data-invalid': isInvalid || undefined,
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/Keyboard.tsx).
|
|
2
|
+
// octane adaptations: `.tsx` → `.ts`, JSX → `createElement`; NO forwardRef — the forwarded ref
|
|
3
|
+
// is `props.ref`, passed into `useContextProps` explicitly and re-applied as the merged object
|
|
4
|
+
// ref; the plain-`.ts` component uses the S()/subSlot component-slot convention; React's
|
|
5
|
+
// HTMLAttributes prop bag → a structural record.
|
|
6
|
+
import { createContext, createElement } from 'octane';
|
|
7
|
+
|
|
8
|
+
import { S, subSlot } from '../internal';
|
|
9
|
+
import { type ContextValue, dom, type DOMRenderProps, useContextProps } from './utils';
|
|
10
|
+
|
|
11
|
+
// octane adaptation: structural prop bag (upstream extends React's HTMLAttributes).
|
|
12
|
+
type HTMLAttributes = Record<string, any>;
|
|
13
|
+
|
|
14
|
+
export interface KeyboardProps extends HTMLAttributes, DOMRenderProps<'kbd', undefined> {}
|
|
15
|
+
|
|
16
|
+
export const KeyboardContext = createContext<ContextValue<KeyboardProps, HTMLElement>>({});
|
|
17
|
+
|
|
18
|
+
export function Keyboard(props: KeyboardProps): any {
|
|
19
|
+
const slot = S('Keyboard');
|
|
20
|
+
let ref: any;
|
|
21
|
+
[props, ref] = useContextProps(props, props.ref, KeyboardContext, subSlot(slot, 'ctx'));
|
|
22
|
+
return createElement(dom.kbd, { dir: 'ltr', ...props, ref });
|
|
23
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/Label.tsx).
|
|
2
|
+
// octane adaptations: `.tsx` → `.ts`, JSX → `createElement`; NO forwardRef — the forwarded ref
|
|
3
|
+
// arrives positionally from `createHideableComponent` (which forwards `props.ref`); the
|
|
4
|
+
// plain-`.ts` component uses the S()/subSlot component-slot convention; React's
|
|
5
|
+
// LabelHTMLAttributes prop bag → a structural record.
|
|
6
|
+
import { createContext, createElement } from 'octane';
|
|
7
|
+
|
|
8
|
+
import { createHideableComponent } from '../collections/Hidden';
|
|
9
|
+
import { S, subSlot } from '../internal';
|
|
10
|
+
import { type ContextValue, dom, type DOMRenderProps, useContextProps } from './utils';
|
|
11
|
+
|
|
12
|
+
// octane adaptation: structural prop bag (upstream extends React's LabelHTMLAttributes).
|
|
13
|
+
type LabelHTMLAttributes = Record<string, any>;
|
|
14
|
+
|
|
15
|
+
export interface LabelProps extends LabelHTMLAttributes, DOMRenderProps<'label', undefined> {
|
|
16
|
+
elementType?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const LabelContext = createContext<ContextValue<LabelProps, HTMLLabelElement>>({});
|
|
20
|
+
|
|
21
|
+
export const Label = /*#__PURE__*/ createHideableComponent(function Label(
|
|
22
|
+
props: LabelProps,
|
|
23
|
+
ref: any,
|
|
24
|
+
) {
|
|
25
|
+
const slot = S('Label');
|
|
26
|
+
[props, ref] = useContextProps(props, ref, LabelContext, subSlot(slot, 'ctx'));
|
|
27
|
+
let { elementType = 'label', ...labelProps } = props;
|
|
28
|
+
let ElementType = dom[elementType];
|
|
29
|
+
return createElement(ElementType, { className: 'react-aria-Label', ...labelProps, ref });
|
|
30
|
+
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/Link.tsx).
|
|
2
|
+
// octane adaptations: `.tsx` → `.ts`, JSX → `createElement`; NO forwardRef — the forwarded ref
|
|
3
|
+
// is `props.ref`, passed into `useContextProps` explicitly and re-applied as the merged object
|
|
4
|
+
// ref; the plain-`.ts` component uses the S()/subSlot component-slot convention.
|
|
5
|
+
import type { DOMProps, HoverEvents } from '@react-types/shared';
|
|
6
|
+
import { createContext, createElement } from 'octane';
|
|
7
|
+
|
|
8
|
+
import { useFocusRing } from '../focus/useFocusRing';
|
|
9
|
+
import { useHover } from '../interactions/useHover';
|
|
10
|
+
import { S, subSlot } from '../internal';
|
|
11
|
+
import { type AriaLinkOptions, useLink } from '../link/useLink';
|
|
12
|
+
import { filterDOMProps } from '../utils/filterDOMProps';
|
|
13
|
+
import { mergeProps } from '../utils/mergeProps';
|
|
14
|
+
import {
|
|
15
|
+
type ClassNameOrFunction,
|
|
16
|
+
type ContextValue,
|
|
17
|
+
dom,
|
|
18
|
+
type PossibleLinkDOMRenderProps,
|
|
19
|
+
type RenderProps,
|
|
20
|
+
type SlotProps,
|
|
21
|
+
useContextProps,
|
|
22
|
+
useRenderProps,
|
|
23
|
+
} from './utils';
|
|
24
|
+
|
|
25
|
+
// octane adaptation: structural bag (upstream's `GlobalDOMAttributes` drags React handler types).
|
|
26
|
+
type GlobalDOMAttributes = Record<string, any>;
|
|
27
|
+
|
|
28
|
+
export interface LinkProps
|
|
29
|
+
extends
|
|
30
|
+
Omit<AriaLinkOptions, 'elementType'>,
|
|
31
|
+
HoverEvents,
|
|
32
|
+
Omit<RenderProps<LinkRenderProps>, 'render'>,
|
|
33
|
+
PossibleLinkDOMRenderProps<'span', LinkRenderProps>,
|
|
34
|
+
SlotProps,
|
|
35
|
+
DOMProps,
|
|
36
|
+
Omit<GlobalDOMAttributes, 'onClick'> {
|
|
37
|
+
/**
|
|
38
|
+
* The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
|
|
39
|
+
* element. A function may be provided to compute the class based on component state.
|
|
40
|
+
*
|
|
41
|
+
* @default 'react-aria-Link'
|
|
42
|
+
*/
|
|
43
|
+
className?: ClassNameOrFunction<LinkRenderProps>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface LinkRenderProps {
|
|
47
|
+
/**
|
|
48
|
+
* Whether the link is the current item within a list.
|
|
49
|
+
*
|
|
50
|
+
* @selector [data-current]
|
|
51
|
+
*/
|
|
52
|
+
isCurrent: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Whether the link is currently hovered with a mouse.
|
|
55
|
+
*
|
|
56
|
+
* @selector [data-hovered]
|
|
57
|
+
*/
|
|
58
|
+
isHovered: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Whether the link is currently in a pressed state.
|
|
61
|
+
*
|
|
62
|
+
* @selector [data-pressed]
|
|
63
|
+
*/
|
|
64
|
+
isPressed: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Whether the link is focused, either via a mouse or keyboard.
|
|
67
|
+
*
|
|
68
|
+
* @selector [data-focused]
|
|
69
|
+
*/
|
|
70
|
+
isFocused: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Whether the link is keyboard focused.
|
|
73
|
+
*
|
|
74
|
+
* @selector [data-focus-visible]
|
|
75
|
+
*/
|
|
76
|
+
isFocusVisible: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Whether the link is disabled.
|
|
79
|
+
*
|
|
80
|
+
* @selector [data-disabled]
|
|
81
|
+
*/
|
|
82
|
+
isDisabled: boolean;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export const LinkContext = createContext<ContextValue<LinkProps, HTMLAnchorElement>>(null);
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* A link allows a user to navigate to another page or resource within a web page
|
|
89
|
+
* or application.
|
|
90
|
+
*/
|
|
91
|
+
export function Link(props: LinkProps): any {
|
|
92
|
+
const slot = S('Link');
|
|
93
|
+
let ref: any;
|
|
94
|
+
[props, ref] = useContextProps(props, props.ref, LinkContext, subSlot(slot, 'ctx'));
|
|
95
|
+
|
|
96
|
+
let elementType = props.href && !props.isDisabled ? 'a' : 'span';
|
|
97
|
+
let { linkProps, isPressed } = useLink({ ...props, elementType }, ref, subSlot(slot, 'link'));
|
|
98
|
+
let ElementType = dom[elementType];
|
|
99
|
+
|
|
100
|
+
let { hoverProps, isHovered } = useHover(props, subSlot(slot, 'hover'));
|
|
101
|
+
let { focusProps, isFocused, isFocusVisible } = useFocusRing(
|
|
102
|
+
undefined,
|
|
103
|
+
subSlot(slot, 'focusRing'),
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
let renderProps = useRenderProps<LinkRenderProps, 'span' | 'a'>(
|
|
107
|
+
{
|
|
108
|
+
...props,
|
|
109
|
+
defaultClassName: 'react-aria-Link',
|
|
110
|
+
values: {
|
|
111
|
+
isCurrent: !!props['aria-current'],
|
|
112
|
+
isDisabled: props.isDisabled || false,
|
|
113
|
+
isPressed,
|
|
114
|
+
isHovered,
|
|
115
|
+
isFocused,
|
|
116
|
+
isFocusVisible,
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
subSlot(slot, 'render'),
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
let DOMProps = filterDOMProps(props, { global: true });
|
|
123
|
+
delete DOMProps.onClick;
|
|
124
|
+
|
|
125
|
+
return createElement(ElementType, {
|
|
126
|
+
ref,
|
|
127
|
+
slot: props.slot || undefined,
|
|
128
|
+
...mergeProps(DOMProps, renderProps, linkProps, hoverProps, focusProps),
|
|
129
|
+
'data-focused': isFocused || undefined,
|
|
130
|
+
'data-hovered': isHovered || undefined,
|
|
131
|
+
'data-pressed': isPressed || undefined,
|
|
132
|
+
'data-focus-visible': isFocusVisible || undefined,
|
|
133
|
+
'data-current': !!props['aria-current'] || undefined,
|
|
134
|
+
'data-disabled': props.isDisabled || undefined,
|
|
135
|
+
children: renderProps.children,
|
|
136
|
+
});
|
|
137
|
+
}
|