@stonedogcode/style 0.9.0 → 0.10.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/package.json
CHANGED
|
@@ -12,6 +12,33 @@ import { textRecipe } from "styled-system/recipes";
|
|
|
12
12
|
|
|
13
13
|
const PandaText = styled("span", textRecipe);
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* The spacing props that only a BLOCK box can honour.
|
|
17
|
+
*
|
|
18
|
+
* Horizontal spacing is deliberately absent. `margin-left` / `margin-right`
|
|
19
|
+
* work perfectly well on an inline box, and inline text inside a sentence is
|
|
20
|
+
* the commonest use of this component — promoting on those would break working
|
|
21
|
+
* layout to fix a different problem.
|
|
22
|
+
*/
|
|
23
|
+
const VERTICAL_SPACING_PROPS = [
|
|
24
|
+
"marginTop",
|
|
25
|
+
"marginBottom",
|
|
26
|
+
"marginBlock",
|
|
27
|
+
"marginBlockStart",
|
|
28
|
+
"marginBlockEnd",
|
|
29
|
+
"paddingTop",
|
|
30
|
+
"paddingBottom",
|
|
31
|
+
"paddingBlock",
|
|
32
|
+
"paddingBlockStart",
|
|
33
|
+
"paddingBlockEnd",
|
|
34
|
+
"mt",
|
|
35
|
+
"mb",
|
|
36
|
+
"my",
|
|
37
|
+
"pt",
|
|
38
|
+
"pb",
|
|
39
|
+
"py",
|
|
40
|
+
] as const;
|
|
41
|
+
|
|
15
42
|
export interface StyledTextProps
|
|
16
43
|
extends React.ComponentProps<typeof PandaText> {
|
|
17
44
|
children?: React.ReactNode | undefined;
|
|
@@ -24,9 +51,50 @@ export interface StyledTextProps
|
|
|
24
51
|
ellipsis?: boolean | undefined;
|
|
25
52
|
wrap?: boolean | undefined;
|
|
26
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Render as a block box rather than the default inline one.
|
|
56
|
+
*
|
|
57
|
+
* Set this when you want block flow without any spacing prop to trigger it —
|
|
58
|
+
* two paragraphs that should stack, for instance. A vertical margin or
|
|
59
|
+
* padding implies it already; see the note on the component.
|
|
60
|
+
*/
|
|
61
|
+
block?: boolean | undefined;
|
|
62
|
+
|
|
27
63
|
variant?: AllowedTextVariant | undefined;
|
|
28
64
|
}
|
|
29
65
|
|
|
66
|
+
/**
|
|
67
|
+
* `StyledText` renders a `<span>`, which is an INLINE box — and CSS ignores
|
|
68
|
+
* `margin-top` / `margin-bottom` on inline boxes outright.
|
|
69
|
+
*
|
|
70
|
+
* So `<StyledText marginBottom="1">` used to emit the rule, put the class in
|
|
71
|
+
* the DOM, report `margin-bottom: 8px` from `getComputedStyle`, and move
|
|
72
|
+
* nothing. Worse, JSX strips the whitespace between two elements on separate
|
|
73
|
+
* lines, so adjacent `StyledText` siblings rendered as a single run with no
|
|
74
|
+
* space at all — shipped in two products as "No dates to show yetThis does not
|
|
75
|
+
* mean nothing is due" and "OverviewYour Personal Dashboard" (NEH-490).
|
|
76
|
+
*
|
|
77
|
+
* **It worked in some places, which is what made it so hard to see.** Flex
|
|
78
|
+
* items are blockified, so a `StyledText` inside a `StyledStack` becomes a
|
|
79
|
+
* block and its margins apply; the identical component inside a `StyledBox`
|
|
80
|
+
* stays inline and breaks. Whoever adds the prop sees it work in the component
|
|
81
|
+
* they tested.
|
|
82
|
+
*
|
|
83
|
+
* So a vertical spacing prop promotes the box to `display: block`. This cannot
|
|
84
|
+
* break anything that currently works: on an inline box those declarations are
|
|
85
|
+
* already discarded, so nothing can be depending on their effect. The call
|
|
86
|
+
* sites were always right — the component was accepting a prop it could not
|
|
87
|
+
* honour and saying nothing.
|
|
88
|
+
*
|
|
89
|
+
* An explicit `display` from the caller always wins, and `block` is available
|
|
90
|
+
* for the case where you want block flow with no spacing prop to imply it.
|
|
91
|
+
*/
|
|
92
|
+
function wantsBlockBox(props: StyledTextProps): boolean {
|
|
93
|
+
if (props.block) return true;
|
|
94
|
+
const bag = props as unknown as Record<string, unknown>;
|
|
95
|
+
return VERTICAL_SPACING_PROPS.some((prop) => bag[prop] !== undefined);
|
|
96
|
+
}
|
|
97
|
+
|
|
30
98
|
const StyledText = React.forwardRef<HTMLSpanElement, StyledTextProps>((props, ref) => {
|
|
31
99
|
log.trace("StyledText rendered");
|
|
32
100
|
const {
|
|
@@ -41,6 +109,7 @@ const StyledText = React.forwardRef<HTMLSpanElement, StyledTextProps>((props, re
|
|
|
41
109
|
wrap,
|
|
42
110
|
textAlign,
|
|
43
111
|
className,
|
|
112
|
+
block: _block,
|
|
44
113
|
...rest
|
|
45
114
|
} = props;
|
|
46
115
|
const fontSizeProfile = useFontSizeProfile();
|
|
@@ -57,6 +126,12 @@ const StyledText = React.forwardRef<HTMLSpanElement, StyledTextProps>((props, re
|
|
|
57
126
|
const fontSize = fontSizeMap[finalSize] || fontSizeMap.md;
|
|
58
127
|
|
|
59
128
|
const extraStyles: React.CSSProperties = {};
|
|
129
|
+
// Before `ellipsis`, which sets its own `display: block` and must keep
|
|
130
|
+
// winning — an ellipsised line is block for a different reason and the two
|
|
131
|
+
// agree anyway.
|
|
132
|
+
if (wantsBlockBox(props)) {
|
|
133
|
+
extraStyles.display = "block";
|
|
134
|
+
}
|
|
60
135
|
if (ellipsis) {
|
|
61
136
|
extraStyles.textOverflow = "ellipsis";
|
|
62
137
|
extraStyles.whiteSpace = "nowrap";
|