foldkit 0.15.0 → 0.16.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 +2 -2
- package/dist/fieldValidation.d.ts +20 -0
- package/dist/fieldValidation.d.ts.map +1 -1
- package/dist/fieldValidation.js +27 -11
- package/dist/html.d.ts +21 -1
- package/dist/html.d.ts.map +1 -1
- package/dist/html.js +10 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/navigation.d.ts +5 -0
- package/dist/navigation.d.ts.map +1 -1
- package/dist/navigation.js +5 -0
- package/dist/parser.d.ts +123 -2
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +91 -0
- package/dist/runtime/runtime.d.ts +18 -1
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +3 -3
- package/dist/runtime/urlRequest.d.ts +6 -0
- package/dist/runtime/urlRequest.d.ts.map +1 -1
- package/dist/runtime/urlRequest.js +3 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +1 -0
- package/dist/ui/tabs.d.ts +65 -0
- package/dist/ui/tabs.d.ts.map +1 -0
- package/dist/ui/tabs.js +140 -0
- package/dist/url.d.ts +3 -0
- package/dist/url.d.ts.map +1 -1
- package/dist/url.js +3 -0
- package/package.json +13 -3
package/dist/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,MAAM,EAGN,MAAM,EACN,MAAM,EAIP,MAAM,QAAQ,CAAA;AAEf,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;;;;AAE3B,qBAAa,UAAW,SAAQ,gBAA+B;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B,CAAC;CAAG;AAEL,
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
|
package/dist/parser.js
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import { Array, Data, Effect, Option, Predicate, Record, Schema, String, flow, pipe, } from 'effect';
|
|
2
|
+
/**
|
|
3
|
+
* Error type for route parsing failures.
|
|
4
|
+
*
|
|
5
|
+
* Includes optional `expected`, `actual`, and `position` fields for
|
|
6
|
+
* diagnostic context when a URL segment does not match.
|
|
7
|
+
*/
|
|
2
8
|
export class ParseError extends Data.TaggedError('ParseError') {
|
|
3
9
|
}
|
|
4
10
|
const makeTerminalParser = (parser) =>
|
|
5
11
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
6
12
|
parser;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a parser that matches an exact URL path segment.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* literal('users') // matches /users
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
7
21
|
export const literal = (segment) => ({
|
|
8
22
|
parse: (segments) => Array.matchLeft(segments, {
|
|
9
23
|
onEmpty: () => Effect.fail(new ParseError({
|
|
@@ -26,6 +40,13 @@ export const literal = (segment) => ({
|
|
|
26
40
|
segments: [...state.segments, segment],
|
|
27
41
|
}),
|
|
28
42
|
});
|
|
43
|
+
/**
|
|
44
|
+
* Creates a parser for a dynamic URL segment with custom parse and print functions.
|
|
45
|
+
*
|
|
46
|
+
* @param label - A descriptive name used in error messages.
|
|
47
|
+
* @param parse - Converts a raw URL segment string into the parsed value.
|
|
48
|
+
* @param print - Converts the parsed value back into a URL segment string.
|
|
49
|
+
*/
|
|
29
50
|
export const param = (label, parse, print) => ({
|
|
30
51
|
parse: (segments) => Array.matchLeft(segments, {
|
|
31
52
|
onEmpty: () => Effect.fail(new ParseError({
|
|
@@ -41,9 +62,27 @@ export const param = (label, parse, print) => ({
|
|
|
41
62
|
segments: [...state.segments, print(value)],
|
|
42
63
|
}),
|
|
43
64
|
});
|
|
65
|
+
/**
|
|
66
|
+
* Creates a parser that captures a URL segment as a named string field.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* string('slug') // parses /hello into { slug: "hello" }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
44
73
|
export const string = (name) => param(`string (${name})`,
|
|
45
74
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
46
75
|
(segment) => Effect.succeed({ [name]: segment }), (record) => record[name]);
|
|
76
|
+
/**
|
|
77
|
+
* Creates a parser that captures a URL segment as a named integer field.
|
|
78
|
+
*
|
|
79
|
+
* Fails if the segment is not a valid integer.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* int('id') // parses /42 into { id: 42 }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
47
86
|
export const int = (name) => param(`integer (${name})`, (segment) => {
|
|
48
87
|
const parsed = parseInt(segment, 10);
|
|
49
88
|
return isNaN(parsed) || parsed.toString() !== segment
|
|
@@ -55,6 +94,11 @@ export const int = (name) => param(`integer (${name})`, (segment) => {
|
|
|
55
94
|
: /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
56
95
|
Effect.succeed({ [name]: parsed });
|
|
57
96
|
}, (record) => record[name].toString());
|
|
97
|
+
/**
|
|
98
|
+
* A parser that matches the root path with no remaining segments.
|
|
99
|
+
*
|
|
100
|
+
* Succeeds only when the URL path is exactly `/`.
|
|
101
|
+
*/
|
|
58
102
|
export const root = {
|
|
59
103
|
parse: (segments) => Array.matchLeft(segments, {
|
|
60
104
|
onEmpty: () => Effect.succeed([{}, []]),
|
|
@@ -80,6 +124,18 @@ export function oneOf(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) {
|
|
|
80
124
|
}),
|
|
81
125
|
};
|
|
82
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Converts a `Biparser` into a `Router` by mapping parsed values to a
|
|
129
|
+
* tagged type constructor.
|
|
130
|
+
*
|
|
131
|
+
* The resulting `Router` can both parse URLs into tagged route values and
|
|
132
|
+
* build URLs from route payloads.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```ts
|
|
136
|
+
* pipe(literal('users'), slash(int('id')), mapTo(UserRoute))
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
83
139
|
export const mapTo = (appRouteConstructor) => {
|
|
84
140
|
return (parser) => {
|
|
85
141
|
return {
|
|
@@ -93,6 +149,16 @@ export const mapTo = (appRouteConstructor) => {
|
|
|
93
149
|
};
|
|
94
150
|
};
|
|
95
151
|
};
|
|
152
|
+
/**
|
|
153
|
+
* Composes two `Biparser`s sequentially, combining their parsed values.
|
|
154
|
+
*
|
|
155
|
+
* Cannot be used after `query` since query parameters are terminal.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* pipe(literal('users'), slash(int('id'))) // matches /users/42
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
96
162
|
export const slash = (parserB) => (parserA) => ({
|
|
97
163
|
parse: (segments, search) => pipe(parserA.parse(segments, search), Effect.flatMap(([valueA, remainingA]) => pipe(parserB.parse(remainingA, search), Effect.map(([valueB, remainingB]) => [
|
|
98
164
|
{ ...valueA, ...valueB },
|
|
@@ -100,6 +166,23 @@ export const slash = (parserB) => (parserA) => ({
|
|
|
100
166
|
])))),
|
|
101
167
|
print: (value, state) => pipe(parserA.print(value, state), Effect.flatMap((newState) => parserB.print(value, newState))),
|
|
102
168
|
});
|
|
169
|
+
/**
|
|
170
|
+
* Adds query parameter parsing to a `Biparser` using an Effect `Schema`.
|
|
171
|
+
*
|
|
172
|
+
* Produces a `TerminalParser` that cannot be extended with `slash`,
|
|
173
|
+
* since query parameters must appear at the end of a route definition.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* pipe(
|
|
178
|
+
* literal('search'),
|
|
179
|
+
* query(S.Struct({ q: S.String })),
|
|
180
|
+
* mapTo(SearchRoute),
|
|
181
|
+
* )
|
|
182
|
+
* ```
|
|
183
|
+
*
|
|
184
|
+
* @param schema - An Effect Schema describing the expected query parameters.
|
|
185
|
+
*/
|
|
103
186
|
export const query = (schema) => (parser) => {
|
|
104
187
|
const queryParser = {
|
|
105
188
|
parse: (segments, search) => {
|
|
@@ -148,6 +231,14 @@ const complete = ([value, remaining]) => Array.match(remaining, {
|
|
|
148
231
|
const parseUrl = (parser) => (url) => {
|
|
149
232
|
return pipe(pathToSegments(url.pathname), (segments) => parser.parse(segments, Option.getOrUndefined(url.search)), Effect.flatMap(complete));
|
|
150
233
|
};
|
|
234
|
+
/**
|
|
235
|
+
* Parses a URL against a parser, falling back to a not-found route if no
|
|
236
|
+
* parser matches.
|
|
237
|
+
*
|
|
238
|
+
* @param parser - The parser (typically from `oneOf`) to attempt.
|
|
239
|
+
* @param notFoundRouteConstructor - Constructor called with `{ path }` when
|
|
240
|
+
* no route matches.
|
|
241
|
+
*/
|
|
151
242
|
export const parseUrlWithFallback = (parser, notFoundRouteConstructor) => (url) => pipe(url, parseUrl(parser), Effect.orElse(() => Effect.succeed(notFoundRouteConstructor.make({ path: url.pathname }))), Effect.runSync);
|
|
152
243
|
const buildUrl = (parser) => (data) => {
|
|
153
244
|
const initialState = {
|
|
@@ -6,13 +6,17 @@ declare const Dispatch_base: Context.TagClass<Dispatch, "@foldkit/Dispatch", {
|
|
|
6
6
|
readonly dispatchAsync: (message: unknown) => Effect.Effect<void>;
|
|
7
7
|
readonly dispatchSync: (message: unknown) => void;
|
|
8
8
|
}>;
|
|
9
|
+
/** Effect service tag that provides message dispatching to the view layer. */
|
|
9
10
|
export declare class Dispatch extends Dispatch_base {
|
|
10
11
|
}
|
|
12
|
+
/** An `Effect` that produces a message, used for side effects in the update function. */
|
|
11
13
|
export type Command<Message> = Effect.Effect<Message>;
|
|
14
|
+
/** Configuration for browser URL integration with handlers for URL requests and URL changes. */
|
|
12
15
|
export type BrowserConfig<Message> = {
|
|
13
16
|
readonly onUrlRequest: (request: UrlRequest) => Message;
|
|
14
17
|
readonly onUrlChange: (url: Url) => Message;
|
|
15
18
|
};
|
|
19
|
+
/** Full runtime configuration including model schema, flags, init, update, view, and optional browser/stream config. */
|
|
16
20
|
export interface RuntimeConfig<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags> {
|
|
17
21
|
Model: Schema.Schema<Model, any, never>;
|
|
18
22
|
Flags: Schema.Schema<Flags, any, never>;
|
|
@@ -33,11 +37,13 @@ interface BaseElementConfig<Model, Message, StreamDepsMap extends Schema.Struct<
|
|
|
33
37
|
readonly container: HTMLElement;
|
|
34
38
|
readonly errorView?: (error: Error) => Html;
|
|
35
39
|
}
|
|
40
|
+
/** Configuration for `makeElement` when the element receives initial data via flags. */
|
|
36
41
|
export interface ElementConfigWithFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags> extends BaseElementConfig<Model, Message, StreamDepsMap> {
|
|
37
42
|
readonly Flags: Schema.Schema<Flags, any, never>;
|
|
38
43
|
readonly flags: Effect.Effect<Flags>;
|
|
39
44
|
readonly init: (flags: Flags) => [Model, ReadonlyArray<Command<Message>>];
|
|
40
45
|
}
|
|
46
|
+
/** Configuration for `makeElement` without flags. */
|
|
41
47
|
export interface ElementConfigWithoutFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>> extends BaseElementConfig<Model, Message, StreamDepsMap> {
|
|
42
48
|
readonly init: () => [Model, ReadonlyArray<Command<Message>>];
|
|
43
49
|
}
|
|
@@ -50,16 +56,21 @@ interface BaseApplicationConfig<Model, Message, StreamDepsMap extends Schema.Str
|
|
|
50
56
|
readonly browser: BrowserConfig<Message>;
|
|
51
57
|
readonly errorView?: (error: Error) => Html;
|
|
52
58
|
}
|
|
59
|
+
/** Configuration for `makeApplication` when the application receives initial data via flags. */
|
|
53
60
|
export interface ApplicationConfigWithFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags> extends BaseApplicationConfig<Model, Message, StreamDepsMap> {
|
|
54
61
|
readonly Flags: Schema.Schema<Flags, any, never>;
|
|
55
62
|
readonly flags: Effect.Effect<Flags>;
|
|
56
63
|
readonly init: (flags: Flags, url: Url) => [Model, ReadonlyArray<Command<Message>>];
|
|
57
64
|
}
|
|
65
|
+
/** Configuration for `makeApplication` without flags. */
|
|
58
66
|
export interface ApplicationConfigWithoutFlags<Model, Message, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>> extends BaseApplicationConfig<Model, Message, StreamDepsMap> {
|
|
59
67
|
readonly init: (url: Url) => [Model, ReadonlyArray<Command<Message>>];
|
|
60
68
|
}
|
|
69
|
+
/** The `init` function type for elements, with an optional `flags` parameter when `Flags` is not `void`. */
|
|
61
70
|
export type ElementInit<Model, Message, Flags = void> = Flags extends void ? () => [Model, ReadonlyArray<Command<Message>>] : (flags: Flags) => [Model, ReadonlyArray<Command<Message>>];
|
|
71
|
+
/** The `init` function type for applications, receives the current URL and optional flags. */
|
|
62
72
|
export type ApplicationInit<Model, Message, Flags = void> = Flags extends void ? (url: Url) => [Model, ReadonlyArray<Command<Message>>] : (flags: Flags, url: Url) => [Model, ReadonlyArray<Command<Message>>];
|
|
73
|
+
/** A reactive stream configuration that maps model changes to a stream of commands. */
|
|
63
74
|
export type CommandStream<Model, Message, StreamDeps> = {
|
|
64
75
|
readonly modelToDeps: (model: Model) => StreamDeps;
|
|
65
76
|
readonly depsToStream: (deps: StreamDeps) => Stream.Stream<Command<Message>>;
|
|
@@ -67,9 +78,11 @@ export type CommandStream<Model, Message, StreamDeps> = {
|
|
|
67
78
|
type CommandStreamConfig<Model, Message, StreamDeps> = {
|
|
68
79
|
readonly schema: Schema.Schema<StreamDeps>;
|
|
69
80
|
} & CommandStream<Model, Message, StreamDeps>;
|
|
81
|
+
/** A record of named command stream configurations, keyed by dependency field name. */
|
|
70
82
|
export type CommandStreams<Model, Message, CommandStreamsDeps extends Schema.Struct<any>> = {
|
|
71
83
|
readonly [K in keyof Schema.Schema.Type<CommandStreamsDeps>]: CommandStreamConfig<Model, Message, Schema.Schema.Type<CommandStreamsDeps>[K]>;
|
|
72
84
|
};
|
|
85
|
+
/** Creates type-safe command stream configurations from a dependency schema. */
|
|
73
86
|
export declare const makeCommandStreams: <CommandStreamsDeps extends Schema.Struct<any>>(CommandStreamsDeps: CommandStreamsDeps) => <Model, Message>(configs: { [K in keyof Schema.Schema.Type<CommandStreamsDeps>]: {
|
|
74
87
|
modelToDeps: (model: Model) => Schema.Schema.Type<CommandStreamsDeps>[K];
|
|
75
88
|
depsToStream: (deps: Schema.Schema.Type<CommandStreamsDeps>[K]) => Stream.Stream<Command<Message>>;
|
|
@@ -78,19 +91,23 @@ export declare const makeCommandStreams: <CommandStreamsDeps extends Schema.Stru
|
|
|
78
91
|
modelToDeps: (model: Model) => Schema.Schema.Type<CommandStreamsDeps>[K];
|
|
79
92
|
depsToStream: (deps: Schema.Schema.Type<CommandStreamsDeps>[K]) => Stream.Stream<Command<Message>>;
|
|
80
93
|
}>;
|
|
81
|
-
|
|
94
|
+
/** A configured Foldkit runtime returned by `makeElement` or `makeApplication`, passed to `run` to start the application. */
|
|
95
|
+
export type MakeRuntimeReturn = (hmrModel?: unknown) => Effect.Effect<void>;
|
|
96
|
+
/** Creates a Foldkit element (no URL routing) and returns a runtime that can be passed to `run`. */
|
|
82
97
|
export declare function makeElement<Model, Message extends {
|
|
83
98
|
_tag: string;
|
|
84
99
|
}, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags>(config: ElementConfigWithFlags<Model, Message, StreamDepsMap, Flags>): MakeRuntimeReturn;
|
|
85
100
|
export declare function makeElement<Model, Message extends {
|
|
86
101
|
_tag: string;
|
|
87
102
|
}, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>>(config: ElementConfigWithoutFlags<Model, Message, StreamDepsMap>): MakeRuntimeReturn;
|
|
103
|
+
/** Creates a Foldkit application with URL routing and returns a runtime that can be passed to `run`. */
|
|
88
104
|
export declare function makeApplication<Model, Message extends {
|
|
89
105
|
_tag: string;
|
|
90
106
|
}, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>, Flags>(config: ApplicationConfigWithFlags<Model, Message, StreamDepsMap, Flags>): MakeRuntimeReturn;
|
|
91
107
|
export declare function makeApplication<Model, Message extends {
|
|
92
108
|
_tag: string;
|
|
93
109
|
}, StreamDepsMap extends Schema.Struct<Schema.Struct.Fields>>(config: ApplicationConfigWithoutFlags<Model, Message, StreamDepsMap>): MakeRuntimeReturn;
|
|
110
|
+
/** Starts a Foldkit runtime, with HMR support for development. */
|
|
94
111
|
export declare const run: (foldkitRuntime: MakeRuntimeReturn) => void;
|
|
95
112
|
export {};
|
|
96
113
|
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,OAAO,EACP,MAAM,EASN,MAAM,EACN,MAAM,EAGP,MAAM,QAAQ,CAAA;AAGf,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC9B,OAAO,EAAE,GAAG,EAA+B,MAAM,QAAQ,CAAA;AAOzD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/runtime.js
CHANGED
|
@@ -5,8 +5,10 @@ import { fromString as urlFromString } from '../url';
|
|
|
5
5
|
import { patch, toVNode } from '../vdom';
|
|
6
6
|
import { addBfcacheRestoreListener, addNavigationEventListeners, } from './browserListeners';
|
|
7
7
|
import { defaultErrorView, noOpDispatch } from './errorUI';
|
|
8
|
+
/** Effect service tag that provides message dispatching to the view layer. */
|
|
8
9
|
export class Dispatch extends Context.Tag('@foldkit/Dispatch')() {
|
|
9
10
|
}
|
|
11
|
+
/** Creates type-safe command stream configurations from a dependency schema. */
|
|
10
12
|
export const makeCommandStreams = (CommandStreamsDeps) => (configs) => Record.map(configs, ({ modelToDeps, depsToStream }, key) => ({
|
|
11
13
|
schema: CommandStreamsDeps.fields[key],
|
|
12
14
|
modelToDeps,
|
|
@@ -183,9 +185,7 @@ const preserveModel = (model) => {
|
|
|
183
185
|
import.meta.hot.send('foldkit:preserve-model', model);
|
|
184
186
|
}
|
|
185
187
|
};
|
|
186
|
-
|
|
187
|
-
* Run a Foldkit application
|
|
188
|
-
*/
|
|
188
|
+
/** Starts a Foldkit runtime, with HMR support for development. */
|
|
189
189
|
export const run = (foldkitRuntime) => {
|
|
190
190
|
if (import.meta.hot) {
|
|
191
191
|
import.meta.hot.on('foldkit:restore-model', (model) => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Schema as S } from 'effect';
|
|
2
|
+
/** A URL request to a page within the application (same origin). */
|
|
2
3
|
export declare const Internal: S.TaggedStruct<"Internal", {
|
|
3
4
|
url: S.Struct<{
|
|
4
5
|
protocol: typeof S.String;
|
|
@@ -9,11 +10,15 @@ export declare const Internal: S.TaggedStruct<"Internal", {
|
|
|
9
10
|
hash: S.OptionFromSelf<typeof S.String>;
|
|
10
11
|
}>;
|
|
11
12
|
}>;
|
|
13
|
+
/** A URL request to a page within the application (same origin). */
|
|
12
14
|
export type Internal = typeof Internal.Type;
|
|
15
|
+
/** A URL request to an external page (different origin). */
|
|
13
16
|
export declare const External: S.TaggedStruct<"External", {
|
|
14
17
|
href: typeof S.String;
|
|
15
18
|
}>;
|
|
19
|
+
/** A URL request to an external page (different origin). */
|
|
16
20
|
export type External = typeof External.Type;
|
|
21
|
+
/** Union of `Internal` and `External` URL request types. */
|
|
17
22
|
export declare const UrlRequest: S.Union<[S.TaggedStruct<"Internal", {
|
|
18
23
|
url: S.Struct<{
|
|
19
24
|
protocol: typeof S.String;
|
|
@@ -26,5 +31,6 @@ export declare const UrlRequest: S.Union<[S.TaggedStruct<"Internal", {
|
|
|
26
31
|
}>, S.TaggedStruct<"External", {
|
|
27
32
|
href: typeof S.String;
|
|
28
33
|
}>]>;
|
|
34
|
+
/** Union of `Internal` and `External` URL request types. */
|
|
29
35
|
export type UrlRequest = typeof UrlRequest.Type;
|
|
30
36
|
//# sourceMappingURL=urlRequest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urlRequest.d.ts","sourceRoot":"","sources":["../../src/runtime/urlRequest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAIpC,eAAO,MAAM,QAAQ;;;;;;;;;EAEnB,CAAA;AACF,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAA;AAE3C,eAAO,MAAM,QAAQ;;EAEnB,CAAA;AACF,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAA;AAE3C,eAAO,MAAM,UAAU;;;;;;;;;;;IAA8B,CAAA;AACrD,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA"}
|
|
1
|
+
{"version":3,"file":"urlRequest.d.ts","sourceRoot":"","sources":["../../src/runtime/urlRequest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAIpC,oEAAoE;AACpE,eAAO,MAAM,QAAQ;;;;;;;;;EAEnB,CAAA;AACF,oEAAoE;AACpE,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAA;AAE3C,4DAA4D;AAC5D,eAAO,MAAM,QAAQ;;EAEnB,CAAA;AACF,4DAA4D;AAC5D,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAA;AAE3C,4DAA4D;AAC5D,eAAO,MAAM,UAAU;;;;;;;;;;;IAA8B,CAAA;AACrD,4DAA4D;AAC5D,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { Schema as S } from 'effect';
|
|
2
2
|
import { Url } from '../url';
|
|
3
|
+
/** A URL request to a page within the application (same origin). */
|
|
3
4
|
export const Internal = S.TaggedStruct('Internal', {
|
|
4
5
|
url: Url,
|
|
5
6
|
});
|
|
7
|
+
/** A URL request to an external page (different origin). */
|
|
6
8
|
export const External = S.TaggedStruct('External', {
|
|
7
9
|
href: S.String,
|
|
8
10
|
});
|
|
11
|
+
/** Union of `Internal` and `External` URL request types. */
|
|
9
12
|
export const UrlRequest = S.Union(Internal, External);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAA"}
|
package/dist/ui/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Tabs from './tabs';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Schema as S } from 'effect';
|
|
2
|
+
import type { Html, TagName } from '../html';
|
|
3
|
+
import type { Command } from '../runtime/runtime';
|
|
4
|
+
export declare const Orientation: S.Literal<["Horizontal", "Vertical"]>;
|
|
5
|
+
export type Orientation = typeof Orientation.Type;
|
|
6
|
+
export declare const ActivationMode: S.Literal<["Automatic", "Manual"]>;
|
|
7
|
+
export type ActivationMode = typeof ActivationMode.Type;
|
|
8
|
+
export declare const Model: S.Struct<{
|
|
9
|
+
id: typeof S.String;
|
|
10
|
+
activeIndex: typeof S.Number;
|
|
11
|
+
focusedIndex: typeof S.Number;
|
|
12
|
+
orientation: S.Literal<["Horizontal", "Vertical"]>;
|
|
13
|
+
activationMode: S.Literal<["Automatic", "Manual"]>;
|
|
14
|
+
}>;
|
|
15
|
+
export type Model = typeof Model.Type;
|
|
16
|
+
export declare const TabSelected: S.TaggedStruct<"TabSelected", {
|
|
17
|
+
index: typeof S.Number;
|
|
18
|
+
}>;
|
|
19
|
+
export declare const TabFocused: S.TaggedStruct<"TabFocused", {
|
|
20
|
+
index: typeof S.Number;
|
|
21
|
+
}>;
|
|
22
|
+
export declare const NoOp: S.TaggedStruct<"NoOp", {}>;
|
|
23
|
+
export declare const Message: S.Union<[S.TaggedStruct<"TabSelected", {
|
|
24
|
+
index: typeof S.Number;
|
|
25
|
+
}>, S.TaggedStruct<"TabFocused", {
|
|
26
|
+
index: typeof S.Number;
|
|
27
|
+
}>, S.TaggedStruct<"NoOp", {}>]>;
|
|
28
|
+
export type TabSelected = typeof TabSelected.Type;
|
|
29
|
+
export type TabFocused = typeof TabFocused.Type;
|
|
30
|
+
export type NoOp = typeof NoOp.Type;
|
|
31
|
+
export type Message = typeof Message.Type;
|
|
32
|
+
export type InitConfig = {
|
|
33
|
+
readonly id: string;
|
|
34
|
+
readonly activeIndex?: number;
|
|
35
|
+
readonly orientation?: Orientation;
|
|
36
|
+
readonly activationMode?: ActivationMode;
|
|
37
|
+
};
|
|
38
|
+
export declare const init: (config: InitConfig) => Model;
|
|
39
|
+
export declare const update: (model: Model, message: Message) => [Model, ReadonlyArray<Command<Message>>];
|
|
40
|
+
export type TabConfig = {
|
|
41
|
+
readonly buttonClassName: string;
|
|
42
|
+
readonly buttonContent: Html;
|
|
43
|
+
readonly panelClassName: string;
|
|
44
|
+
readonly panelContent: Html;
|
|
45
|
+
};
|
|
46
|
+
export type ViewConfig<Message, Tab extends string> = {
|
|
47
|
+
readonly model: Model;
|
|
48
|
+
readonly toMessage: (message: TabSelected | TabFocused | NoOp) => Message;
|
|
49
|
+
readonly tabs: ReadonlyArray<Tab>;
|
|
50
|
+
readonly tabToConfig: (tab: Tab, context: {
|
|
51
|
+
isActive: boolean;
|
|
52
|
+
}) => TabConfig;
|
|
53
|
+
readonly isTabDisabled?: (tab: Tab, index: number) => boolean;
|
|
54
|
+
readonly persistPanels?: boolean;
|
|
55
|
+
readonly tabListElement?: TagName;
|
|
56
|
+
readonly tabElement?: TagName;
|
|
57
|
+
readonly panelElement?: TagName;
|
|
58
|
+
readonly className?: string;
|
|
59
|
+
readonly tabListClassName?: string;
|
|
60
|
+
};
|
|
61
|
+
export declare const wrapIndex: (index: number, length: number) => number;
|
|
62
|
+
export declare const findFirstEnabledIndex: (tabCount: number, focusedIndex: number, isDisabled: (index: number) => boolean) => (startIndex: number, direction: 1 | -1) => number;
|
|
63
|
+
export declare const keyToIndex: (nextKey: string, previousKey: string, tabCount: number, focusedIndex: number, isDisabled: (index: number) => boolean) => ((key: string) => number);
|
|
64
|
+
export declare const view: <Message, Tab extends string>(config: ViewConfig<Message, Tab>) => Html;
|
|
65
|
+
//# sourceMappingURL=tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/ui/tabs.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/tabs.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { Array, Match as M, Option, Predicate, Schema as S, String, pipe, } from 'effect';
|
|
2
|
+
import { html } from '../html';
|
|
3
|
+
import { ts } from '../schema';
|
|
4
|
+
import { evo } from '../struct';
|
|
5
|
+
import * as Task from '../task';
|
|
6
|
+
// MODEL
|
|
7
|
+
export const Orientation = S.Literal('Horizontal', 'Vertical');
|
|
8
|
+
export const ActivationMode = S.Literal('Automatic', 'Manual');
|
|
9
|
+
export const Model = S.Struct({
|
|
10
|
+
id: S.String,
|
|
11
|
+
activeIndex: S.Number,
|
|
12
|
+
focusedIndex: S.Number,
|
|
13
|
+
orientation: Orientation,
|
|
14
|
+
activationMode: ActivationMode,
|
|
15
|
+
});
|
|
16
|
+
// MESSAGE
|
|
17
|
+
export const TabSelected = ts('TabSelected', { index: S.Number });
|
|
18
|
+
export const TabFocused = ts('TabFocused', { index: S.Number });
|
|
19
|
+
export const NoOp = ts('NoOp');
|
|
20
|
+
export const Message = S.Union(TabSelected, TabFocused, NoOp);
|
|
21
|
+
export const init = (config) => {
|
|
22
|
+
const activeIndex = config.activeIndex ?? 0;
|
|
23
|
+
return {
|
|
24
|
+
id: config.id,
|
|
25
|
+
activeIndex,
|
|
26
|
+
focusedIndex: activeIndex,
|
|
27
|
+
orientation: config.orientation ?? 'Horizontal',
|
|
28
|
+
activationMode: config.activationMode ?? 'Automatic',
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
// UPDATE
|
|
32
|
+
export const update = (model, message) => M.value(message).pipe(M.withReturnType(), M.tagsExhaustive({
|
|
33
|
+
TabSelected: ({ index }) => {
|
|
34
|
+
const tabSelector = `#${tabId(model.id, index)}`;
|
|
35
|
+
return [
|
|
36
|
+
evo(model, {
|
|
37
|
+
activeIndex: () => index,
|
|
38
|
+
focusedIndex: () => index,
|
|
39
|
+
}),
|
|
40
|
+
[Task.focus(tabSelector, () => NoOp.make())],
|
|
41
|
+
];
|
|
42
|
+
},
|
|
43
|
+
TabFocused: ({ index }) => {
|
|
44
|
+
const tabSelector = `#${tabId(model.id, index)}`;
|
|
45
|
+
return [
|
|
46
|
+
evo(model, { focusedIndex: () => index }),
|
|
47
|
+
[Task.focus(tabSelector, () => NoOp.make())],
|
|
48
|
+
];
|
|
49
|
+
},
|
|
50
|
+
NoOp: () => [model, []],
|
|
51
|
+
}));
|
|
52
|
+
const tabPanelId = (id, index) => `${id}-panel-${index}`;
|
|
53
|
+
const tabId = (id, index) => `${id}-tab-${index}`;
|
|
54
|
+
export const wrapIndex = (index, length) => ((index % length) + length) % length;
|
|
55
|
+
export const findFirstEnabledIndex = (tabCount, focusedIndex, isDisabled) => (startIndex, direction) => pipe(tabCount, Array.makeBy((step) => wrapIndex(startIndex + step * direction, tabCount)), Array.findFirst(Predicate.not(isDisabled)), Option.getOrElse(() => focusedIndex));
|
|
56
|
+
export const keyToIndex = (nextKey, previousKey, tabCount, focusedIndex, isDisabled) => {
|
|
57
|
+
const find = findFirstEnabledIndex(tabCount, focusedIndex, isDisabled);
|
|
58
|
+
return (key) => M.value(key).pipe(M.when(nextKey, () => find(focusedIndex + 1, 1)), M.when(previousKey, () => find(focusedIndex - 1, -1)), M.whenOr('Home', 'PageUp', () => find(0, 1)), M.whenOr('End', 'PageDown', () => find(tabCount - 1, -1)), M.orElse(() => focusedIndex));
|
|
59
|
+
};
|
|
60
|
+
export const view = (config) => {
|
|
61
|
+
const { div, empty, AriaControls, AriaDisabled, AriaLabelledBy, AriaOrientation, AriaSelected, Class, DataAttribute, Disabled, Hidden, Id, OnClick, OnKeyDown, Role, Tabindex, Type, keyed, } = html();
|
|
62
|
+
const { model, model: { id, orientation, activationMode, focusedIndex }, toMessage, tabs, tabToConfig, isTabDisabled, persistPanels, tabListElement = 'div', tabElement = 'button', panelElement = 'div', className, tabListClassName, } = config;
|
|
63
|
+
const isDisabled = (index) => !!isTabDisabled &&
|
|
64
|
+
pipe(tabs, Array.get(index), Option.exists((tab) => isTabDisabled(tab, index)));
|
|
65
|
+
const { nextKey, previousKey } = M.value(orientation).pipe(M.when('Horizontal', () => ({
|
|
66
|
+
nextKey: 'ArrowRight',
|
|
67
|
+
previousKey: 'ArrowLeft',
|
|
68
|
+
})), M.when('Vertical', () => ({
|
|
69
|
+
nextKey: 'ArrowDown',
|
|
70
|
+
previousKey: 'ArrowUp',
|
|
71
|
+
})), M.exhaustive);
|
|
72
|
+
const resolveKeyIndex = keyToIndex(nextKey, previousKey, tabs.length, focusedIndex, isDisabled);
|
|
73
|
+
const handleAutomaticKeyDown = (key) =>
|
|
74
|
+
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
75
|
+
M.value(key).pipe(M.whenOr(nextKey, previousKey, 'Home', 'End', 'PageUp', 'PageDown', () => toMessage(TabSelected.make({ index: resolveKeyIndex(key) }))), M.whenOr('Enter', ' ', () => toMessage(TabSelected.make({ index: focusedIndex }))), M.orElse(() => toMessage(NoOp.make())));
|
|
76
|
+
const handleManualKeyDown = (key) =>
|
|
77
|
+
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
78
|
+
M.value(key).pipe(M.whenOr(nextKey, previousKey, 'Home', 'End', 'PageUp', 'PageDown', () => toMessage(TabFocused.make({ index: resolveKeyIndex(key) }))), M.whenOr('Enter', ' ', () => toMessage(TabSelected.make({ index: focusedIndex }))), M.orElse(() => toMessage(NoOp.make())));
|
|
79
|
+
const handleKeyDown = (key) =>
|
|
80
|
+
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
81
|
+
M.value(activationMode).pipe(M.when('Automatic', () => handleAutomaticKeyDown(key)), M.when('Manual', () => handleManualKeyDown(key)), M.exhaustive);
|
|
82
|
+
const tabButtons = Array.map(tabs, (tab, index) => {
|
|
83
|
+
const isActive = index === model.activeIndex;
|
|
84
|
+
const isFocused = index === focusedIndex;
|
|
85
|
+
const isTabDisabledAtIndex = isDisabled(index);
|
|
86
|
+
const tabConfig = tabToConfig(tab, { isActive });
|
|
87
|
+
return keyed(tabElement)(tabId(id, index), [
|
|
88
|
+
Class(tabConfig.buttonClassName),
|
|
89
|
+
Id(tabId(id, index)),
|
|
90
|
+
Role('tab'),
|
|
91
|
+
Type('button'),
|
|
92
|
+
AriaSelected(isActive),
|
|
93
|
+
AriaControls(tabPanelId(id, index)),
|
|
94
|
+
Tabindex(isFocused ? 0 : -1),
|
|
95
|
+
...(isActive ? [DataAttribute('selected', '')] : []),
|
|
96
|
+
...(isTabDisabledAtIndex
|
|
97
|
+
? [Disabled(true), AriaDisabled(true), DataAttribute('disabled', '')]
|
|
98
|
+
: [OnClick(toMessage(TabSelected.make({ index })))]),
|
|
99
|
+
OnKeyDown(handleKeyDown),
|
|
100
|
+
], [tabConfig.buttonContent]);
|
|
101
|
+
});
|
|
102
|
+
const allPanels = Array.map(tabs, (tab, index) => {
|
|
103
|
+
const isActive = index === model.activeIndex;
|
|
104
|
+
const panelConfig = tabToConfig(tab, { isActive });
|
|
105
|
+
return keyed(panelElement)(tabPanelId(id, index), [
|
|
106
|
+
Class(panelConfig.panelClassName),
|
|
107
|
+
Id(tabPanelId(id, index)),
|
|
108
|
+
Role('tabpanel'),
|
|
109
|
+
AriaLabelledBy(tabId(id, index)),
|
|
110
|
+
Tabindex(isActive ? 0 : -1),
|
|
111
|
+
Hidden(!isActive),
|
|
112
|
+
...(isActive ? [DataAttribute('selected', '')] : []),
|
|
113
|
+
], [panelConfig.panelContent]);
|
|
114
|
+
});
|
|
115
|
+
const activePanelOnly = pipe(tabs, Array.get(model.activeIndex), Option.match({
|
|
116
|
+
onNone: () => empty,
|
|
117
|
+
onSome: (tab) => {
|
|
118
|
+
const activeConfig = tabToConfig(tab, { isActive: true });
|
|
119
|
+
return keyed(panelElement)(tabPanelId(id, model.activeIndex), [
|
|
120
|
+
Class(activeConfig.panelClassName),
|
|
121
|
+
Id(tabPanelId(id, model.activeIndex)),
|
|
122
|
+
Role('tabpanel'),
|
|
123
|
+
AriaLabelledBy(tabId(id, model.activeIndex)),
|
|
124
|
+
Tabindex(0),
|
|
125
|
+
DataAttribute('selected', ''),
|
|
126
|
+
], [activeConfig.panelContent]);
|
|
127
|
+
},
|
|
128
|
+
}));
|
|
129
|
+
const tabPanels = persistPanels ? allPanels : [activePanelOnly];
|
|
130
|
+
const tabListAttributes = [
|
|
131
|
+
Role('tablist'),
|
|
132
|
+
AriaOrientation(String.toLowerCase(orientation)),
|
|
133
|
+
...(tabListClassName ? [Class(tabListClassName)] : []),
|
|
134
|
+
];
|
|
135
|
+
const wrapperAttributes = className ? [Class(className)] : [];
|
|
136
|
+
return div(wrapperAttributes, [
|
|
137
|
+
keyed(tabListElement)(`${id}-tablist`, tabListAttributes, tabButtons),
|
|
138
|
+
...tabPanels,
|
|
139
|
+
]);
|
|
140
|
+
};
|
package/dist/url.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Option, Schema as S } from 'effect';
|
|
2
|
+
/** Schema representing a parsed URL with protocol, host, port, pathname, search, and hash fields. */
|
|
2
3
|
export declare const Url: S.Struct<{
|
|
3
4
|
protocol: typeof S.String;
|
|
4
5
|
host: typeof S.String;
|
|
@@ -8,6 +9,7 @@ export declare const Url: S.Struct<{
|
|
|
8
9
|
hash: S.OptionFromSelf<typeof S.String>;
|
|
9
10
|
}>;
|
|
10
11
|
export type Url = typeof Url.Type;
|
|
12
|
+
/** Parses a URL string into a `Url`, returning `Option.None` if invalid. */
|
|
11
13
|
export declare const fromString: (str: string) => Option.Option<{
|
|
12
14
|
readonly protocol: string;
|
|
13
15
|
readonly host: string;
|
|
@@ -16,5 +18,6 @@ export declare const fromString: (str: string) => Option.Option<{
|
|
|
16
18
|
readonly search: Option.Option<string>;
|
|
17
19
|
readonly hash: Option.Option<string>;
|
|
18
20
|
}>;
|
|
21
|
+
/** Serializes a `Url` back to a string. */
|
|
19
22
|
export declare const toString: (url: Url) => string;
|
|
20
23
|
//# sourceMappingURL=url.d.ts.map
|
package/dist/url.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,EAAe,MAAM,IAAI,CAAC,EAAU,MAAM,QAAQ,CAAA;AAIzE,eAAO,MAAM,GAAG;;;;;;;EAOd,CAAA;AACF,MAAM,MAAM,GAAG,GAAG,OAAO,GAAG,CAAC,IAAI,CAAA;AA+EjC,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM;;;;;;;EAAuC,CAAA;AAC7E,eAAO,MAAM,QAAQ,GAAI,KAAK,GAAG,WAAqC,CAAA"}
|
|
1
|
+
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,EAAe,MAAM,IAAI,CAAC,EAAU,MAAM,QAAQ,CAAA;AAIzE,qGAAqG;AACrG,eAAO,MAAM,GAAG;;;;;;;EAOd,CAAA;AACF,MAAM,MAAM,GAAG,GAAG,OAAO,GAAG,CAAC,IAAI,CAAA;AA+EjC,4EAA4E;AAC5E,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM;;;;;;;EAAuC,CAAA;AAC7E,2CAA2C;AAC3C,eAAO,MAAM,QAAQ,GAAI,KAAK,GAAG,WAAqC,CAAA"}
|