gbs-add-block 1.2.13 → 1.2.15
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 +4 -12
- package/index.cjs +9 -0
- package/package.json +1 -1
- package/source/beta-components/breadcrumb/README.md +34 -0
- package/source/beta-components/breadcrumb/__tests__/core.test.ts +58 -0
- package/source/beta-components/breadcrumb/core/index.ts +4 -0
- package/source/beta-components/breadcrumb/core/trail.ts +42 -0
- package/source/beta-components/breadcrumb/core/types.ts +20 -0
- package/source/beta-components/breadcrumb/index.ts +5 -0
- package/source/beta-components/breadcrumb/react/Breadcrumb.tsx +177 -0
- package/source/beta-components/breadcrumb/react/locale.ts +6 -0
- package/source/beta-components/breadcrumb/react/props.ts +14 -0
- package/source/beta-components/breadcrumb/styles.css +139 -0
- package/source/beta-components/button/README.md +32 -0
- package/source/beta-components/button/__tests__/core.test.ts +31 -0
- package/source/beta-components/button/core/index.ts +3 -0
- package/source/beta-components/button/core/state.ts +16 -0
- package/source/beta-components/button/core/types.ts +28 -0
- package/source/beta-components/button/index.ts +5 -0
- package/source/beta-components/button/react/Button.tsx +173 -0
- package/source/beta-components/button/react/locale.ts +5 -0
- package/source/beta-components/button/react/props.ts +23 -0
- package/source/beta-components/button/styles.css +233 -0
- package/source/beta-components/checkbox/README.md +36 -0
- package/source/beta-components/checkbox/__tests__/core.test.ts +40 -0
- package/source/beta-components/checkbox/core/group.ts +30 -0
- package/source/beta-components/checkbox/core/index.ts +3 -0
- package/source/beta-components/checkbox/core/types.ts +17 -0
- package/source/beta-components/checkbox/index.ts +9 -0
- package/source/beta-components/checkbox/react/Checkbox.tsx +146 -0
- package/source/beta-components/checkbox/react/CheckboxGroup.tsx +149 -0
- package/source/beta-components/checkbox/react/context.ts +16 -0
- package/source/beta-components/checkbox/react/locale.ts +5 -0
- package/source/beta-components/checkbox/react/props.ts +6 -0
- package/source/beta-components/checkbox/styles.css +212 -0
- package/source/beta-components/dialog/README.md +39 -0
- package/source/beta-components/dialog/__tests__/core.test.ts +86 -0
- package/source/beta-components/dialog/core/api.ts +34 -0
- package/source/beta-components/dialog/core/dialog.ts +11 -0
- package/source/beta-components/dialog/core/index.ts +7 -0
- package/source/beta-components/dialog/core/store.ts +81 -0
- package/source/beta-components/dialog/core/types.ts +59 -0
- package/source/beta-components/dialog/index.ts +7 -0
- package/source/beta-components/dialog/react/Dialog.tsx +279 -0
- package/source/beta-components/dialog/react/DialogHost.tsx +45 -0
- package/source/beta-components/dialog/react/icons.tsx +51 -0
- package/source/beta-components/dialog/react/locale.ts +8 -0
- package/source/beta-components/dialog/react/props.ts +13 -0
- package/source/beta-components/dialog/styles.css +278 -0
- package/source/beta-components/input/README.md +44 -0
- package/source/beta-components/input/__tests__/core.test.ts +75 -0
- package/source/beta-components/input/core/count.ts +14 -0
- package/source/beta-components/input/core/index.ts +11 -0
- package/source/beta-components/input/core/otp.ts +64 -0
- package/source/beta-components/input/core/types.ts +14 -0
- package/source/beta-components/input/index.ts +8 -0
- package/source/beta-components/input/react/Input.tsx +219 -0
- package/source/beta-components/input/react/OtpInput.tsx +256 -0
- package/source/beta-components/input/react/dom.ts +10 -0
- package/source/beta-components/input/react/icons.tsx +35 -0
- package/source/beta-components/input/react/locale.ts +9 -0
- package/source/beta-components/input/react/props.ts +6 -0
- package/source/beta-components/input/styles.css +296 -0
- package/source/beta-components/modal/README.md +51 -0
- package/source/beta-components/modal/__tests__/core.test.ts +55 -0
- package/source/beta-components/modal/core/dismiss.ts +29 -0
- package/source/beta-components/modal/core/index.ts +3 -0
- package/source/beta-components/modal/core/types.ts +27 -0
- package/source/beta-components/modal/index.ts +5 -0
- package/source/beta-components/modal/react/Modal.tsx +238 -0
- package/source/beta-components/modal/react/icons.tsx +19 -0
- package/source/beta-components/modal/react/locale.ts +5 -0
- package/source/beta-components/modal/react/props.ts +17 -0
- package/source/beta-components/modal/styles.css +235 -0
- package/source/beta-components/spinner/README.md +29 -0
- package/source/beta-components/spinner/__tests__/core.test.ts +48 -0
- package/source/beta-components/spinner/core/index.ts +3 -0
- package/source/beta-components/spinner/core/types.ts +28 -0
- package/source/beta-components/spinner/core/visibility.ts +34 -0
- package/source/beta-components/spinner/index.ts +6 -0
- package/source/beta-components/spinner/react/Spinner.tsx +96 -0
- package/source/beta-components/spinner/react/locale.ts +5 -0
- package/source/beta-components/spinner/react/props.ts +4 -0
- package/source/beta-components/spinner/react/useDelayedLoading.ts +39 -0
- package/source/beta-components/spinner/styles.css +167 -0
- package/source/beta-components/tabs/README.md +32 -0
- package/source/beta-components/tabs/__tests__/core.test.ts +51 -0
- package/source/beta-components/tabs/core/index.ts +3 -0
- package/source/beta-components/tabs/core/navigation.ts +54 -0
- package/source/beta-components/tabs/core/types.ts +16 -0
- package/source/beta-components/tabs/index.ts +5 -0
- package/source/beta-components/tabs/react/Tabs.tsx +260 -0
- package/source/beta-components/tabs/react/context.ts +21 -0
- package/source/beta-components/tabs/styles.css +257 -0
- package/source/beta-components/textarea/README.md +39 -0
- package/source/beta-components/textarea/__tests__/core.test.ts +38 -0
- package/source/beta-components/textarea/core/count.ts +14 -0
- package/source/beta-components/textarea/core/index.ts +4 -0
- package/source/beta-components/textarea/core/size.ts +23 -0
- package/source/beta-components/textarea/core/types.ts +17 -0
- package/source/beta-components/textarea/index.ts +5 -0
- package/source/beta-components/textarea/react/Textarea.tsx +209 -0
- package/source/beta-components/textarea/react/locale.ts +5 -0
- package/source/beta-components/textarea/react/props.ts +4 -0
- package/source/beta-components/textarea/styles.css +159 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useId,
|
|
7
|
+
useImperativeHandle,
|
|
8
|
+
useLayoutEffect,
|
|
9
|
+
useMemo,
|
|
10
|
+
useRef,
|
|
11
|
+
useState,
|
|
12
|
+
type ChangeEvent,
|
|
13
|
+
type CSSProperties,
|
|
14
|
+
type ReactNode,
|
|
15
|
+
type Ref,
|
|
16
|
+
type TextareaHTMLAttributes,
|
|
17
|
+
} from "react";
|
|
18
|
+
import { countCharacters } from "../core/count";
|
|
19
|
+
import { fitHeight } from "../core/size";
|
|
20
|
+
import type { FieldSize, TextareaLocaleText, TextareaResize } from "../core/types";
|
|
21
|
+
import { defaultTextareaText } from "./locale";
|
|
22
|
+
import { cx, type TextareaSlot } from "./props";
|
|
23
|
+
|
|
24
|
+
export interface TextareaProps
|
|
25
|
+
extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "value" | "defaultValue"> {
|
|
26
|
+
value?: string;
|
|
27
|
+
defaultValue?: string;
|
|
28
|
+
/** The new text on every change. The native `onChange` fires as well. */
|
|
29
|
+
onValueChange?(value: string): void;
|
|
30
|
+
label?: ReactNode;
|
|
31
|
+
description?: ReactNode;
|
|
32
|
+
/** Message below the field; also marks it invalid. */
|
|
33
|
+
error?: ReactNode;
|
|
34
|
+
size?: FieldSize;
|
|
35
|
+
/** Grow and shrink with the text, between `minRows` and `maxRows`. Default false. */
|
|
36
|
+
autoResize?: boolean;
|
|
37
|
+
/** Smallest height in rows. Default `rows`, or 3. */
|
|
38
|
+
minRows?: number;
|
|
39
|
+
/** Largest height in rows before the text scrolls. No limit by default. */
|
|
40
|
+
maxRows?: number;
|
|
41
|
+
/** Which way people can drag to resize. Default `vertical`, or `none` with `autoResize`. */
|
|
42
|
+
resize?: TextareaResize;
|
|
43
|
+
/** A character counter; shows `count / maxLength` when `maxLength` is set. */
|
|
44
|
+
showCount?: boolean;
|
|
45
|
+
classNames?: Partial<Record<TextareaSlot, string>>;
|
|
46
|
+
localeText?: Partial<TextareaLocaleText>;
|
|
47
|
+
/** The `<textarea>` element. */
|
|
48
|
+
ref?: Ref<HTMLTextAreaElement>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const supportsFieldSizing = () =>
|
|
52
|
+
typeof CSS !== "undefined" && CSS.supports("field-sizing", "content");
|
|
53
|
+
|
|
54
|
+
const px = (value: string) => Number.parseFloat(value) || 0;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A multi-line text field with label, hint, error, character counter and
|
|
58
|
+
* auto-resize. Every other prop goes to the `<textarea>`.
|
|
59
|
+
*/
|
|
60
|
+
export function Textarea(props: TextareaProps) {
|
|
61
|
+
const {
|
|
62
|
+
ref,
|
|
63
|
+
value: valueProp,
|
|
64
|
+
defaultValue,
|
|
65
|
+
onChange,
|
|
66
|
+
onValueChange,
|
|
67
|
+
label,
|
|
68
|
+
description,
|
|
69
|
+
error,
|
|
70
|
+
size = "md",
|
|
71
|
+
autoResize = false,
|
|
72
|
+
minRows,
|
|
73
|
+
maxRows,
|
|
74
|
+
rows,
|
|
75
|
+
resize,
|
|
76
|
+
showCount = false,
|
|
77
|
+
className,
|
|
78
|
+
classNames,
|
|
79
|
+
style,
|
|
80
|
+
localeText,
|
|
81
|
+
id: idProp,
|
|
82
|
+
disabled,
|
|
83
|
+
readOnly,
|
|
84
|
+
required,
|
|
85
|
+
maxLength,
|
|
86
|
+
"aria-describedby": describedByProp,
|
|
87
|
+
...textareaProps
|
|
88
|
+
} = props;
|
|
89
|
+
|
|
90
|
+
const reactId = useId();
|
|
91
|
+
const id = idProp ?? reactId;
|
|
92
|
+
const text = useMemo(() => ({ ...defaultTextareaText, ...localeText }), [localeText]);
|
|
93
|
+
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
|
94
|
+
useImperativeHandle(ref, () => textareaRef.current as HTMLTextAreaElement, []);
|
|
95
|
+
|
|
96
|
+
// Mirrors the text even when uncontrolled, for the counter and auto-resize.
|
|
97
|
+
const [internal, setInternal] = useState(defaultValue ?? "");
|
|
98
|
+
const current = valueProp ?? internal;
|
|
99
|
+
const floor = Math.max(1, minRows ?? rows ?? 3);
|
|
100
|
+
|
|
101
|
+
const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
|
102
|
+
if (valueProp === undefined) setInternal(event.target.value);
|
|
103
|
+
onChange?.(event);
|
|
104
|
+
onValueChange?.(event.target.value);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Browsers with `field-sizing: content` resize in CSS; others are measured here.
|
|
108
|
+
const measure = useCallback(() => {
|
|
109
|
+
const element = textareaRef.current;
|
|
110
|
+
if (!autoResize || !element || supportsFieldSizing()) return;
|
|
111
|
+
const computed = getComputedStyle(element);
|
|
112
|
+
const metrics = {
|
|
113
|
+
lineHeight: px(computed.lineHeight) || px(computed.fontSize) * 1.5,
|
|
114
|
+
paddingBlock: px(computed.paddingTop) + px(computed.paddingBottom),
|
|
115
|
+
borderBlock: px(computed.borderTopWidth) + px(computed.borderBottomWidth),
|
|
116
|
+
};
|
|
117
|
+
element.style.height = "auto";
|
|
118
|
+
const { height, overflow } = fitHeight(element.scrollHeight, metrics, floor, maxRows);
|
|
119
|
+
element.style.height = `${height}px`;
|
|
120
|
+
element.style.overflowY = overflow ? "auto" : "hidden";
|
|
121
|
+
}, [autoResize, floor, maxRows]);
|
|
122
|
+
|
|
123
|
+
useLayoutEffect(() => {
|
|
124
|
+
measure();
|
|
125
|
+
}, [measure, current]);
|
|
126
|
+
|
|
127
|
+
// A narrower field wraps more lines, so measure again when the width changes.
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
const element = textareaRef.current;
|
|
130
|
+
if (!autoResize || !element || supportsFieldSizing()) return;
|
|
131
|
+
let width = element.offsetWidth;
|
|
132
|
+
const observer = new ResizeObserver(() => {
|
|
133
|
+
if (element.offsetWidth === width) return;
|
|
134
|
+
width = element.offsetWidth;
|
|
135
|
+
measure();
|
|
136
|
+
});
|
|
137
|
+
observer.observe(element);
|
|
138
|
+
return () => observer.disconnect();
|
|
139
|
+
}, [autoResize, measure]);
|
|
140
|
+
|
|
141
|
+
const invalid = Boolean(error);
|
|
142
|
+
const count = countCharacters(current);
|
|
143
|
+
const describedBy =
|
|
144
|
+
cx(describedByProp, description ? `${id}-description` : "", error ? `${id}-error` : "") || undefined;
|
|
145
|
+
const rowVariables = {
|
|
146
|
+
"--ta-min-rows": floor,
|
|
147
|
+
"--ta-max-rows": maxRows ?? "none",
|
|
148
|
+
} as CSSProperties;
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<div
|
|
152
|
+
className={cx("ta-root", classNames?.root, className)}
|
|
153
|
+
style={style}
|
|
154
|
+
data-size={size}
|
|
155
|
+
data-disabled={disabled || undefined}
|
|
156
|
+
data-invalid={invalid ? "" : undefined}
|
|
157
|
+
>
|
|
158
|
+
{label && (
|
|
159
|
+
<label htmlFor={id} className={cx("ta-label", classNames?.label)} data-required={required || undefined}>
|
|
160
|
+
{label}
|
|
161
|
+
</label>
|
|
162
|
+
)}
|
|
163
|
+
|
|
164
|
+
<textarea
|
|
165
|
+
{...textareaProps}
|
|
166
|
+
ref={textareaRef}
|
|
167
|
+
id={id}
|
|
168
|
+
className={cx("ta-input", classNames?.textarea)}
|
|
169
|
+
style={rowVariables}
|
|
170
|
+
rows={autoResize ? floor : (rows ?? floor)}
|
|
171
|
+
value={valueProp}
|
|
172
|
+
defaultValue={valueProp === undefined ? defaultValue : undefined}
|
|
173
|
+
disabled={disabled}
|
|
174
|
+
readOnly={readOnly}
|
|
175
|
+
required={required}
|
|
176
|
+
maxLength={maxLength}
|
|
177
|
+
data-autoresize={autoResize || undefined}
|
|
178
|
+
data-resize={resize ?? (autoResize ? "none" : "vertical")}
|
|
179
|
+
data-invalid={invalid ? "" : undefined}
|
|
180
|
+
aria-invalid={invalid || undefined}
|
|
181
|
+
aria-describedby={describedBy}
|
|
182
|
+
onChange={handleChange}
|
|
183
|
+
/>
|
|
184
|
+
|
|
185
|
+
{(description || showCount) && (
|
|
186
|
+
<div className="ta-footer">
|
|
187
|
+
{description && (
|
|
188
|
+
<span id={`${id}-description`} className={cx("ta-description", classNames?.description)}>
|
|
189
|
+
{description}
|
|
190
|
+
</span>
|
|
191
|
+
)}
|
|
192
|
+
{showCount && (
|
|
193
|
+
<span
|
|
194
|
+
className={cx("ta-count", classNames?.count)}
|
|
195
|
+
data-over={maxLength !== undefined && count > maxLength ? "" : undefined}
|
|
196
|
+
>
|
|
197
|
+
{text.characterCount(String(count), maxLength !== undefined ? String(maxLength) : undefined)}
|
|
198
|
+
</span>
|
|
199
|
+
)}
|
|
200
|
+
</div>
|
|
201
|
+
)}
|
|
202
|
+
{error && (
|
|
203
|
+
<span id={`${id}-error`} className={cx("ta-error", classNames?.error)} role="alert">
|
|
204
|
+
{error}
|
|
205
|
+
</span>
|
|
206
|
+
)}
|
|
207
|
+
</div>
|
|
208
|
+
);
|
|
209
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Textarea styles.
|
|
3
|
+
*
|
|
4
|
+
* Tokens read the DataGrid's --dg-* variables when they are set on an ancestor
|
|
5
|
+
* (set them on :root to share one theme) and fall back to the same palette
|
|
6
|
+
* otherwise. Rules live in the `components` layer, so utility classes passed
|
|
7
|
+
* through `className` / `classNames` override them.
|
|
8
|
+
*/
|
|
9
|
+
@layer theme, base, components, utilities;
|
|
10
|
+
|
|
11
|
+
@layer components {
|
|
12
|
+
.ta-root {
|
|
13
|
+
--ta-fg: var(--dg-fg, light-dark(#18181b, #f4f4f5));
|
|
14
|
+
--ta-muted: var(--dg-muted, light-dark(#71717a, #a1a1aa));
|
|
15
|
+
--ta-border: var(--dg-border, light-dark(#e4e4e7, #27272a));
|
|
16
|
+
--ta-input-bg: var(--dg-input-bg, light-dark(#ffffff, #121216));
|
|
17
|
+
--ta-readonly-bg: light-dark(#fafafa, #0e0e12);
|
|
18
|
+
--ta-focus: var(--dg-focus, light-dark(#2563eb, #60a5fa));
|
|
19
|
+
--ta-danger: var(--dg-danger, light-dark(#dc2626, #f87171));
|
|
20
|
+
--ta-radius: var(--dg-radius, 8px);
|
|
21
|
+
--ta-font-size: var(--dg-font-size, 13px);
|
|
22
|
+
--ta-px: 10px;
|
|
23
|
+
--ta-py: 8px;
|
|
24
|
+
|
|
25
|
+
color-scheme: inherit;
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
gap: 4px;
|
|
29
|
+
width: 100%;
|
|
30
|
+
min-width: 0;
|
|
31
|
+
font-size: var(--ta-font-size);
|
|
32
|
+
line-height: 1.4;
|
|
33
|
+
color: var(--ta-fg);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
:where(.dark, [data-theme="dark"]) .ta-root {
|
|
37
|
+
color-scheme: dark;
|
|
38
|
+
}
|
|
39
|
+
:where(.light, [data-theme="light"]) .ta-root {
|
|
40
|
+
color-scheme: light;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:where(.ta-root) *,
|
|
44
|
+
:where(.ta-root) *::before,
|
|
45
|
+
:where(.ta-root) *::after {
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.ta-root[data-size="sm"] {
|
|
50
|
+
--ta-font-size: 12px;
|
|
51
|
+
--ta-px: 8px;
|
|
52
|
+
--ta-py: 6px;
|
|
53
|
+
}
|
|
54
|
+
.ta-root[data-size="lg"] {
|
|
55
|
+
--ta-font-size: 14px;
|
|
56
|
+
--ta-px: 12px;
|
|
57
|
+
--ta-py: 10px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.ta-label {
|
|
61
|
+
font-weight: 500;
|
|
62
|
+
}
|
|
63
|
+
.ta-label[data-required]::after {
|
|
64
|
+
content: " *";
|
|
65
|
+
color: var(--ta-danger);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.ta-input {
|
|
69
|
+
display: block;
|
|
70
|
+
width: 100%;
|
|
71
|
+
min-height: calc(1lh + 2 * var(--ta-py) + 2px);
|
|
72
|
+
margin: 0;
|
|
73
|
+
padding: var(--ta-py) var(--ta-px);
|
|
74
|
+
border: 1px solid var(--ta-border);
|
|
75
|
+
border-radius: var(--ta-radius);
|
|
76
|
+
background: var(--ta-input-bg);
|
|
77
|
+
color: inherit;
|
|
78
|
+
font: inherit;
|
|
79
|
+
line-height: 1.5;
|
|
80
|
+
}
|
|
81
|
+
.ta-input::placeholder {
|
|
82
|
+
color: var(--ta-muted);
|
|
83
|
+
}
|
|
84
|
+
.ta-input:hover:not(:disabled) {
|
|
85
|
+
border-color: color-mix(in oklab, var(--ta-border), var(--ta-fg) 25%);
|
|
86
|
+
}
|
|
87
|
+
.ta-input:focus-visible {
|
|
88
|
+
outline: 2px solid var(--ta-focus);
|
|
89
|
+
outline-offset: -1px;
|
|
90
|
+
}
|
|
91
|
+
.ta-input[data-invalid] {
|
|
92
|
+
border-color: var(--ta-danger);
|
|
93
|
+
outline-color: var(--ta-danger);
|
|
94
|
+
}
|
|
95
|
+
.ta-input:read-only {
|
|
96
|
+
background: var(--ta-readonly-bg);
|
|
97
|
+
}
|
|
98
|
+
.ta-input:disabled {
|
|
99
|
+
opacity: 0.55;
|
|
100
|
+
cursor: not-allowed;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.ta-input[data-resize="none"] {
|
|
104
|
+
resize: none;
|
|
105
|
+
}
|
|
106
|
+
.ta-input[data-resize="vertical"] {
|
|
107
|
+
resize: vertical;
|
|
108
|
+
}
|
|
109
|
+
.ta-input[data-resize="horizontal"] {
|
|
110
|
+
resize: horizontal;
|
|
111
|
+
}
|
|
112
|
+
.ta-input[data-resize="both"] {
|
|
113
|
+
resize: both;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/*
|
|
117
|
+
* Auto-resize in CSS where supported. The row limits come from the
|
|
118
|
+
* component; `--ta-max-rows: none` makes max-height invalid, which means no limit.
|
|
119
|
+
*/
|
|
120
|
+
@supports (field-sizing: content) {
|
|
121
|
+
.ta-input[data-autoresize] {
|
|
122
|
+
field-sizing: content;
|
|
123
|
+
min-height: calc(var(--ta-min-rows, 3) * 1lh + 2 * var(--ta-py) + 2px);
|
|
124
|
+
max-height: calc(var(--ta-max-rows) * 1lh + 2 * var(--ta-py) + 2px);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.ta-footer {
|
|
129
|
+
display: flex;
|
|
130
|
+
align-items: baseline;
|
|
131
|
+
gap: 8px;
|
|
132
|
+
}
|
|
133
|
+
.ta-description {
|
|
134
|
+
flex: 1 1 auto;
|
|
135
|
+
min-width: 0;
|
|
136
|
+
color: var(--ta-muted);
|
|
137
|
+
font-size: 0.92em;
|
|
138
|
+
}
|
|
139
|
+
.ta-count {
|
|
140
|
+
flex: none;
|
|
141
|
+
margin-inline-start: auto;
|
|
142
|
+
color: var(--ta-muted);
|
|
143
|
+
font-size: 0.92em;
|
|
144
|
+
font-variant-numeric: tabular-nums;
|
|
145
|
+
}
|
|
146
|
+
.ta-count[data-over] {
|
|
147
|
+
color: var(--ta-danger);
|
|
148
|
+
}
|
|
149
|
+
.ta-error {
|
|
150
|
+
color: var(--ta-danger);
|
|
151
|
+
font-size: 0.92em;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@media (forced-colors: active) {
|
|
155
|
+
.ta-input:focus-visible {
|
|
156
|
+
outline-color: Highlight;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|