@lo-ink/ui 0.2.0 → 0.3.1
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/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 +9 -6
- package/dist/Typography.d.ts.map +1 -1
- package/dist/Typography.js +6 -5
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/styles.css +150 -15
- package/package.json +3 -3
- package/src/AppIcon.tsx +1 -0
- package/src/Dialog.tsx +16 -0
- 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 +25 -9
- package/src/index.ts +4 -0
- package/src/styles.css +150 -15
package/dist/AppIcon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppIcon.d.ts","sourceRoot":"","sources":["../src/AppIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG1E,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,eAAe,CAAC;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,UAAU,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC;CACvE;AAED,wBAAgB,OAAO,CAAC,EACtB,GAAG,EACH,GAAQ,EACR,IAAe,EACf,QAAQ,EACR,UAAU,EACV,SAAS,EACT,GAAG,KAAK,EACT,EAAE,YAAY,+
|
|
1
|
+
{"version":3,"file":"AppIcon.d.ts","sourceRoot":"","sources":["../src/AppIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG1E,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,eAAe,CAAC;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,UAAU,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC;CACvE;AAED,wBAAgB,OAAO,CAAC,EACtB,GAAG,EACH,GAAQ,EACR,IAAe,EACf,QAAQ,EACR,UAAU,EACV,SAAS,EACT,GAAG,KAAK,EACT,EAAE,YAAY,+BAcd"}
|
package/dist/AppIcon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { classes } from "./utils.js";
|
|
3
3
|
export function AppIcon({ src, alt = "", size = "medium", children, imageProps, className, ...props }) {
|
|
4
|
-
return (_jsx("span", { ...props, className: classes("lo-ui-app-icon", `lo-ui-app-icon--${size}`, className), children: src ? _jsx("img", { ...imageProps, src: src, alt: alt }) : children }));
|
|
4
|
+
return (_jsx("span", { ...props, role: props.role ?? (!src && props["aria-label"] ? "img" : undefined), className: classes("lo-ui-app-icon", `lo-ui-app-icon--${size}`, className), children: src ? _jsx("img", { ...imageProps, src: src, alt: alt }) : children }));
|
|
5
5
|
}
|
package/dist/Dialog.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type DialogHTMLAttributes } from "react";
|
|
2
|
+
/** Native modal semantics; the caller controls showModal(), close() and cancellation. */
|
|
3
|
+
export declare const Dialog: import("react").ForwardRefExoticComponent<DialogHTMLAttributes<HTMLDialogElement> & import("react").RefAttributes<HTMLDialogElement>>;
|
|
4
|
+
//# sourceMappingURL=Dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../src/Dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAG9D,yFAAyF;AACzF,eAAO,MAAM,MAAM,uIAWjB,CAAC"}
|
package/dist/Dialog.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { classes } from "./utils.js";
|
|
4
|
+
/** Native modal semantics; the caller controls showModal(), close() and cancellation. */
|
|
5
|
+
export const Dialog = forwardRef(function Dialog({ className, ...props }, ref) {
|
|
6
|
+
return (_jsx("dialog", { ...props, ref: ref, className: classes("lo-ui-dialog", className) }));
|
|
7
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../src/Progress.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAGpD,wBAAgB,QAAQ,CAAC,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,sBAAsB,CAAC,mBAAmB,CAAC,+BAI7C"}
|
package/dist/Progress.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "react";
|
|
2
|
+
import type { SpacingToken } from "@lo-ink/design-tokens";
|
|
3
|
+
export interface SurfaceProps extends HTMLAttributes<HTMLElement> {
|
|
4
|
+
padding?: SpacingToken;
|
|
5
|
+
}
|
|
6
|
+
export declare function Surface({ padding, className, style, ...props }: SurfaceProps): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=Surface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Surface.d.ts","sourceRoot":"","sources":["../src/Surface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1D,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,WAAW,CAAC;IAC/D,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AACD,wBAAgB,OAAO,CAAC,EACtB,OAAW,EACX,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,YAAY,+BAad"}
|
package/dist/Surface.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { classes } from "./utils.js";
|
|
3
|
+
export function Surface({ padding = 4, className, style, ...props }) {
|
|
4
|
+
return (_jsx("section", { ...props, className: classes("lo-ui-surface", className), style: {
|
|
5
|
+
"--lo-surface-padding": `var(--lo-space-${padding})`,
|
|
6
|
+
...style,
|
|
7
|
+
} }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ReactNode, type TextareaHTMLAttributes } from "react";
|
|
2
|
+
export interface TextAreaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
3
|
+
label: ReactNode;
|
|
4
|
+
description?: ReactNode;
|
|
5
|
+
error?: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare const TextArea: import("react").ForwardRefExoticComponent<TextAreaProps & import("react").RefAttributes<HTMLTextAreaElement>>;
|
|
8
|
+
//# sourceMappingURL=TextArea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../src/TextArea.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,sBAAsB,EAC5B,MAAM,OAAO,CAAC;AAGf,MAAM,WAAW,aAAc,SAAQ,sBAAsB,CAAC,mBAAmB,CAAC;IAChF,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AACD,eAAO,MAAM,QAAQ,+GA8CpB,CAAC"}
|
package/dist/TextArea.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useId, } from "react";
|
|
3
|
+
import { classes } from "./utils.js";
|
|
4
|
+
export const TextArea = forwardRef(function TextArea({ label, description, error, id: providedId, className, "aria-describedby": describedBy, ...props }, ref) {
|
|
5
|
+
const generatedId = useId();
|
|
6
|
+
const id = providedId ?? generatedId;
|
|
7
|
+
const descriptionId = description ? `${id}-description` : undefined;
|
|
8
|
+
const errorId = error ? `${id}-error` : undefined;
|
|
9
|
+
return (_jsxs("div", { className: classes("lo-ui-field", className), children: [_jsx("label", { className: "lo-ui-field__label", htmlFor: id, children: label }), _jsx("textarea", { ...props, ref: ref, id: id, "aria-invalid": error ? true : props["aria-invalid"], "aria-describedby": [describedBy, descriptionId, errorId].filter(Boolean).join(" ") ||
|
|
10
|
+
undefined, className: "lo-ui-field__input lo-ui-textarea" }), description && (_jsx("div", { className: "lo-ui-field__description", id: descriptionId, children: description })), error && (_jsx("div", { className: "lo-ui-field__error", id: errorId, children: error }))] }));
|
|
11
|
+
});
|
package/dist/TextField.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export interface TextFieldProps extends Omit<InputHTMLAttributes<HTMLInputElemen
|
|
|
4
4
|
description?: ReactNode;
|
|
5
5
|
error?: ReactNode;
|
|
6
6
|
inputClassName?: string;
|
|
7
|
+
labelHidden?: boolean;
|
|
7
8
|
}
|
|
8
9
|
export declare const TextField: import("react").ForwardRefExoticComponent<TextFieldProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
9
10
|
//# sourceMappingURL=TextField.d.ts.map
|
package/dist/TextField.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextField.d.ts","sourceRoot":"","sources":["../src/TextField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,mBAAmB,CAAC,gBAAgB,CAAC,EACrC,MAAM,CACP;IACC,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"TextField.d.ts","sourceRoot":"","sources":["../src/TextField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,mBAAmB,CAAC,gBAAgB,CAAC,EACrC,MAAM,CACP;IACC,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,SAAS,6GAuDrB,CAAC"}
|
package/dist/TextField.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useId, } from "react";
|
|
3
3
|
import { classes } from "./utils.js";
|
|
4
|
-
export const TextField = forwardRef(function TextField({ label, description, error, id: providedId, className, inputClassName, "aria-describedby": ariaDescribedBy, ...props }, ref) {
|
|
4
|
+
export const TextField = forwardRef(function TextField({ label, description, error, id: providedId, className, inputClassName, labelHidden = false, "aria-describedby": ariaDescribedBy, ...props }, ref) {
|
|
5
5
|
const generatedId = useId();
|
|
6
6
|
const id = providedId ?? generatedId;
|
|
7
7
|
const descriptionId = description ? `${id}-description` : undefined;
|
|
@@ -9,5 +9,5 @@ export const TextField = forwardRef(function TextField({ label, description, err
|
|
|
9
9
|
const describedBy = [ariaDescribedBy, descriptionId, errorId]
|
|
10
10
|
.filter(Boolean)
|
|
11
11
|
.join(" ");
|
|
12
|
-
return (_jsxs("div", { className: classes("lo-ui-field", className), children: [_jsx("label", { className: "lo-ui-field__label", htmlFor: id, children: label }), _jsx("input", { ...props, ref: ref, id: id, "aria-invalid": error ? true : props["aria-invalid"], "aria-describedby": describedBy || undefined, className: classes("lo-ui-field__input", inputClassName) }), description && (_jsx("div", { className: "lo-ui-field__description", id: descriptionId, children: description })), error && (_jsx("div", { className: "lo-ui-field__error", id: errorId, children: error }))] }));
|
|
12
|
+
return (_jsxs("div", { className: classes("lo-ui-field", labelHidden && "lo-ui-field--label-hidden", className), children: [_jsx("label", { className: "lo-ui-field__label", htmlFor: id, children: label }), _jsx("input", { ...props, ref: ref, id: id, "aria-invalid": error ? true : props["aria-invalid"], "aria-describedby": describedBy || undefined, className: classes("lo-ui-field__input", inputClassName) }), description && (_jsx("div", { className: "lo-ui-field__description", id: descriptionId, children: description })), error && (_jsx("div", { className: "lo-ui-field__error", id: errorId, children: error }))] }));
|
|
13
13
|
});
|
package/dist/Typography.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import type
|
|
2
|
-
export interface TextProps extends HTMLAttributes<
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { type HTMLAttributes } from "react";
|
|
2
|
+
export interface TextProps extends HTMLAttributes<HTMLElement> {
|
|
3
|
+
as?: "p" | "span" | "strong" | "code" | "pre";
|
|
4
|
+
tone?: "primary" | "secondary" | "danger" | "success";
|
|
5
|
+
weight?: "regular" | "medium" | "bold";
|
|
6
|
+
family?: "ui" | "display" | "mono";
|
|
7
|
+
size?: "caption" | "label" | "body" | "title" | "display";
|
|
5
8
|
}
|
|
6
|
-
export declare function Text({ tone, size, className, ...props }: TextProps): import("react").JSX.Element;
|
|
9
|
+
export declare function Text({ as: Tag, tone, weight, family, size, className, ...props }: TextProps): import("react").JSX.Element;
|
|
7
10
|
export interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
|
|
8
11
|
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
9
12
|
}
|
|
10
|
-
export declare
|
|
13
|
+
export declare const Heading: import("react").ForwardRefExoticComponent<HeadingProps & import("react").RefAttributes<HTMLHeadingElement>>;
|
|
11
14
|
//# sourceMappingURL=Typography.d.ts.map
|
package/dist/Typography.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Typography.d.ts","sourceRoot":"","sources":["../src/Typography.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"Typography.d.ts","sourceRoot":"","sources":["../src/Typography.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAGxD,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,WAAW,CAAC;IAC5D,EAAE,CAAC,EAAE,GAAG,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;IAC9C,IAAI,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtD,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IACvC,MAAM,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC;IACnC,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CAC3D;AAED,wBAAgB,IAAI,CAAC,EACnB,EAAE,EAAE,GAAS,EACb,IAAgB,EAChB,MAAM,EACN,MAAM,EACN,IAAa,EACb,SAAS,EACT,GAAG,KAAK,EACT,EAAE,SAAS,+BAcX;AAED,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,kBAAkB,CAAC;IACtE,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC/B;AAED,eAAO,MAAM,OAAO,6GAWnB,CAAC"}
|
package/dist/Typography.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
2
3
|
import { classes } from "./utils.js";
|
|
3
|
-
export function Text({ tone = "primary", size = "body", className, ...props }) {
|
|
4
|
-
return (_jsx(
|
|
4
|
+
export function Text({ as: Tag = "p", tone = "primary", weight, family, size = "body", className, ...props }) {
|
|
5
|
+
return (_jsx(Tag, { ...props, className: classes("lo-ui-text", `lo-ui-text--${tone}`, `lo-ui-text--${size}`, weight && `lo-ui-text--weight-${weight}`, family && `lo-ui-text--family-${family}`, className) }));
|
|
5
6
|
}
|
|
6
|
-
export function Heading({ level = 1, className, ...props }) {
|
|
7
|
+
export const Heading = forwardRef(function Heading({ level = 1, className, ...props }, ref) {
|
|
7
8
|
const Tag = `h${level}`;
|
|
8
|
-
return _jsx(Tag, { ...props, className: classes("lo-ui-heading", className) });
|
|
9
|
-
}
|
|
9
|
+
return (_jsx(Tag, { ...props, ref: ref, className: classes("lo-ui-heading", className) }));
|
|
10
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -6,4 +6,8 @@ export { Cell, List, type CellProps, type ListProps } from "./List.js";
|
|
|
6
6
|
export { Checkbox, Switch, type SelectionControlProps, } from "./SelectionControl.js";
|
|
7
7
|
export { TextField, type TextFieldProps } from "./TextField.js";
|
|
8
8
|
export { Heading, Text, type HeadingProps, type TextProps, } from "./Typography.js";
|
|
9
|
+
export { TextArea, type TextAreaProps } from "./TextArea.js";
|
|
10
|
+
export { Surface, type SurfaceProps } from "./Surface.js";
|
|
11
|
+
export { Dialog } from "./Dialog.js";
|
|
12
|
+
export { Progress } from "./Progress.js";
|
|
9
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EACL,QAAQ,EACR,MAAM,EACN,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EACL,OAAO,EACP,IAAI,EACJ,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EACL,QAAQ,EACR,MAAM,EACN,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EACL,OAAO,EACP,IAAI,EACJ,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,3 +6,7 @@ export { Cell, List } from "./List.js";
|
|
|
6
6
|
export { Checkbox, Switch, } from "./SelectionControl.js";
|
|
7
7
|
export { TextField } from "./TextField.js";
|
|
8
8
|
export { Heading, Text, } from "./Typography.js";
|
|
9
|
+
export { TextArea } from "./TextArea.js";
|
|
10
|
+
export { Surface } from "./Surface.js";
|
|
11
|
+
export { Dialog } from "./Dialog.js";
|
|
12
|
+
export { Progress } from "./Progress.js";
|
package/dist/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
|
}
|
|
@@ -221,7 +225,8 @@
|
|
|
221
225
|
justify-content: center;
|
|
222
226
|
}
|
|
223
227
|
|
|
224
|
-
.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 {
|
|
225
230
|
position: absolute;
|
|
226
231
|
width: 1px;
|
|
227
232
|
height: 1px;
|
|
@@ -443,18 +448,23 @@
|
|
|
443
448
|
border-radius: 11px;
|
|
444
449
|
color: var(--lo-color-accent-contrast);
|
|
445
450
|
background: var(--lo-color-accent-fill);
|
|
451
|
+
font-size: 18px;
|
|
452
|
+
font-weight: var(--lo-font-weight-medium);
|
|
453
|
+
line-height: 1;
|
|
446
454
|
}
|
|
447
455
|
|
|
448
456
|
.lo-ui-app-icon--small {
|
|
449
457
|
width: 32px;
|
|
450
458
|
height: 32px;
|
|
451
459
|
border-radius: 8px;
|
|
460
|
+
font-size: 14px;
|
|
452
461
|
}
|
|
453
462
|
|
|
454
463
|
.lo-ui-app-icon--large {
|
|
455
464
|
width: 64px;
|
|
456
465
|
height: 64px;
|
|
457
466
|
border-radius: 16px;
|
|
467
|
+
font-size: 26px;
|
|
458
468
|
}
|
|
459
469
|
|
|
460
470
|
.lo-ui-app-icon > img {
|
|
@@ -470,28 +480,25 @@
|
|
|
470
480
|
}
|
|
471
481
|
|
|
472
482
|
.lo-ui-empty-state {
|
|
473
|
-
|
|
474
|
-
padding: var(--lo-space-8) var(--lo-space-6);
|
|
483
|
+
padding: 30px 15px;
|
|
475
484
|
display: flex;
|
|
476
485
|
flex-direction: column;
|
|
477
486
|
align-items: center;
|
|
478
487
|
justify-content: center;
|
|
479
|
-
gap:
|
|
488
|
+
gap: 10px;
|
|
480
489
|
text-align: center;
|
|
481
|
-
border: 1px
|
|
482
|
-
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);
|
|
483
492
|
background: var(--lo-color-surface);
|
|
484
493
|
}
|
|
485
494
|
|
|
486
495
|
.lo-ui-empty-state__icon {
|
|
487
496
|
width: 52px;
|
|
488
497
|
height: 52px;
|
|
489
|
-
margin-bottom:
|
|
498
|
+
margin-bottom: 5px;
|
|
490
499
|
display: grid;
|
|
491
500
|
place-items: center;
|
|
492
|
-
|
|
493
|
-
color: var(--lo-color-accent);
|
|
494
|
-
background: var(--lo-color-accent-soft);
|
|
501
|
+
color: var(--lo-color-accent-text);
|
|
495
502
|
}
|
|
496
503
|
|
|
497
504
|
.lo-ui-empty-state__icon > svg {
|
|
@@ -507,19 +514,20 @@
|
|
|
507
514
|
}
|
|
508
515
|
|
|
509
516
|
.lo-ui-empty-state__title {
|
|
517
|
+
font-family: var(--lo-font-family);
|
|
510
518
|
color: var(--lo-color-text);
|
|
511
|
-
font-size:
|
|
519
|
+
font-size: 26px;
|
|
512
520
|
line-height: var(--lo-line-height-tight);
|
|
513
521
|
}
|
|
514
522
|
|
|
515
523
|
.lo-ui-empty-state__description {
|
|
516
524
|
max-width: 36ch;
|
|
517
525
|
color: var(--lo-color-text-secondary);
|
|
518
|
-
font-size: var(--lo-font-size-
|
|
526
|
+
font-size: var(--lo-font-size-body);
|
|
519
527
|
}
|
|
520
528
|
|
|
521
529
|
.lo-ui-empty-state__action {
|
|
522
|
-
margin-top:
|
|
530
|
+
margin-top: 5px;
|
|
523
531
|
}
|
|
524
532
|
|
|
525
533
|
.lo-ui-stack,
|
|
@@ -538,6 +546,7 @@
|
|
|
538
546
|
}
|
|
539
547
|
|
|
540
548
|
.lo-ui-heading {
|
|
549
|
+
font-family: var(--lo-font-family);
|
|
541
550
|
color: var(--lo-color-text);
|
|
542
551
|
font-weight: var(--lo-font-weight-bold);
|
|
543
552
|
font-size: var(--lo-font-size-title);
|
|
@@ -580,3 +589,129 @@
|
|
|
580
589
|
animation: none;
|
|
581
590
|
}
|
|
582
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
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lo-ink/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Accessible React components for LO miniapps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"prepack": "npm run build",
|
|
33
|
-
"build": "
|
|
33
|
+
"build": "node ../../scripts/build-package.mjs"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@lo-ink/design-tokens": "0.
|
|
36
|
+
"@lo-ink/design-tokens": "0.3.1"
|
|
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/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,24 +1,32 @@
|
|
|
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
|
/>
|
|
@@ -29,7 +37,15 @@ export interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
|
|
|
29
37
|
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
30
38
|
}
|
|
31
39
|
|
|
32
|
-
export
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
@@ -15,3 +15,7 @@ export {
|
|
|
15
15
|
type HeadingProps,
|
|
16
16
|
type TextProps,
|
|
17
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
|
}
|
|
@@ -221,7 +225,8 @@
|
|
|
221
225
|
justify-content: center;
|
|
222
226
|
}
|
|
223
227
|
|
|
224
|
-
.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 {
|
|
225
230
|
position: absolute;
|
|
226
231
|
width: 1px;
|
|
227
232
|
height: 1px;
|
|
@@ -443,18 +448,23 @@
|
|
|
443
448
|
border-radius: 11px;
|
|
444
449
|
color: var(--lo-color-accent-contrast);
|
|
445
450
|
background: var(--lo-color-accent-fill);
|
|
451
|
+
font-size: 18px;
|
|
452
|
+
font-weight: var(--lo-font-weight-medium);
|
|
453
|
+
line-height: 1;
|
|
446
454
|
}
|
|
447
455
|
|
|
448
456
|
.lo-ui-app-icon--small {
|
|
449
457
|
width: 32px;
|
|
450
458
|
height: 32px;
|
|
451
459
|
border-radius: 8px;
|
|
460
|
+
font-size: 14px;
|
|
452
461
|
}
|
|
453
462
|
|
|
454
463
|
.lo-ui-app-icon--large {
|
|
455
464
|
width: 64px;
|
|
456
465
|
height: 64px;
|
|
457
466
|
border-radius: 16px;
|
|
467
|
+
font-size: 26px;
|
|
458
468
|
}
|
|
459
469
|
|
|
460
470
|
.lo-ui-app-icon > img {
|
|
@@ -470,28 +480,25 @@
|
|
|
470
480
|
}
|
|
471
481
|
|
|
472
482
|
.lo-ui-empty-state {
|
|
473
|
-
|
|
474
|
-
padding: var(--lo-space-8) var(--lo-space-6);
|
|
483
|
+
padding: 30px 15px;
|
|
475
484
|
display: flex;
|
|
476
485
|
flex-direction: column;
|
|
477
486
|
align-items: center;
|
|
478
487
|
justify-content: center;
|
|
479
|
-
gap:
|
|
488
|
+
gap: 10px;
|
|
480
489
|
text-align: center;
|
|
481
|
-
border: 1px
|
|
482
|
-
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);
|
|
483
492
|
background: var(--lo-color-surface);
|
|
484
493
|
}
|
|
485
494
|
|
|
486
495
|
.lo-ui-empty-state__icon {
|
|
487
496
|
width: 52px;
|
|
488
497
|
height: 52px;
|
|
489
|
-
margin-bottom:
|
|
498
|
+
margin-bottom: 5px;
|
|
490
499
|
display: grid;
|
|
491
500
|
place-items: center;
|
|
492
|
-
|
|
493
|
-
color: var(--lo-color-accent);
|
|
494
|
-
background: var(--lo-color-accent-soft);
|
|
501
|
+
color: var(--lo-color-accent-text);
|
|
495
502
|
}
|
|
496
503
|
|
|
497
504
|
.lo-ui-empty-state__icon > svg {
|
|
@@ -507,19 +514,20 @@
|
|
|
507
514
|
}
|
|
508
515
|
|
|
509
516
|
.lo-ui-empty-state__title {
|
|
517
|
+
font-family: var(--lo-font-family);
|
|
510
518
|
color: var(--lo-color-text);
|
|
511
|
-
font-size:
|
|
519
|
+
font-size: 26px;
|
|
512
520
|
line-height: var(--lo-line-height-tight);
|
|
513
521
|
}
|
|
514
522
|
|
|
515
523
|
.lo-ui-empty-state__description {
|
|
516
524
|
max-width: 36ch;
|
|
517
525
|
color: var(--lo-color-text-secondary);
|
|
518
|
-
font-size: var(--lo-font-size-
|
|
526
|
+
font-size: var(--lo-font-size-body);
|
|
519
527
|
}
|
|
520
528
|
|
|
521
529
|
.lo-ui-empty-state__action {
|
|
522
|
-
margin-top:
|
|
530
|
+
margin-top: 5px;
|
|
523
531
|
}
|
|
524
532
|
|
|
525
533
|
.lo-ui-stack,
|
|
@@ -538,6 +546,7 @@
|
|
|
538
546
|
}
|
|
539
547
|
|
|
540
548
|
.lo-ui-heading {
|
|
549
|
+
font-family: var(--lo-font-family);
|
|
541
550
|
color: var(--lo-color-text);
|
|
542
551
|
font-weight: var(--lo-font-weight-bold);
|
|
543
552
|
font-size: var(--lo-font-size-title);
|
|
@@ -580,3 +589,129 @@
|
|
|
580
589
|
animation: none;
|
|
581
590
|
}
|
|
582
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
|
+
}
|