fontdue-js 3.2.2 → 3.2.3

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 CHANGED
@@ -1,3 +1,9 @@
1
+ ## 3.2.3
2
+
3
+ - **Fixed `TypeTester` text drifting out of alignment at small font sizes.** The automatic columns (`columns: {count: 'auto', width: '40ch', gap: '1em'}` by default) sat on the full-width text container, and `ch` tracks the font size — so once the font was small enough for two columns to fit, multicol partitioned the strip and short content landed in the first column, leaving `alignment="center"` centred within *that column* rather than the tester. Right-aligned and RTL testers drifted the same way. The column properties now ride on the inner `[data-contents]` block, which shrink-wraps (`width: max-content`, capped at 100%) and is placed by alignment-driven auto margins; wrapping content still spans the full width and flows into columns as before. The editable container keeps its full width, so click-anywhere-to-edit and autofit width measurement are unchanged, and the SSR branch renders the same wrapper so the first paint matches. Truncating testers keep their columns on the height-capped container their sideways-overflow design requires. Ships new stylesheet rules, so take the `fontdue-js/dist/fontdue.css` from this version alongside the JS.
4
+ - Also fixed centred testers sitting half the autofit side buffer off centre at *every* size — the buffer was applied entirely on one side and is now split across both.
5
+ - **`FontdueAdminToolbar`: the collapsed pill now carries the Fontdue wordmark** — *Fontdue* idle, *Fontdue · Previewing hidden fonts* while previewing, *Fontdue · Preview expired* when the token lapses, matching the connection-error pill's existing wording. The `F` mark and the warning glyph leave the pill (the mark still brands the panel header, the glyph the expired notice). If you style the toolbar yourself: `__mark` no longer appears inside `__button`, and the expired suffix is a new `__expired-suffix` span. Chrome, sizing, shadow, the panel, and `data-testid="preview-toggle"` are unchanged.
6
+
1
7
  ## 3.2.2
2
8
 
3
9
  - **Fixed the reCAPTCHA forms failing to server-render under Vite SSR** (Astro, and any framework whose dev SSR externalizes CJS deps through Node's ESM interop). 3.2.1 switched to `react-google-recaptcha`'s default export, which bundlers honouring the `__esModule` marker (webpack/Next, and Vite's browser optimizer) unwrap straight to the widget wrapper — but Node's strict ESM↔CJS interop models that same default import as the whole module *namespace*, so `<ReCAPTCHA>` was an object at SSR time. React threw "Element type is invalid … got: object" and the checkout, `NewsletterSignup` and `TestFontsForm` islands fell back to client rendering with a console error. The re-export now normalises the binding (`__esModule ? .default : obj`), resolving the wrapper on every path. A no-op for webpack and Vite's browser build. No public API change.
@@ -262,12 +262,14 @@ export default function FontdueAdminToolbar() {
262
262
  onClick: () => setOpen(v => !v),
263
263
  "aria-expanded": open,
264
264
  "data-testid": "fontdue-admin-toolbar-button"
265
- }, expired ? /*#__PURE__*/React.createElement(WarningIcon, null) : /*#__PURE__*/React.createElement(FontdueMark, null), expired ? 'Preview expired' : previewing ? 'Previewing hidden fonts' : 'Preview'));
265
+ }, /*#__PURE__*/React.createElement("span", null, "Fontdue", expired ? /*#__PURE__*/React.createElement("span", {
266
+ className: "fontdue-admin-toolbar__expired-suffix"
267
+ }, ' · Preview expired') : previewing ? ' · Previewing hidden fonts' : null)));
266
268
  }
267
269
 
268
- // The Fontdue mark: a serif F on an iris square. Brands the pill and the panel
269
- // header so the control can name its function ("Preview") instead of the
270
- // vendor; the full attribution lives in the panel footer.
270
+ // The Fontdue mark: a serif F on an iris square. Brands the panel header
271
+ // the collapsed pill carries the wordmark itself, so it doesn't also wear
272
+ // the mark (F next to "Fontdue" would say the brand twice).
271
273
  function FontdueMark() {
272
274
  return /*#__PURE__*/React.createElement("span", {
273
275
  className: "fontdue-admin-toolbar__mark",
@@ -46,6 +46,12 @@ const TypeTesterContent = /*#__PURE__*/React.forwardRef((_ref, ref) => {
46
46
  stripPastedStyles: true,
47
47
  textDirectionality: direction === 'rtl' ? 'RTL' : 'LTR',
48
48
  textAlignment: alignment
49
- }) : plainText);
49
+ }) :
50
+ /*#__PURE__*/
51
+ // Mirror Draft's wrapper so the column rules already apply to the
52
+ // SSR/pre-hydration paint.
53
+ React.createElement("div", {
54
+ "data-contents": "true"
55
+ }, plainText));
50
56
  });
51
57
  export default TypeTesterContent;
@@ -81,12 +81,30 @@ const useTypeTesterStyler = _ref => {
81
81
  columnGap: columns.gap
82
82
  } : undefined;
83
83
 
84
+ // Outside truncation the columns apply to Draft's `[data-contents]` block
85
+ // (via _type-tester.scss), which shrink-wraps — on the full-width container,
86
+ // short content at small sizes lands in the first column and center/right
87
+ // alignment goes off-center (FD-1017). Truncation keeps its columns here:
88
+ // its sideways overflow needs the multicol box to be the height-capped one.
89
+ const columnVars = columns ? {
90
+ '--type-tester--column-count': `${columns.count}`,
91
+ '--type-tester--column-width': columns.width,
92
+ '--type-tester--column-gap': columns.gap,
93
+ '--type-tester--content-width': 'max-content'
94
+ } : undefined;
95
+
84
96
  // A glyph's side bearings — ink that sits outside its advance width, like a
