@lo-ink/ui 0.1.1 → 0.3.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/dist/AppIcon.d.ts.map +1 -1
- package/dist/AppIcon.js +1 -1
- package/dist/Dialog.d.ts +4 -0
- package/dist/Dialog.d.ts.map +1 -0
- package/dist/Dialog.js +7 -0
- package/dist/EmptyState.d.ts +2 -1
- package/dist/EmptyState.d.ts.map +1 -1
- package/dist/EmptyState.js +3 -2
- package/dist/List.d.ts +2 -1
- package/dist/List.d.ts.map +1 -1
- package/dist/List.js +3 -2
- package/dist/Progress.d.ts +3 -0
- package/dist/Progress.d.ts.map +1 -0
- package/dist/Progress.js +5 -0
- package/dist/Surface.d.ts +7 -0
- package/dist/Surface.d.ts.map +1 -0
- package/dist/Surface.js +8 -0
- package/dist/TextArea.d.ts +8 -0
- package/dist/TextArea.d.ts.map +1 -0
- package/dist/TextArea.js +11 -0
- package/dist/TextField.d.ts +1 -0
- package/dist/TextField.d.ts.map +1 -1
- package/dist/TextField.js +2 -2
- package/dist/Typography.d.ts +12 -6
- package/dist/Typography.d.ts.map +1 -1
- package/dist/Typography.js +7 -5
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/styles.css +186 -29
- package/package.json +2 -2
- package/src/AppIcon.tsx +1 -0
- package/src/Dialog.tsx +16 -0
- package/src/EmptyState.tsx +4 -1
- package/src/List.tsx +5 -2
- package/src/Progress.tsx +11 -0
- package/src/Surface.tsx +26 -0
- package/src/TextArea.tsx +60 -0
- package/src/TextField.tsx +9 -1
- package/src/Typography.tsx +28 -10
- package/src/index.ts +10 -1
- package/src/styles.css +186 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lo-ink/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Accessible React components for LO miniapps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"build": "tsc -p tsconfig.json && node scripts/copy-assets.mjs"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@lo-ink/design-tokens": "0.
|
|
36
|
+
"@lo-ink/design-tokens": "0.3.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"react": ">=18 <20",
|
package/src/AppIcon.tsx
CHANGED
package/src/Dialog.tsx
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { forwardRef, type DialogHTMLAttributes } from "react";
|
|
2
|
+
import { classes } from "./utils.js";
|
|
3
|
+
|
|
4
|
+
/** Native modal semantics; the caller controls showModal(), close() and cancellation. */
|
|
5
|
+
export const Dialog = forwardRef<
|
|
6
|
+
HTMLDialogElement,
|
|
7
|
+
DialogHTMLAttributes<HTMLDialogElement>
|
|
8
|
+
>(function Dialog({ className, ...props }, ref) {
|
|
9
|
+
return (
|
|
10
|
+
<dialog
|
|
11
|
+
{...props}
|
|
12
|
+
ref={ref}
|
|
13
|
+
className={classes("lo-ui-dialog", className)}
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
16
|
+
});
|
package/src/EmptyState.tsx
CHANGED
|
@@ -6,6 +6,7 @@ export interface EmptyStateProps extends Omit<
|
|
|
6
6
|
"title"
|
|
7
7
|
> {
|
|
8
8
|
title: ReactNode;
|
|
9
|
+
headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
9
10
|
description?: ReactNode;
|
|
10
11
|
icon?: ReactNode;
|
|
11
12
|
action?: ReactNode;
|
|
@@ -13,12 +14,14 @@ export interface EmptyStateProps extends Omit<
|
|
|
13
14
|
|
|
14
15
|
export function EmptyState({
|
|
15
16
|
title,
|
|
17
|
+
headingLevel = 2,
|
|
16
18
|
description,
|
|
17
19
|
icon,
|
|
18
20
|
action,
|
|
19
21
|
className,
|
|
20
22
|
...props
|
|
21
23
|
}: EmptyStateProps) {
|
|
24
|
+
const Tag = `h${headingLevel}` as "h2" | "h3" | "h4" | "h5" | "h6";
|
|
22
25
|
return (
|
|
23
26
|
<div {...props} className={classes("lo-ui-empty-state", className)}>
|
|
24
27
|
{icon && (
|
|
@@ -26,7 +29,7 @@ export function EmptyState({
|
|
|
26
29
|
{icon}
|
|
27
30
|
</div>
|
|
28
31
|
)}
|
|
29
|
-
<
|
|
32
|
+
<Tag className="lo-ui-empty-state__title">{title}</Tag>
|
|
30
33
|
{description && (
|
|
31
34
|
<p className="lo-ui-empty-state__description">{description}</p>
|
|
32
35
|
)}
|
package/src/List.tsx
CHANGED
|
@@ -3,16 +3,19 @@ import { classes } from "./utils.js";
|
|
|
3
3
|
|
|
4
4
|
export interface ListProps extends HTMLAttributes<HTMLUListElement> {
|
|
5
5
|
label?: ReactNode;
|
|
6
|
+
headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
export function List({
|
|
9
10
|
label,
|
|
11
|
+
headingLevel = 2,
|
|
10
12
|
children,
|
|
11
13
|
className,
|
|
12
14
|
"aria-label": ariaLabel,
|
|
13
15
|
"aria-labelledby": ariaLabelledBy,
|
|
14
16
|
...props
|
|
15
17
|
}: ListProps) {
|
|
18
|
+
const Tag = `h${headingLevel}` as "h2" | "h3" | "h4" | "h5" | "h6";
|
|
16
19
|
const generatedId = useId();
|
|
17
20
|
const labelId = label ? `${generatedId}-label` : undefined;
|
|
18
21
|
const effectiveLabelledBy =
|
|
@@ -20,9 +23,9 @@ export function List({
|
|
|
20
23
|
return (
|
|
21
24
|
<section className="lo-ui-list-section">
|
|
22
25
|
{label && (
|
|
23
|
-
<
|
|
26
|
+
<Tag className="lo-ui-list-label" id={labelId}>
|
|
24
27
|
{label}
|
|
25
|
-
</
|
|
28
|
+
</Tag>
|
|
26
29
|
)}
|
|
27
30
|
<ul
|
|
28
31
|
{...props}
|
package/src/Progress.tsx
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProgressHTMLAttributes } from "react";
|
|
2
|
+
import { classes } from "./utils.js";
|
|
3
|
+
|
|
4
|
+
export function Progress({
|
|
5
|
+
className,
|
|
6
|
+
...props
|
|
7
|
+
}: ProgressHTMLAttributes<HTMLProgressElement>) {
|
|
8
|
+
return (
|
|
9
|
+
<progress {...props} className={classes("lo-ui-progress", className)} />
|
|
10
|
+
);
|
|
11
|
+
}
|
package/src/Surface.tsx
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CSSProperties, HTMLAttributes } from "react";
|
|
2
|
+
import type { SpacingToken } from "@lo-ink/design-tokens";
|
|
3
|
+
import { classes } from "./utils.js";
|
|
4
|
+
|
|
5
|
+
export interface SurfaceProps extends HTMLAttributes<HTMLElement> {
|
|
6
|
+
padding?: SpacingToken;
|
|
7
|
+
}
|
|
8
|
+
export function Surface({
|
|
9
|
+
padding = 4,
|
|
10
|
+
className,
|
|
11
|
+
style,
|
|
12
|
+
...props
|
|
13
|
+
}: SurfaceProps) {
|
|
14
|
+
return (
|
|
15
|
+
<section
|
|
16
|
+
{...props}
|
|
17
|
+
className={classes("lo-ui-surface", className)}
|
|
18
|
+
style={
|
|
19
|
+
{
|
|
20
|
+
"--lo-surface-padding": `var(--lo-space-${padding})`,
|
|
21
|
+
...style,
|
|
22
|
+
} as CSSProperties
|
|
23
|
+
}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
}
|
package/src/TextArea.tsx
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useId,
|
|
4
|
+
type ReactNode,
|
|
5
|
+
type TextareaHTMLAttributes,
|
|
6
|
+
} from "react";
|
|
7
|
+
import { classes } from "./utils.js";
|
|
8
|
+
|
|
9
|
+
export interface TextAreaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
10
|
+
label: ReactNode;
|
|
11
|
+
description?: ReactNode;
|
|
12
|
+
error?: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
|
|
15
|
+
function TextArea(
|
|
16
|
+
{
|
|
17
|
+
label,
|
|
18
|
+
description,
|
|
19
|
+
error,
|
|
20
|
+
id: providedId,
|
|
21
|
+
className,
|
|
22
|
+
"aria-describedby": describedBy,
|
|
23
|
+
...props
|
|
24
|
+
},
|
|
25
|
+
ref,
|
|
26
|
+
) {
|
|
27
|
+
const generatedId = useId();
|
|
28
|
+
const id = providedId ?? generatedId;
|
|
29
|
+
const descriptionId = description ? `${id}-description` : undefined;
|
|
30
|
+
const errorId = error ? `${id}-error` : undefined;
|
|
31
|
+
return (
|
|
32
|
+
<div className={classes("lo-ui-field", className)}>
|
|
33
|
+
<label className="lo-ui-field__label" htmlFor={id}>
|
|
34
|
+
{label}
|
|
35
|
+
</label>
|
|
36
|
+
<textarea
|
|
37
|
+
{...props}
|
|
38
|
+
ref={ref}
|
|
39
|
+
id={id}
|
|
40
|
+
aria-invalid={error ? true : props["aria-invalid"]}
|
|
41
|
+
aria-describedby={
|
|
42
|
+
[describedBy, descriptionId, errorId].filter(Boolean).join(" ") ||
|
|
43
|
+
undefined
|
|
44
|
+
}
|
|
45
|
+
className="lo-ui-field__input lo-ui-textarea"
|
|
46
|
+
/>
|
|
47
|
+
{description && (
|
|
48
|
+
<div className="lo-ui-field__description" id={descriptionId}>
|
|
49
|
+
{description}
|
|
50
|
+
</div>
|
|
51
|
+
)}
|
|
52
|
+
{error && (
|
|
53
|
+
<div className="lo-ui-field__error" id={errorId}>
|
|
54
|
+
{error}
|
|
55
|
+
</div>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
},
|
|
60
|
+
);
|
package/src/TextField.tsx
CHANGED
|
@@ -14,6 +14,7 @@ export interface TextFieldProps extends Omit<
|
|
|
14
14
|
description?: ReactNode;
|
|
15
15
|
error?: ReactNode;
|
|
16
16
|
inputClassName?: string;
|
|
17
|
+
labelHidden?: boolean;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
@@ -25,6 +26,7 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
25
26
|
id: providedId,
|
|
26
27
|
className,
|
|
27
28
|
inputClassName,
|
|
29
|
+
labelHidden = false,
|
|
28
30
|
"aria-describedby": ariaDescribedBy,
|
|
29
31
|
...props
|
|
30
32
|
},
|
|
@@ -39,7 +41,13 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
39
41
|
.join(" ");
|
|
40
42
|
|
|
41
43
|
return (
|
|
42
|
-
<div
|
|
44
|
+
<div
|
|
45
|
+
className={classes(
|
|
46
|
+
"lo-ui-field",
|
|
47
|
+
labelHidden && "lo-ui-field--label-hidden",
|
|
48
|
+
className,
|
|
49
|
+
)}
|
|
50
|
+
>
|
|
43
51
|
<label className="lo-ui-field__label" htmlFor={id}>
|
|
44
52
|
{label}
|
|
45
53
|
</label>
|
package/src/Typography.tsx
CHANGED
|
@@ -1,33 +1,51 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { forwardRef, type HTMLAttributes } from "react";
|
|
2
2
|
import { classes } from "./utils.js";
|
|
3
3
|
|
|
4
|
-
export interface TextProps extends HTMLAttributes<
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
export interface TextProps extends HTMLAttributes<HTMLElement> {
|
|
5
|
+
as?: "p" | "span" | "strong" | "code" | "pre";
|
|
6
|
+
tone?: "primary" | "secondary" | "danger" | "success";
|
|
7
|
+
weight?: "regular" | "medium" | "bold";
|
|
8
|
+
family?: "ui" | "display" | "mono";
|
|
9
|
+
size?: "caption" | "label" | "body" | "title" | "display";
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
export function Text({
|
|
13
|
+
as: Tag = "p",
|
|
10
14
|
tone = "primary",
|
|
15
|
+
weight,
|
|
16
|
+
family,
|
|
11
17
|
size = "body",
|
|
12
18
|
className,
|
|
13
19
|
...props
|
|
14
20
|
}: TextProps) {
|
|
15
21
|
return (
|
|
16
|
-
<
|
|
22
|
+
<Tag
|
|
17
23
|
{...props}
|
|
18
24
|
className={classes(
|
|
19
25
|
"lo-ui-text",
|
|
20
26
|
`lo-ui-text--${tone}`,
|
|
21
27
|
`lo-ui-text--${size}`,
|
|
28
|
+
weight && `lo-ui-text--weight-${weight}`,
|
|
29
|
+
family && `lo-ui-text--family-${family}`,
|
|
22
30
|
className,
|
|
23
31
|
)}
|
|
24
32
|
/>
|
|
25
33
|
);
|
|
26
34
|
}
|
|
27
35
|
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
...props
|
|
31
|
-
}: HTMLAttributes<HTMLHeadingElement>) {
|
|
32
|
-
return <h1 {...props} className={classes("lo-ui-heading", className)} />;
|
|
36
|
+
export interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
|
|
37
|
+
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
33
38
|
}
|
|
39
|
+
|
|
40
|
+
export const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(
|
|
41
|
+
function Heading({ level = 1, className, ...props }, ref) {
|
|
42
|
+
const Tag = `h${level}` as "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
|
43
|
+
return (
|
|
44
|
+
<Tag
|
|
45
|
+
{...props}
|
|
46
|
+
ref={ref}
|
|
47
|
+
className={classes("lo-ui-heading", className)}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
},
|
|
51
|
+
);
|
package/src/index.ts
CHANGED
|
@@ -9,4 +9,13 @@ export {
|
|
|
9
9
|
type SelectionControlProps,
|
|
10
10
|
} from "./SelectionControl.js";
|
|
11
11
|
export { TextField, type TextFieldProps } from "./TextField.js";
|
|
12
|
-
export {
|
|
12
|
+
export {
|
|
13
|
+
Heading,
|
|
14
|
+
Text,
|
|
15
|
+
type HeadingProps,
|
|
16
|
+
type TextProps,
|
|
17
|
+
} from "./Typography.js";
|
|
18
|
+
export { TextArea, type TextAreaProps } from "./TextArea.js";
|
|
19
|
+
export { Surface, type SurfaceProps } from "./Surface.js";
|
|
20
|
+
export { Dialog } from "./Dialog.js";
|
|
21
|
+
export { Progress } from "./Progress.js";
|
package/src/styles.css
CHANGED
|
@@ -13,12 +13,16 @@
|
|
|
13
13
|
box-sizing: border-box;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
:where(.lo-ui-root button, .lo-ui-root input) {
|
|
16
|
+
:where(.lo-ui-root button, .lo-ui-root input, .lo-ui-root textarea) {
|
|
17
17
|
font: inherit;
|
|
18
18
|
-webkit-tap-highlight-color: transparent;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
:where(
|
|
21
|
+
:where(
|
|
22
|
+
.lo-ui-root button,
|
|
23
|
+
.lo-ui-root input,
|
|
24
|
+
.lo-ui-root textarea
|
|
25
|
+
):focus-visible {
|
|
22
26
|
outline: 3px solid var(--lo-color-focus);
|
|
23
27
|
outline-offset: 2px;
|
|
24
28
|
}
|
|
@@ -27,7 +31,12 @@
|
|
|
27
31
|
min-height: var(--lo-size-control);
|
|
28
32
|
padding: 0 var(--lo-space-5);
|
|
29
33
|
border: 1px solid transparent;
|
|
30
|
-
border-radius: var(--lo-radius-
|
|
34
|
+
border-radius: var(--lo-radius-full);
|
|
35
|
+
min-width: 0;
|
|
36
|
+
max-width: 100%;
|
|
37
|
+
white-space: normal;
|
|
38
|
+
overflow-wrap: anywhere;
|
|
39
|
+
text-align: center;
|
|
31
40
|
display: inline-flex;
|
|
32
41
|
align-items: center;
|
|
33
42
|
justify-content: center;
|
|
@@ -62,7 +71,7 @@
|
|
|
62
71
|
|
|
63
72
|
.lo-ui-button--primary {
|
|
64
73
|
color: var(--lo-color-accent-contrast);
|
|
65
|
-
background: var(--lo-color-accent);
|
|
74
|
+
background: var(--lo-color-accent-fill);
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
.lo-ui-button--primary:hover:not(:disabled) {
|
|
@@ -70,12 +79,19 @@
|
|
|
70
79
|
}
|
|
71
80
|
|
|
72
81
|
.lo-ui-button--secondary {
|
|
73
|
-
color: var(--lo-color-text);
|
|
74
|
-
background: var(--lo-color-
|
|
75
|
-
border-color:
|
|
82
|
+
color: var(--lo-color-accent-text);
|
|
83
|
+
background: var(--lo-color-accent-soft);
|
|
84
|
+
border-color: transparent;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.lo-ui-button--secondary:hover:not(:disabled) {
|
|
88
|
+
background: color-mix(
|
|
89
|
+
in srgb,
|
|
90
|
+
var(--lo-color-accent) 20%,
|
|
91
|
+
var(--lo-color-surface)
|
|
92
|
+
);
|
|
76
93
|
}
|
|
77
94
|
|
|
78
|
-
.lo-ui-button--secondary:hover:not(:disabled),
|
|
79
95
|
.lo-ui-button--quiet:hover:not(:disabled) {
|
|
80
96
|
background: var(--lo-color-accent-soft);
|
|
81
97
|
}
|
|
@@ -91,7 +107,7 @@
|
|
|
91
107
|
}
|
|
92
108
|
|
|
93
109
|
.lo-ui-button--quiet {
|
|
94
|
-
color: var(--lo-color-accent);
|
|
110
|
+
color: var(--lo-color-accent-text);
|
|
95
111
|
background: transparent;
|
|
96
112
|
}
|
|
97
113
|
|
|
@@ -135,7 +151,7 @@
|
|
|
135
151
|
padding: 10px var(--lo-space-3);
|
|
136
152
|
color: var(--lo-color-text);
|
|
137
153
|
background: var(--lo-color-surface);
|
|
138
|
-
border: 1px solid var(--lo-color-border);
|
|
154
|
+
border: 1px solid var(--lo-color-control-border);
|
|
139
155
|
border-radius: var(--lo-radius-md);
|
|
140
156
|
font-size: 16px;
|
|
141
157
|
transition:
|
|
@@ -209,7 +225,8 @@
|
|
|
209
225
|
justify-content: center;
|
|
210
226
|
}
|
|
211
227
|
|
|
212
|
-
.lo-ui-selection--control-only .lo-ui-selection__copy
|
|
228
|
+
.lo-ui-selection--control-only .lo-ui-selection__copy,
|
|
229
|
+
.lo-ui-field--label-hidden .lo-ui-field__label {
|
|
213
230
|
position: absolute;
|
|
214
231
|
width: 1px;
|
|
215
232
|
height: 1px;
|
|
@@ -228,7 +245,7 @@
|
|
|
228
245
|
padding: 2px;
|
|
229
246
|
border: 0;
|
|
230
247
|
border-radius: var(--lo-radius-full);
|
|
231
|
-
background: var(--lo-color-border);
|
|
248
|
+
background: var(--lo-color-control-border);
|
|
232
249
|
cursor: pointer;
|
|
233
250
|
transition: background-color var(--lo-motion-fast) var(--lo-ease-out);
|
|
234
251
|
}
|
|
@@ -245,7 +262,7 @@
|
|
|
245
262
|
}
|
|
246
263
|
|
|
247
264
|
.lo-ui-switch:checked {
|
|
248
|
-
background: var(--lo-color-accent);
|
|
265
|
+
background: var(--lo-color-accent-fill);
|
|
249
266
|
}
|
|
250
267
|
|
|
251
268
|
.lo-ui-switch:checked::after {
|
|
@@ -265,7 +282,7 @@
|
|
|
265
282
|
margin: 0;
|
|
266
283
|
display: grid;
|
|
267
284
|
place-items: center;
|
|
268
|
-
border: 1.5px solid var(--lo-color-border);
|
|
285
|
+
border: 1.5px solid var(--lo-color-control-border);
|
|
269
286
|
border-radius: 7px;
|
|
270
287
|
background: var(--lo-color-surface);
|
|
271
288
|
cursor: pointer;
|
|
@@ -282,8 +299,13 @@
|
|
|
282
299
|
}
|
|
283
300
|
|
|
284
301
|
.lo-ui-checkbox:checked {
|
|
285
|
-
background: var(--lo-color-accent);
|
|
286
|
-
border-color: var(--lo-color-accent);
|
|
302
|
+
background: var(--lo-color-accent-fill);
|
|
303
|
+
border-color: var(--lo-color-accent-fill);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.lo-ui-checkbox:disabled {
|
|
307
|
+
cursor: default;
|
|
308
|
+
opacity: 0.5;
|
|
287
309
|
}
|
|
288
310
|
|
|
289
311
|
.lo-ui-checkbox:checked::after {
|
|
@@ -384,6 +406,7 @@
|
|
|
384
406
|
|
|
385
407
|
.lo-ui-cell__title {
|
|
386
408
|
font-size: var(--lo-font-size-body);
|
|
409
|
+
font-weight: var(--lo-font-weight-medium);
|
|
387
410
|
}
|
|
388
411
|
|
|
389
412
|
.lo-ui-cell__subtitle {
|
|
@@ -424,19 +447,24 @@
|
|
|
424
447
|
place-items: center;
|
|
425
448
|
border-radius: 11px;
|
|
426
449
|
color: var(--lo-color-accent-contrast);
|
|
427
|
-
background: var(--lo-color-accent);
|
|
450
|
+
background: var(--lo-color-accent-fill);
|
|
451
|
+
font-size: 18px;
|
|
452
|
+
font-weight: var(--lo-font-weight-medium);
|
|
453
|
+
line-height: 1;
|
|
428
454
|
}
|
|
429
455
|
|
|
430
456
|
.lo-ui-app-icon--small {
|
|
431
457
|
width: 32px;
|
|
432
458
|
height: 32px;
|
|
433
459
|
border-radius: 8px;
|
|
460
|
+
font-size: 14px;
|
|
434
461
|
}
|
|
435
462
|
|
|
436
463
|
.lo-ui-app-icon--large {
|
|
437
464
|
width: 64px;
|
|
438
465
|
height: 64px;
|
|
439
466
|
border-radius: 16px;
|
|
467
|
+
font-size: 26px;
|
|
440
468
|
}
|
|
441
469
|
|
|
442
470
|
.lo-ui-app-icon > img {
|
|
@@ -452,28 +480,25 @@
|
|
|
452
480
|
}
|
|
453
481
|
|
|
454
482
|
.lo-ui-empty-state {
|
|
455
|
-
|
|
456
|
-
padding: var(--lo-space-8) var(--lo-space-6);
|
|
483
|
+
padding: 30px 15px;
|
|
457
484
|
display: flex;
|
|
458
485
|
flex-direction: column;
|
|
459
486
|
align-items: center;
|
|
460
487
|
justify-content: center;
|
|
461
|
-
gap:
|
|
488
|
+
gap: 10px;
|
|
462
489
|
text-align: center;
|
|
463
|
-
border: 1px
|
|
464
|
-
border-radius: var(--lo-radius-lg);
|
|
490
|
+
border: 1px solid color-mix(in srgb, var(--lo-color-accent) 4%, transparent);
|
|
491
|
+
border-radius: calc(var(--lo-radius-lg) + 2px);
|
|
465
492
|
background: var(--lo-color-surface);
|
|
466
493
|
}
|
|
467
494
|
|
|
468
495
|
.lo-ui-empty-state__icon {
|
|
469
496
|
width: 52px;
|
|
470
497
|
height: 52px;
|
|
471
|
-
margin-bottom:
|
|
498
|
+
margin-bottom: 5px;
|
|
472
499
|
display: grid;
|
|
473
500
|
place-items: center;
|
|
474
|
-
|
|
475
|
-
color: var(--lo-color-accent);
|
|
476
|
-
background: var(--lo-color-accent-soft);
|
|
501
|
+
color: var(--lo-color-accent-text);
|
|
477
502
|
}
|
|
478
503
|
|
|
479
504
|
.lo-ui-empty-state__icon > svg {
|
|
@@ -489,18 +514,20 @@
|
|
|
489
514
|
}
|
|
490
515
|
|
|
491
516
|
.lo-ui-empty-state__title {
|
|
492
|
-
font-
|
|
517
|
+
font-family: var(--lo-font-family);
|
|
518
|
+
color: var(--lo-color-text);
|
|
519
|
+
font-size: 26px;
|
|
493
520
|
line-height: var(--lo-line-height-tight);
|
|
494
521
|
}
|
|
495
522
|
|
|
496
523
|
.lo-ui-empty-state__description {
|
|
497
524
|
max-width: 36ch;
|
|
498
525
|
color: var(--lo-color-text-secondary);
|
|
499
|
-
font-size: var(--lo-font-size-
|
|
526
|
+
font-size: var(--lo-font-size-body);
|
|
500
527
|
}
|
|
501
528
|
|
|
502
529
|
.lo-ui-empty-state__action {
|
|
503
|
-
margin-top:
|
|
530
|
+
margin-top: 5px;
|
|
504
531
|
}
|
|
505
532
|
|
|
506
533
|
.lo-ui-stack,
|
|
@@ -519,11 +546,15 @@
|
|
|
519
546
|
}
|
|
520
547
|
|
|
521
548
|
.lo-ui-heading {
|
|
549
|
+
font-family: var(--lo-font-family);
|
|
550
|
+
color: var(--lo-color-text);
|
|
551
|
+
font-weight: var(--lo-font-weight-bold);
|
|
522
552
|
font-size: var(--lo-font-size-title);
|
|
523
553
|
line-height: var(--lo-line-height-tight);
|
|
524
554
|
}
|
|
525
555
|
|
|
526
556
|
.lo-ui-text {
|
|
557
|
+
color: var(--lo-color-text);
|
|
527
558
|
line-height: var(--lo-line-height-body);
|
|
528
559
|
}
|
|
529
560
|
|
|
@@ -558,3 +589,129 @@
|
|
|
558
589
|
animation: none;
|
|
559
590
|
}
|
|
560
591
|
}
|
|
592
|
+
|
|
593
|
+
.lo-ui-surface {
|
|
594
|
+
min-width: 0;
|
|
595
|
+
padding: var(--lo-surface-padding);
|
|
596
|
+
border: 1px solid var(--lo-color-border);
|
|
597
|
+
border-radius: var(--lo-radius-lg);
|
|
598
|
+
background: var(--lo-color-surface);
|
|
599
|
+
color: var(--lo-color-text);
|
|
600
|
+
}
|
|
601
|
+
.lo-ui-dialog {
|
|
602
|
+
box-sizing: border-box;
|
|
603
|
+
width: min(560px, calc(100% - 32px));
|
|
604
|
+
max-height: calc(100dvh - 32px);
|
|
605
|
+
overflow-y: auto;
|
|
606
|
+
padding: var(--lo-space-5);
|
|
607
|
+
border: 1px solid var(--lo-color-border);
|
|
608
|
+
border-radius: var(--lo-radius-lg);
|
|
609
|
+
color: var(--lo-color-text);
|
|
610
|
+
background: var(--lo-color-surface);
|
|
611
|
+
}
|
|
612
|
+
.lo-ui-dialog::backdrop {
|
|
613
|
+
background: #12162466;
|
|
614
|
+
}
|
|
615
|
+
.lo-ui-textarea {
|
|
616
|
+
resize: vertical;
|
|
617
|
+
line-height: var(--lo-line-height-body);
|
|
618
|
+
}
|
|
619
|
+
.lo-ui-field__input[type="file"] {
|
|
620
|
+
padding: var(--lo-space-2);
|
|
621
|
+
}
|
|
622
|
+
.lo-ui-field__input::file-selector-button {
|
|
623
|
+
font: inherit;
|
|
624
|
+
color: var(--lo-color-accent-text);
|
|
625
|
+
background: var(--lo-color-accent-soft);
|
|
626
|
+
border: 0;
|
|
627
|
+
border-radius: var(--lo-radius-full);
|
|
628
|
+
padding: var(--lo-space-2) var(--lo-space-3);
|
|
629
|
+
margin-right: var(--lo-space-2);
|
|
630
|
+
cursor: pointer;
|
|
631
|
+
}
|
|
632
|
+
.lo-ui-progress {
|
|
633
|
+
display: block;
|
|
634
|
+
appearance: none;
|
|
635
|
+
border: 0;
|
|
636
|
+
width: 100%;
|
|
637
|
+
height: 10px;
|
|
638
|
+
border-radius: var(--lo-radius-full);
|
|
639
|
+
overflow: hidden;
|
|
640
|
+
background: var(--lo-color-border);
|
|
641
|
+
color: var(--lo-color-accent);
|
|
642
|
+
}
|
|
643
|
+
.lo-ui-progress::-webkit-progress-bar {
|
|
644
|
+
background: var(--lo-color-border);
|
|
645
|
+
}
|
|
646
|
+
.lo-ui-progress::-webkit-progress-value {
|
|
647
|
+
background: var(--lo-color-accent);
|
|
648
|
+
border-radius: var(--lo-radius-full);
|
|
649
|
+
}
|
|
650
|
+
.lo-ui-progress::-moz-progress-bar {
|
|
651
|
+
background: var(--lo-color-accent);
|
|
652
|
+
border-radius: var(--lo-radius-full);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
:where(.lo-ui-root code, .lo-ui-root pre) {
|
|
656
|
+
font-family: var(--lo-font-family-mono);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
.lo-ui-app-icon:has(> img) {
|
|
660
|
+
background: transparent;
|
|
661
|
+
}
|
|
662
|
+
.lo-ui-progress:indeterminate {
|
|
663
|
+
background-image: linear-gradient(
|
|
664
|
+
90deg,
|
|
665
|
+
var(--lo-color-border) 0% 30%,
|
|
666
|
+
var(--lo-color-accent) 30% 50%,
|
|
667
|
+
var(--lo-color-border) 50% 100%
|
|
668
|
+
);
|
|
669
|
+
background-size: 200% 100%;
|
|
670
|
+
animation: lo-ui-progress-pending 1.4s linear infinite;
|
|
671
|
+
}
|
|
672
|
+
.lo-ui-progress:indeterminate::-webkit-progress-bar {
|
|
673
|
+
background: transparent;
|
|
674
|
+
}
|
|
675
|
+
@keyframes lo-ui-progress-pending {
|
|
676
|
+
from {
|
|
677
|
+
background-position: 100% 0;
|
|
678
|
+
}
|
|
679
|
+
to {
|
|
680
|
+
background-position: 0% 0;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
@media (prefers-reduced-motion: reduce) {
|
|
684
|
+
.lo-ui-progress:indeterminate {
|
|
685
|
+
animation: none;
|
|
686
|
+
background-position: 50% 0;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.lo-ui-text--title {
|
|
691
|
+
font-size: 26px;
|
|
692
|
+
}
|
|
693
|
+
.lo-ui-text--display {
|
|
694
|
+
font-size: 40px;
|
|
695
|
+
line-height: var(--lo-line-height-tight);
|
|
696
|
+
}
|
|
697
|
+
.lo-ui-text--success {
|
|
698
|
+
color: var(--lo-color-success);
|
|
699
|
+
}
|
|
700
|
+
.lo-ui-text--weight-regular {
|
|
701
|
+
font-weight: var(--lo-font-weight-regular);
|
|
702
|
+
}
|
|
703
|
+
.lo-ui-text--weight-medium {
|
|
704
|
+
font-weight: var(--lo-font-weight-medium);
|
|
705
|
+
}
|
|
706
|
+
.lo-ui-text--weight-bold {
|
|
707
|
+
font-weight: var(--lo-font-weight-bold);
|
|
708
|
+
}
|
|
709
|
+
.lo-ui-text--family-ui {
|
|
710
|
+
font-family: var(--lo-font-family);
|
|
711
|
+
}
|
|
712
|
+
.lo-ui-text--family-display {
|
|
713
|
+
font-family: var(--lo-font-family-display);
|
|
714
|
+
}
|
|
715
|
+
.lo-ui-text--family-mono {
|
|
716
|
+
font-family: var(--lo-font-family-mono);
|
|
717
|
+
}
|