shelving 1.288.0 → 1.289.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shelving",
3
- "version": "1.288.0",
3
+ "version": "1.289.1",
4
4
  "author": "Dave Houlbrooke <dave@shax.com>",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,15 +1,15 @@
1
1
  import type { ReactElement } from "react";
2
+ import { type BlockVariants } from "../style/Block.js";
2
3
  import { type FlexVariants } from "../style/Flex.js";
3
4
  import { type StatusVariants } from "../style/Status.js";
4
- import { type TypographyVariants } from "../style/Typography.js";
5
5
  import type { ClassProps } from "../util/props.js";
6
6
  import { type ClickableProps } from "./Clickable.js";
7
7
  /**
8
- * Styling variants for a `Button`, combining flex, color, status, and typography options with button-specific toggles.
8
+ * Styling variants for a `Button`: the block variants (space, padding, indent, width, typography), flex, and status, plus button-specific toggles.
9
9
  *
10
10
  * @see https://shelving.cc/ui/ButtonVariants
11
11
  */
12
- export interface ButtonVariants extends FlexVariants, StatusVariants, TypographyVariants {
12
+ export interface ButtonVariants extends BlockVariants, FlexVariants, StatusVariants {
13
13
  /** Solid styling: a strong fill of the tint colour with white text. Use it for the main action. */
14
14
  solid?: boolean | undefined;
15
15
  /** Plain styling: no fill or border until hover or focus. */
@@ -31,7 +31,7 @@ export interface ButtonVariants extends FlexVariants, StatusVariants, Typography
31
31
  /**
32
32
  * Get the full combined `className` string for a button from its styling variants.
33
33
  *
34
- * @param variants The button styling variants (flex, color, status, typography, plus button toggles).
34
+ * @param variants The button styling variants (block, flex, status, plus button toggles).
35
35
  * @returns A space-separated `className` string combining all the resolved variant classes.
36
36
  * @see https://shelving.cc/ui/getButtonClass
37
37
  */
@@ -1,19 +1,19 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { getBlockClass } from "../style/Block.js";
2
3
  import { getFlexClass } from "../style/Flex.js";
3
4
  import { getStatusClass } from "../style/Status.js";
4
- import { getTypographyClass } from "../style/Typography.js";
5
5
  import { getClass, getModuleClass } from "../util/css.js";
6
6
  import BUTTON_CSS from "./Button.module.css";
7
7
  import { Clickable } from "./Clickable.js";
8
8
  /**
9
9
  * Get the full combined `className` string for a button from its styling variants.
10
10
  *
11
- * @param variants The button styling variants (flex, color, status, typography, plus button toggles).
11
+ * @param variants The button styling variants (block, flex, status, plus button toggles).
12
12
  * @returns A space-separated `className` string combining all the resolved variant classes.
13
13
  * @see https://shelving.cc/ui/getButtonClass
14
14
  */
15
15
  export function getButtonClass(variants) {
16
- return getClass(getModuleClass(BUTTON_CSS, "button", variants, variants.selected === false && "unselected"), getFlexClass(variants), getStatusClass(variants), getTypographyClass(variants));
16
+ return getClass(getBlockClass(variants), getModuleClass(BUTTON_CSS, "button", variants, variants.selected === false && "unselected"), getFlexClass(variants), getStatusClass(variants));
17
17
  }
18
18
  /**
19
19
  * Render either a `<button>` or an `<a href="">` styled as a button, based on whether an `onClick` or `href` prop is provided.
@@ -14,6 +14,7 @@ A clickable styled as a button. Renders an `<a href="">` when given `href`, or a
14
14
  - `color=` / `status=` move the tint anchor, so they set the colour of every look. A colourless button stays a neutral grey.
15
15
  - `selected` makes a group of buttons, such as tabs. `selected={true}` sets `aria-pressed` (or `aria-current` on a link) and keeps the button's normal look. `selected={false}` also drops the fill until hover or focus, like `plain`, so the selected button stands out. Leave it `undefined` for a button that is not in a group.
16
16
  - `small` tightens the padding.
17
+ - It takes the block variants, like any block: `space` sets its outer margin (`space="none"` removes it), `padding` and `indent` set its inner padding, and `width` sizes it. A `padding` variant sets the padding but not the minimum height, which `--button-padding` and `--button-height` set.
17
18
  - `getButtonClass(variants)` returns the same `className` the component composes — use it to style a non-`<button>` element as a button when `Button` itself doesn't fit.
18
19
  - `className` attaches an app class to one button, merged after the computed classes so an app stylesheet wins — see `ClassProps`.
19
20
 
@@ -30,6 +31,15 @@ import { Button } from "shelving/ui";
30
31
  <Button onClick={share} outline>Share</Button>
31
32
  ```
32
33
 
34
+ ### Spacing and size
35
+
36
+ ```tsx
37
+ import { Button } from "shelving/ui";
38
+
39
+ // No outer margin: it sits flush with the content around it.
40
+ <Button full space="none" onClick={start}>Start</Button>
41
+ ```
42
+
33
43
  ### A row of buttons
34
44
 
35
45
  ```tsx
@@ -153,14 +153,6 @@
153
153
  /* The border is transparent by default, so background images/gradients must size to the border box to reach the button's edge. Lives in the overrides layer because every state's `background` shorthand resets the origin to `padding-box`. */
154
154
  background-origin: border-box;
155
155
 
156
- &:first-child {
157
- margin-block-start: 0;
158
- }
159
-
160
- &:last-child {
161
- margin-block-end: 0;
162
- }
163
-
164
156
  /* Pseudo-classes */
165
157
  &:not(:focus-visible) {
166
158
  outline-color: transparent;
@@ -170,17 +162,17 @@
170
162
  &:is(.plain, .outline, .unselected) {
171
163
  box-shadow: none;
172
164
 
173
- &:not(:enabled:hover, :any-link:hover, :active, :focus) {
165
+ &:not(:enabled:hover, :any-link:hover, :enabled:active, :any-link:active, :focus) {
174
166
  border: var(--button-plain-border, var(--button-stroke, var(--stroke-normal)) solid transparent);
175
167
  background: transparent;
176
168
  }
177
169
  }
178
170
 
179
- &.unselected:not(:enabled:hover, :any-link:hover, :active, :focus) {
171
+ &.unselected:not(:enabled:hover, :any-link:hover, :enabled:active, :any-link:active, :focus) {
180
172
  background: var(--button-unselected-background, transparent);
181
173
  }
182
174
 
183
- &.outline:not(:enabled:hover, :any-link:hover, :active, :focus) {
175
+ &.outline:not(:enabled:hover, :any-link:hover, :enabled:active, :any-link:active, :focus) {
184
176
  border: var(--button-outline-border, var(--button-stroke, var(--stroke-normal)) solid var(--tint-80));
185
177
  }
186
178
  }
@@ -1,18 +1,18 @@
1
1
  import type { ReactElement } from "react";
2
+ import { type BlockVariants, getBlockClass } from "../style/Block.js";
2
3
  import { type FlexVariants, getFlexClass } from "../style/Flex.js";
3
4
  import { getStatusClass, type StatusVariants } from "../style/Status.js";
4
- import { getTypographyClass, type TypographyVariants } from "../style/Typography.js";
5
5
  import { getClass, getModuleClass } from "../util/css.js";
6
6
  import type { ClassProps } from "../util/props.js";
7
7
  import BUTTON_CSS from "./Button.module.css";
8
8
  import { Clickable, type ClickableProps } from "./Clickable.js";
9
9
 
10
10
  /**
11
- * Styling variants for a `Button`, combining flex, color, status, and typography options with button-specific toggles.
11
+ * Styling variants for a `Button`: the block variants (space, padding, indent, width, typography), flex, and status, plus button-specific toggles.
12
12
  *
13
13
  * @see https://shelving.cc/ui/ButtonVariants
14
14
  */
15
- export interface ButtonVariants extends FlexVariants, StatusVariants, TypographyVariants {
15
+ export interface ButtonVariants extends BlockVariants, FlexVariants, StatusVariants {
16
16
  /** Solid styling: a strong fill of the tint colour with white text. Use it for the main action. */
17
17
  solid?: boolean | undefined;
18
18
  /** Plain styling: no fill or border until hover or focus. */
@@ -35,16 +35,16 @@ export interface ButtonVariants extends FlexVariants, StatusVariants, Typography
35
35
  /**
36
36
  * Get the full combined `className` string for a button from its styling variants.
37
37
  *
38
- * @param variants The button styling variants (flex, color, status, typography, plus button toggles).
38
+ * @param variants The button styling variants (block, flex, status, plus button toggles).
39
39
  * @returns A space-separated `className` string combining all the resolved variant classes.
40
40
  * @see https://shelving.cc/ui/getButtonClass
41
41
  */
42
42
  export function getButtonClass(variants: ButtonVariants): string {
43
43
  return getClass(
44
+ getBlockClass(variants),
44
45
  getModuleClass(BUTTON_CSS, "button", variants, variants.selected === false && "unselected"),
45
46
  getFlexClass(variants),
46
47
  getStatusClass(variants),
47
- getTypographyClass(variants),
48
48
  );
49
49
  }
50
50
 
@@ -1,14 +1,14 @@
1
1
  import type { ReactElement } from "react";
2
- import { type WidthVariants } from "../style/Width.js";
2
+ import { type BlockVariants } from "../style/Block.js";
3
3
  import type { ChildProps, ClassProps } from "../util/props.js";
4
4
  /**
5
- * Styling variants shared by every form input — currently the `width` variant (`width="narrow"`, `"normal"`, `"wide"`, `"full"`, `"fit"`).
6
- * - Extends `WidthVariants` so any input can be sized (e.g. `<CheckboxInput width="fit">` to shrink to its content).
7
- * - Designed to grow: new cross-cutting input styling props (e.g. spacing) should be added here so every input picks them up consistently.
5
+ * Styling variants shared by every form input — the block variants: `space`, `padding`, `indent`, `width`, and typography.
6
+ * - Any input can be spaced and sized like a block (e.g. `<TextInput space="none">`, `<CheckboxInput width="fit">`).
7
+ * - Designed to grow: new cross-cutting input styling props should be added here so every input picks them up consistently.
8
8
  *
9
9
  * @see https://shelving.cc/ui/InputVariants
10
10
  */
11
- export interface InputVariants extends WidthVariants {
11
+ export interface InputVariants extends BlockVariants {
12
12
  }
13
13
  /**
14
14
  * Build the shared base `className` for a form input from its styling variants — the base input class plus any `InputVariants`.
package/ui/input/Input.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { LOADING } from "../misc/Loading.js";
3
+ import { getBlockClass } from "../style/Block.js";
3
4
  import { getFlexClass } from "../style/Flex.js";
4
- import { getWidthClass } from "../style/Width.js";
5
5
  import { getClass, getModuleClass } from "../util/css.js";
6
6
  import INPUT_CSS from "./Input.module.css";
7
7
  /**
@@ -12,7 +12,7 @@ import INPUT_CSS from "./Input.module.css";
12
12
  * @see https://shelving.cc/ui/getInputClass
13
13
  */
14
14
  export function getInputClass(props) {
15
- return getClass(getModuleClass(INPUT_CSS, "input"), getWidthClass(props));
15
+ return getClass(getBlockClass(props), getModuleClass(INPUT_CSS, "input"));
16
16
  }
17
17
  /** Input that is loading. */
18
18
  export const LOADING_INPUT = _jsx("div", { className: getClass(getInputClass({}), getFlexClass({})), children: LOADING });
@@ -210,14 +210,6 @@
210
210
 
211
211
  @layer overrides {
212
212
  .input {
213
- &:first-child {
214
- margin-block-start: 0;
215
- }
216
-
217
- &:last-child {
218
- margin-block-end: 0;
219
- }
220
-
221
213
  &:not(:focus, :focus-within) {
222
214
  outline-color: transparent;
223
215
  }
@@ -1,19 +1,19 @@
1
1
  import type { ReactElement } from "react";
2
2
  import { LOADING } from "../misc/Loading.js";
3
+ import { type BlockVariants, getBlockClass } from "../style/Block.js";
3
4
  import { getFlexClass } from "../style/Flex.js";
4
- import { getWidthClass, type WidthVariants } from "../style/Width.js";
5
5
  import { getClass, getModuleClass } from "../util/css.js";
6
6
  import type { ChildProps, ClassProps } from "../util/props.js";
7
7
  import INPUT_CSS from "./Input.module.css";
8
8
 
9
9
  /**
10
- * Styling variants shared by every form input — currently the `width` variant (`width="narrow"`, `"normal"`, `"wide"`, `"full"`, `"fit"`).
11
- * - Extends `WidthVariants` so any input can be sized (e.g. `<CheckboxInput width="fit">` to shrink to its content).
12
- * - Designed to grow: new cross-cutting input styling props (e.g. spacing) should be added here so every input picks them up consistently.
10
+ * Styling variants shared by every form input — the block variants: `space`, `padding`, `indent`, `width`, and typography.
11
+ * - Any input can be spaced and sized like a block (e.g. `<TextInput space="none">`, `<CheckboxInput width="fit">`).
12
+ * - Designed to grow: new cross-cutting input styling props should be added here so every input picks them up consistently.
13
13
  *
14
14
  * @see https://shelving.cc/ui/InputVariants
15
15
  */
16
- export interface InputVariants extends WidthVariants {}
16
+ export interface InputVariants extends BlockVariants {}
17
17
 
18
18
  /**
19
19
  * Build the shared base `className` for a form input from its styling variants — the base input class plus any `InputVariants`.
@@ -23,7 +23,7 @@ export interface InputVariants extends WidthVariants {}
23
23
  * @see https://shelving.cc/ui/getInputClass
24
24
  */
25
25
  export function getInputClass(props: InputVariants): string {
26
- return getClass(getModuleClass(INPUT_CSS, "input"), getWidthClass(props));
26
+ return getClass(getBlockClass(props), getModuleClass(INPUT_CSS, "input"));
27
27
  }
28
28
 
29
29
  /**