{children}
- {appliedTagName &&
}
+ {appliedTagName &&
}
-
-
- {actionButtons}
- {onCancel && }
-
-
-
-
+
+ {actionButtons}
+ {onCancel && }
+
diff --git a/app/src/components/ui/ui.css b/app/src/components/ui/ui.css
index fbd75c1c..464da8c8 100644
--- a/app/src/components/ui/ui.css
+++ b/app/src/components/ui/ui.css
@@ -342,6 +342,54 @@ html[data-theme="amber"] .wrolpi-searchbox-control:focus-within {
border-top: 1px solid var(--border);
}
+/* A stack of form rows, replacing Semantic's `ui stackable grid` in edit forms. */
+.wrolpi-form-rows {
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
+}
+
+/* ------------------------------------------------------------- Form fields */
+/*
+ * `hooks/useForm.js` renders its own
-
-
-
+
+
+
{messageElm}
>
}
@@ -463,31 +463,36 @@ export function UrlsTextarea({name = 'urls', required, form}) {
};
return (
-
-
-
+
);
}
export function ToggleForm({form, name, label, path, icon = null, iconSize = 'big', disabled = false}) {
const [inputProps, inputAttrs] = form.getCustomProps({name, path})
- const iconElm = icon ?
: null;
- return
- {iconElm}
-
-
+ const iconElm = icon ? : null;
+ return
+
+
+ {iconElm}
+
+
+
}
diff --git a/app/src/index.css b/app/src/index.css
index da92873c..f97b4fe3 100644
--- a/app/src/index.css
+++ b/app/src/index.css
@@ -1,8 +1,6 @@
body {
margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
+ /* The font comes from the theme's `--font-body` role token; see themes/tokens.css. */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
diff --git a/app/src/semantic-baseline.json b/app/src/semantic-baseline.json
index d6769cfd..fe51488c 100644
--- a/app/src/semantic-baseline.json
+++ b/app/src/semantic-baseline.json
@@ -1,16 +1 @@
-[
- "src/components/Archive.js",
- "src/components/BulkTagModal.js",
- "src/components/Channels.js",
- "src/components/Docs.js",
- "src/components/FileBrowser.js",
- "src/components/FilePreview.js",
- "src/components/Flasher.js",
- "src/components/Nav.js",
- "src/components/Playlists.js",
- "src/components/Theme.tsx",
- "src/components/Upload.js",
- "src/components/VideoPlayer.js",
- "src/components/Zim.js",
- "src/components/admin/Downloads.js"
-]
+[]
diff --git a/app/src/semantic-baseline.test.js b/app/src/semantic-baseline.test.js
index 1718773e..92c20ab1 100644
--- a/app/src/semantic-baseline.test.js
+++ b/app/src/semantic-baseline.test.js
@@ -13,7 +13,10 @@ import baseline from './semantic-baseline.json';
* print 75 warnings on every dev rebuild, or fail the build outright, and CI
* already unsets CI= for the build step so warnings there guard nothing.
*
- * When the list reaches zero, delete this test, the JSON, and the dependencies.
+ * The list has reached zero. The test stays as a guard rather than being deleted: it now
+ * asserts that nothing imports Semantic UI, nothing calls its toast library, nothing leans
+ * on its stylesheet, and no migrated file reaches back through Theme.tsx. It can go when
+ * the packages themselves are uninstalled.
*/
const SRC = path.join(__dirname);
@@ -74,7 +77,9 @@ describe('Semantic UI removal', () => {
* collapse. Anything on this list is a deliberate bridge that must be revisited
* then; anything NOT on it is an accident.
*/
- const allowed = ['src/components/collections/CollectionEditForm.js'];
+ // Empty, and it should stay that way: Semantic's stylesheet is no longer loaded,
+ // so a `ui ...` class name now styles nothing at all.
+ const allowed = [];
const bridges = sourceFiles()
.filter(file => !baseline.includes(file))
diff --git a/app/src/themes/tokens.css b/app/src/themes/tokens.css
index 7c7e2170..387c67a2 100644
--- a/app/src/themes/tokens.css
+++ b/app/src/themes/tokens.css
@@ -158,12 +158,61 @@ html[data-theme="amber"] {
/* Shell */
/* ------------------------------------------------------------------------- */
+/*
+ * Base element styling.
+ *
+ * semantic.min.css used to supply all of this, and removing it took the lot with it --
+ * links lost their colour and gained the browser's underline and visited purple, and
+ * every padded element silently changed size when `box-sizing: border-box` went away.
+ * None of it belonged to Semantic; it belongs here, expressed in tokens.
+ */
+
+html {
+ box-sizing: border-box;
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: inherit;
+}
+
body {
background: var(--bg);
color: var(--text);
font-family: var(--font-body);
}
+/*
+ * Links take the primary token rather than the browser's blue, and carry no underline
+ * until hovered -- a great many of them wrap cards, posters, statistics and icons, where
+ * a permanent underline is noise. `--blue` remaps per theme, so night gets a dim red
+ * link and amber an amber one without another rule.
+ */
+a {
+ color: var(--blue);
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+/* A link wrapping a card, poster or icon carries no text of its own to underline. */
+a:has(img, svg, .wrolpi-card-icon):hover {
+ text-decoration: none;
+}
+
+a:focus-visible {
+ outline: 2px solid var(--blue);
+ outline-offset: 2px;
+}
+
+html[data-theme="night"] a:focus-visible,
+html[data-theme="amber"] a:focus-visible {
+ outline-color: var(--text);
+}
+
/* ------------------------------------------------------------------------- */
/* Media filtering */
/* ------------------------------------------------------------------------- */
diff --git a/app/src/types/theme.ts b/app/src/types/theme.ts
index db8a98f7..43c9c1c7 100644
--- a/app/src/types/theme.ts
+++ b/app/src/types/theme.ts
@@ -31,14 +31,6 @@ export interface StyleProps {
// ThemeContext value type
export interface ThemeContextValue {
- /** Props for Semantic elements that support "inverted" */
- i: InvertedProps;
- /** Props to invert styles on elements */
- s: StyleProps;
- /** Props to invert text color */
- t: StyleProps;
- /** Class name string: 'inverted' or '' */
- inverted: string;
/** Current applied theme */
theme: ThemeName;
/** User's saved theme preference */