@foldkit/ui 0.122.1 → 0.124.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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/nav/index.d.ts +49 -0
- package/dist/nav/index.d.ts.map +1 -0
- package/dist/nav/index.js +43 -0
- package/dist/nav/public.d.ts +3 -0
- package/dist/nav/public.d.ts.map +1 -0
- package/dist/nav/public.js +1 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * as FileDrop from './fileDrop/public.js';
|
|
|
12
12
|
export * as Input from './input/public.js';
|
|
13
13
|
export * as Listbox from './listbox/public.js';
|
|
14
14
|
export * as Menu from './menu/public.js';
|
|
15
|
+
export * as Nav from './nav/public.js';
|
|
15
16
|
export * as Popover from './popover/public.js';
|
|
16
17
|
export * as RadioGroup from './radioGroup/public.js';
|
|
17
18
|
export * as Select from './select/public.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAC5C,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAC5C,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAA;AACtD,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAA;AAC1C,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAA;AAC9C,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAA;AACxC,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAA;AAC9C,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAC5C,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAC5C,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAC5C,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAA;AACxC,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAA;AAC1C,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAA;AAC9C,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAC5C,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAC5C,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAA;AACtD,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAA;AAC1C,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAA;AAC9C,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAA;AACxC,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAA;AACtC,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAA;AAC9C,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAC5C,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAC5C,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAC5C,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAA;AACxC,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAA;AAC1C,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAA;AAC9C,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export * as FileDrop from './fileDrop/public.js';
|
|
|
12
12
|
export * as Input from './input/public.js';
|
|
13
13
|
export * as Listbox from './listbox/public.js';
|
|
14
14
|
export * as Menu from './menu/public.js';
|
|
15
|
+
export * as Nav from './nav/public.js';
|
|
15
16
|
export * as Popover from './popover/public.js';
|
|
16
17
|
export * as RadioGroup from './radioGroup/public.js';
|
|
17
18
|
export * as Select from './select/public.js';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ChildAttribute, type Html } from 'foldkit/html';
|
|
2
|
+
/** Per-item render info passed to the consumer's `toView`. Generic over
|
|
3
|
+
* `Value extends string`: the item value is typed as the consumer's union
|
|
4
|
+
* (typically a route tag) so `toView` can switch on it without casting. */
|
|
5
|
+
export type ItemInfo<Value extends string = string> = Readonly<{
|
|
6
|
+
value: Value;
|
|
7
|
+
index: number;
|
|
8
|
+
isCurrent: boolean;
|
|
9
|
+
link: ReadonlyArray<ChildAttribute>;
|
|
10
|
+
}>;
|
|
11
|
+
/** Render-time payload published to the consumer's `toView`.
|
|
12
|
+
*
|
|
13
|
+
* - `nav`: ARIA attributes for the wrapping navigation landmark. Carries
|
|
14
|
+
* `aria-label` only; the `<nav>` element already supplies the navigation
|
|
15
|
+
* role, so spread this onto an `h.nav`.
|
|
16
|
+
* - `items`: one entry per `viewInputs.items`, in the same order, each with
|
|
17
|
+
* the anchor's attribute bundle and derived current state. */
|
|
18
|
+
export type RenderInfo<Value extends string = string> = Readonly<{
|
|
19
|
+
nav: ReadonlyArray<ChildAttribute>;
|
|
20
|
+
items: ReadonlyArray<ItemInfo<Value>>;
|
|
21
|
+
}>;
|
|
22
|
+
/** View inputs for `Nav.view`. Generic over `Value extends string` so the
|
|
23
|
+
* consumer's section/route union flows into `toView`, `toHref`, and
|
|
24
|
+
* `isItemCurrent` without casting. */
|
|
25
|
+
export type ViewInputs<Value extends string = string> = Readonly<{
|
|
26
|
+
items: ReadonlyArray<Value>;
|
|
27
|
+
ariaLabel: string;
|
|
28
|
+
toHref: (value: Value, index: number) => string;
|
|
29
|
+
isItemCurrent: (value: Value, index: number) => boolean;
|
|
30
|
+
toView: (render: RenderInfo<Value>) => Html;
|
|
31
|
+
}>;
|
|
32
|
+
/** Renders a navigation landmark whose items are links, marking the current
|
|
33
|
+
* destination with `aria-current="page"`. Stateless: the current item is
|
|
34
|
+
* derived from `isItemCurrent`, which the consumer drives from the URL, the
|
|
35
|
+
* single source of truth for which page is showing.
|
|
36
|
+
*
|
|
37
|
+
* Use this for URL-driven navigation where each section is a separate
|
|
38
|
+
* route with its own URL, deep-linking, and browser-history behavior.
|
|
39
|
+
* Reach for `Tabs` instead when switching content within a single page;
|
|
40
|
+
* `Tabs` carries the `tablist`/`tab`/`tabpanel` semantics, which are
|
|
41
|
+
* wrong for URL-driven navigation.
|
|
42
|
+
*
|
|
43
|
+
* Headless: `toView` owns all markup, spreading the `nav` bundle onto an
|
|
44
|
+
* `h.nav` and each `item.link` bundle onto an `h.a`. Keyboard support is the
|
|
45
|
+
* browser's native link handling (Tab to move, Enter to follow); no roving
|
|
46
|
+
* tabindex is imposed, since that is a composite-widget pattern, not a
|
|
47
|
+
* navigation-landmark one. */
|
|
48
|
+
export declare const view: <Value extends string = string>(viewInputs: ViewInputs<Value>) => Html;
|
|
49
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nav/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,IAAI,EAGV,MAAM,cAAc,CAAA;AAIrB;;4EAE4E;AAC5E,MAAM,MAAM,QAAQ,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IAC7D,KAAK,EAAE,KAAK,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;CACpC,CAAC,CAAA;AAEF;;;;;;iEAMiE;AACjE,MAAM,MAAM,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IAC/D,GAAG,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;IAClC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;CACtC,CAAC,CAAA;AAEF;;uCAEuC;AACvC,MAAM,MAAM,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IAC/D,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC/C,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;IACvD,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,CAAA;CAC5C,CAAC,CAAA;AAMF;;;;;;;;;;;;;;;+BAe+B;AAC/B,eAAO,MAAM,IAAI,GAAI,KAAK,SAAS,MAAM,GAAG,MAAM,EAChD,YAAY,UAAU,CAAC,KAAK,CAAC,KAC5B,IAmCF,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Array, Option } from 'effect';
|
|
2
|
+
import { childAttributes, html, } from 'foldkit/html';
|
|
3
|
+
// VIEW
|
|
4
|
+
const ARIA_CURRENT_PAGE = 'page';
|
|
5
|
+
/** Renders a navigation landmark whose items are links, marking the current
|
|
6
|
+
* destination with `aria-current="page"`. Stateless: the current item is
|
|
7
|
+
* derived from `isItemCurrent`, which the consumer drives from the URL, the
|
|
8
|
+
* single source of truth for which page is showing.
|
|
9
|
+
*
|
|
10
|
+
* Use this for URL-driven navigation where each section is a separate
|
|
11
|
+
* route with its own URL, deep-linking, and browser-history behavior.
|
|
12
|
+
* Reach for `Tabs` instead when switching content within a single page;
|
|
13
|
+
* `Tabs` carries the `tablist`/`tab`/`tabpanel` semantics, which are
|
|
14
|
+
* wrong for URL-driven navigation.
|
|
15
|
+
*
|
|
16
|
+
* Headless: `toView` owns all markup, spreading the `nav` bundle onto an
|
|
17
|
+
* `h.nav` and each `item.link` bundle onto an `h.a`. Keyboard support is the
|
|
18
|
+
* browser's native link handling (Tab to move, Enter to follow); no roving
|
|
19
|
+
* tabindex is imposed, since that is a composite-widget pattern, not a
|
|
20
|
+
* navigation-landmark one. */
|
|
21
|
+
export const view = (viewInputs) => {
|
|
22
|
+
const h = html();
|
|
23
|
+
const { items, ariaLabel, toHref, isItemCurrent, toView } = viewInputs;
|
|
24
|
+
const itemInfos = Array.map(items, (value, index) => {
|
|
25
|
+
const isCurrent = isItemCurrent(value, index);
|
|
26
|
+
const maybeCurrentAttributes = Option.liftPredicate([h.AriaCurrent(ARIA_CURRENT_PAGE), h.DataAttribute('current', '')], () => isCurrent);
|
|
27
|
+
const linkAttributes = [
|
|
28
|
+
h.Href(toHref(value, index)),
|
|
29
|
+
...Option.getOrElse(maybeCurrentAttributes, () => []),
|
|
30
|
+
];
|
|
31
|
+
return {
|
|
32
|
+
value,
|
|
33
|
+
index,
|
|
34
|
+
isCurrent,
|
|
35
|
+
link: childAttributes(linkAttributes),
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
const navAttributes = [h.AriaLabel(ariaLabel)];
|
|
39
|
+
return toView({
|
|
40
|
+
nav: childAttributes(navAttributes),
|
|
41
|
+
items: itemInfos,
|
|
42
|
+
});
|
|
43
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/nav/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEjC,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { view } from './index.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foldkit/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.124.0",
|
|
4
4
|
"description": "Headless, accessible UI components for Foldkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"typedoc": "^0.28.19",
|
|
128
128
|
"typescript": "^6.0.3",
|
|
129
129
|
"vitest": "^4.1.9",
|
|
130
|
-
"foldkit": "0.
|
|
130
|
+
"foldkit": "0.124.0"
|
|
131
131
|
},
|
|
132
132
|
"keywords": [
|
|
133
133
|
"foldkit",
|