@data-slot/ui 0.2.130 → 0.2.132
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 +23 -18
- package/dist/alert-dialog.cjs +1 -0
- package/dist/alert-dialog.d.cts +2 -0
- package/dist/alert-dialog.d.ts +2 -0
- package/dist/alert-dialog.js +1 -0
- package/dist/collapsible.d.cts +1 -1
- package/dist/collapsible.d.ts +1 -1
- package/dist/command.d.cts +1 -1
- package/dist/command.d.ts +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/dialog.d.cts +1 -1
- package/dist/dialog.d.ts +1 -1
- package/dist/hover-card.d.cts +1 -1
- package/dist/hover-card.d.ts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index10.d.cts +14 -0
- package/dist/index10.d.ts +14 -0
- package/dist/index2.d.cts +16 -33
- package/dist/index2.d.ts +16 -33
- package/dist/index3.d.cts +42 -38
- package/dist/index3.d.ts +42 -38
- package/dist/index4.d.cts +38 -58
- package/dist/index4.d.ts +38 -58
- package/dist/index5.d.cts +39 -46
- package/dist/index5.d.ts +39 -46
- package/dist/index6.d.cts +54 -48
- package/dist/index6.d.ts +54 -48
- package/dist/index7.d.cts +45 -53
- package/dist/index7.d.ts +45 -53
- package/dist/index8.d.cts +49 -49
- package/dist/index8.d.ts +49 -49
- package/dist/index9.d.cts +71 -13
- package/dist/index9.d.ts +71 -13
- package/dist/popover.d.cts +1 -1
- package/dist/popover.d.ts +1 -1
- package/dist/popup.d.cts +13 -1
- package/dist/popup.d.ts +13 -1
- package/dist/tabs.d.cts +1 -1
- package/dist/tabs.d.ts +1 -1
- package/dist/tooltip.d.cts +1 -1
- package/dist/tooltip.d.ts +1 -1
- package/package.json +23 -16
package/dist/index9.d.cts
CHANGED
|
@@ -1,13 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
//#region ../tooltip/src/index.d.ts
|
|
2
|
+
type TooltipSide = "top" | "right" | "bottom" | "left";
|
|
3
|
+
type TooltipAlign = "start" | "center" | "end";
|
|
4
|
+
type TooltipReason = "pointer" | "focus" | "blur" | "escape" | "api";
|
|
5
|
+
interface TooltipOptions {
|
|
6
|
+
/** Delay before showing tooltip (ms). Default: 300 */
|
|
7
|
+
delay?: number;
|
|
8
|
+
/** Duration to skip delay after closing (ms). Set to 0 to disable warm-up. Default: 300 */
|
|
9
|
+
skipDelayDuration?: number;
|
|
10
|
+
/** Preferred side of tooltip relative to trigger. Default: 'top'. */
|
|
11
|
+
side?: TooltipSide;
|
|
12
|
+
/** Preferred alignment along the side. Default: 'center'. */
|
|
13
|
+
align?: TooltipAlign;
|
|
14
|
+
/** Distance from trigger in pixels. Default: 4 */
|
|
15
|
+
sideOffset?: number;
|
|
16
|
+
/** Alignment-axis offset in pixels. Default: 0 */
|
|
17
|
+
alignOffset?: number;
|
|
18
|
+
/** Enable collision handling. Default: true */
|
|
19
|
+
avoidCollisions?: boolean;
|
|
20
|
+
/** Viewport edge padding used by collision handling. Default: 8 */
|
|
21
|
+
collisionPadding?: number;
|
|
22
|
+
/** Portal content to body while open. Default: true */
|
|
23
|
+
portal?: boolean;
|
|
24
|
+
/** Callback when visibility changes */
|
|
25
|
+
onOpenChange?: (open: boolean) => void;
|
|
26
|
+
}
|
|
27
|
+
interface TooltipController {
|
|
28
|
+
/** Show the tooltip immediately. Respects disabled state. */
|
|
29
|
+
show(): void;
|
|
30
|
+
/** Hide the tooltip */
|
|
31
|
+
hide(): void;
|
|
32
|
+
/** Current visibility state */
|
|
33
|
+
readonly isOpen: boolean;
|
|
34
|
+
/** Cleanup all event listeners */
|
|
35
|
+
destroy(): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create a tooltip controller for a root element
|
|
39
|
+
*
|
|
40
|
+
* Expected markup:
|
|
41
|
+
* ```html
|
|
42
|
+
* <div data-slot="tooltip">
|
|
43
|
+
* <button data-slot="tooltip-trigger">Hover me</button>
|
|
44
|
+
* <div data-slot="tooltip-content" data-side="top" data-align="center">
|
|
45
|
+
* Tooltip text
|
|
46
|
+
* </div>
|
|
47
|
+
* </div>
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* Placement data attributes are resolved as: content -> authored positioner -> root.
|
|
51
|
+
* - `data-side`: 'top' | 'right' | 'bottom' | 'left' (bind-time preferred side)
|
|
52
|
+
* - `data-align`: 'start' | 'center' | 'end' (bind-time preferred align)
|
|
53
|
+
* - `data-side-offset`: number (px)
|
|
54
|
+
* - `data-align-offset`: number (px)
|
|
55
|
+
* - `data-avoid-collisions`: boolean
|
|
56
|
+
* - `data-collision-padding`: number (px)
|
|
57
|
+
* - `data-delay`: number (ms)
|
|
58
|
+
* - `data-skip-delay-duration`: number (ms)
|
|
59
|
+
*
|
|
60
|
+
* Opens on hover (non-touch) and focus. Touch devices: focus-only.
|
|
61
|
+
* Content is hoverable: moving pointer from trigger to content keeps it open.
|
|
62
|
+
* Tooltip stays open while trigger has focus, even if pointer leaves.
|
|
63
|
+
*/
|
|
64
|
+
declare function createTooltip(root: Element, options?: TooltipOptions): TooltipController;
|
|
65
|
+
/**
|
|
66
|
+
* Find and bind all tooltip components in a scope
|
|
67
|
+
* Returns array of controllers for programmatic access
|
|
68
|
+
*/
|
|
69
|
+
declare function create(scope?: ParentNode): TooltipController[];
|
|
70
|
+
//#endregion
|
|
71
|
+
export { TooltipSide as a, TooltipReason as i, TooltipController as n, create as o, TooltipOptions as r, createTooltip as s, TooltipAlign as t };
|
package/dist/index9.d.ts
CHANGED
|
@@ -1,13 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
//#region ../tooltip/src/index.d.ts
|
|
2
|
+
type TooltipSide = "top" | "right" | "bottom" | "left";
|
|
3
|
+
type TooltipAlign = "start" | "center" | "end";
|
|
4
|
+
type TooltipReason = "pointer" | "focus" | "blur" | "escape" | "api";
|
|
5
|
+
interface TooltipOptions {
|
|
6
|
+
/** Delay before showing tooltip (ms). Default: 300 */
|
|
7
|
+
delay?: number;
|
|
8
|
+
/** Duration to skip delay after closing (ms). Set to 0 to disable warm-up. Default: 300 */
|
|
9
|
+
skipDelayDuration?: number;
|
|
10
|
+
/** Preferred side of tooltip relative to trigger. Default: 'top'. */
|
|
11
|
+
side?: TooltipSide;
|
|
12
|
+
/** Preferred alignment along the side. Default: 'center'. */
|
|
13
|
+
align?: TooltipAlign;
|
|
14
|
+
/** Distance from trigger in pixels. Default: 4 */
|
|
15
|
+
sideOffset?: number;
|
|
16
|
+
/** Alignment-axis offset in pixels. Default: 0 */
|
|
17
|
+
alignOffset?: number;
|
|
18
|
+
/** Enable collision handling. Default: true */
|
|
19
|
+
avoidCollisions?: boolean;
|
|
20
|
+
/** Viewport edge padding used by collision handling. Default: 8 */
|
|
21
|
+
collisionPadding?: number;
|
|
22
|
+
/** Portal content to body while open. Default: true */
|
|
23
|
+
portal?: boolean;
|
|
24
|
+
/** Callback when visibility changes */
|
|
25
|
+
onOpenChange?: (open: boolean) => void;
|
|
26
|
+
}
|
|
27
|
+
interface TooltipController {
|
|
28
|
+
/** Show the tooltip immediately. Respects disabled state. */
|
|
29
|
+
show(): void;
|
|
30
|
+
/** Hide the tooltip */
|
|
31
|
+
hide(): void;
|
|
32
|
+
/** Current visibility state */
|
|
33
|
+
readonly isOpen: boolean;
|
|
34
|
+
/** Cleanup all event listeners */
|
|
35
|
+
destroy(): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create a tooltip controller for a root element
|
|
39
|
+
*
|
|
40
|
+
* Expected markup:
|
|
41
|
+
* ```html
|
|
42
|
+
* <div data-slot="tooltip">
|
|
43
|
+
* <button data-slot="tooltip-trigger">Hover me</button>
|
|
44
|
+
* <div data-slot="tooltip-content" data-side="top" data-align="center">
|
|
45
|
+
* Tooltip text
|
|
46
|
+
* </div>
|
|
47
|
+
* </div>
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* Placement data attributes are resolved as: content -> authored positioner -> root.
|
|
51
|
+
* - `data-side`: 'top' | 'right' | 'bottom' | 'left' (bind-time preferred side)
|
|
52
|
+
* - `data-align`: 'start' | 'center' | 'end' (bind-time preferred align)
|
|
53
|
+
* - `data-side-offset`: number (px)
|
|
54
|
+
* - `data-align-offset`: number (px)
|
|
55
|
+
* - `data-avoid-collisions`: boolean
|
|
56
|
+
* - `data-collision-padding`: number (px)
|
|
57
|
+
* - `data-delay`: number (ms)
|
|
58
|
+
* - `data-skip-delay-duration`: number (ms)
|
|
59
|
+
*
|
|
60
|
+
* Opens on hover (non-touch) and focus. Touch devices: focus-only.
|
|
61
|
+
* Content is hoverable: moving pointer from trigger to content keeps it open.
|
|
62
|
+
* Tooltip stays open while trigger has focus, even if pointer leaves.
|
|
63
|
+
*/
|
|
64
|
+
declare function createTooltip(root: Element, options?: TooltipOptions): TooltipController;
|
|
65
|
+
/**
|
|
66
|
+
* Find and bind all tooltip components in a scope
|
|
67
|
+
* Returns array of controllers for programmatic access
|
|
68
|
+
*/
|
|
69
|
+
declare function create(scope?: ParentNode): TooltipController[];
|
|
70
|
+
//#endregion
|
|
71
|
+
export { TooltipSide as a, TooltipReason as i, TooltipController as n, create as o, TooltipOptions as r, createTooltip as s, TooltipAlign as t };
|
package/dist/popover.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as PopoverSide, i as PopoverPosition, n as PopoverController, o as create, r as PopoverOptions, s as createPopover, t as PopoverAlign } from "./
|
|
1
|
+
import { a as PopoverSide, i as PopoverPosition, n as PopoverController, o as create, r as PopoverOptions, s as createPopover, t as PopoverAlign } from "./index8.cjs";
|
|
2
2
|
export { PopoverAlign, PopoverController, PopoverOptions, PopoverPosition, PopoverSide, create, createPopover };
|
package/dist/popover.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as PopoverSide, i as PopoverPosition, n as PopoverController, o as create, r as PopoverOptions, s as createPopover, t as PopoverAlign } from "./
|
|
1
|
+
import { a as PopoverSide, i as PopoverPosition, n as PopoverController, o as create, r as PopoverOptions, s as createPopover, t as PopoverAlign } from "./index8.js";
|
|
2
2
|
export { PopoverAlign, PopoverController, PopoverOptions, PopoverPosition, PopoverSide, create, createPopover };
|
package/dist/popup.d.cts
CHANGED
|
@@ -158,6 +158,18 @@ declare const computeFloatingTransformOrigin: (input: ComputeFloatingTransformOr
|
|
|
158
158
|
*/
|
|
159
159
|
declare function measurePopupContentRect(element: HTMLElement): Pick<DOMRectReadOnly, "top" | "right" | "bottom" | "left" | "width" | "height">;
|
|
160
160
|
declare const focusElement: (el: HTMLElement | null | undefined) => void;
|
|
161
|
+
interface ModalStackItemOptions {
|
|
162
|
+
content: HTMLElement;
|
|
163
|
+
overlay?: HTMLElement | null;
|
|
164
|
+
onTabKeydown?: (event: KeyboardEvent) => void;
|
|
165
|
+
cssVarPrefix: string;
|
|
166
|
+
}
|
|
167
|
+
interface ModalStackItemController {
|
|
168
|
+
open(): void;
|
|
169
|
+
close(): void;
|
|
170
|
+
destroy(): void;
|
|
171
|
+
}
|
|
172
|
+
declare function createModalStackItem(options: ModalStackItemOptions): ModalStackItemController;
|
|
161
173
|
declare function computeFloatingPosition(input: ComputeFloatingPositionInput): FloatingPosition;
|
|
162
174
|
declare function ensureItemVisibleInContainer(item: HTMLElement, container: HTMLElement, padding?: number): void;
|
|
163
175
|
interface PositionSyncOptions {
|
|
@@ -226,4 +238,4 @@ interface PresenceLifecycleController {
|
|
|
226
238
|
}
|
|
227
239
|
declare function createPresenceLifecycle(options: PresenceLifecycleOptions): PresenceLifecycleController;
|
|
228
240
|
//#endregion
|
|
229
|
-
export {
|
|
241
|
+
export { composeHandlers as A, getDataEnum as B, createPresenceLifecycle as C, measurePopupContentRect as D, getFloatingTransformOriginAnchor as E, setAria as F, getRootBinding as G, getDataString as H, PortalState as I, portalToBody as J, getRoots as K, clearRootBinding as L, on as M, ensureId as N, lockScroll as O, linkLabelledBy as P, warnRootBindingOnce as Q, containsWithPortals as R, createPositionSync as S, focusElement as T, getPart as U, getDataNumber as V, getParts as W, reuseRootBinding as X, restorePortal as Y, setRootBinding as Z, computeFloatingPosition as _, FloatingTransformOriginAnchor as a, createModalStackItem as b, PopupAlign as c, PortalLifecycleController as d, PortalLifecycleOptions as f, PresenceLifecycleOptions as g, PresenceLifecycleController as h, FloatingPosition as i, emit as j, unlockScroll as k, PopupPlacementOptions as l, PositionSyncOptions as m, ComputeFloatingTransformOriginInput as n, ModalStackItemController as o, PositionSyncController as p, hasRootBinding as q, DismissLayerOptions as r, ModalStackItemOptions as s, ComputeFloatingPositionInput as t, PopupSide as u, computeFloatingTransformOrigin as v, ensureItemVisibleInContainer as w, createPortalLifecycle as x, createDismissLayer as y, getDataBool as z };
|
package/dist/popup.d.ts
CHANGED
|
@@ -158,6 +158,18 @@ declare const computeFloatingTransformOrigin: (input: ComputeFloatingTransformOr
|
|
|
158
158
|
*/
|
|
159
159
|
declare function measurePopupContentRect(element: HTMLElement): Pick<DOMRectReadOnly, "top" | "right" | "bottom" | "left" | "width" | "height">;
|
|
160
160
|
declare const focusElement: (el: HTMLElement | null | undefined) => void;
|
|
161
|
+
interface ModalStackItemOptions {
|
|
162
|
+
content: HTMLElement;
|
|
163
|
+
overlay?: HTMLElement | null;
|
|
164
|
+
onTabKeydown?: (event: KeyboardEvent) => void;
|
|
165
|
+
cssVarPrefix: string;
|
|
166
|
+
}
|
|
167
|
+
interface ModalStackItemController {
|
|
168
|
+
open(): void;
|
|
169
|
+
close(): void;
|
|
170
|
+
destroy(): void;
|
|
171
|
+
}
|
|
172
|
+
declare function createModalStackItem(options: ModalStackItemOptions): ModalStackItemController;
|
|
161
173
|
declare function computeFloatingPosition(input: ComputeFloatingPositionInput): FloatingPosition;
|
|
162
174
|
declare function ensureItemVisibleInContainer(item: HTMLElement, container: HTMLElement, padding?: number): void;
|
|
163
175
|
interface PositionSyncOptions {
|
|
@@ -226,4 +238,4 @@ interface PresenceLifecycleController {
|
|
|
226
238
|
}
|
|
227
239
|
declare function createPresenceLifecycle(options: PresenceLifecycleOptions): PresenceLifecycleController;
|
|
228
240
|
//#endregion
|
|
229
|
-
export {
|
|
241
|
+
export { composeHandlers as A, getDataEnum as B, createPresenceLifecycle as C, measurePopupContentRect as D, getFloatingTransformOriginAnchor as E, setAria as F, getRootBinding as G, getDataString as H, PortalState as I, portalToBody as J, getRoots as K, clearRootBinding as L, on as M, ensureId as N, lockScroll as O, linkLabelledBy as P, warnRootBindingOnce as Q, containsWithPortals as R, createPositionSync as S, focusElement as T, getPart as U, getDataNumber as V, getParts as W, reuseRootBinding as X, restorePortal as Y, setRootBinding as Z, computeFloatingPosition as _, FloatingTransformOriginAnchor as a, createModalStackItem as b, PopupAlign as c, PortalLifecycleController as d, PortalLifecycleOptions as f, PresenceLifecycleOptions as g, PresenceLifecycleController as h, FloatingPosition as i, emit as j, unlockScroll as k, PopupPlacementOptions as l, PositionSyncOptions as m, ComputeFloatingTransformOriginInput as n, ModalStackItemController as o, PositionSyncController as p, hasRootBinding as q, DismissLayerOptions as r, ModalStackItemOptions as s, ComputeFloatingPositionInput as t, PopupSide as u, computeFloatingTransformOrigin as v, ensureItemVisibleInContainer as w, createPortalLifecycle as x, createDismissLayer as y, getDataBool as z };
|
package/dist/tabs.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as createTabs, n as TabsOptions, r as create, t as TabsController } from "./
|
|
1
|
+
import { i as createTabs, n as TabsOptions, r as create, t as TabsController } from "./index7.cjs";
|
|
2
2
|
export { TabsController, TabsOptions, create, createTabs };
|
package/dist/tabs.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as createTabs, n as TabsOptions, r as create, t as TabsController } from "./
|
|
1
|
+
import { i as createTabs, n as TabsOptions, r as create, t as TabsController } from "./index7.js";
|
|
2
2
|
export { TabsController, TabsOptions, create, createTabs };
|
package/dist/tooltip.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as TooltipSide, i as TooltipReason, n as TooltipController, o as create, r as TooltipOptions, s as createTooltip, t as TooltipAlign } from "./
|
|
1
|
+
import { a as TooltipSide, i as TooltipReason, n as TooltipController, o as create, r as TooltipOptions, s as createTooltip, t as TooltipAlign } from "./index9.cjs";
|
|
2
2
|
export { TooltipAlign, TooltipController, TooltipOptions, TooltipReason, TooltipSide, create, createTooltip };
|
package/dist/tooltip.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as TooltipSide, i as TooltipReason, n as TooltipController, o as create, r as TooltipOptions, s as createTooltip, t as TooltipAlign } from "./
|
|
1
|
+
import { a as TooltipSide, i as TooltipReason, n as TooltipController, o as create, r as TooltipOptions, s as createTooltip, t as TooltipAlign } from "./index9.js";
|
|
2
2
|
export { TooltipAlign, TooltipController, TooltipOptions, TooltipReason, TooltipSide, create, createTooltip };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@data-slot/ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.132",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "Headless UI components for vanilla JavaScript. Convenience re-exports from @data-slot/* packages.",
|
|
@@ -32,6 +32,12 @@
|
|
|
32
32
|
"require": "./dist/dialog.cjs",
|
|
33
33
|
"default": "./dist/dialog.js"
|
|
34
34
|
},
|
|
35
|
+
"./alert-dialog": {
|
|
36
|
+
"types": "./dist/alert-dialog.d.ts",
|
|
37
|
+
"import": "./dist/alert-dialog.js",
|
|
38
|
+
"require": "./dist/alert-dialog.cjs",
|
|
39
|
+
"default": "./dist/alert-dialog.js"
|
|
40
|
+
},
|
|
35
41
|
"./accordion": {
|
|
36
42
|
"types": "./dist/accordion.d.ts",
|
|
37
43
|
"import": "./dist/accordion.js",
|
|
@@ -112,21 +118,22 @@
|
|
|
112
118
|
"build": "tsdown"
|
|
113
119
|
},
|
|
114
120
|
"dependencies": {
|
|
115
|
-
"@data-slot/core": "0.2.
|
|
116
|
-
"@data-slot/tabs": "0.2.
|
|
117
|
-
"@data-slot/dialog": "0.2.
|
|
118
|
-
"@data-slot/
|
|
119
|
-
"@data-slot/
|
|
120
|
-
"@data-slot/
|
|
121
|
-
"@data-slot/
|
|
122
|
-
"@data-slot/
|
|
123
|
-
"@data-slot/
|
|
124
|
-
"@data-slot/
|
|
125
|
-
"@data-slot/
|
|
126
|
-
"@data-slot/toggle
|
|
127
|
-
"@data-slot/
|
|
128
|
-
"@data-slot/
|
|
129
|
-
"@data-slot/
|
|
121
|
+
"@data-slot/core": "0.2.132",
|
|
122
|
+
"@data-slot/tabs": "0.2.132",
|
|
123
|
+
"@data-slot/dialog": "0.2.132",
|
|
124
|
+
"@data-slot/alert-dialog": "0.2.132",
|
|
125
|
+
"@data-slot/accordion": "0.2.132",
|
|
126
|
+
"@data-slot/popover": "0.2.132",
|
|
127
|
+
"@data-slot/hover-card": "0.2.132",
|
|
128
|
+
"@data-slot/tooltip": "0.2.132",
|
|
129
|
+
"@data-slot/collapsible": "0.2.132",
|
|
130
|
+
"@data-slot/navigation-menu": "0.2.132",
|
|
131
|
+
"@data-slot/dropdown-menu": "0.2.132",
|
|
132
|
+
"@data-slot/toggle": "0.2.132",
|
|
133
|
+
"@data-slot/toggle-group": "0.2.132",
|
|
134
|
+
"@data-slot/select": "0.2.132",
|
|
135
|
+
"@data-slot/combobox": "0.2.132",
|
|
136
|
+
"@data-slot/command": "0.2.132"
|
|
130
137
|
},
|
|
131
138
|
"keywords": [
|
|
132
139
|
"headless",
|