Skip to content

Commit 239d6be

Browse files
chore: primitive type (#271)
* chore: primitive type * fix: export type
1 parent 102cc3b commit 239d6be

File tree

4 files changed

+222
-2
lines changed

4 files changed

+222
-2
lines changed

packages/components/toggle/src/toggle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const Toggle = defineComponent({
6464
const originalReturn = () => h(
6565
Primitive.button, {
6666
'type': 'button',
67-
'aria-pressed': state.value,
67+
'aria-pressed': state.value ? 'true' : 'false',
6868
'data-state': state.value ? 'on' : 'off',
6969
'data-disabled': disabled ? '' : undefined,
7070
...toggleProps,

packages/core/primitive/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ export type {
1010
InstanceTypeRef,
1111
ComponentPublicInstanceRef,
1212
} from './primitive'
13+
14+
export type { AriaAttributes } from './types'

packages/core/primitive/src/primitive.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
onMounted,
1818
} from 'vue'
1919
import { isValidVNodeElement, renderSlotFragments } from './utils'
20+
import type { AriaAttributes } from './types'
2021

2122
const NODES = [
2223
'a',
@@ -37,6 +38,25 @@ const NODES = [
3738
'ul',
3839
] as const
3940

41+
interface NodeElementTagNameMap {
42+
a: HTMLAnchorElement
43+
button: HTMLButtonElement
44+
div: HTMLDivElement
45+
form: HTMLFormElement
46+
h2: HTMLHeadingElement
47+
h3: HTMLHeadingElement
48+
img: HTMLImageElement
49+
input: HTMLInputElement
50+
label: HTMLLabelElement
51+
li: HTMLLIElement
52+
nav: HTMLElement
53+
ol: HTMLOListElement
54+
p: HTMLParagraphElement
55+
span: HTMLSpanElement
56+
svg: SVGSVGElement
57+
ul: HTMLUListElement
58+
}
59+
4060
type ElementConstructor<P> =
4161
| (new () => { $props: P })
4262
| ((props: P, ...args: any) => FunctionalComponent<any, any>)
@@ -88,7 +108,7 @@ type ComponentPropsWithoutRef<
88108
type Primitives = {
89109
[E in (typeof NODES)[number]]: DefineComponent<{
90110
asChild?: boolean
91-
}>;
111+
} & IntrinsicElementAttributes[E]> & NodeElementTagNameMap[E] & AriaAttributes
92112
}
93113

94114
type ElementType<T extends keyof IntrinsicElementAttributes> = Partial<

packages/core/primitive/src/types.ts

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/**
2+
* Wraps an array around itself at a given start index
3+
* Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
4+
*/
5+
export function wrapArray<T>(array: T[], startIndex: number) {
6+
return array.map((_, index) => array[(startIndex + index) % array.length])
7+
}
8+
9+
type Booleanish = boolean | 'true' | 'false'
10+
type Numberish = number | string
11+
12+
// All the WAI-ARIA 1.1 attributes from https://www.w3.org/TR/wai-aria-1.1/
13+
export interface AriaAttributes {
14+
/** Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application. */
15+
'aria-activedescendant'?: string
16+
/** Indicates whether assistive technologies will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute. */
17+
'aria-atomic'?: Booleanish
18+
/**
19+
* Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be
20+
* presented if they are made.
21+
*/
22+
'aria-autocomplete'?: 'none' | 'inline' | 'list' | 'both'
23+
/** Indicates an element is being modified and that assistive technologies MAY want to wait until the modifications are complete before exposing them to the user. */
24+
'aria-busy'?: Booleanish
25+
/**
26+
* Indicates the current "checked" state of checkboxes, radio buttons, and other widgets.
27+
* @see aria-pressed @see aria-selected.
28+
*/
29+
'aria-checked'?: Booleanish | 'mixed'
30+
/**
31+
* Defines the total number of columns in a table, grid, or treegrid.
32+
* @see aria-colindex.
33+
*/
34+
'aria-colcount'?: Numberish
35+
/**
36+
* Defines an element's column index or position with respect to the total number of columns within a table, grid, or treegrid.
37+
* @see aria-colcount @see aria-colspan.
38+
*/
39+
'aria-colindex'?: Numberish
40+
/**
41+
* Defines the number of columns spanned by a cell or gridcell within a table, grid, or treegrid.
42+
* @see aria-colindex @see aria-rowspan.
43+
*/
44+
'aria-colspan'?: Numberish
45+
/**
46+
* Identifies the element (or elements) whose contents or presence are controlled by the current element.
47+
* @see aria-owns.
48+
*/
49+
'aria-controls'?: string
50+
/** Indicates the element that represents the current item within a container or set of related elements. */
51+
'aria-current'?: Booleanish | 'page' | 'step' | 'location' | 'date' | 'time'
52+
/**
53+
* Identifies the element (or elements) that describes the object.
54+
* @see aria-labelledby
55+
*/
56+
'aria-describedby'?: string
57+
/**
58+
* Identifies the element that provides a detailed, extended description for the object.
59+
* @see aria-describedby.
60+
*/
61+
'aria-details'?: string
62+
/**
63+
* Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable.
64+
* @see aria-hidden @see aria-readonly.
65+
*/
66+
'aria-disabled'?: Booleanish
67+
/**
68+
* Indicates what functions can be performed when a dragged object is released on the drop target.
69+
* @deprecated in ARIA 1.1
70+
*/
71+
'aria-dropeffect'?: 'none' | 'copy' | 'execute' | 'link' | 'move' | 'popup'
72+
/**
73+
* Identifies the element that provides an error message for the object.
74+
* @see aria-invalid @see aria-describedby.
75+
*/
76+
'aria-errormessage'?: string
77+
/** Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed. */
78+
'aria-expanded'?: Booleanish
79+
/**
80+
* Identifies the next element (or elements) in an alternate reading order of content which, at the user's discretion,
81+
* allows assistive technology to override the general default of reading in document source order.
82+
*/
83+
'aria-flowto'?: string
84+
/**
85+
* Indicates an element's "grabbed" state in a drag-and-drop operation.
86+
* @deprecated in ARIA 1.1
87+
*/
88+
'aria-grabbed'?: Booleanish
89+
/** Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element. */
90+
'aria-haspopup'?: Booleanish | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog'
91+
/**
92+
* Indicates whether the element is exposed to an accessibility API.
93+
* @see aria-disabled.
94+
*/
95+
'aria-hidden'?: Booleanish
96+
/**
97+
* Indicates the entered value does not conform to the format expected by the application.
98+
* @see aria-errormessage.
99+
*/
100+
'aria-invalid'?: Booleanish | 'grammar' | 'spelling'
101+
/** Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element. */
102+
'aria-keyshortcuts'?: string
103+
/**
104+
* Defines a string value that labels the current element.
105+
* @see aria-labelledby.
106+
*/
107+
'aria-label'?: string
108+
/**
109+
* Identifies the element (or elements) that labels the current element.
110+
* @see aria-describedby.
111+
*/
112+
'aria-labelledby'?: string
113+
/** Defines the hierarchical level of an element within a structure. */
114+
'aria-level'?: Numberish
115+
/** Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region. */
116+
'aria-live'?: 'off' | 'assertive' | 'polite'
117+
/** Indicates whether an element is modal when displayed. */
118+
'aria-modal'?: Booleanish
119+
/** Indicates whether a text box accepts multiple lines of input or only a single line. */
120+
'aria-multiline'?: Booleanish
121+
/** Indicates that the user may select more than one item from the current selectable descendants. */
122+
'aria-multiselectable'?: Booleanish
123+
/** Indicates whether the element's orientation is horizontal, vertical, or unknown/ambiguous. */
124+
'aria-orientation'?: 'horizontal' | 'vertical'
125+
/**
126+
* Identifies an element (or elements) in order to define a visual, functional, or contextual parent/child relationship
127+
* between DOM elements where the DOM hierarchy cannot be used to represent the relationship.
128+
* @see aria-controls.
129+
*/
130+
'aria-owns'?: string
131+
/**
132+
* Defines a short hint (a word or short phrase) intended to aid the user with data entry when the control has no value.
133+
* A hint could be a sample value or a brief description of the expected format.
134+
*/
135+
'aria-placeholder'?: string
136+
/**
137+
* Defines an element's number or position in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM.
138+
* @see aria-setsize.
139+
*/
140+
'aria-posinset'?: Numberish
141+
/**
142+
* Indicates the current "pressed" state of toggle buttons.
143+
* @see aria-checked @see aria-selected.
144+
*/
145+
'aria-pressed'?: Booleanish | 'mixed'
146+
/**
147+
* Indicates that the element is not editable, but is otherwise operable.
148+
* @see aria-disabled.
149+
*/
150+
'aria-readonly'?: Booleanish
151+
/**
152+
* Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified.
153+
* @see aria-atomic.
154+
*/
155+
'aria-relevant'?: 'additions' | 'additions text' | 'all' | 'removals' | 'text'
156+
/** Indicates that user input is required on the element before a form may be submitted. */
157+
'aria-required'?: Booleanish
158+
/** Defines a human-readable, author-localized description for the role of an element. */
159+
'aria-roledescription'?: string
160+
/**
161+
* Defines the total number of rows in a table, grid, or treegrid.
162+
* @see aria-rowindex.
163+
*/
164+
'aria-rowcount'?: Numberish
165+
/**
166+
* Defines an element's row index or position with respect to the total number of rows within a table, grid, or treegrid.
167+
* @see aria-rowcount @see aria-rowspan.
168+
*/
169+
'aria-rowindex'?: Numberish
170+
/**
171+
* Defines the number of rows spanned by a cell or gridcell within a table, grid, or treegrid.
172+
* @see aria-rowindex @see aria-colspan.
173+
*/
174+
'aria-rowspan'?: Numberish
175+
/**
176+
* Indicates the current "selected" state of various widgets.
177+
* @see aria-checked @see aria-pressed.
178+
*/
179+
'aria-selected'?: Booleanish
180+
/**
181+
* Defines the number of items in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM.
182+
* @see aria-posinset.
183+
*/
184+
'aria-setsize'?: Numberish
185+
/** Indicates if items in a table or grid are sorted in ascending or descending order. */
186+
'aria-sort'?: 'none' | 'ascending' | 'descending' | 'other'
187+
/** Defines the maximum allowed value for a range widget. */
188+
'aria-valuemax'?: Numberish
189+
/** Defines the minimum allowed value for a range widget. */
190+
'aria-valuemin'?: Numberish
191+
/**
192+
* Defines the current value for a range widget.
193+
* @see aria-valuetext.
194+
*/
195+
'aria-valuenow'?: Numberish
196+
/** Defines the human readable text alternative of aria-valuenow for a range widget. */
197+
'aria-valuetext'?: string
198+
}

0 commit comments

Comments
 (0)