katalyst-koi 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +23 -0
- data/Upgrade.md +6 -0
- data/app/assets/builds/koi/admin.css +1 -0
- data/app/assets/builds/koi/nav_items.css +1 -0
- data/app/assets/config/koi.js +10 -0
- data/app/assets/images/koi/application/chevron-right.svg +10 -0
- data/app/assets/images/koi/application/glyphicons-halflings-white.png +0 -0
- data/app/assets/images/koi/application/glyphicons-halflings.png +0 -0
- data/app/assets/images/koi/application/icon-collapse-down.png +0 -0
- data/app/assets/images/koi/application/icon-collapse-up.png +0 -0
- data/app/assets/images/koi/application/icon-file-doc.png +0 -0
- data/app/assets/images/koi/application/icon-file-img.png +0 -0
- data/app/assets/images/koi/application/icon-file-pdf.png +0 -0
- data/app/assets/images/koi/application/icon-file-ppt.png +0 -0
- data/app/assets/images/koi/application/icon-file-unknown.png +0 -0
- data/app/assets/images/koi/application/icon-file-xls.png +0 -0
- data/app/assets/images/koi/application/icon-file-zip.png +0 -0
- data/app/assets/images/koi/application/icon-form-date-picker.png +0 -0
- data/app/assets/images/koi/application/icon-form-error.png +0 -0
- data/app/assets/images/koi/application/icon-index-sort-ascending.png +0 -0
- data/app/assets/images/koi/application/icon-index-sort-descending.png +0 -0
- data/app/assets/images/koi/application/icon-index-sort.png +0 -0
- data/app/assets/images/koi/application/icon-index-sortable.png +0 -0
- data/app/assets/images/koi/application/icon-menu-cursor.png +0 -0
- data/app/assets/images/koi/application/icon-overlay-add.png +0 -0
- data/app/assets/images/koi/application/icon-overlay-close.png +0 -0
- data/app/assets/images/koi/application/icon-sortable.png +0 -0
- data/app/assets/images/koi/application/jcrop.gif +0 -0
- data/app/assets/images/koi/application/loading.gif +0 -0
- data/app/assets/images/koi/application/select-arrow.svg +3 -0
- data/app/assets/images/koi/application/select_arrow.png +0 -0
- data/app/assets/images/koi/application/sort-ascending.png +0 -0
- data/app/assets/images/koi/application/sort-descending.png +0 -0
- data/app/assets/javascripts/koi/admin.js +4 -0
- data/app/assets/javascripts/koi/controllers/application.js +11 -0
- data/app/assets/javascripts/koi/controllers/document_field_controller.js +26 -0
- data/app/assets/javascripts/koi/controllers/file_field_controller.js +143 -0
- data/app/assets/javascripts/koi/controllers/flash_controller.js +12 -0
- data/app/assets/javascripts/koi/controllers/form_request_submit_controller.js +11 -0
- data/app/assets/javascripts/koi/controllers/image_field_controller.js +24 -0
- data/app/assets/javascripts/koi/controllers/index.js +6 -0
- data/app/assets/javascripts/koi/controllers/index_actions_controller.js +61 -0
- data/app/assets/javascripts/koi/controllers/keyboard_controller.js +149 -0
- data/app/assets/javascripts/koi/controllers/navigation_controller.js +84 -0
- data/app/assets/javascripts/koi/controllers/navigation_toggle_controller.js +7 -0
- data/app/assets/javascripts/koi/controllers/show_hide_controller.js +25 -0
- data/app/assets/javascripts/koi/controllers/sluggable_controller.js +30 -0
- data/app/assets/javascripts/koi/controllers/webauthn_authentication_controller.js +23 -0
- data/app/assets/javascripts/koi/controllers/webauthn_registration_controller.js +30 -0
- data/app/assets/javascripts/koi/utils/transition.js +220 -0
- data/app/assets/stylesheets/koi/admin.scss +27 -0
- data/app/assets/stylesheets/koi/base/_button.scss +122 -0
- data/app/assets/stylesheets/koi/base/_icon.scss +29 -0
- data/app/assets/stylesheets/koi/base/_index.scss +18 -0
- data/app/assets/stylesheets/koi/base/_input.scss +13 -0
- data/app/assets/stylesheets/koi/base/_link.scss +26 -0
- data/app/assets/stylesheets/koi/base/_list.scss +11 -0
- data/app/assets/stylesheets/koi/base/_typography.scss +160 -0
- data/app/assets/stylesheets/koi/components/_actions-group.scss +7 -0
- data/app/assets/stylesheets/koi/components/_image-field.scss +33 -0
- data/app/assets/stylesheets/koi/components/_index-actions.scss +69 -0
- data/app/assets/stylesheets/koi/components/_index-table.scss +91 -0
- data/app/assets/stylesheets/koi/components/_index.scss +6 -0
- data/app/assets/stylesheets/koi/components/_item-table.scss +33 -0
- data/app/assets/stylesheets/koi/components/_pagy.scss +41 -0
- data/app/assets/stylesheets/koi/layouts/_banner.scss +7 -0
- data/app/assets/stylesheets/koi/layouts/_content.scss +40 -0
- data/app/assets/stylesheets/koi/layouts/_flash.scss +41 -0
- data/app/assets/stylesheets/koi/layouts/_header.scss +62 -0
- data/app/assets/stylesheets/koi/layouts/_index.scss +48 -0
- data/app/assets/stylesheets/koi/layouts/_main.scss +23 -0
- data/app/assets/stylesheets/koi/layouts/_navigation.scss +156 -0
- data/app/assets/stylesheets/koi/layouts/_stack.scss +13 -0
- data/app/assets/stylesheets/koi/pages/_index.scss +1 -0
- data/app/assets/stylesheets/koi/pages/_login.scss +40 -0
- data/app/assets/stylesheets/koi/themes/_content.scss +5 -0
- data/app/assets/stylesheets/koi/themes/_govuk.scss +52 -0
- data/app/assets/stylesheets/koi/themes/_index.scss +5 -0
- data/app/assets/stylesheets/koi/themes/_kpop.scss +5 -0
- data/app/assets/stylesheets/koi/themes/_navigation.scss +5 -0
- data/app/assets/stylesheets/koi/themes/_trix.scss +32 -0
- data/app/assets/stylesheets/koi/utils/_breakpoints.scss +13 -0
- data/app/assets/stylesheets/koi/utils/_hide.scss +11 -0
- data/app/assets/stylesheets/koi/utils/_index.scss +2 -0
- data/app/assets/stylesheets/koi/utils/_typography.scss +24 -0
- data/app/components/koi/header/edit_component.rb +58 -0
- data/app/components/koi/header/index_component.rb +23 -0
- data/app/components/koi/header/new_component.rb +40 -0
- data/app/components/koi/header/show_component.rb +51 -0
- data/app/components/koi/header_component.html.erb +16 -0
- data/app/components/koi/header_component.rb +28 -0
- data/app/components/koi/index_table_component.rb +21 -0
- data/app/controllers/admin/admin_users_controller.rb +88 -0
- data/app/controllers/admin/application_controller.rb +9 -0
- data/app/controllers/admin/caches_controller.rb +11 -0
- data/app/controllers/admin/credentials_controller.rb +64 -0
- data/app/controllers/admin/dashboards_controller.rb +7 -0
- data/app/controllers/admin/sessions_controller.rb +78 -0
- data/app/controllers/admin/url_rewrites_controller.rb +87 -0
- data/app/controllers/concerns/koi/controller/has_admin_users.rb +49 -0
- data/app/controllers/concerns/koi/controller/has_webauthn.rb +45 -0
- data/app/controllers/concerns/koi/controller/is_admin_controller.rb +52 -0
- data/app/helpers/katalyst/content/editor/errors.rb +21 -0
- data/app/helpers/katalyst/navigation/editor/errors.rb +21 -0
- data/app/helpers/koi/application_helper.rb +7 -0
- data/app/helpers/koi/date_helper.rb +36 -0
- data/app/helpers/koi/definition_list_helper.rb +92 -0
- data/app/helpers/koi/index_actions_helper.rb +99 -0
- data/app/jobs/koi/application_job.rb +6 -0
- data/app/mailers/koi/application_mailer.rb +8 -0
- data/app/models/admin/credential.rb +14 -0
- data/app/models/admin/user.rb +51 -0
- data/app/models/application_record.rb +5 -0
- data/app/models/concerns/koi/model/archivable.rb +55 -0
- data/app/models/url_rewrite.rb +25 -0
- data/app/views/admin/admin_users/_admin.html+row.erb +4 -0
- data/app/views/admin/admin_users/_authentication.html.erb +15 -0
- data/app/views/admin/admin_users/_fields.html.erb +4 -0
- data/app/views/admin/admin_users/edit.html.erb +11 -0
- data/app/views/admin/admin_users/index.html.erb +9 -0
- data/app/views/admin/admin_users/new.html.erb +11 -0
- data/app/views/admin/admin_users/show.html.erb +22 -0
- data/app/views/admin/credentials/new.html.erb +14 -0
- data/app/views/admin/dashboards/show.html.erb +1 -0
- data/app/views/admin/sessions/new.html.erb +19 -0
- data/app/views/admin/shared/icons/_close.html.erb +8 -0
- data/app/views/admin/shared/icons/_cross.html.erb +3 -0
- data/app/views/admin/shared/icons/_menu.html.erb +3 -0
- data/app/views/admin/shared/icons/_refresh.html.erb +8 -0
- data/app/views/admin/url_rewrites/_form_fields.html.erb +3 -0
- data/app/views/admin/url_rewrites/_url_rewrite.html+row.erb +7 -0
- data/app/views/admin/url_rewrites/edit.html.erb +12 -0
- data/app/views/admin/url_rewrites/index.html.erb +10 -0
- data/app/views/admin/url_rewrites/new.html.erb +11 -0
- data/app/views/admin/url_rewrites/show.html.erb +16 -0
- data/app/views/katalyst/content/asides/_aside.html+form.erb +18 -0
- data/app/views/katalyst/content/columns/_column.html+form.erb +18 -0
- data/app/views/katalyst/content/contents/_content.html+form.erb +20 -0
- data/app/views/katalyst/content/figures/_figure.html+form.erb +17 -0
- data/app/views/katalyst/content/groups/_group.html+form.erb +18 -0
- data/app/views/katalyst/content/items/_item.html+form.erb +18 -0
- data/app/views/katalyst/content/sections/_section.html+form.erb +18 -0
- data/app/views/katalyst/navigation/items/_button.html.erb +15 -0
- data/app/views/katalyst/navigation/items/_heading.html.erb +11 -0
- data/app/views/katalyst/navigation/items/_link.html.erb +13 -0
- data/app/views/katalyst/navigation/menus/edit.html.erb +12 -0
- data/app/views/katalyst/navigation/menus/new.html.erb +9 -0
- data/app/views/katalyst/navigation/menus/show.html.erb +18 -0
- data/app/views/layouts/koi/_environment.html.erb +4 -0
- data/app/views/layouts/koi/_flash.html.erb +8 -0
- data/app/views/layouts/koi/_header.html.erb +11 -0
- data/app/views/layouts/koi/_navigation.html.erb +13 -0
- data/app/views/layouts/koi/_navigation_collapse.html.erb +3 -0
- data/app/views/layouts/koi/_navigation_header.html.erb +6 -0
- data/app/views/layouts/koi/_navigation_item.html.erb +12 -0
- data/app/views/layouts/koi/application.html.erb +59 -0
- data/app/views/layouts/koi/login.html.erb +29 -0
- data/config/importmap.rb +9 -0
- data/config/initializers/flipper.rb +13 -0
- data/config/initializers/pagy.rb +1 -0
- data/config/initializers/time_formats.rb +5 -0
- data/config/locales/koi.en.yml +18 -0
- data/config/locales/pagy.en.yml +6 -0
- data/config/routes.rb +25 -0
- data/db/migrate/20120220130849_devise_create_admins.rb +56 -0
- data/db/migrate/20130509235316_add_url_rewriter.rb +13 -0
- data/db/migrate/20230213053854_convert_devise_admins_to_rails.rb +7 -0
- data/db/migrate/20230412023411_create_admin_user_credentials.rb +20 -0
- data/db/migrate/20230531063707_update_admin_users.rb +37 -0
- data/db/migrate/20230602033610_add_archived_to_admin_users.rb +7 -0
- data/db/seeds.rb +9 -0
- data/lib/generators/koi/active_record/active_record_generator.rb +43 -0
- data/lib/generators/koi/admin/USAGE +8 -0
- data/lib/generators/koi/admin/admin_generator.rb +20 -0
- data/lib/generators/koi/admin_controller/USAGE +17 -0
- data/lib/generators/koi/admin_controller/admin_controller_generator.rb +51 -0
- data/lib/generators/koi/admin_controller/templates/controller.rb.tt +81 -0
- data/lib/generators/koi/admin_controller/templates/controller_spec.rb.tt +135 -0
- data/lib/generators/koi/admin_route/admin_route_generator.rb +62 -0
- data/lib/generators/koi/admin_views/USAGE +12 -0
- data/lib/generators/koi/admin_views/admin_views_generator.rb +54 -0
- data/lib/generators/koi/admin_views/templates/_fields.html.erb.tt +3 -0
- data/lib/generators/koi/admin_views/templates/_record.html+row.erb.tt +10 -0
- data/lib/generators/koi/admin_views/templates/edit.html.erb.tt +12 -0
- data/lib/generators/koi/admin_views/templates/index.html.erb.tt +7 -0
- data/lib/generators/koi/admin_views/templates/new.html.erb.tt +11 -0
- data/lib/generators/koi/admin_views/templates/show.html.erb.tt +18 -0
- data/lib/govuk_design_system_formbuilder/concerns/file_element.rb +115 -0
- data/lib/govuk_design_system_formbuilder/elements/document.rb +59 -0
- data/lib/govuk_design_system_formbuilder/elements/image.rb +86 -0
- data/lib/katalyst/koi.rb +3 -0
- data/lib/koi/caching.rb +15 -0
- data/lib/koi/config.rb +11 -0
- data/lib/koi/engine.rb +40 -0
- data/lib/koi/form_builder.rb +76 -0
- data/lib/koi/menu/builder.rb +68 -0
- data/lib/koi/menu.rb +46 -0
- data/lib/koi/middleware/url_redirect.rb +44 -0
- data/lib/koi/release.rb +52 -0
- data/lib/koi/version.rb +5 -0
- data/lib/koi.rb +37 -0
- data/spec/factories/admins.rb +9 -0
- data/spec/factories/url_rewrites.rb +9 -0
- metadata +430 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
import {
|
4
|
+
get,
|
5
|
+
parseRequestOptionsFromJSON,
|
6
|
+
} from "@github/webauthn-json/browser-ponyfill";
|
7
|
+
|
8
|
+
export default class WebauthnAuthenticationController extends Controller {
|
9
|
+
static targets = ["response"];
|
10
|
+
static values = { options: Object };
|
11
|
+
|
12
|
+
authenticate() {
|
13
|
+
get(this.options).then((response) => {
|
14
|
+
this.responseTarget.value = JSON.stringify(response);
|
15
|
+
|
16
|
+
this.element.requestSubmit();
|
17
|
+
});
|
18
|
+
}
|
19
|
+
|
20
|
+
get options() {
|
21
|
+
return parseRequestOptionsFromJSON(this.optionsValue);
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
import {
|
4
|
+
create,
|
5
|
+
parseCreationOptionsFromJSON,
|
6
|
+
} from "@github/webauthn-json/browser-ponyfill";
|
7
|
+
|
8
|
+
export default class WebauthnRegistrationController extends Controller {
|
9
|
+
static values = { options: Object };
|
10
|
+
static targets = ["response"];
|
11
|
+
|
12
|
+
submit(e) {
|
13
|
+
if (this.responseTarget.value === "") {
|
14
|
+
e.preventDefault();
|
15
|
+
this.createCredential();
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
createCredential() {
|
20
|
+
create(this.options).then((response) => {
|
21
|
+
this.responseTarget.value = JSON.stringify(response);
|
22
|
+
|
23
|
+
this.element.requestSubmit();
|
24
|
+
});
|
25
|
+
}
|
26
|
+
|
27
|
+
get options() {
|
28
|
+
return parseCreationOptionsFromJSON(this.optionsValue);
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,220 @@
|
|
1
|
+
const DEFAULT_DELAY = 250;
|
2
|
+
|
3
|
+
/**
|
4
|
+
* A utility class for managing CSS transition animations.
|
5
|
+
*
|
6
|
+
* Transition uses Javascript timers to track state instead of relying on
|
7
|
+
* CSS transition events, which is a more complicated API. Please call `cancel`
|
8
|
+
* when the node being animated is detached from the DOM to avoid unexpected
|
9
|
+
* errors or animation glitches.
|
10
|
+
*
|
11
|
+
* Transition assumes that CSS already specifies styles to achieve the expected
|
12
|
+
* start and end states. Transition adds temporary overrides and then animates
|
13
|
+
* between those values using CSS transitions. For example, to use the collapse
|
14
|
+
* transition:
|
15
|
+
*
|
16
|
+
* @example
|
17
|
+
* // CSS:
|
18
|
+
* target {
|
19
|
+
* max-height: unset;
|
20
|
+
* overflow: 0;
|
21
|
+
* }
|
22
|
+
* target.hidden {
|
23
|
+
* max-height: 0;
|
24
|
+
* }
|
25
|
+
*
|
26
|
+
* @example
|
27
|
+
* // Javascript
|
28
|
+
* target.addClass("hidden");
|
29
|
+
* new Transition(target).collapse().start();
|
30
|
+
*/
|
31
|
+
class Transition {
|
32
|
+
constructor(target, options) {
|
33
|
+
const { delay } = this._setDefaults(options);
|
34
|
+
|
35
|
+
this.target = target;
|
36
|
+
this.runner = new Runner(this, delay);
|
37
|
+
this.properties = [];
|
38
|
+
|
39
|
+
this.startingCallbacks = [];
|
40
|
+
this.startedCallbacks = [];
|
41
|
+
this.completeCallbacks = [];
|
42
|
+
}
|
43
|
+
|
44
|
+
add(property) {
|
45
|
+
this.properties.push(property);
|
46
|
+
return this;
|
47
|
+
}
|
48
|
+
|
49
|
+
/** Adds callback for transition events */
|
50
|
+
addCallback(type, callback) {
|
51
|
+
switch (type) {
|
52
|
+
case "starting":
|
53
|
+
this.startingCallbacks.push(callback);
|
54
|
+
break;
|
55
|
+
case "started":
|
56
|
+
this.startedCallbacks.push(callback);
|
57
|
+
break;
|
58
|
+
case "complete":
|
59
|
+
this.completeCallbacks.push(callback);
|
60
|
+
break;
|
61
|
+
}
|
62
|
+
return this;
|
63
|
+
}
|
64
|
+
|
65
|
+
/** Collapse an element in place, assumes overflow is set appropriately, margin is not collapsed */
|
66
|
+
collapse() {
|
67
|
+
return this.add(
|
68
|
+
new PropertyTransition(
|
69
|
+
"max-height",
|
70
|
+
`${this.target.scrollHeight}px`,
|
71
|
+
"0px",
|
72
|
+
),
|
73
|
+
);
|
74
|
+
}
|
75
|
+
|
76
|
+
/** Restore a collapsed element */
|
77
|
+
expand() {
|
78
|
+
return this.add(
|
79
|
+
new PropertyTransition(
|
80
|
+
"max-height",
|
81
|
+
"0px",
|
82
|
+
`${this.target.scrollHeight}px`,
|
83
|
+
),
|
84
|
+
);
|
85
|
+
}
|
86
|
+
|
87
|
+
/** Slide an element left or right by its scroll width, assumes position relative */
|
88
|
+
slideOut(direction) {
|
89
|
+
return this.add(
|
90
|
+
new PropertyTransition(direction, "0px", `-${this.target.scrollWidth}px`),
|
91
|
+
);
|
92
|
+
}
|
93
|
+
|
94
|
+
/** Restore an element that has been slid */
|
95
|
+
slideIn(direction) {
|
96
|
+
return this.add(
|
97
|
+
new PropertyTransition(direction, `-${this.target.scrollWidth}px`, "0px"),
|
98
|
+
);
|
99
|
+
}
|
100
|
+
|
101
|
+
/** Cause an element to become transparent by transforming opacity */
|
102
|
+
fadeOut() {
|
103
|
+
return this.add(new PropertyTransition("opacity", "100%", "0%"));
|
104
|
+
}
|
105
|
+
|
106
|
+
/** Cause a transparent element to become visible again */
|
107
|
+
fadeIn() {
|
108
|
+
return this.add(new PropertyTransition("opacity", "0%", "100%"));
|
109
|
+
}
|
110
|
+
|
111
|
+
start(callback = null) {
|
112
|
+
// start the runner on next tick so that any side-effects of the current execution can occur first
|
113
|
+
requestAnimationFrame(() => {
|
114
|
+
this.runner.start(this.target);
|
115
|
+
if (callback) callback();
|
116
|
+
});
|
117
|
+
return this;
|
118
|
+
}
|
119
|
+
|
120
|
+
cancel() {
|
121
|
+
this.runner.stop(this.target);
|
122
|
+
return this;
|
123
|
+
}
|
124
|
+
|
125
|
+
_starting() {
|
126
|
+
const event = new Event("transition:starting");
|
127
|
+
this.startingCallbacks.forEach((cb) => cb(event));
|
128
|
+
this.target.dispatchEvent(event);
|
129
|
+
}
|
130
|
+
|
131
|
+
_started() {
|
132
|
+
const event = new Event("transition:started");
|
133
|
+
this.startedCallbacks.forEach((cb) => cb(event));
|
134
|
+
this.target.dispatchEvent(event);
|
135
|
+
}
|
136
|
+
|
137
|
+
_complete() {
|
138
|
+
const event = new Event("transition:complete");
|
139
|
+
this.completeCallbacks.forEach((cb) => cb(event));
|
140
|
+
this.target.dispatchEvent(event);
|
141
|
+
}
|
142
|
+
|
143
|
+
_setDefaults(options) {
|
144
|
+
return Object.assign({ delay: DEFAULT_DELAY }, options);
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
/**
|
149
|
+
* Encapsulates internal execution and timing functionality for `Transition`
|
150
|
+
*/
|
151
|
+
class Runner {
|
152
|
+
constructor(transition, delay) {
|
153
|
+
this.transition = transition;
|
154
|
+
this.running = null;
|
155
|
+
this.delay = delay;
|
156
|
+
}
|
157
|
+
|
158
|
+
start(target) {
|
159
|
+
// 1. Set the initial state(s)
|
160
|
+
this.transition.properties.forEach((t) => t.onStarting(target));
|
161
|
+
|
162
|
+
// 2. On next update, set transition and final state(s)
|
163
|
+
requestAnimationFrame(() => this.onStarted(target));
|
164
|
+
|
165
|
+
// 3. After transition has finished, clean up
|
166
|
+
this.running = setTimeout(() => this.stop(target, true), this.delay);
|
167
|
+
|
168
|
+
this.transition._starting();
|
169
|
+
}
|
170
|
+
|
171
|
+
onStarted(target) {
|
172
|
+
target.style.transitionProperty = this.transition.properties
|
173
|
+
.map((t) => t.property)
|
174
|
+
.join(",");
|
175
|
+
target.style.transitionDuration = `${this.delay}ms`;
|
176
|
+
this.transition.properties.forEach((t) => t.onStarted(target));
|
177
|
+
|
178
|
+
this.transition._started();
|
179
|
+
}
|
180
|
+
|
181
|
+
stop(target, timeout = false) {
|
182
|
+
if (!this.running) return;
|
183
|
+
if (!timeout) clearTimeout(this.running);
|
184
|
+
|
185
|
+
this.running = null;
|
186
|
+
|
187
|
+
target.style.removeProperty("transition-property");
|
188
|
+
target.style.removeProperty("transition-duration");
|
189
|
+
this.transition.properties.forEach((t) => t.onComplete(target));
|
190
|
+
|
191
|
+
this.transition._complete();
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
/**
|
196
|
+
* Represents animation of a single CSS property. Currently only CSS animations
|
197
|
+
* are supported, but this could be a natural extension point for Javascript
|
198
|
+
* animations in the future.
|
199
|
+
*/
|
200
|
+
class PropertyTransition {
|
201
|
+
constructor(property, from, to) {
|
202
|
+
this.property = property;
|
203
|
+
this.from = from;
|
204
|
+
this.to = to;
|
205
|
+
}
|
206
|
+
|
207
|
+
onStarting(target) {
|
208
|
+
target.style.setProperty(this.property, this.from);
|
209
|
+
}
|
210
|
+
|
211
|
+
onStarted(target) {
|
212
|
+
target.style.setProperty(this.property, this.to);
|
213
|
+
}
|
214
|
+
|
215
|
+
onComplete(target) {
|
216
|
+
target.style.removeProperty(this.property);
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
export { Transition };
|
@@ -0,0 +1,27 @@
|
|
1
|
+
// DEPENDENCIES
|
2
|
+
|
3
|
+
@use "base";
|
4
|
+
@use "components";
|
5
|
+
@use "layouts";
|
6
|
+
@use "pages";
|
7
|
+
@use "themes";
|
8
|
+
@use "utils";
|
9
|
+
|
10
|
+
:root {
|
11
|
+
/* Color styles */
|
12
|
+
--site-primary-light: #5a87c9;
|
13
|
+
--site-primary: #266dd3;
|
14
|
+
--site-primary-dark: #344055;
|
15
|
+
--site-on-primary: #ffffff;
|
16
|
+
--site-secondary-light: #5a87c9;
|
17
|
+
--site-secondary: #266dd3;
|
18
|
+
--site-secondary-dark: #344055;
|
19
|
+
--site-on-secondary: #ffffff;
|
20
|
+
--site-text-color: #000000;
|
21
|
+
--site-success: #129d7f;
|
22
|
+
--site-warning: #ffc759;
|
23
|
+
--site-alert: #ea3946;
|
24
|
+
--site-notice: rgb(37, 99, 235);
|
25
|
+
--site-disabled: #9ca3af;
|
26
|
+
--site-link: #266dd3;
|
27
|
+
}
|
@@ -0,0 +1,122 @@
|
|
1
|
+
%button-base {
|
2
|
+
display: inline-block;
|
3
|
+
position: relative;
|
4
|
+
padding: 5px 1rem;
|
5
|
+
cursor: pointer;
|
6
|
+
height: 2.5rem;
|
7
|
+
|
8
|
+
border: none;
|
9
|
+
outline: none;
|
10
|
+
transition:
|
11
|
+
color 0.2s ease,
|
12
|
+
background 0.2s ease,
|
13
|
+
border-color 0.2s ease;
|
14
|
+
text-decoration: none;
|
15
|
+
|
16
|
+
font-weight: 500;
|
17
|
+
}
|
18
|
+
|
19
|
+
@mixin button-filled {
|
20
|
+
@extend %button-base;
|
21
|
+
background: var(--site-primary);
|
22
|
+
border: 2px solid var(--site-primary);
|
23
|
+
color: var(--site-on-primary);
|
24
|
+
|
25
|
+
&:hover,
|
26
|
+
&:focus {
|
27
|
+
background: var(--site-primary-dark);
|
28
|
+
border-color: var(--site-primary-dark);
|
29
|
+
text-decoration: none;
|
30
|
+
}
|
31
|
+
|
32
|
+
&:active {
|
33
|
+
background: var(--site-primary-dark);
|
34
|
+
border-color: var(--site-primary-dark);
|
35
|
+
text-decoration: none;
|
36
|
+
}
|
37
|
+
|
38
|
+
&[disabled] {
|
39
|
+
background: var(--site-primary-light);
|
40
|
+
border-color: var(--site-primary-light);
|
41
|
+
opacity: 0.45;
|
42
|
+
|
43
|
+
&:hover,
|
44
|
+
&:focus {
|
45
|
+
background: var(--site-primary-light);
|
46
|
+
border-color: var(--site-primary-light);
|
47
|
+
}
|
48
|
+
|
49
|
+
&:active {
|
50
|
+
background: var(--site-primary-light);
|
51
|
+
border-color: var(--site-primary-light);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
@mixin button-outline {
|
57
|
+
@extend %button-base;
|
58
|
+
|
59
|
+
color: var(--site-secondary);
|
60
|
+
border: 2px solid var(--site-secondary);
|
61
|
+
background: transparent;
|
62
|
+
|
63
|
+
&:hover,
|
64
|
+
&:focus {
|
65
|
+
border-color: var(--site-secondary);
|
66
|
+
background: var(--site-secondary);
|
67
|
+
color: var(--site-on-secondary);
|
68
|
+
text-decoration: none;
|
69
|
+
}
|
70
|
+
|
71
|
+
&:active {
|
72
|
+
border-color: var(--site-secondary);
|
73
|
+
background: var(--site-secondary);
|
74
|
+
color: var(--site-on-secondary);
|
75
|
+
text-decoration: none;
|
76
|
+
}
|
77
|
+
|
78
|
+
&[disabled] {
|
79
|
+
background: none;
|
80
|
+
&:hover,
|
81
|
+
&:focus {
|
82
|
+
background: none;
|
83
|
+
}
|
84
|
+
|
85
|
+
&:active {
|
86
|
+
background: none;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
@mixin button-text {
|
92
|
+
@extend %button-base;
|
93
|
+
|
94
|
+
color: var(--site-primary);
|
95
|
+
background: none;
|
96
|
+
|
97
|
+
&:hover,
|
98
|
+
&:focus {
|
99
|
+
background: none;
|
100
|
+
color: var(--site-text-color);
|
101
|
+
}
|
102
|
+
|
103
|
+
&:active {
|
104
|
+
background: none;
|
105
|
+
color: var(--site-text-color);
|
106
|
+
}
|
107
|
+
|
108
|
+
&[disabled] {
|
109
|
+
background: none;
|
110
|
+
|
111
|
+
&:hover,
|
112
|
+
&:focus {
|
113
|
+
color: var(--site-primary-light);
|
114
|
+
background: none;
|
115
|
+
}
|
116
|
+
|
117
|
+
&:active {
|
118
|
+
color: var(--site-primary-light);
|
119
|
+
background: none;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
.icon {
|
2
|
+
width: 1.5em;
|
3
|
+
height: 1.5em;
|
4
|
+
display: inline-block;
|
5
|
+
}
|
6
|
+
|
7
|
+
.icon-large {
|
8
|
+
width: 2em;
|
9
|
+
height: 2em;
|
10
|
+
display: inline-block;
|
11
|
+
}
|
12
|
+
|
13
|
+
.icon-small {
|
14
|
+
width: 0.75em;
|
15
|
+
height: 0.75em;
|
16
|
+
display: inline-block;
|
17
|
+
}
|
18
|
+
|
19
|
+
.icon-medium {
|
20
|
+
width: 1em;
|
21
|
+
height: 1em;
|
22
|
+
display: inline-block;
|
23
|
+
}
|
24
|
+
|
25
|
+
.leading-icon {
|
26
|
+
display: flex;
|
27
|
+
gap: 0.25rem;
|
28
|
+
align-items: center;
|
29
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
@use "button";
|
2
|
+
@use "icon";
|
3
|
+
@use "input";
|
4
|
+
@use "link";
|
5
|
+
@use "list";
|
6
|
+
@use "typography";
|
7
|
+
|
8
|
+
.button--primary {
|
9
|
+
@include button.button-filled;
|
10
|
+
}
|
11
|
+
|
12
|
+
.button--secondary {
|
13
|
+
@include button.button-outline;
|
14
|
+
}
|
15
|
+
|
16
|
+
.button--text {
|
17
|
+
@include button.button-text;
|
18
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
a[href]:not(.button) {
|
2
|
+
color: var(--site-link);
|
3
|
+
text-decoration: none;
|
4
|
+
|
5
|
+
&:hover,
|
6
|
+
&:focus {
|
7
|
+
color: var(--site-link);
|
8
|
+
text-decoration: underline;
|
9
|
+
outline: none;
|
10
|
+
}
|
11
|
+
|
12
|
+
&.no-hover-link {
|
13
|
+
text-decoration: none;
|
14
|
+
|
15
|
+
&:hover,
|
16
|
+
&:focus {
|
17
|
+
text-decoration: none;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
&[disabled] {
|
22
|
+
color: var(--site-disabled);
|
23
|
+
pointer-events: none;
|
24
|
+
opacity: 0.45;
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,160 @@
|
|
1
|
+
$font-sizes: (
|
2
|
+
h1: 3.3125rem,
|
3
|
+
h2: 2rem,
|
4
|
+
h3: 1.5rem,
|
5
|
+
h4: 1.125rem,
|
6
|
+
h5: 1.125rem,
|
7
|
+
h6: 1rem,
|
8
|
+
paragraph: 1rem,
|
9
|
+
small: 0.875rem,
|
10
|
+
) !default;
|
11
|
+
|
12
|
+
$line-heights: (
|
13
|
+
h1: 1.03em,
|
14
|
+
h2: 1.09em,
|
15
|
+
h3: 1.04em,
|
16
|
+
h4: 1.11em,
|
17
|
+
h5: 1.11em,
|
18
|
+
// used for labels
|
19
|
+
h6: 1.5em,
|
20
|
+
paragraph: 1.14em,
|
21
|
+
small: 1.25em,
|
22
|
+
) !default;
|
23
|
+
|
24
|
+
@use "../utils/breakpoints";
|
25
|
+
@use "../utils/typography" as * with (
|
26
|
+
$-font-sizes: $font-sizes,
|
27
|
+
$-line-heights: $line-heights
|
28
|
+
);
|
29
|
+
|
30
|
+
:root {
|
31
|
+
font-family: "Inter", sans-serif;
|
32
|
+
font-size: 100%; // defaults to 16px
|
33
|
+
color: var(--site-text-color);
|
34
|
+
|
35
|
+
/* Text-size styles */
|
36
|
+
/* base size: paragraph (16px) */
|
37
|
+
--heading--h1: #{font-size(h1)};
|
38
|
+
--heading--h2: #{font-size(h2)};
|
39
|
+
--heading--h3: #{font-size(h3)};
|
40
|
+
--heading--h4: #{font-size(h4)};
|
41
|
+
--heading--h5: #{font-size(h5)};
|
42
|
+
--heading--h6: #{font-size(h6)};
|
43
|
+
--paragraph: #{font-size(paragraph)};
|
44
|
+
--paragraph--strong: #{font-size(paragraph)};
|
45
|
+
--paragraph--em: #{font-size(paragraph)};
|
46
|
+
--paragraph--small: #{font-size(small)};
|
47
|
+
--text-width: 70ch;
|
48
|
+
}
|
49
|
+
|
50
|
+
@supports (font-variation-settings: normal) {
|
51
|
+
:root {
|
52
|
+
font-family: "Inter var", sans-serif;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
h1,
|
57
|
+
.heading-one {
|
58
|
+
font-size: var(--heading--h1);
|
59
|
+
font-weight: 400;
|
60
|
+
line-height: line-height(h1);
|
61
|
+
margin-bottom: 0.25em;
|
62
|
+
letter-spacing: -0.015em;
|
63
|
+
color: var(--site-text-color);
|
64
|
+
}
|
65
|
+
|
66
|
+
h2,
|
67
|
+
.heading-two {
|
68
|
+
font-size: var(--heading--h2);
|
69
|
+
font-weight: 400;
|
70
|
+
line-height: line-height(h2);
|
71
|
+
margin-bottom: 0.25em;
|
72
|
+
letter-spacing: -0.015em;
|
73
|
+
color: var(--site-text-color);
|
74
|
+
}
|
75
|
+
|
76
|
+
h3,
|
77
|
+
.heading-three {
|
78
|
+
font-size: var(--heading--h3);
|
79
|
+
font-weight: 400;
|
80
|
+
line-height: line-height(h3);
|
81
|
+
margin: 0 0 0.25em;
|
82
|
+
letter-spacing: -0.015em;
|
83
|
+
color: var(--site-text-color);
|
84
|
+
}
|
85
|
+
|
86
|
+
h4,
|
87
|
+
.heading-four {
|
88
|
+
font-size: var(--heading--h4);
|
89
|
+
font-weight: 400;
|
90
|
+
line-height: line-height(h4);
|
91
|
+
margin: 0 0 0.25em;
|
92
|
+
letter-spacing: -0.015em;
|
93
|
+
color: var(--site-text-color);
|
94
|
+
}
|
95
|
+
|
96
|
+
h5,
|
97
|
+
.heading-five {
|
98
|
+
font-size: var(--heading--h5);
|
99
|
+
font-weight: 400;
|
100
|
+
line-height: line-height(h5);
|
101
|
+
margin: 0 0 0.25em;
|
102
|
+
letter-spacing: -0.015em;
|
103
|
+
color: var(--site-text-color);
|
104
|
+
}
|
105
|
+
|
106
|
+
h6,
|
107
|
+
.heading-six {
|
108
|
+
font-size: var(--heading--h6);
|
109
|
+
font-weight: 400; // Bold
|
110
|
+
line-height: line-height(h6);
|
111
|
+
margin: 0 0 0.25em;
|
112
|
+
letter-spacing: -0.015em;
|
113
|
+
color: var(--site-text-color);
|
114
|
+
}
|
115
|
+
|
116
|
+
label {
|
117
|
+
font-size: var(--heading-h6);
|
118
|
+
font-weight: 500; // Bold
|
119
|
+
line-height: line-height(h6);
|
120
|
+
margin-bottom: 0.125rem;
|
121
|
+
letter-spacing: 0.01em;
|
122
|
+
color: var(--site-text-color);
|
123
|
+
}
|
124
|
+
|
125
|
+
p,
|
126
|
+
.body-one {
|
127
|
+
font-size: var(--paragraph);
|
128
|
+
line-height: line-height(paragraph);
|
129
|
+
letter-spacing: 0.01em;
|
130
|
+
color: var(--site-text-color);
|
131
|
+
}
|
132
|
+
|
133
|
+
small,
|
134
|
+
em {
|
135
|
+
font-size: var(--paragraph--em);
|
136
|
+
line-height: line-height(paragraph);
|
137
|
+
letter-spacing: 0.01em;
|
138
|
+
font-weight: 300;
|
139
|
+
color: var(--site-text-color);
|
140
|
+
}
|
141
|
+
|
142
|
+
strong {
|
143
|
+
font-size: var(--paragraph--strong);
|
144
|
+
font-weight: 600;
|
145
|
+
letter-spacing: 0.01em;
|
146
|
+
color: var(--site-text-color);
|
147
|
+
}
|
148
|
+
|
149
|
+
h1,
|
150
|
+
h2,
|
151
|
+
h3,
|
152
|
+
h4,
|
153
|
+
p,
|
154
|
+
small,
|
155
|
+
legend,
|
156
|
+
label,
|
157
|
+
input,
|
158
|
+
textarea {
|
159
|
+
max-width: var(--text-width);
|
160
|
+
}
|