@usableapp/cardds 0.2.2 → 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/README.md +26 -102
- package/cardds.js +6 -449
- package/css/actions.css +3 -8
- package/css/card.css +2 -2
- package/css/sheet.css +8 -8
- package/css/step.css +6 -6
- package/css/tokens.css +2 -0
- package/dist/actions/Dropdown.d.ts +34 -17
- package/dist/actions/Dropdown.js +41 -11
- package/dist/actions/IconBtn.d.ts +296 -9
- package/dist/actions/IconBtn.js +6 -8
- package/dist/cardds.css +21 -24
- package/dist/choice/Calendar.d.ts +17 -6
- package/dist/choice/Calendar.js +9 -3
- package/dist/choice/Slider.d.ts +1 -1
- package/dist/choice/Slider.js +12 -8
- package/dist/forms/Pin.d.ts +9 -6
- package/dist/forms/Pin.js +47 -18
- package/dist/media/Postcard.d.ts +8 -4
- package/dist/media/Postcard.js +8 -3
- package/dist/numbers/Picker.d.ts +19 -7
- package/dist/numbers/Picker.js +51 -13
- package/dist/scaffold/BaseContent.d.ts +4 -4
- package/dist/scaffold/BaseContent.js +4 -4
- package/dist/sheets/Drawer.d.ts +14 -3
- package/dist/sheets/Drawer.js +29 -5
- package/dist/sheets/Sheet.d.ts +28 -15
- package/dist/sheets/Sheet.js +157 -11
- package/dist/sheets/SheetStack.d.ts +13 -1
- package/dist/sheets/SheetStack.js +74 -2
- package/package.json +1 -1
|
@@ -1,38 +1,55 @@
|
|
|
1
1
|
import type { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
2
|
import { type IconName } from '../type/Icon.js';
|
|
3
|
-
export interface DropdownProps extends ComponentPropsWithoutRef<'div'> {
|
|
3
|
+
export interface DropdownProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onChange' | 'defaultValue'> {
|
|
4
4
|
/** unique id — the popover menu's id the trigger targets */
|
|
5
5
|
id: string;
|
|
6
|
-
/** the
|
|
7
|
-
|
|
6
|
+
/** CONTROLLED: the chosen MenuItem's `value`. The app owns it — pair it with `onChange`. */
|
|
7
|
+
value?: string;
|
|
8
|
+
/** UNCONTROLLED: the value it starts with; the dropdown then keeps its own */
|
|
9
|
+
defaultValue?: string;
|
|
10
|
+
/** a MenuItem was picked */
|
|
11
|
+
onChange?: (value: string) => void;
|
|
12
|
+
/** what the pill says; default = the chosen MenuItem's own label */
|
|
13
|
+
label?: ReactNode;
|
|
8
14
|
/** right-aligned trigger: the panel grows leftwards (in TopBar actions) */
|
|
9
15
|
end?: boolean;
|
|
10
|
-
/** MenuItems */
|
|
16
|
+
/** MenuItems, each with a `value` */
|
|
11
17
|
children?: ReactNode;
|
|
12
18
|
}
|
|
13
19
|
/**
|
|
14
|
-
* Dropdown — THE select: a pill trigger +
|
|
15
|
-
*
|
|
16
|
-
*
|
|
20
|
+
* Dropdown — THE select: a pill trigger + its Menu popover anchored under it (native popover: light dismiss, Esc). Never a native
|
|
21
|
+
* `<select>`. ONE component, like `<select>` is — the pill and the panel are its own anatomy. It holds a VALUE, controlled like an
|
|
22
|
+
* input: `value` + `onChange`, or `defaultValue`. Children are MenuItems with a `value`; the chosen one is marked and names the pill.
|
|
23
|
+
* In a FilterRow dropdowns share the width.
|
|
17
24
|
*/
|
|
18
|
-
export declare function Dropdown({ id, label, end, className, children, ...rest }: DropdownProps): import("react").JSX.Element;
|
|
19
|
-
export interface MenuProps extends Omit<ComponentPropsWithoutRef<'div'>, 'popover'> {
|
|
20
|
-
/** render as a popover panel
|
|
25
|
+
export declare function Dropdown({ id, value, defaultValue, onChange, label, end, className, children, ...rest }: DropdownProps): import("react").JSX.Element;
|
|
26
|
+
export interface MenuProps extends Omit<ComponentPropsWithoutRef<'div'>, 'popover' | 'onChange' | 'defaultValue'> {
|
|
27
|
+
/** render as a popover panel: give it an `id`, and ANY button opens it with the platform's own `popoverTarget={id}` — the Menu does
|
|
28
|
+
* not know which. Omit for an inline menu card */
|
|
21
29
|
popover?: boolean;
|
|
22
|
-
/** an ACTIONS menu — things to do, not a value to hold: no item stays current */
|
|
30
|
+
/** an ACTIONS menu — things to do, not a value to hold: no item stays current; each MenuItem has the app's `onClick` */
|
|
23
31
|
actions?: boolean;
|
|
32
|
+
/** a VALUE menu, controlled: the chosen MenuItem's `value` (+ `onChange`) */
|
|
33
|
+
value?: string;
|
|
34
|
+
/** …or the value it starts with */
|
|
35
|
+
defaultValue?: string;
|
|
36
|
+
onChange?: (value: string) => void;
|
|
24
37
|
/** the trigger sits at the far right: the panel grows leftwards */
|
|
25
38
|
end?: boolean;
|
|
26
39
|
}
|
|
27
|
-
/**
|
|
28
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Menu — a card of MenuItems: a popover, or inline rows of icon + label. A COMPONENT on its own — what opens a popover Menu is any
|
|
42
|
+
* button carrying `popoverTarget={its id}` (HTML's own link; the panel anchors to that button). `actions` = a to-do list (plain
|
|
43
|
+
* `onClick`s); otherwise it holds a value (`value` + `onChange`, or `defaultValue`). Its one behaviour: picking an item closes it.
|
|
44
|
+
*/
|
|
45
|
+
export declare function Menu({ popover, actions, value, defaultValue, onChange, end, className, onClick, ...rest }: MenuProps): import("react").JSX.Element;
|
|
29
46
|
export interface MenuItemProps extends ComponentPropsWithoutRef<'button'> {
|
|
30
|
-
/**
|
|
47
|
+
/** in a value Menu / Dropdown: what picking this row reports */
|
|
31
48
|
value?: string;
|
|
32
|
-
/**
|
|
49
|
+
/** mark it current yourself (default: it is, when its `value` is the menu's) */
|
|
33
50
|
current?: boolean;
|
|
34
51
|
/** a leading icon */
|
|
35
52
|
icon?: IconName;
|
|
36
53
|
}
|
|
37
|
-
/** MenuItem — one row in a Menu (48px tall): optional icon, label; the current one is filled. */
|
|
38
|
-
export declare function MenuItem({ value, current, icon, className, children, ...rest }: MenuItemProps): import("react").JSX.Element;
|
|
54
|
+
/** MenuItem — one row in a Menu (48px tall): optional icon, label; the current one is filled. In an `actions` Menu give it an `onClick`. */
|
|
55
|
+
export declare function MenuItem({ value, current, icon, className, children, onClick, ...rest }: MenuItemProps): import("react").JSX.Element;
|
package/dist/actions/Dropdown.js
CHANGED
|
@@ -1,19 +1,49 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Children, createContext, isValidElement, useContext, useRef, useState } from 'react';
|
|
2
3
|
import { cx } from '../cx.js';
|
|
3
4
|
import { Icon } from '../type/Icon.js';
|
|
5
|
+
/* what a Menu tells its items: the value it holds (so the matching item marks itself current) and how to pick one */
|
|
6
|
+
const MenuContext = createContext(null);
|
|
7
|
+
/* a menu's value is controlled (`value` + `onChange`) or its own (`defaultValue`) — like an input */
|
|
8
|
+
function useValue(value, defaultValue, onChange) {
|
|
9
|
+
const [inner, setInner] = useState(defaultValue);
|
|
10
|
+
const current = value ?? inner;
|
|
11
|
+
const pick = (next) => { if (value === undefined)
|
|
12
|
+
setInner(next); if (next !== current)
|
|
13
|
+
onChange?.(next); };
|
|
14
|
+
return [current, pick];
|
|
15
|
+
}
|
|
4
16
|
/**
|
|
5
|
-
* Dropdown — THE select: a pill trigger +
|
|
6
|
-
*
|
|
7
|
-
*
|
|
17
|
+
* Dropdown — THE select: a pill trigger + its Menu popover anchored under it (native popover: light dismiss, Esc). Never a native
|
|
18
|
+
* `<select>`. ONE component, like `<select>` is — the pill and the panel are its own anatomy. It holds a VALUE, controlled like an
|
|
19
|
+
* input: `value` + `onChange`, or `defaultValue`. Children are MenuItems with a `value`; the chosen one is marked and names the pill.
|
|
20
|
+
* In a FilterRow dropdowns share the width.
|
|
8
21
|
*/
|
|
9
|
-
export function Dropdown({ id, label, end, className, children, ...rest }) {
|
|
10
|
-
|
|
22
|
+
export function Dropdown({ id, value, defaultValue, onChange, label, end, className, children, ...rest }) {
|
|
23
|
+
const [current, pick] = useValue(value, defaultValue, onChange);
|
|
24
|
+
const chosen = Children.toArray(children).find((c) => isValidElement(c) && c.props.value === current);
|
|
25
|
+
return (_jsxs("div", { className: cx('dropdown', end && 'dropdown--end', className), "data-value": current, ...rest, children: [_jsxs("button", { type: "button", className: "dropdown__btn", popoverTarget: id, children: [_jsx("span", { className: "dropdown__label", children: label ?? (isValidElement(chosen) ? chosen.props.children : null) }), _jsx(Icon, { name: "chevron-down", size: "xs" })] }), _jsx(Menu, { popover: true, id: id, value: current, onChange: pick, children: children })] }));
|
|
11
26
|
}
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Menu — a card of MenuItems: a popover, or inline rows of icon + label. A COMPONENT on its own — what opens a popover Menu is any
|
|
29
|
+
* button carrying `popoverTarget={its id}` (HTML's own link; the panel anchors to that button). `actions` = a to-do list (plain
|
|
30
|
+
* `onClick`s); otherwise it holds a value (`value` + `onChange`, or `defaultValue`). Its one behaviour: picking an item closes it.
|
|
31
|
+
*/
|
|
32
|
+
export function Menu({ popover, actions, value, defaultValue, onChange, end, className, onClick, ...rest }) {
|
|
33
|
+
const ref = useRef(null);
|
|
34
|
+
const [current, pick] = useValue(value, defaultValue, onChange);
|
|
35
|
+
const click = (e) => {
|
|
36
|
+
onClick?.(e);
|
|
37
|
+
const el = ref.current;
|
|
38
|
+
if (el && e.target.closest('.menu__item') && el.matches(':popover-open'))
|
|
39
|
+
el.hidePopover();
|
|
40
|
+
};
|
|
41
|
+
return (_jsx(MenuContext.Provider, { value: actions ? null : { value: current, pick }, children: _jsx("div", { ref: ref, className: cx('menu', actions && 'menu--actions', end && 'menu--end', className), popover: popover ? 'auto' : undefined, onClick: click, ...rest }) }));
|
|
15
42
|
}
|
|
16
|
-
/** MenuItem — one row in a Menu (48px tall): optional icon, label; the current one is filled. */
|
|
17
|
-
export function MenuItem({ value, current, icon, className, children, ...rest }) {
|
|
18
|
-
|
|
43
|
+
/** MenuItem — one row in a Menu (48px tall): optional icon, label; the current one is filled. In an `actions` Menu give it an `onClick`. */
|
|
44
|
+
export function MenuItem({ value, current, icon, className, children, onClick, ...rest }) {
|
|
45
|
+
const menu = useContext(MenuContext);
|
|
46
|
+
const on = current ?? (menu?.value !== undefined && value !== undefined && menu.value === value);
|
|
47
|
+
return (_jsxs("button", { type: "button", className: cx('menu__item', className), "data-value": value, "aria-current": on ? 'true' : undefined, onClick: (e) => { onClick?.(e); if (!e.defaultPrevented && value !== undefined)
|
|
48
|
+
menu?.pick?.(value); }, ...rest, children: [icon && _jsx(Icon, { name: icon }), children] }));
|
|
19
49
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ComponentPropsWithoutRef
|
|
1
|
+
import { type ComponentPropsWithoutRef } from 'react';
|
|
2
2
|
import { type IconName } from '../type/Icon.js';
|
|
3
3
|
export interface IconBtnProps extends ComponentPropsWithoutRef<'button'> {
|
|
4
4
|
/** the accessible name — required, the button has no text */
|
|
@@ -11,13 +11,300 @@ export interface IconBtnProps extends ComponentPropsWithoutRef<'button'> {
|
|
|
11
11
|
invert?: boolean;
|
|
12
12
|
/** a link styled as a round button */
|
|
13
13
|
href?: string;
|
|
14
|
-
/** an actions menu the button opens (MenuItems) — the popover anchored under it, growing leftwards (`menuStart` for a left-side button); needs `menuId` */
|
|
15
|
-
menu?: ReactNode;
|
|
16
|
-
/** the menu popover's id (unique on the page) */
|
|
17
|
-
menuId?: string;
|
|
18
|
-
/** the button sits at the left: the panel grows rightwards */
|
|
19
|
-
menuStart?: boolean;
|
|
20
14
|
}
|
|
21
15
|
/** IconBtn — the round icon button: `sm` in heads and bars, full size in rows and composers, `invert` for the one filled move.
|
|
22
|
-
*
|
|
23
|
-
|
|
16
|
+
* It is a button and nothing more: to open a Menu, give it the platform's `popoverTarget={the Menu's id}` and render that `<Menu popover actions id>`
|
|
17
|
+
* wherever you like — the panel anchors to the button that opened it. To open anything else, `onClick`. */
|
|
18
|
+
export declare function IconBtn({ label, icon, sm, invert, href, className, type, children, ...rest }: IconBtnProps): import("react").DetailedReactHTMLElement<{
|
|
19
|
+
form?: string | undefined | undefined;
|
|
20
|
+
slot?: string | undefined | undefined;
|
|
21
|
+
style?: import("react").CSSProperties | undefined;
|
|
22
|
+
title?: string | undefined | undefined;
|
|
23
|
+
suppressHydrationWarning?: boolean | undefined | undefined;
|
|
24
|
+
color?: string | undefined | undefined;
|
|
25
|
+
id?: string | undefined | undefined;
|
|
26
|
+
lang?: string | undefined | undefined;
|
|
27
|
+
name?: string | undefined | undefined;
|
|
28
|
+
nonce?: string | undefined | undefined;
|
|
29
|
+
part?: string | undefined | undefined;
|
|
30
|
+
role?: import("react").AriaRole | undefined;
|
|
31
|
+
tabIndex?: number | undefined | undefined;
|
|
32
|
+
"aria-activedescendant"?: string | undefined | undefined;
|
|
33
|
+
"aria-atomic"?: (boolean | "true" | "false") | undefined;
|
|
34
|
+
"aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
|
|
35
|
+
"aria-braillelabel"?: string | undefined | undefined;
|
|
36
|
+
"aria-brailleroledescription"?: string | undefined | undefined;
|
|
37
|
+
"aria-busy"?: (boolean | "true" | "false") | undefined;
|
|
38
|
+
"aria-checked"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
|
|
39
|
+
"aria-colcount"?: number | undefined | undefined;
|
|
40
|
+
"aria-colindex"?: number | undefined | undefined;
|
|
41
|
+
"aria-colindextext"?: string | undefined | undefined;
|
|
42
|
+
"aria-colspan"?: number | undefined | undefined;
|
|
43
|
+
"aria-controls"?: string | undefined | undefined;
|
|
44
|
+
"aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined | undefined;
|
|
45
|
+
"aria-describedby"?: string | undefined | undefined;
|
|
46
|
+
"aria-description"?: string | undefined | undefined;
|
|
47
|
+
"aria-details"?: string | undefined | undefined;
|
|
48
|
+
"aria-disabled"?: (boolean | "true" | "false") | undefined;
|
|
49
|
+
"aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined | undefined;
|
|
50
|
+
"aria-errormessage"?: string | undefined | undefined;
|
|
51
|
+
"aria-expanded"?: (boolean | "true" | "false") | undefined;
|
|
52
|
+
"aria-flowto"?: string | undefined | undefined;
|
|
53
|
+
"aria-grabbed"?: (boolean | "true" | "false") | undefined;
|
|
54
|
+
"aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined | undefined;
|
|
55
|
+
"aria-hidden"?: (boolean | "true" | "false") | undefined;
|
|
56
|
+
"aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined | undefined;
|
|
57
|
+
"aria-keyshortcuts"?: string | undefined | undefined;
|
|
58
|
+
"aria-label": string;
|
|
59
|
+
"aria-labelledby"?: string | undefined | undefined;
|
|
60
|
+
"aria-level"?: number | undefined | undefined;
|
|
61
|
+
"aria-live"?: "off" | "assertive" | "polite" | undefined | undefined;
|
|
62
|
+
"aria-modal"?: (boolean | "true" | "false") | undefined;
|
|
63
|
+
"aria-multiline"?: (boolean | "true" | "false") | undefined;
|
|
64
|
+
"aria-multiselectable"?: (boolean | "true" | "false") | undefined;
|
|
65
|
+
"aria-orientation"?: "horizontal" | "vertical" | undefined | undefined;
|
|
66
|
+
"aria-owns"?: string | undefined | undefined;
|
|
67
|
+
"aria-placeholder"?: string | undefined | undefined;
|
|
68
|
+
"aria-posinset"?: number | undefined | undefined;
|
|
69
|
+
"aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
|
|
70
|
+
"aria-readonly"?: (boolean | "true" | "false") | undefined;
|
|
71
|
+
"aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined | undefined;
|
|
72
|
+
"aria-required"?: (boolean | "true" | "false") | undefined;
|
|
73
|
+
"aria-roledescription"?: string | undefined | undefined;
|
|
74
|
+
"aria-rowcount"?: number | undefined | undefined;
|
|
75
|
+
"aria-rowindex"?: number | undefined | undefined;
|
|
76
|
+
"aria-rowindextext"?: string | undefined | undefined;
|
|
77
|
+
"aria-rowspan"?: number | undefined | undefined;
|
|
78
|
+
"aria-selected"?: (boolean | "true" | "false") | undefined;
|
|
79
|
+
"aria-setsize"?: number | undefined | undefined;
|
|
80
|
+
"aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined | undefined;
|
|
81
|
+
"aria-valuemax"?: number | undefined | undefined;
|
|
82
|
+
"aria-valuemin"?: number | undefined | undefined;
|
|
83
|
+
"aria-valuenow"?: number | undefined | undefined;
|
|
84
|
+
"aria-valuetext"?: string | undefined | undefined;
|
|
85
|
+
dangerouslySetInnerHTML?: {
|
|
86
|
+
__html: string | TrustedHTML;
|
|
87
|
+
} | undefined | undefined;
|
|
88
|
+
onCopy?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
|
|
89
|
+
onCopyCapture?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
|
|
90
|
+
onCut?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
|
|
91
|
+
onCutCapture?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
|
|
92
|
+
onPaste?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
|
|
93
|
+
onPasteCapture?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
|
|
94
|
+
onCompositionEnd?: import("react").CompositionEventHandler<HTMLButtonElement> | undefined;
|
|
95
|
+
onCompositionEndCapture?: import("react").CompositionEventHandler<HTMLButtonElement> | undefined;
|
|
96
|
+
onCompositionStart?: import("react").CompositionEventHandler<HTMLButtonElement> | undefined;
|
|
97
|
+
onCompositionStartCapture?: import("react").CompositionEventHandler<HTMLButtonElement> | undefined;
|
|
98
|
+
onCompositionUpdate?: import("react").CompositionEventHandler<HTMLButtonElement> | undefined;
|
|
99
|
+
onCompositionUpdateCapture?: import("react").CompositionEventHandler<HTMLButtonElement> | undefined;
|
|
100
|
+
onFocus?: import("react").FocusEventHandler<HTMLButtonElement> | undefined;
|
|
101
|
+
onFocusCapture?: import("react").FocusEventHandler<HTMLButtonElement> | undefined;
|
|
102
|
+
onBlur?: import("react").FocusEventHandler<HTMLButtonElement> | undefined;
|
|
103
|
+
onBlurCapture?: import("react").FocusEventHandler<HTMLButtonElement> | undefined;
|
|
104
|
+
onChange?: import("react").ChangeEventHandler<HTMLButtonElement, Element> | undefined;
|
|
105
|
+
onChangeCapture?: import("react").ChangeEventHandler<HTMLButtonElement, Element> | undefined;
|
|
106
|
+
onBeforeInput?: import("react").InputEventHandler<HTMLButtonElement> | undefined;
|
|
107
|
+
onBeforeInputCapture?: import("react").InputEventHandler<HTMLButtonElement> | undefined;
|
|
108
|
+
onInput?: import("react").InputEventHandler<HTMLButtonElement> | undefined;
|
|
109
|
+
onInputCapture?: import("react").InputEventHandler<HTMLButtonElement> | undefined;
|
|
110
|
+
onReset?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
111
|
+
onResetCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
112
|
+
onSubmit?: import("react").SubmitEventHandler<HTMLButtonElement> | undefined;
|
|
113
|
+
onSubmitCapture?: import("react").SubmitEventHandler<HTMLButtonElement> | undefined;
|
|
114
|
+
onInvalid?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
115
|
+
onInvalidCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
116
|
+
onLoad?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
117
|
+
onLoadCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
118
|
+
onError?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
119
|
+
onErrorCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
120
|
+
onKeyDown?: import("react").KeyboardEventHandler<HTMLButtonElement> | undefined;
|
|
121
|
+
onKeyDownCapture?: import("react").KeyboardEventHandler<HTMLButtonElement> | undefined;
|
|
122
|
+
onKeyPress?: import("react").KeyboardEventHandler<HTMLButtonElement> | undefined;
|
|
123
|
+
onKeyPressCapture?: import("react").KeyboardEventHandler<HTMLButtonElement> | undefined;
|
|
124
|
+
onKeyUp?: import("react").KeyboardEventHandler<HTMLButtonElement> | undefined;
|
|
125
|
+
onKeyUpCapture?: import("react").KeyboardEventHandler<HTMLButtonElement> | undefined;
|
|
126
|
+
onAbort?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
127
|
+
onAbortCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
128
|
+
onCanPlay?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
129
|
+
onCanPlayCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
130
|
+
onCanPlayThrough?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
131
|
+
onCanPlayThroughCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
132
|
+
onDurationChange?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
133
|
+
onDurationChangeCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
134
|
+
onEmptied?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
135
|
+
onEmptiedCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
136
|
+
onEncrypted?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
137
|
+
onEncryptedCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
138
|
+
onEnded?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
139
|
+
onEndedCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
140
|
+
onLoadedData?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
141
|
+
onLoadedDataCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
142
|
+
onLoadedMetadata?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
143
|
+
onLoadedMetadataCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
144
|
+
onLoadStart?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
145
|
+
onLoadStartCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
146
|
+
onPause?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
147
|
+
onPauseCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
148
|
+
onPlay?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
149
|
+
onPlayCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
150
|
+
onPlaying?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
151
|
+
onPlayingCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
152
|
+
onProgress?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
153
|
+
onProgressCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
154
|
+
onRateChange?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
155
|
+
onRateChangeCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
156
|
+
onSeeked?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
157
|
+
onSeekedCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
158
|
+
onSeeking?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
159
|
+
onSeekingCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
160
|
+
onStalled?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
161
|
+
onStalledCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
162
|
+
onSuspend?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
163
|
+
onSuspendCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
164
|
+
onTimeUpdate?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
165
|
+
onTimeUpdateCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
166
|
+
onVolumeChange?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
167
|
+
onVolumeChangeCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
168
|
+
onWaiting?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
169
|
+
onWaitingCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
170
|
+
onAuxClick?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
171
|
+
onAuxClickCapture?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
172
|
+
onClick?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
173
|
+
onClickCapture?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
174
|
+
onContextMenu?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
175
|
+
onContextMenuCapture?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
176
|
+
onDoubleClick?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
177
|
+
onDoubleClickCapture?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
178
|
+
onDrag?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
179
|
+
onDragCapture?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
180
|
+
onDragEnd?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
181
|
+
onDragEndCapture?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
182
|
+
onDragEnter?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
183
|
+
onDragEnterCapture?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
184
|
+
onDragExit?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
185
|
+
onDragExitCapture?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
186
|
+
onDragLeave?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
187
|
+
onDragLeaveCapture?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
188
|
+
onDragOver?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
189
|
+
onDragOverCapture?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
190
|
+
onDragStart?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
191
|
+
onDragStartCapture?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
192
|
+
onDrop?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
193
|
+
onDropCapture?: import("react").DragEventHandler<HTMLButtonElement> | undefined;
|
|
194
|
+
onMouseDown?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
195
|
+
onMouseDownCapture?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
196
|
+
onMouseEnter?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
197
|
+
onMouseLeave?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
198
|
+
onMouseMove?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
199
|
+
onMouseMoveCapture?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
200
|
+
onMouseOut?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
201
|
+
onMouseOutCapture?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
202
|
+
onMouseOver?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
203
|
+
onMouseOverCapture?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
204
|
+
onMouseUp?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
205
|
+
onMouseUpCapture?: import("react").MouseEventHandler<HTMLButtonElement> | undefined;
|
|
206
|
+
onSelect?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
207
|
+
onSelectCapture?: import("react").ReactEventHandler<HTMLButtonElement> | undefined;
|
|
208
|
+
onTouchCancel?: import("react").TouchEventHandler<HTMLButtonElement> | undefined;
|
|
209
|
+
onTouchCancelCapture?: import("react").TouchEventHandler<HTMLButtonElement> | undefined;
|
|
210
|
+
onTouchEnd?: import("react").TouchEventHandler<HTMLButtonElement> | undefined;
|
|
211
|
+
onTouchEndCapture?: import("react").TouchEventHandler<HTMLButtonElement> | undefined;
|
|
212
|
+
onTouchMove?: import("react").TouchEventHandler<HTMLButtonElement> | undefined;
|
|
213
|
+
onTouchMoveCapture?: import("react").TouchEventHandler<HTMLButtonElement> | undefined;
|
|
214
|
+
onTouchStart?: import("react").TouchEventHandler<HTMLButtonElement> | undefined;
|
|
215
|
+
onTouchStartCapture?: import("react").TouchEventHandler<HTMLButtonElement> | undefined;
|
|
216
|
+
onPointerDown?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
217
|
+
onPointerDownCapture?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
218
|
+
onPointerMove?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
219
|
+
onPointerMoveCapture?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
220
|
+
onPointerUp?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
221
|
+
onPointerUpCapture?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
222
|
+
onPointerCancel?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
223
|
+
onPointerCancelCapture?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
224
|
+
onPointerEnter?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
225
|
+
onPointerLeave?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
226
|
+
onPointerOver?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
227
|
+
onPointerOverCapture?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
228
|
+
onPointerOut?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
229
|
+
onPointerOutCapture?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
230
|
+
onGotPointerCapture?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
231
|
+
onGotPointerCaptureCapture?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
232
|
+
onLostPointerCapture?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
233
|
+
onLostPointerCaptureCapture?: import("react").PointerEventHandler<HTMLButtonElement> | undefined;
|
|
234
|
+
onScroll?: import("react").UIEventHandler<HTMLButtonElement> | undefined;
|
|
235
|
+
onScrollCapture?: import("react").UIEventHandler<HTMLButtonElement> | undefined;
|
|
236
|
+
onScrollEnd?: import("react").UIEventHandler<HTMLButtonElement> | undefined;
|
|
237
|
+
onScrollEndCapture?: import("react").UIEventHandler<HTMLButtonElement> | undefined;
|
|
238
|
+
onWheel?: import("react").WheelEventHandler<HTMLButtonElement> | undefined;
|
|
239
|
+
onWheelCapture?: import("react").WheelEventHandler<HTMLButtonElement> | undefined;
|
|
240
|
+
onAnimationStart?: import("react").AnimationEventHandler<HTMLButtonElement> | undefined;
|
|
241
|
+
onAnimationStartCapture?: import("react").AnimationEventHandler<HTMLButtonElement> | undefined;
|
|
242
|
+
onAnimationEnd?: import("react").AnimationEventHandler<HTMLButtonElement> | undefined;
|
|
243
|
+
onAnimationEndCapture?: import("react").AnimationEventHandler<HTMLButtonElement> | undefined;
|
|
244
|
+
onAnimationIteration?: import("react").AnimationEventHandler<HTMLButtonElement> | undefined;
|
|
245
|
+
onAnimationIterationCapture?: import("react").AnimationEventHandler<HTMLButtonElement> | undefined;
|
|
246
|
+
onToggle?: import("react").ToggleEventHandler<HTMLButtonElement> | undefined;
|
|
247
|
+
onBeforeToggle?: import("react").ToggleEventHandler<HTMLButtonElement> | undefined;
|
|
248
|
+
onTransitionCancel?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
249
|
+
onTransitionCancelCapture?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
250
|
+
onTransitionEnd?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
251
|
+
onTransitionEndCapture?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
252
|
+
onTransitionRun?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
253
|
+
onTransitionRunCapture?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
254
|
+
onTransitionStart?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
255
|
+
onTransitionStartCapture?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
256
|
+
key?: import("react").Key | null | undefined;
|
|
257
|
+
defaultChecked?: boolean | undefined | undefined;
|
|
258
|
+
defaultValue?: string | number | readonly string[] | undefined;
|
|
259
|
+
suppressContentEditableWarning?: boolean | undefined | undefined;
|
|
260
|
+
accessKey?: string | undefined | undefined;
|
|
261
|
+
autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {}) | undefined;
|
|
262
|
+
autoFocus?: boolean | undefined | undefined;
|
|
263
|
+
contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
|
|
264
|
+
contextMenu?: string | undefined | undefined;
|
|
265
|
+
dir?: string | undefined | undefined;
|
|
266
|
+
draggable?: (boolean | "true" | "false") | undefined;
|
|
267
|
+
enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
|
|
268
|
+
hidden?: boolean | undefined | undefined;
|
|
269
|
+
spellCheck?: (boolean | "true" | "false") | undefined;
|
|
270
|
+
translate?: "yes" | "no" | undefined | undefined;
|
|
271
|
+
radioGroup?: string | undefined | undefined;
|
|
272
|
+
about?: string | undefined | undefined;
|
|
273
|
+
content?: string | undefined | undefined;
|
|
274
|
+
datatype?: string | undefined | undefined;
|
|
275
|
+
inlist?: any;
|
|
276
|
+
prefix?: string | undefined | undefined;
|
|
277
|
+
property?: string | undefined | undefined;
|
|
278
|
+
rel?: string | undefined | undefined;
|
|
279
|
+
resource?: string | undefined | undefined;
|
|
280
|
+
rev?: string | undefined | undefined;
|
|
281
|
+
typeof?: string | undefined | undefined;
|
|
282
|
+
vocab?: string | undefined | undefined;
|
|
283
|
+
autoCorrect?: string | undefined | undefined;
|
|
284
|
+
autoSave?: string | undefined | undefined;
|
|
285
|
+
itemProp?: string | undefined | undefined;
|
|
286
|
+
itemScope?: boolean | undefined | undefined;
|
|
287
|
+
itemType?: string | undefined | undefined;
|
|
288
|
+
itemID?: string | undefined | undefined;
|
|
289
|
+
itemRef?: string | undefined | undefined;
|
|
290
|
+
results?: number | undefined | undefined;
|
|
291
|
+
security?: string | undefined | undefined;
|
|
292
|
+
unselectable?: "on" | "off" | undefined | undefined;
|
|
293
|
+
popover?: "" | "auto" | "manual" | "hint" | undefined | undefined;
|
|
294
|
+
popoverTargetAction?: "toggle" | "show" | "hide" | undefined | undefined;
|
|
295
|
+
popoverTarget?: string | undefined | undefined;
|
|
296
|
+
inert?: boolean | undefined | undefined;
|
|
297
|
+
inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined | undefined;
|
|
298
|
+
is?: string | undefined | undefined;
|
|
299
|
+
exportparts?: string | undefined | undefined;
|
|
300
|
+
disabled?: boolean | undefined | undefined;
|
|
301
|
+
formAction?: string | ((formData: FormData) => void | Promise<void>) | undefined;
|
|
302
|
+
formEncType?: string | undefined | undefined;
|
|
303
|
+
formMethod?: string | undefined | undefined;
|
|
304
|
+
formNoValidate?: boolean | undefined | undefined;
|
|
305
|
+
formTarget?: string | undefined | undefined;
|
|
306
|
+
value?: string | number | readonly string[] | undefined;
|
|
307
|
+
href: string | undefined;
|
|
308
|
+
type: "button" | "reset" | "submit" | undefined;
|
|
309
|
+
className: string;
|
|
310
|
+
}, HTMLElement>;
|
package/dist/actions/IconBtn.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createElement } from 'react';
|
|
3
|
-
import { Menu } from './Dropdown.js';
|
|
4
3
|
import { cx } from '../cx.js';
|
|
5
4
|
import { Icon } from '../type/Icon.js';
|
|
6
5
|
/** IconBtn — the round icon button: `sm` in heads and bars, full size in rows and composers, `invert` for the one filled move.
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return (_jsxs(_Fragment, { children: [btn, _jsx(Menu, { popover: true, actions: true, end: !menuStart, id: menuId, children: menu })] }));
|
|
6
|
+
* It is a button and nothing more: to open a Menu, give it the platform's `popoverTarget={the Menu's id}` and render that `<Menu popover actions id>`
|
|
7
|
+
* wherever you like — the panel anchors to the button that opened it. To open anything else, `onClick`. */
|
|
8
|
+
export function IconBtn({ label, icon, sm, invert, href, className, type, children, ...rest }) {
|
|
9
|
+
const btn = createElement(href ? 'a' : 'button', { href, type: href ? undefined : type ?? 'button', 'aria-label': label, className: cx('icon-btn', sm && 'icon-btn--sm', invert && 'icon-btn--invert', className), ...rest }, icon ? _jsx(Icon, { name: icon, size: sm ? 'sm' : 'md' }) : children);
|
|
10
|
+
return btn;
|
|
13
11
|
}
|
package/dist/cardds.css
CHANGED
|
@@ -90,6 +90,8 @@
|
|
|
90
90
|
--chip-h: calc(var(--tap-base) * 19 / 24); /* 38 chip height */
|
|
91
91
|
--bar-h: calc(var(--tap-base) * 4 / 3); /* 64 float bar, day cell, deck actions */
|
|
92
92
|
--header-h: calc(var(--tap-base) * 5 / 4); /* 60 top bar — .topbar and .appbar alike */
|
|
93
|
+
--card-pad-rest: var(--sp-5); /* 20 a card's padding before any variant — .card publishes it as --card-pad; the sheet's peek strip is built from it where no card is in scope */
|
|
94
|
+
--card-gap-rest: var(--sp-4); /* 16 …and its gap */
|
|
93
95
|
--screen-pad: var(--sp-4); /* 16 the screen's inset — .sheet-stack cancels it */
|
|
94
96
|
--map-ring: calc(var(--tap-base) * 10 / 3); /* the rough-area ring on a map (sheet.css .map__ring) — a neighbourhood, not a house */
|
|
95
97
|
--fab: calc(var(--tap-base) * 3 / 2); /* 72 square floating action */
|
|
@@ -521,8 +523,8 @@ button { font: inherit; cursor: pointer; }
|
|
|
521
523
|
.card {
|
|
522
524
|
--card-bg: var(--card-1-bg); /* the slot, readable by children (avatar rings, fold) */
|
|
523
525
|
--card-ink: var(--card-1-ink);
|
|
524
|
-
--card-pad: var(--
|
|
525
|
-
--card-gap: var(--
|
|
526
|
+
--card-pad: var(--card-pad-rest); /* published so .bleed can cancel it exactly */
|
|
527
|
+
--card-gap: var(--card-gap-rest); /* published so a sheet's peek strip (sheet.css) is exact */
|
|
526
528
|
background: var(--card-bg);
|
|
527
529
|
color: var(--card-ink);
|
|
528
530
|
border: var(--border-w) solid var(--card-border);
|
|
@@ -1105,7 +1107,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
1105
1107
|
page. Many sheets stacked as the app's menu are the other system,
|
|
1106
1108
|
.sheet-stack (stack.css): the same material, its own class and file.
|
|
1107
1109
|
|
|
1108
|
-
<article class="card sheet sheet--half"
|
|
1110
|
+
<article class="card sheet sheet--half">
|
|
1109
1111
|
A tap on the handle TOGGLES the sheet between its own state and peek
|
|
1110
1112
|
(Lh 2026-09-16) — never a step-by-step climb; a drag snaps to any of
|
|
1111
1113
|
the listed states, and the state it lands on becomes the one a tap
|
|
@@ -1123,14 +1125,12 @@ button { font: inherit; cursor: pointer; }
|
|
|
1123
1125
|
============================================================ */
|
|
1124
1126
|
|
|
1125
1127
|
.sheet {
|
|
1126
|
-
--_handle: var(--sp-1);
|
|
1127
1128
|
/* the strip a peeked sheet shows: the card's own top padding, the handle,
|
|
1128
1129
|
the gap, one title row (--tap — the head rule below makes every head at
|
|
1129
1130
|
least that tall) and the gap under it, so the cut lands exactly where
|
|
1130
1131
|
the first control starts and nothing of it leaks through. Published
|
|
1131
1132
|
(and registered in tokens.css) so a sheet whose head is taller can
|
|
1132
1133
|
retune it: .my-sheet { --sheet-peek: … } */
|
|
1133
|
-
--sheet-peek: calc(var(--card-pad) + var(--_handle) + 2 * var(--card-gap) + var(--tap));
|
|
1134
1134
|
--sheet-half: 0.5; /* a share of the sheet's own height */
|
|
1135
1135
|
--sheet-3q: 0.25; /* three quarters showing: slid by a quarter */
|
|
1136
1136
|
/* the sheet's own height, seen from inside it: the box it slides in is the
|
|
@@ -1165,14 +1165,16 @@ button { font: inherit; cursor: pointer; }
|
|
|
1165
1165
|
.sheet--half { --_y: calc(var(--sheet-half) * 100%); --_cover: calc(var(--sheet-half) * var(--_box)); }
|
|
1166
1166
|
.sheet--3q { --_y: calc(var(--sheet-3q) * 100%); --_cover: calc(var(--sheet-3q) * var(--_box)); }
|
|
1167
1167
|
.sheet--peek { --_y: calc(100% - var(--sheet-peek)); --_cover: calc(var(--_box) - var(--sheet-peek)); }
|
|
1168
|
+
/* --sheet-peek is declared on the BOX the sheet slides in, not on the sheet: the words behind a peeked sheet
|
|
1169
|
+
have to read it too (step.css keeps that much room under them), and a token only flows down. The sheet
|
|
1170
|
+
inherits it. A sheet whose head is taller retunes it on the box. */
|
|
1171
|
+
:is(.step, .sheet-stage) { --_handle: var(--sp-1); --sheet-peek: calc(var(--card-pad-rest) + var(--_handle) + 2 * var(--card-gap-rest) + var(--tap)); }
|
|
1172
|
+
|
|
1168
1173
|
/* ---- called sheets (Lh, 2026-09-20): a .step whose .base-content has buttons that each CALL a sheet ----
|
|
1169
1174
|
.sheet--away = not on the screen: slid all the way out (translate, like every state — the material never
|
|
1170
1175
|
changes), and hidden once it has left so its shadow does not lie on the step's bottom edge; write it
|
|
1171
|
-
with `inert
|
|
1172
|
-
|
|
1173
|
-
sheet up to full and sends any other one away; the handle takes it down to peek, never further, so the
|
|
1174
|
-
words and the other buttons are back in reach; the same button again raises it from peek to full.
|
|
1175
|
-
Nothing waits at peek before the first call. No bar on such a screen (actions.css).
|
|
1176
|
+
with `inert` (the React Sheet does). WHO brings it onto the screen is the app's business — a button, a route:
|
|
1177
|
+
cardds ties no component to another. Nothing waits at peek before the first call.
|
|
1176
1178
|
WHAT IT IS FOR: the base offers WAYS IN — sign in · new phone · join — and each button calls a sheet
|
|
1177
1179
|
that holds that way's WHOLE form, its submit on the sheet's foot, leading to the next page. The base
|
|
1178
1180
|
carries no control. It is NOT for a form taken apart — one sheet per field, a "send" left on the base:
|
|
@@ -1497,8 +1499,9 @@ button { font: inherit; cursor: pointer; }
|
|
|
1497
1499
|
:has(> .action-bar) .step { margin-bottom: calc(var(--bar-reserve) + var(--kb, 0rem)); }
|
|
1498
1500
|
/* LAYERS (Lh, 2026-09-20): the base, then the sheet over it, then the top bar. A bar is the BASE's — the
|
|
1499
1501
|
move of a page of words — so a step with a sheet has NO bar: the sheet finishes on its own .card__foot
|
|
1500
|
-
(sheet.css), and a form lives whole in ONE sheet, never item by item on the base.
|
|
1501
|
-
|
|
1502
|
+
(sheet.css), and a form lives whole in ONE sheet, never item by item on the base. That is how cardds's
|
|
1503
|
+
own screens are composed (the guide); the framework does not police it — a component never changes
|
|
1504
|
+
because another one is there. */
|
|
1502
1505
|
|
|
1503
1506
|
/* the reading block: a .base-content (base.css) — the same words-on-the-base
|
|
1504
1507
|
block as anywhere else (it was .step__card, and a .card before 2026-09-16;
|
|
@@ -1517,11 +1520,10 @@ button { font: inherit; cursor: pointer; }
|
|
|
1517
1520
|
color: var(--on-surface);
|
|
1518
1521
|
}
|
|
1519
1522
|
/* the reading block is the .base-content — or the .pages that holds several of them, a walk of words
|
|
1520
|
-
(card.css).
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
+
(card.css). Behind a PEEKED sheet the words keep the strip's room under them, so whatever is down there
|
|
1524
|
+
(the buttons that call the other sheets) scrolls clear of it — CSS alone: the box declares --sheet-peek. */
|
|
1525
|
+
.step:has(> .sheet--peek) > :is(.base-content, .pages) { padding-bottom: var(--sheet-peek); }
|
|
1523
1526
|
.step > :is(.base-content, .pages) {
|
|
1524
|
-
padding-bottom: var(--sheet-room, 0rem);
|
|
1525
1527
|
flex: 0 1 auto;
|
|
1526
1528
|
}
|
|
1527
1529
|
.step > :is(.base-content, .pages) {
|
|
@@ -1896,14 +1898,9 @@ button { font: inherit; cursor: pointer; }
|
|
|
1896
1898
|
<button class="icon-btn icon-btn--invert" aria-label="ถัดไป">…</button>
|
|
1897
1899
|
</div> — or the same two in an .action-bar__tier--pager under a control */
|
|
1898
1900
|
.action-bar--pager { align-items: center; }
|
|
1899
|
-
/* The bar belongs to the BASE
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
foot (sheet.css). So a pager never works beside a sheet — that screen has work that cannot be walked
|
|
1903
|
-
past — and neither does any other bar: while a sheet is on (only .sheet--away, a sheet not called yet,
|
|
1904
|
-
is not), the bar takes no pointer here and cardds.js makes it inert, so the keyboard cannot reach what
|
|
1905
|
-
the eye cannot see. */
|
|
1906
|
-
:has(.step > .sheet:not(.sheet--away)) > .action-bar { pointer-events: none; }
|
|
1901
|
+
/* The bar belongs to the BASE: the move of a page of words — a pager turning them, or one wide button. A screen
|
|
1902
|
+
with a sheet finishes on the sheet's own foot instead (sheet.css). Guidance for composing, not a rule the
|
|
1903
|
+
CSS enforces: a component never changes because another one is there. */
|
|
1907
1904
|
/* the page dots: under the card in a .screen__centre group; tight gaps */
|
|
1908
1905
|
.pager__at { flex: 0 1 auto; min-width: 0; overflow: hidden; display: flex; align-items: center; gap: var(--sp-1); }
|
|
1909
1906
|
.pager__at > * {
|