85
97
  // leading lowercase 'j' or an italic overhang — would be shorn by the inline
86
98
  // clip. Per-glyph bearings aren't in the font metrics, so reserve a flat 0.1em
87
99
  // on each inline edge and cancel it with a negative margin so
88
100
  // wrapping and text position stay put.
89
101
  const sideBearing = shouldTruncate ? '0.1em' : '0px';
102
+
103
+ // The autofit slack must sit where it is invisible: after the text for
104
+ // left, before it for right, half on each side for center — one-sided it
105
+ // left centered text `sideBuffer / 2` off center (FD-804).
106
+ const bufferRight = alignment === 'center' ? sideBuffer / 2 : alignment === 'left' ? sideBuffer : 0;
107
+ const bufferLeft = alignment === 'center' ? sideBuffer / 2 : alignment === 'right' ? sideBuffer : 0;
90
108
  const style = {
91
109
  fontSize: autofit ? `${size}px` : `calc(var(--type-tester--adjustment, 1) * ${size}px)`,
92
110
  lineHeight: `${lineHeight}`,
@@ -127,11 +145,11 @@ const useTypeTesterStyler = _ref => {
127
145
  } : {
128
146
  height: 'auto',
129
147
  overflow: 'visible',
130
- ...columnStyle
148
+ ...columnVars
131
149
  }),
132
150
  fontFeatureSettings,
133
- marginRight: `calc(${alignment !== 'right' ? -sideBuffer : 0}px - ${sideBearing})`,
134
- marginLeft: `calc(${alignment === 'right' ? -sideBuffer : 0}px - ${sideBearing})`,
151
+ marginRight: `calc(${-bufferRight}px - ${sideBearing})`,
152
+ marginLeft: `calc(${-bufferLeft}px - ${sideBearing})`,
135
153
  letterSpacing: `${letterSpacing}em`,
136
154
  fontVariationSettings,
137
155
  textAlign: alignment
package/dist/fontdue.css CHANGED
@@ -798,6 +798,23 @@ fontdue-type-tester {
798
798
  position: relative;
799
799
  z-index: 0;
800
800
  }
801
+ .type-tester__text__container [data-contents=true] {
802
+ column-count: var(--type-tester--column-count, auto);
803
+ column-width: var(--type-tester--column-width, auto);
804
+ column-gap: var(--type-tester--column-gap, normal);
805
+ width: var(--type-tester--content-width, auto);
806
+ max-width: 100%;
807
+ }
808
+ .type-tester[data-alignment=left] .type-tester__text__container [data-contents=true] {
809
+ margin-right: auto;
810
+ }
811
+ .type-tester[data-alignment=center] .type-tester__text__container [data-contents=true] {
812
+ margin-left: auto;
813
+ margin-right: auto;
814
+ }
815
+ .type-tester[data-alignment=right] .type-tester__text__container [data-contents=true] {
816
+ margin-left: auto;
817
+ }
801
818
 
802
819
  .type-tester-select {
803
820
  display: flex;
@@ -2872,7 +2889,11 @@ body[data-fontdue-store-modal=open] {
2872
2889
  .cart-item__license-variable__option-name {
2873
2890
  margin-bottom: 0.5em;
2874
2891
  }
2892
+ .cart-item__license-variable__text-input-form {
2893
+ flex: 1;
2894
+ }
2875
2895
  .cart-item__license-variable__text-input {
2896
+ width: 100%;
2876
2897
  background: transparent;
2877
2898
  color: var(--primary_text_color);
2878
2899
  font-family: inherit;
@@ -3550,6 +3571,10 @@ textarea.text-field__input {
3550
3571
  border-color: #fff;
3551
3572
  }
3552
3573
 
3574
+ .fontdue-admin-toolbar__expired-suffix {
3575
+ color: #e8c07a;
3576
+ }
3577
+
3553
3578
  .fontdue-admin-toolbar__mark {
3554
3579
  flex: none;
3555
3580
  width: 16px;
@@ -3563,10 +3588,6 @@ textarea.text-field__input {
3563
3588
  font-size: 10px;
3564
3589
  line-height: 1;
3565
3590
  }
3566
- .fontdue-admin-toolbar[data-previewing=true] .fontdue-admin-toolbar__button .fontdue-admin-toolbar__mark {
3567
- background: #fff;
3568
- color: var(--fdat-accent);
3569
- }
3570
3591
 
3571
3592
  .fontdue-admin-toolbar__panel {
3572
3593
  width: 280px;
@@ -8,7 +8,7 @@ import { NODE_ACCESS_HEADER } from '../nodeAccess.js';
8
8
  // (defineVersionPlugin in .babelrc.cjs) with the literal package.json#version.
9
9
  // Exported so UI (the admin toolbar) can surface it without re-reading the
10
10
  // build-time global in a 'use client' module.
11
- export const version = "3.2.2";
11
+ export const version = "3.2.3";
12
12
  const IS_SERVER = typeof window === typeof undefined;
13
13
 
14
14
  // Opt server fetches into Next's data cache only in production; dev stays
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fontdue-js",
3
- "version": "3.2.2",
3
+ "version": "3.2.3",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "npm run relay && run-p build-js build-css build-ts",
@@ -135,4 +135,4 @@
135
135
  "./useFont": "./dist/components/useFont.js",
136
136
  "./useFontStyle": "./dist/components/useFont.js"
137
137
  }
138
- }
138
+ }