@sukramj/fabric-ui 0.2.1 → 0.2.2
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 +8 -1
- package/package.json +1 -1
- package/src/lib/kit/Button.svelte +3 -2
- package/src/lib/kit/Tabs.svelte +5 -2
- package/src/lib/theme/ha-bridge.ts +3 -0
- package/src/lib/theme/tokens.css +11 -1
package/README.md
CHANGED
|
@@ -74,7 +74,14 @@ host's stylesheet, after Tailwind:
|
|
|
74
74
|
`.dark` on `<html>` switches the dark tokens; `data-skin="ha"` on `<html>`
|
|
75
75
|
resolves the tokens from Home Assistant's variables. `applySkin("ha")` and
|
|
76
76
|
`startHaBridge()` (from `@sukramj/fabric-ui/theme`) do both inside an
|
|
77
|
-
Ingress frame and are inert elsewhere.
|
|
77
|
+
Ingress frame and are inert elsewhere. A host on a skin of its own (any
|
|
78
|
+
other `data-skin`, or none) keeps the standalone tokens; the HA skin's
|
|
79
|
+
extras (`accent-color` and `color-scheme` on native controls,
|
|
80
|
+
`--ha-on-primary-color` from Home Assistant's `--text-primary-color`) apply
|
|
81
|
+
only under `data-skin="ha"`. The standalone shell sets the HA skin and the
|
|
82
|
+
mode in a pre-paint script (`src/shell/index.html`) so the first frame
|
|
83
|
+
already wears them; a host that wants the same does it in its own
|
|
84
|
+
`index.html`.
|
|
78
85
|
|
|
79
86
|
### Event stream
|
|
80
87
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sukramj/fabric-ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "The web interface of go-fabric nodes: Svelte 5 pages, UI kit, design tokens with a Home Assistant theme bridge, and the generated API client.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "SukramJ",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<!-- Ported from openccu-loom assets/ui/src/lib/components/ui//Button.svelte:1-72 at b40b289a; the disabled fills use the
|
|
2
|
-
tokens instead of the slate ramp
|
|
2
|
+
tokens instead of the slate ramp, and the label on the primary fill uses --ha-on-primary-color (Home Assistant's
|
|
3
|
+
--text-primary-color under the HA skin). -->
|
|
3
4
|
<script lang="ts">
|
|
4
5
|
import type { Snippet } from "svelte";
|
|
5
6
|
import type { HTMLButtonAttributes } from "svelte/elements";
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
"disabled:bg-[var(--ha-secondary-background-color)] disabled:text-[var(--ha-disabled-text-color)] disabled:shadow-none";
|
|
19
20
|
const disabledMuted = "disabled:opacity-50 disabled:text-[var(--ha-disabled-text-color)]";
|
|
20
21
|
const variants: Record<Variant, string> = {
|
|
21
|
-
default: `bg-[var(--ha-primary-color)] text-
|
|
22
|
+
default: `bg-[var(--ha-primary-color)] text-[var(--ha-on-primary-color)] hover:bg-[var(--ha-primary-color-hover)] shadow-sm ${disabledFill}`,
|
|
22
23
|
outline: `border border-[var(--ha-divider-color)] bg-[var(--ha-card-background-color)] text-[var(--ha-primary-text-color)] hover:bg-[var(--ha-secondary-background-color)] ${disabledMuted}`,
|
|
23
24
|
ghost: `text-[var(--ha-primary-text-color)] hover:bg-[var(--ha-secondary-background-color)] ${disabledMuted}`,
|
|
24
25
|
destructive: `bg-[var(--ha-error-color)] text-white hover:brightness-95 shadow-sm ${disabledFill}`,
|
package/src/lib/kit/Tabs.svelte
CHANGED
|
@@ -20,14 +20,17 @@
|
|
|
20
20
|
|
|
21
21
|
const listClass = $derived(
|
|
22
22
|
variant === "underline"
|
|
23
|
-
?
|
|
23
|
+
? // The divider is an inset shadow, not a border the active marker
|
|
24
|
+
// overlaps with -mb-px: that 1px overflow made the scrollable list
|
|
25
|
+
// show a vertical scrollbar.
|
|
26
|
+
cn("flex gap-1 overflow-x-auto overflow-y-hidden shadow-[inset_0_-1px_0_var(--ha-divider-color)]", cls)
|
|
24
27
|
: cn("inline-flex flex-wrap gap-0.5 rounded-lg bg-[var(--ha-secondary-background-color)] p-0.5", cls),
|
|
25
28
|
);
|
|
26
29
|
|
|
27
30
|
function itemClass(isActive: boolean): string {
|
|
28
31
|
if (variant === "underline") {
|
|
29
32
|
return cn(
|
|
30
|
-
"
|
|
33
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap border-b-2 px-4 py-3 text-center text-sm font-medium transition",
|
|
31
34
|
fill && "flex-1",
|
|
32
35
|
isActive
|
|
33
36
|
? "border-[var(--ha-primary-color)] text-[var(--ha-primary-color)]"
|
|
@@ -115,7 +115,10 @@ export function startHaBridge(): () => void {
|
|
|
115
115
|
const ps = parentWin.getComputedStyle(parentRoot);
|
|
116
116
|
for (const name of HA_THEME_VARS) {
|
|
117
117
|
const value = ps.getPropertyValue(name).trim();
|
|
118
|
+
// A variable the parent no longer defines (a theme switched back
|
|
119
|
+
// to the default) is dropped, so the token falls back again.
|
|
118
120
|
if (value) ourRoot.style.setProperty(name, value);
|
|
121
|
+
else ourRoot.style.removeProperty(name);
|
|
119
122
|
}
|
|
120
123
|
// Follow Home Assistant's light/dark by its background luminance;
|
|
121
124
|
// this overrides the page's own choice while embedded.
|
package/src/lib/theme/tokens.css
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* on <html> flips it).
|
|
8
8
|
* - html[data-skin="ha"] — the tokens resolve from Home Assistant's own
|
|
9
9
|
* variables (var(--primary-color, …)); ha-bridge.ts copies the live values
|
|
10
|
-
* onto :root inside an Ingress frame, and the literals are the defaults
|
|
10
|
+
* onto :root inside an Ingress frame, and the literals are the defaults:
|
|
11
|
+
* Home Assistant's own default light and dark palettes. The standalone
|
|
12
|
+
* shell uses this skin too, set before the first paint (index.html).
|
|
11
13
|
* - the palette remap recolours plain Tailwind palette utilities under the
|
|
12
14
|
* HA skin.
|
|
13
15
|
* - .table-reflow turns a data table into cards on a phone.
|
|
@@ -45,6 +47,8 @@
|
|
|
45
47
|
--ha-elevation-modal: 0 10px 25px -5px rgb(0 0 0 / 0.15);
|
|
46
48
|
--ha-radius-card: 12px;
|
|
47
49
|
--ha-radius-control: 8px;
|
|
50
|
+
/* The label on a primary fill. */
|
|
51
|
+
--ha-on-primary-color: #ffffff;
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
html.dark {
|
|
@@ -92,6 +96,11 @@ html[data-skin="ha"] {
|
|
|
92
96
|
--ha-elevation-card: var(--ha-card-box-shadow, none); /* HA cards are flat */
|
|
93
97
|
--ha-elevation-modal: var(--ha-card-box-shadow, 0 8px 24px rgba(0, 0, 0, 0.18));
|
|
94
98
|
--font-sans: var(--ha-font-family-body, "Roboto", "Noto", "Helvetica Neue", Arial, sans-serif);
|
|
99
|
+
/* Home Assistant's text-on-primary, for a light primary in a custom theme. */
|
|
100
|
+
--ha-on-primary-color: var(--text-primary-color, #ffffff);
|
|
101
|
+
/* Native controls (checkboxes, radios, range, scrollbars) take the theme. */
|
|
102
|
+
accent-color: var(--ha-primary-color);
|
|
103
|
+
color-scheme: light;
|
|
95
104
|
}
|
|
96
105
|
|
|
97
106
|
html[data-skin="ha"].dark {
|
|
@@ -105,6 +114,7 @@ html[data-skin="ha"].dark {
|
|
|
105
114
|
--ha-primary-text-color: var(--primary-text-color, #e1e1e1);
|
|
106
115
|
--ha-secondary-text-color: var(--secondary-text-color, #9b9b9b);
|
|
107
116
|
--ha-disabled-text-color: var(--disabled-text-color, #6f6f6f);
|
|
117
|
+
color-scheme: dark;
|
|
108
118
|
}
|
|
109
119
|
|
|
110
120
|
/* Base document colours track the theme tokens so the boot paint and any
|