@unabridged/midwest 0.26.0 → 0.27.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 +1 -1
- package/app/assets/javascript/midwest/async_runtime.ts +90 -0
- package/app/assets/javascript/midwest.js +16 -16
- package/app/assets/javascript/midwest.js.map +1 -1
- package/app/assets/stylesheets/midwest/tailwind.css +39 -69
- package/app/assets/stylesheets/midwest/tailwind.theme.css +68 -0
- package/app/assets/stylesheets/midwest.css +1 -1
- package/app/assets/stylesheets/midwest.tailwind.css +15 -1
- package/dist/css/midwest.css +1 -1
- package/dist/javascript/collection/app/components/midwest/assets_component/assets_component_controller.js +16 -16
- package/dist/javascript/collection/app/components/midwest/assets_component/assets_component_controller.js.map +1 -1
- package/dist/javascript/midwest.js +16 -16
- package/dist/javascript/midwest.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://github.com/unabridged/midwest/actions/workflows/rails-tests.yml)
|
|
4
4
|
[](https://github.com/unabridged/midwest/actions/workflows/bridgetown-tests.yml)
|
|
5
5
|
[](https://github.com/unabridged/midwest/actions/workflows/ci.yml)
|
|
6
|
-
[](https://github.com/unabridged/midwest/actions/workflows/ci.yml)
|
|
7
7
|
|
|
8
8
|
Midwest Component Library is an implementation of the Midwest Design System using [ViewComponent](https://github.com/github/view_component).
|
|
9
9
|
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Shared runtime for the async (per-component) JS build.
|
|
2
|
+
//
|
|
3
|
+
// In bundled mode every controller is registered up front by
|
|
4
|
+
// `registerMidwestControllers(application)`. In async mode each component's
|
|
5
|
+
// module is fetched on its own, whenever that component first appears on a
|
|
6
|
+
// page — which may be long before or long after the host application calls
|
|
7
|
+
// `Application.start()`. So registration cannot assume an application exists
|
|
8
|
+
// yet: anything that arrives early is queued and flushed once one does.
|
|
9
|
+
//
|
|
10
|
+
// Wiring, for a host app that follows the Rails convention of exposing its
|
|
11
|
+
// instance as `window.Stimulus`, is nothing — the runtime adopts it. Otherwise:
|
|
12
|
+
//
|
|
13
|
+
// import { Application } from '@hotwired/stimulus'
|
|
14
|
+
// const application = Application.start()
|
|
15
|
+
// window.Midwest.useApplication(application)
|
|
16
|
+
//
|
|
17
|
+
// See ASYNC_ASSETS.md §6.2.
|
|
18
|
+
|
|
19
|
+
type ControllerConstructor = unknown
|
|
20
|
+
|
|
21
|
+
interface StimulusApplication {
|
|
22
|
+
register: (identifier: string, controllerConstructor: ControllerConstructor) => void
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface MidwestRuntime {
|
|
26
|
+
register: (identifier: string, controllerConstructor: ControllerConstructor) => void
|
|
27
|
+
useApplication: (application: StimulusApplication) => void
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare global {
|
|
31
|
+
interface Window {
|
|
32
|
+
Stimulus?: StimulusApplication
|
|
33
|
+
Midwest?: MidwestRuntime
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const pending: [string, ControllerConstructor][] = []
|
|
38
|
+
const registered = new Set<string>()
|
|
39
|
+
let application: StimulusApplication | null = null
|
|
40
|
+
|
|
41
|
+
// Idempotent by identifier: a component's module can legitimately be requested
|
|
42
|
+
// twice (a Turbo Frame carrying a component the page already had), and while
|
|
43
|
+
// the browser's module map means it only *executes* once per URL, a rebuilt
|
|
44
|
+
// file with a new hash is a different URL and would execute again.
|
|
45
|
+
export function register (identifier: string, controllerConstructor: ControllerConstructor): void {
|
|
46
|
+
if (registered.has(identifier)) return
|
|
47
|
+
registered.add(identifier)
|
|
48
|
+
|
|
49
|
+
if (application) {
|
|
50
|
+
application.register(identifier, controllerConstructor)
|
|
51
|
+
} else {
|
|
52
|
+
pending.push([identifier, controllerConstructor])
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function useApplication (app: StimulusApplication): void {
|
|
57
|
+
application = app
|
|
58
|
+
while (pending.length > 0) {
|
|
59
|
+
const [identifier, controllerConstructor] = pending.shift() as [string, ControllerConstructor]
|
|
60
|
+
app.register(identifier, controllerConstructor)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Adoption has to cope with either order, and the common one is the awkward
|
|
65
|
+
// one: `midwest_asset_tags` sits in <head>, so Midwest's modules are usually
|
|
66
|
+
// parsed — and executed — BEFORE the application's own Stimulus boot. Checking
|
|
67
|
+
// `window.Stimulus` once at load time therefore finds nothing, queues every
|
|
68
|
+
// controller, and never flushes. Nothing errors; the page is simply inert.
|
|
69
|
+
//
|
|
70
|
+
// So when there is no application yet, watch the property for one being
|
|
71
|
+
// assigned. Rails' convention of `window.Stimulus = Application.start()` then
|
|
72
|
+
// wires everything up on its own, whichever script happens to run first.
|
|
73
|
+
if (typeof window !== 'undefined') {
|
|
74
|
+
window.Midwest = { register, useApplication }
|
|
75
|
+
|
|
76
|
+
if (window.Stimulus) {
|
|
77
|
+
useApplication(window.Stimulus)
|
|
78
|
+
} else {
|
|
79
|
+
let assigned: StimulusApplication | undefined
|
|
80
|
+
Object.defineProperty(window, 'Stimulus', {
|
|
81
|
+
configurable: true,
|
|
82
|
+
enumerable: true,
|
|
83
|
+
get: () => assigned,
|
|
84
|
+
set (value: StimulusApplication) {
|
|
85
|
+
assigned = value
|
|
86
|
+
if (value) useApplication(value)
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -9428,21 +9428,19 @@ class SplitView extends Controller {
|
|
|
9428
9428
|
|
|
9429
9429
|
class Assets extends Controller {
|
|
9430
9430
|
static values = {
|
|
9431
|
-
css:
|
|
9432
|
-
js:
|
|
9431
|
+
css: Array,
|
|
9432
|
+
js: Array
|
|
9433
9433
|
};
|
|
9434
9434
|
connect() {
|
|
9435
|
-
|
|
9436
|
-
this.ensureStylesheet(
|
|
9437
|
-
|
|
9438
|
-
|
|
9435
|
+
this.cssValue.forEach((href) => {
|
|
9436
|
+
this.ensureStylesheet(href);
|
|
9437
|
+
});
|
|
9438
|
+
this.jsValue.forEach((src) => {
|
|
9439
|
+
this.ensureScript(src);
|
|
9440
|
+
});
|
|
9439
9441
|
}
|
|
9440
9442
|
ensureStylesheet(href) {
|
|
9441
|
-
|
|
9442
|
-
const present = Array.from(
|
|
9443
|
-
document.querySelectorAll('link[rel="stylesheet"]')
|
|
9444
|
-
).some((link2) => link2.href === url);
|
|
9445
|
-
if (present)
|
|
9443
|
+
if (!href || this.present('link[rel="stylesheet"]', "href", href))
|
|
9446
9444
|
return;
|
|
9447
9445
|
const link = document.createElement("link");
|
|
9448
9446
|
link.rel = "stylesheet";
|
|
@@ -9450,17 +9448,19 @@ class Assets extends Controller {
|
|
|
9450
9448
|
document.head.appendChild(link);
|
|
9451
9449
|
}
|
|
9452
9450
|
ensureScript(src) {
|
|
9453
|
-
|
|
9454
|
-
const present = Array.from(
|
|
9455
|
-
document.querySelectorAll("script[src]")
|
|
9456
|
-
).some((script2) => script2.src === url);
|
|
9457
|
-
if (present)
|
|
9451
|
+
if (!src || this.present("script[src]", "src", src))
|
|
9458
9452
|
return;
|
|
9459
9453
|
const script = document.createElement("script");
|
|
9460
9454
|
script.type = "module";
|
|
9461
9455
|
script.src = src;
|
|
9462
9456
|
document.head.appendChild(script);
|
|
9463
9457
|
}
|
|
9458
|
+
present(selector, attribute, url) {
|
|
9459
|
+
const absolute = this.absolute(url);
|
|
9460
|
+
return Array.from(document.querySelectorAll(selector)).some(
|
|
9461
|
+
(element) => element[attribute] === absolute
|
|
9462
|
+
);
|
|
9463
|
+
}
|
|
9464
9464
|
// Resolve a possibly-relative URL to its absolute form for comparison.
|
|
9465
9465
|
absolute(url) {
|
|
9466
9466
|
const anchor = document.createElement("a");
|