@usableapp/cardds 0.7.12 → 0.7.14
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/CHANGELOG.md +19 -0
- package/css/actions.css +1 -0
- package/dist/actions/Btn.d.ts +110 -108
- package/dist/actions/Btn.js +2 -2
- package/dist/cardds.css +1 -0
- package/dist/sheets/SheetSteps.js +12 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
> For: a project that consumes `@usableapp/cardds` and its AI — what changed between versions, written as before → after, so a screen can be brought up to date without reading the source. Newest first. A consumer never edits cardds; if something here leaves you without a way to do what you did before, report the gap.
|
|
4
4
|
|
|
5
|
+
## 0.7.14 — 2026-09-25
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `Btn form`: a form's button. It is sized to its words with wide sides (58px, knob `--btn-form-pad-x`) and centred on its
|
|
9
|
+
own row under the field, so it reads as part of the form, not a page CTA. Use it for a SheetStep's button:
|
|
10
|
+
`<Btn primary block>` → `<Btn primary form>`. Don't combine it with `block` (block wins). Replaces the native `form`
|
|
11
|
+
attribute on `Btn`. Story `Btn · Form`.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Gallery: `IconBtn`'s stories are on the Btn page (no IconBtn page). The component and its API are unchanged.
|
|
15
|
+
|
|
16
|
+
## 0.7.13 — 2026-09-25
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- `SheetStep`: Enter in a field of the step presses the step's button, through the step's checks like a tap (a wrong
|
|
20
|
+
number stays on the step). It is the phone keyboard's next/go key. Give the field `enterKeyHint="next"` (or `"go"`) so
|
|
21
|
+
the key says so. iPhone's number/tel pads have no Enter key: there the member taps the step's button. No auto-advance on a
|
|
22
|
+
full number, on purpose (the member checks the number before the code is sent).
|
|
23
|
+
|
|
5
24
|
## 0.7.12 — 2026-09-25
|
|
6
25
|
|
|
7
26
|
### Changed
|
package/css/actions.css
CHANGED
|
@@ -123,6 +123,7 @@
|
|
|
123
123
|
would take the light-card action ink and vanish */
|
|
124
124
|
.btn--quiet { background: transparent; color: inherit; border-color: color-mix(in srgb, currentColor 35%, transparent); }
|
|
125
125
|
.btn--block { width: 100%; }
|
|
126
|
+
.btn--form { justify-self: center; align-self: center; margin-inline: auto; padding-inline: var(--btn-form-pad-x, calc(var(--sp-base) * 14.5)); /* 58px: "ส่งรหัส OTP" at 213px, 20% longer than at 40px sides (Lh 2026-09-25) */ } /* a form's button: its words + wide sides, centred in a grid (a step) or a block (Lh 2026-09-25) */
|
|
126
127
|
/* xl: the one giant call to action in a tinted card ("Taxi!") */
|
|
127
128
|
.btn--xl { min-height: var(--btn-xl-h); font: 800 var(--fs-3xl)/1 var(--font-display); letter-spacing: var(--track-h1); border-radius: var(--r-card); padding-inline: var(--sp-8); }
|
|
128
129
|
/* disabled keeps the slot — a control that vanishes moves everything else,
|
package/dist/actions/Btn.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { type ComponentProps } from 'react';
|
|
2
|
-
export interface BtnProps extends ComponentProps<'button'> {
|
|
2
|
+
export interface BtnProps extends Omit<ComponentProps<'button'>, 'form'> {
|
|
3
3
|
/** the filled accent button — the one forward move */
|
|
4
4
|
primary?: boolean;
|
|
5
5
|
/** ink on whatever it sits on, a faint outline */
|
|
6
6
|
quiet?: boolean;
|
|
7
7
|
/** full width */
|
|
8
8
|
block?: boolean;
|
|
9
|
+
/** a form's button: sized to its words with wide side padding, centred on its own row — it reads as part of the form above it,
|
|
10
|
+
* not a page CTA (Lh 2026-09-25). Replaces the native `form` attribute (a button outside its <form> — not a cardds pattern). */
|
|
11
|
+
form?: boolean;
|
|
9
12
|
/** the one giant call to action in a tinted card ("Taxi!") */
|
|
10
13
|
xl?: boolean;
|
|
11
14
|
/** a link styled as a button */
|
|
@@ -15,129 +18,76 @@ export interface BtnProps extends ComponentProps<'button'> {
|
|
|
15
18
|
* Btn — the pill button (48px+ tall). Plain by default; `primary` for the one move; `quiet` on tinted cards.
|
|
16
19
|
* In a CardFoot up to four share the line; in an ActionBar it takes the width. An Icon xs may lead or trail the label.
|
|
17
20
|
*/
|
|
18
|
-
export declare function Btn({ primary, quiet, block, xl, href, className, type, ...rest }: BtnProps): import("react").DetailedReactHTMLElement<{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
disabled?: boolean | undefined;
|
|
22
|
-
form?: string | undefined;
|
|
23
|
-
formAction?: string | ((formData: FormData) => void | Promise<void>) | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_FORM_ACTIONS[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_FORM_ACTIONS] | undefined;
|
|
24
|
-
formEncType?: string | undefined;
|
|
25
|
-
formMethod?: string | undefined;
|
|
26
|
-
formNoValidate?: boolean | undefined;
|
|
27
|
-
formTarget?: string | undefined;
|
|
28
|
-
name?: string | undefined;
|
|
29
|
-
value?: string | readonly string[] | number | undefined;
|
|
30
|
-
defaultChecked?: boolean | undefined;
|
|
31
|
-
defaultValue?: string | number | readonly string[] | undefined;
|
|
32
|
-
suppressContentEditableWarning?: boolean | undefined;
|
|
33
|
-
suppressHydrationWarning?: boolean | undefined;
|
|
34
|
-
accessKey?: string | undefined;
|
|
35
|
-
autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {});
|
|
36
|
-
autoFocus?: boolean | undefined;
|
|
37
|
-
contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
|
|
38
|
-
contextMenu?: string | undefined;
|
|
39
|
-
dir?: string | undefined;
|
|
40
|
-
draggable?: (boolean | "true" | "false") | undefined;
|
|
41
|
-
enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined;
|
|
42
|
-
hidden?: boolean | undefined;
|
|
43
|
-
id?: string | undefined;
|
|
44
|
-
lang?: string | undefined;
|
|
45
|
-
nonce?: string | undefined;
|
|
46
|
-
slot?: string | undefined;
|
|
47
|
-
spellCheck?: (boolean | "true" | "false") | undefined;
|
|
21
|
+
export declare function Btn({ primary, quiet, block, form, xl, href, className, type, ...rest }: BtnProps): import("react").DetailedReactHTMLElement<{
|
|
22
|
+
name?: string | undefined | undefined;
|
|
23
|
+
slot?: string | undefined | undefined;
|
|
48
24
|
style?: import("react").CSSProperties | undefined;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
25
|
+
title?: string | undefined | undefined;
|
|
26
|
+
children?: import("react").ReactNode;
|
|
27
|
+
suppressHydrationWarning?: boolean | undefined | undefined;
|
|
28
|
+
color?: string | undefined | undefined;
|
|
29
|
+
id?: string | undefined | undefined;
|
|
30
|
+
lang?: string | undefined | undefined;
|
|
31
|
+
nonce?: string | undefined | undefined;
|
|
32
|
+
part?: string | undefined | undefined;
|
|
53
33
|
role?: import("react").AriaRole | undefined;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
datatype?: string | undefined;
|
|
57
|
-
inlist?: any;
|
|
58
|
-
prefix?: string | undefined;
|
|
59
|
-
property?: string | undefined;
|
|
60
|
-
rel?: string | undefined;
|
|
61
|
-
resource?: string | undefined;
|
|
62
|
-
rev?: string | undefined;
|
|
63
|
-
typeof?: string | undefined;
|
|
64
|
-
vocab?: string | undefined;
|
|
65
|
-
autoCorrect?: string | undefined;
|
|
66
|
-
autoSave?: string | undefined;
|
|
67
|
-
color?: string | undefined;
|
|
68
|
-
itemProp?: string | undefined;
|
|
69
|
-
itemScope?: boolean | undefined;
|
|
70
|
-
itemType?: string | undefined;
|
|
71
|
-
itemID?: string | undefined;
|
|
72
|
-
itemRef?: string | undefined;
|
|
73
|
-
results?: number | undefined;
|
|
74
|
-
security?: string | undefined;
|
|
75
|
-
unselectable?: "on" | "off" | undefined;
|
|
76
|
-
popover?: "" | "auto" | "manual" | "hint" | undefined;
|
|
77
|
-
popoverTargetAction?: "toggle" | "show" | "hide" | undefined;
|
|
78
|
-
popoverTarget?: string | undefined;
|
|
79
|
-
inert?: boolean | undefined;
|
|
80
|
-
inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined;
|
|
81
|
-
is?: string | undefined;
|
|
82
|
-
exportparts?: string | undefined;
|
|
83
|
-
part?: string | undefined;
|
|
84
|
-
"aria-activedescendant"?: string | undefined;
|
|
34
|
+
tabIndex?: number | undefined | undefined;
|
|
35
|
+
"aria-activedescendant"?: string | undefined | undefined;
|
|
85
36
|
"aria-atomic"?: (boolean | "true" | "false") | undefined;
|
|
86
|
-
"aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined;
|
|
87
|
-
"aria-braillelabel"?: string | undefined;
|
|
88
|
-
"aria-brailleroledescription"?: string | undefined;
|
|
37
|
+
"aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
|
|
38
|
+
"aria-braillelabel"?: string | undefined | undefined;
|
|
39
|
+
"aria-brailleroledescription"?: string | undefined | undefined;
|
|
89
40
|
"aria-busy"?: (boolean | "true" | "false") | undefined;
|
|
90
|
-
"aria-checked"?: boolean | "false" | "mixed" | "true" | undefined;
|
|
91
|
-
"aria-colcount"?: number | undefined;
|
|
92
|
-
"aria-colindex"?: number | undefined;
|
|
93
|
-
"aria-colindextext"?: string | undefined;
|
|
94
|
-
"aria-colspan"?: number | undefined;
|
|
95
|
-
"aria-controls"?: string | undefined;
|
|
96
|
-
"aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined;
|
|
97
|
-
"aria-describedby"?: string | undefined;
|
|
98
|
-
"aria-description"?: string | undefined;
|
|
99
|
-
"aria-details"?: string | undefined;
|
|
41
|
+
"aria-checked"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
|
|
42
|
+
"aria-colcount"?: number | undefined | undefined;
|
|
43
|
+
"aria-colindex"?: number | undefined | undefined;
|
|
44
|
+
"aria-colindextext"?: string | undefined | undefined;
|
|
45
|
+
"aria-colspan"?: number | undefined | undefined;
|
|
46
|
+
"aria-controls"?: string | undefined | undefined;
|
|
47
|
+
"aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined | undefined;
|
|
48
|
+
"aria-describedby"?: string | undefined | undefined;
|
|
49
|
+
"aria-description"?: string | undefined | undefined;
|
|
50
|
+
"aria-details"?: string | undefined | undefined;
|
|
100
51
|
"aria-disabled"?: (boolean | "true" | "false") | undefined;
|
|
101
|
-
"aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined;
|
|
102
|
-
"aria-errormessage"?: string | undefined;
|
|
52
|
+
"aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined | undefined;
|
|
53
|
+
"aria-errormessage"?: string | undefined | undefined;
|
|
103
54
|
"aria-expanded"?: (boolean | "true" | "false") | undefined;
|
|
104
|
-
"aria-flowto"?: string | undefined;
|
|
55
|
+
"aria-flowto"?: string | undefined | undefined;
|
|
105
56
|
"aria-grabbed"?: (boolean | "true" | "false") | undefined;
|
|
106
|
-
"aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined;
|
|
57
|
+
"aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined | undefined;
|
|
107
58
|
"aria-hidden"?: (boolean | "true" | "false") | undefined;
|
|
108
|
-
"aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined;
|
|
109
|
-
"aria-keyshortcuts"?: string | undefined;
|
|
110
|
-
"aria-label"?: string | undefined;
|
|
111
|
-
"aria-labelledby"?: string | undefined;
|
|
112
|
-
"aria-level"?: number | undefined;
|
|
113
|
-
"aria-live"?: "off" | "assertive" | "polite" | undefined;
|
|
59
|
+
"aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined | undefined;
|
|
60
|
+
"aria-keyshortcuts"?: string | undefined | undefined;
|
|
61
|
+
"aria-label"?: string | undefined | undefined;
|
|
62
|
+
"aria-labelledby"?: string | undefined | undefined;
|
|
63
|
+
"aria-level"?: number | undefined | undefined;
|
|
64
|
+
"aria-live"?: "off" | "assertive" | "polite" | undefined | undefined;
|
|
114
65
|
"aria-modal"?: (boolean | "true" | "false") | undefined;
|
|
115
66
|
"aria-multiline"?: (boolean | "true" | "false") | undefined;
|
|
116
67
|
"aria-multiselectable"?: (boolean | "true" | "false") | undefined;
|
|
117
|
-
"aria-orientation"?: "horizontal" | "vertical" | undefined;
|
|
118
|
-
"aria-owns"?: string | undefined;
|
|
119
|
-
"aria-placeholder"?: string | undefined;
|
|
120
|
-
"aria-posinset"?: number | undefined;
|
|
121
|
-
"aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined;
|
|
68
|
+
"aria-orientation"?: "horizontal" | "vertical" | undefined | undefined;
|
|
69
|
+
"aria-owns"?: string | undefined | undefined;
|
|
70
|
+
"aria-placeholder"?: string | undefined | undefined;
|
|
71
|
+
"aria-posinset"?: number | undefined | undefined;
|
|
72
|
+
"aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
|
|
122
73
|
"aria-readonly"?: (boolean | "true" | "false") | undefined;
|
|
123
|
-
"aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined;
|
|
74
|
+
"aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined | undefined;
|
|
124
75
|
"aria-required"?: (boolean | "true" | "false") | undefined;
|
|
125
|
-
"aria-roledescription"?: string | undefined;
|
|
126
|
-
"aria-rowcount"?: number | undefined;
|
|
127
|
-
"aria-rowindex"?: number | undefined;
|
|
128
|
-
"aria-rowindextext"?: string | undefined;
|
|
129
|
-
"aria-rowspan"?: number | undefined;
|
|
76
|
+
"aria-roledescription"?: string | undefined | undefined;
|
|
77
|
+
"aria-rowcount"?: number | undefined | undefined;
|
|
78
|
+
"aria-rowindex"?: number | undefined | undefined;
|
|
79
|
+
"aria-rowindextext"?: string | undefined | undefined;
|
|
80
|
+
"aria-rowspan"?: number | undefined | undefined;
|
|
130
81
|
"aria-selected"?: (boolean | "true" | "false") | undefined;
|
|
131
|
-
"aria-setsize"?: number | undefined;
|
|
132
|
-
"aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined;
|
|
133
|
-
"aria-valuemax"?: number | undefined;
|
|
134
|
-
"aria-valuemin"?: number | undefined;
|
|
135
|
-
"aria-valuenow"?: number | undefined;
|
|
136
|
-
"aria-valuetext"?: string | undefined;
|
|
137
|
-
children?: import("react").ReactNode | undefined;
|
|
82
|
+
"aria-setsize"?: number | undefined | undefined;
|
|
83
|
+
"aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined | undefined;
|
|
84
|
+
"aria-valuemax"?: number | undefined | undefined;
|
|
85
|
+
"aria-valuemin"?: number | undefined | undefined;
|
|
86
|
+
"aria-valuenow"?: number | undefined | undefined;
|
|
87
|
+
"aria-valuetext"?: string | undefined | undefined;
|
|
138
88
|
dangerouslySetInnerHTML?: {
|
|
139
89
|
__html: string | TrustedHTML;
|
|
140
|
-
} | undefined;
|
|
90
|
+
} | undefined | undefined;
|
|
141
91
|
onCopy?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
|
|
142
92
|
onCopyCapture?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
|
|
143
93
|
onCut?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
|
|
@@ -306,6 +256,58 @@ export declare function Btn({ primary, quiet, block, xl, href, className, type,
|
|
|
306
256
|
onTransitionRunCapture?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
307
257
|
onTransitionStart?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
308
258
|
onTransitionStartCapture?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
|
|
259
|
+
ref?: import("react").Ref<HTMLButtonElement> | undefined;
|
|
260
|
+
key?: import("react").Key | null | undefined;
|
|
261
|
+
defaultChecked?: boolean | undefined | undefined;
|
|
262
|
+
defaultValue?: string | number | readonly string[] | undefined;
|
|
263
|
+
suppressContentEditableWarning?: boolean | undefined | undefined;
|
|
264
|
+
accessKey?: string | undefined | undefined;
|
|
265
|
+
autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {}) | undefined;
|
|
266
|
+
autoFocus?: boolean | undefined | undefined;
|
|
267
|
+
contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
|
|
268
|
+
contextMenu?: string | undefined | undefined;
|
|
269
|
+
dir?: string | undefined | undefined;
|
|
270
|
+
draggable?: (boolean | "true" | "false") | undefined;
|
|
271
|
+
enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
|
|
272
|
+
hidden?: boolean | undefined | undefined;
|
|
273
|
+
spellCheck?: (boolean | "true" | "false") | undefined;
|
|
274
|
+
translate?: "yes" | "no" | undefined | undefined;
|
|
275
|
+
radioGroup?: string | undefined | undefined;
|
|
276
|
+
about?: string | undefined | undefined;
|
|
277
|
+
content?: string | undefined | undefined;
|
|
278
|
+
datatype?: string | undefined | undefined;
|
|
279
|
+
inlist?: any;
|
|
280
|
+
prefix?: string | undefined | undefined;
|
|
281
|
+
property?: string | undefined | undefined;
|
|
282
|
+
rel?: string | undefined | undefined;
|
|
283
|
+
resource?: string | undefined | undefined;
|
|
284
|
+
rev?: string | undefined | undefined;
|
|
285
|
+
typeof?: string | undefined | undefined;
|
|
286
|
+
vocab?: string | undefined | undefined;
|
|
287
|
+
autoCorrect?: string | undefined | undefined;
|
|
288
|
+
autoSave?: string | undefined | undefined;
|
|
289
|
+
itemProp?: string | undefined | undefined;
|
|
290
|
+
itemScope?: boolean | undefined | undefined;
|
|
291
|
+
itemType?: string | undefined | undefined;
|
|
292
|
+
itemID?: string | undefined | undefined;
|
|
293
|
+
itemRef?: string | undefined | undefined;
|
|
294
|
+
results?: number | undefined | undefined;
|
|
295
|
+
security?: string | undefined | undefined;
|
|
296
|
+
unselectable?: "on" | "off" | undefined | undefined;
|
|
297
|
+
popover?: "" | "auto" | "manual" | "hint" | undefined | undefined;
|
|
298
|
+
popoverTargetAction?: "toggle" | "show" | "hide" | undefined | undefined;
|
|
299
|
+
popoverTarget?: string | undefined | undefined;
|
|
300
|
+
inert?: boolean | undefined | undefined;
|
|
301
|
+
inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined | undefined;
|
|
302
|
+
is?: string | undefined | undefined;
|
|
303
|
+
exportparts?: string | undefined | undefined;
|
|
304
|
+
disabled?: boolean | undefined | undefined;
|
|
305
|
+
formAction?: string | ((formData: FormData) => void | Promise<void>) | undefined;
|
|
306
|
+
formEncType?: string | undefined | undefined;
|
|
307
|
+
formMethod?: string | undefined | undefined;
|
|
308
|
+
formNoValidate?: boolean | undefined | undefined;
|
|
309
|
+
formTarget?: string | undefined | undefined;
|
|
310
|
+
value?: string | number | readonly string[] | undefined;
|
|
309
311
|
href: string | undefined;
|
|
310
312
|
type: "button" | "submit" | "reset" | undefined;
|
|
311
313
|
className: string;
|
package/dist/actions/Btn.js
CHANGED
|
@@ -4,11 +4,11 @@ import { cx } from '../cx.js';
|
|
|
4
4
|
* Btn — the pill button (48px+ tall). Plain by default; `primary` for the one move; `quiet` on tinted cards.
|
|
5
5
|
* In a CardFoot up to four share the line; in an ActionBar it takes the width. An Icon xs may lead or trail the label.
|
|
6
6
|
*/
|
|
7
|
-
export function Btn({ primary, quiet, block, xl, href, className, type, ...rest }) {
|
|
7
|
+
export function Btn({ primary, quiet, block, form, xl, href, className, type, ...rest }) {
|
|
8
8
|
return createElement(href ? 'a' : 'button', {
|
|
9
9
|
href,
|
|
10
10
|
type: href ? undefined : type ?? 'button',
|
|
11
|
-
className: cx('btn', primary && 'btn--primary', quiet && 'btn--quiet', block && 'btn--block', xl && 'btn--xl', className),
|
|
11
|
+
className: cx('btn', primary && 'btn--primary', quiet && 'btn--quiet', block && 'btn--block', form && 'btn--form', xl && 'btn--xl', className),
|
|
12
12
|
...rest,
|
|
13
13
|
});
|
|
14
14
|
}
|
package/dist/cardds.css
CHANGED
|
@@ -2053,6 +2053,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
2053
2053
|
would take the light-card action ink and vanish */
|
|
2054
2054
|
.btn--quiet { background: transparent; color: inherit; border-color: color-mix(in srgb, currentColor 35%, transparent); }
|
|
2055
2055
|
.btn--block { width: 100%; }
|
|
2056
|
+
.btn--form { justify-self: center; align-self: center; margin-inline: auto; padding-inline: var(--btn-form-pad-x, calc(var(--sp-base) * 14.5)); /* 58px: "ส่งรหัส OTP" at 213px, 20% longer than at 40px sides (Lh 2026-09-25) */ } /* a form's button: its words + wide sides, centred in a grid (a step) or a block (Lh 2026-09-25) */
|
|
2056
2057
|
/* xl: the one giant call to action in a tinted card ("Taxi!") */
|
|
2057
2058
|
.btn--xl { min-height: var(--btn-xl-h); font: 800 var(--fs-3xl)/1 var(--font-display); letter-spacing: var(--track-h1); border-radius: var(--r-card); padding-inline: var(--sp-8); }
|
|
2058
2059
|
/* disabled keeps the slot — a control that vanishes moves everything else,
|
|
@@ -238,5 +238,16 @@ export function SheetStep({ title, summary, skippable, skipLabel = 'Skip', error
|
|
|
238
238
|
bad.focus();
|
|
239
239
|
}
|
|
240
240
|
};
|
|
241
|
-
|
|
241
|
+
/* Enter on the keyboard in a field of the step = a press on the step's button (the phone's "go"/"next" key, a desktop's Enter);
|
|
242
|
+
the press goes through the step's checks like a tap (Lh 2026-09-25) */
|
|
243
|
+
const enter = (e) => {
|
|
244
|
+
if (e.key !== 'Enter' || e.nativeEvent.isComposing || !(e.target instanceof HTMLInputElement))
|
|
245
|
+
return;
|
|
246
|
+
const btn = e.currentTarget.querySelector('.btn:not(:disabled)');
|
|
247
|
+
if (btn) {
|
|
248
|
+
e.preventDefault();
|
|
249
|
+
btn.click();
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
return (_jsxs("li", { className: cx('sheet-step', `sheet-step--${phase}`, busy != null && busy !== false && 'sheet-step--busy', className), "aria-current": phase === 'now' ? 'step' : undefined, "aria-busy": busy != null && busy !== false ? true : undefined, "data-skippable": skippable || undefined, ...rest, children: [_jsxs("div", { className: "sheet-step__head", inert: off || undefined, children: [numbered && _jsx("span", { className: "sheet-step__num", "aria-hidden": true, children: i + 1 }), _jsx("h3", { className: "sheet-step__title", tabIndex: -1, children: title }), phase === 'done' && summary != null && _jsx("span", { className: "sheet-step__summary t-caption", children: summary }), phase === 'done' && _jsx(Icon, { name: "check", size: "xs", className: "sheet-step__check" })] }), _jsx("div", { className: "sheet-step__body", children: _jsxs("div", { className: "sheet-step__inner", inert: off || undefined, onClickCapture: press, onPointerDown: keepCursor, onKeyDown: enter, children: [_jsx(CheckContext.Provider, { value: group, children: children }), _jsx(FormNote, { error: error ?? note, busy: busy }), skippable && _jsx(Link, { sm: true, muted: true, className: "sheet-step__skip", onClick: () => go(i + 1, 'skip'), children: skipLabel })] }) }), reversible && off && (_jsx("button", { type: "button", className: "sheet-step__go", "aria-label": typeof title === 'string' ? title : `${i + 1} / ${count}`, onClick: () => go(i, 'tap') }))] }));
|
|
242
253
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usableapp/cardds",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.14",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "card-first mobile design system, React-first: the components in src/ are thin wrappers over the CSS contract (css/*.css stays the only truth); gallery/ shows every story live (npm run dev), tests/ measures the geometry.",
|