fontdue-js 3.0.5 → 3.1.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/__generated__/FeatureTesterCard_fontStyle.graphql.d.ts +23 -0
  3. package/dist/__generated__/FeatureTesterCard_fontStyle.graphql.js +62 -0
  4. package/dist/__generated__/FeatureTesterStandaloneQuery.graphql.d.ts +25 -0
  5. package/dist/__generated__/FeatureTesterStandaloneQuery.graphql.js +240 -0
  6. package/dist/__generated__/FeatureTestersIdQuery.graphql.d.ts +21 -0
  7. package/dist/__generated__/FeatureTestersIdQuery.graphql.js +344 -0
  8. package/dist/__generated__/FeatureTestersSlugQuery.graphql.d.ts +25 -0
  9. package/dist/__generated__/FeatureTestersSlugQuery.graphql.js +364 -0
  10. package/dist/__generated__/FeatureTesters_collection.graphql.d.ts +39 -0
  11. package/dist/__generated__/FeatureTesters_collection.graphql.js +145 -0
  12. package/dist/__generated__/NodePasswordFormAccessNodeMutation.graphql.d.ts +2 -1
  13. package/dist/__generated__/NodePasswordFormAccessNodeMutation.graphql.js +10 -4
  14. package/dist/__generated__/NodePasswordFormElementIDQuery.graphql.d.ts +21 -0
  15. package/dist/__generated__/NodePasswordFormElementIDQuery.graphql.js +86 -0
  16. package/dist/__generated__/NodePasswordFormElementSlugQuery.graphql.d.ts +25 -0
  17. package/dist/__generated__/NodePasswordFormElementSlugQuery.graphql.js +108 -0
  18. package/dist/__generated__/TypeTestersIDQuery.graphql.d.ts +1 -1
  19. package/dist/__generated__/TypeTestersIDQuery.graphql.js +9 -3
  20. package/dist/__generated__/TypeTestersRefetchQuery.graphql.d.ts +1 -1
  21. package/dist/__generated__/TypeTestersRefetchQuery.graphql.js +10 -4
  22. package/dist/__generated__/TypeTestersSlugQuery.graphql.d.ts +1 -1
  23. package/dist/__generated__/TypeTestersSlugQuery.graphql.js +9 -3
  24. package/dist/__generated__/TypeTesters_collection.graphql.d.ts +2 -1
  25. package/dist/__generated__/TypeTesters_collection.graphql.js +8 -2
  26. package/dist/__tests__/createFontdueFetch.test.js +128 -4
  27. package/dist/__tests__/highlight.test.js +141 -0
  28. package/dist/__tests__/middleware.test.js +132 -0
  29. package/dist/components/FeatureTester/FeatureTesterCard.d.ts +30 -0
  30. package/dist/components/FeatureTester/FeatureTesterCard.js +167 -0
  31. package/dist/components/FeatureTester/FeatureTesterElement.d.ts +19 -0
  32. package/dist/components/FeatureTester/FeatureTesterElement.js +42 -0
  33. package/dist/components/FeatureTester/FeatureTesters.d.ts +43 -0
  34. package/dist/components/FeatureTester/FeatureTesters.js +156 -0
  35. package/dist/components/FeatureTester/FeatureTesters.server.d.ts +9 -0
  36. package/dist/components/FeatureTester/FeatureTesters.server.js +40 -0
  37. package/dist/components/FeatureTester/FeatureTestersElement.d.ts +10 -0
  38. package/dist/components/FeatureTester/FeatureTestersElement.js +27 -0
  39. package/dist/components/FeatureTester/highlight.d.ts +19 -0
  40. package/dist/components/FeatureTester/highlight.js +71 -0
  41. package/dist/components/FeatureTester/index.d.ts +26 -0
  42. package/dist/components/FeatureTester/index.js +66 -0
  43. package/dist/components/FeatureTester/index.server.d.ts +7 -0
  44. package/dist/components/FeatureTester/index.server.js +30 -0
  45. package/dist/components/NodePasswordForm/NodePasswordFormElement.d.ts +3 -0
  46. package/dist/components/NodePasswordForm/NodePasswordFormElement.js +65 -0
  47. package/dist/components/NodePasswordForm/index.d.ts +16 -1
  48. package/dist/components/NodePasswordForm/index.js +30 -59
  49. package/dist/components/Root/index.js +2 -1
  50. package/dist/components/TypeTesters/index.js +5 -1
  51. package/dist/fontdue.css +145 -0
  52. package/dist/hooks/useFeatureTesterAutofit.d.ts +17 -0
  53. package/dist/hooks/useFeatureTesterAutofit.js +106 -0
  54. package/dist/next/index.d.ts +2 -0
  55. package/dist/next/index.js +16 -1
  56. package/dist/next/registerSingleTenantResolver.js +13 -1
  57. package/dist/next/tenant.d.ts +1 -0
  58. package/dist/next/tenant.js +27 -2
  59. package/dist/nodeAccess.d.ts +18 -0
  60. package/dist/nodeAccess.js +84 -0
  61. package/dist/preview/server.d.ts +1 -20
  62. package/dist/preview/server.js +16 -85
  63. package/dist/relay/environment.js +8 -2
  64. package/dist/relay/serverConfig.d.ts +3 -0
  65. package/dist/relay/serverConfig.js +22 -1
  66. package/dist/server/index.d.ts +8 -0
  67. package/dist/server/index.js +90 -7
  68. package/dist/server/middleware.d.ts +37 -0
  69. package/dist/server/middleware.js +144 -0
  70. package/package.json +8 -2
@@ -0,0 +1,156 @@
1
+ 'use client';
2
+
3
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
4
+ import _FeatureTestersSlugQuery from "../../__generated__/FeatureTestersSlugQuery.graphql.js";
5
+ import _FeatureTestersIdQuery from "../../__generated__/FeatureTestersIdQuery.graphql.js";
6
+ import _FeatureTesters_collection from "../../__generated__/FeatureTesters_collection.graphql.js";
7
+ import React from 'react';
8
+ import { graphql, useFragment, useLazyLoadQuery, usePreloadedQuery } from 'react-relay';
9
+ import FeatureTesterCard from './FeatureTesterCard.js';
10
+ import { EnsureFontdueContext } from '../FontdueContextProvider/index.js';
11
+ import FeatureTestersIdQueryNode from '../../__generated__/FeatureTestersIdQuery.graphql.js';
12
+ import FeatureTestersSlugQueryNode from '../../__generated__/FeatureTestersSlugQuery.graphql.js';
13
+ import loadSerializableQuery from '../../relay/loadSerializableQuery.js';
14
+ import useSerializablePreloadedQuery from '../../relay/useSerializablePreloadedQuery.js';
15
+ const collectionFragment = (_FeatureTesters_collection.hash && _FeatureTesters_collection.hash !== "933c122b193ca5df430509d87e9c4e1d" && console.error("The definition of 'FeatureTesters_collection' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _FeatureTesters_collection);
16
+ function FeatureTestersList(_ref) {
17
+ let {
18
+ collection,
19
+ highlightColor,
20
+ toggle,
21
+ autofit
22
+ } = _ref;
23
+ const data = useFragment(collectionFragment, collection);
24
+ return /*#__PURE__*/React.createElement(React.Fragment, null, data.featureTesters.map(ft => ft.fontStyle ? /*#__PURE__*/React.createElement(FeatureTesterCard, {
25
+ key: ft.id,
26
+ fontStyle: ft.fontStyle,
27
+ feature: ft.feature,
28
+ label: ft.label ?? undefined,
29
+ content: ft.content,
30
+ fontSize: ft.size != null ? Number(ft.size) : undefined,
31
+ lineHeight: ft.lineHeight != null ? Number(ft.lineHeight) : undefined,
32
+ alignment: ft.alignment === 'left' || ft.alignment === 'center' || ft.alignment === 'right' ? ft.alignment : undefined,
33
+ defaultOn: data.featureTesterDefaultOn,
34
+ changedRanges: ft.changedRanges,
35
+ variableSettings: ft.variableSettings,
36
+ highlightColor: highlightColor,
37
+ toggle: toggle,
38
+ autofit: autofit ?? ft.autofit,
39
+ showTag: data.featureTesterShowTag
40
+ }) : null));
41
+ }
42
+ const idQuery = (_FeatureTestersIdQuery.hash && _FeatureTestersIdQuery.hash !== "55f152ae85db4ebafd21ff7945f4079a" && console.error("The definition of 'FeatureTestersIdQuery' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _FeatureTestersIdQuery);
43
+ const slugQuery = (_FeatureTestersSlugQuery.hash && _FeatureTestersSlugQuery.hash !== "726fca18c4a30ca9dd8f5aaf074c8139" && console.error("The definition of 'FeatureTestersSlugQuery' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _FeatureTestersSlugQuery);
44
+ function ById(_ref2) {
45
+ let {
46
+ collectionId,
47
+ ...rest
48
+ } = _ref2;
49
+ const data = useLazyLoadQuery(idQuery, {
50
+ id: collectionId
51
+ });
52
+ return data.node ? /*#__PURE__*/React.createElement(FeatureTestersList, _extends({
53
+ collection: data.node
54
+ }, rest)) : null;
55
+ }
56
+ function BySlug(_ref3) {
57
+ var _data$viewer, _data$viewer$slug;
58
+ let {
59
+ collectionSlug,
60
+ ...rest
61
+ } = _ref3;
62
+ const data = useLazyLoadQuery(slugQuery, {
63
+ slug: collectionSlug
64
+ });
65
+ const coll = (_data$viewer = data.viewer) === null || _data$viewer === void 0 ? void 0 : (_data$viewer$slug = _data$viewer.slug) === null || _data$viewer$slug === void 0 ? void 0 : _data$viewer$slug.fontCollection;
66
+ return coll ? /*#__PURE__*/React.createElement(FeatureTestersList, _extends({
67
+ collection: coll
68
+ }, rest)) : null;
69
+ }
70
+
71
+ // ---- Server-preload path (RSC): the server awaits the query and hands the
72
+ // serialized response to these client renderers, which commit it into the store
73
+ // so `usePreloadedQuery` resolves synchronously on the client (no refetch on
74
+ // hydration). Mirrors CharacterViewer.
75
+
76
+ export async function loadFeatureTestersQuery(variables, options) {
77
+ if (variables.collectionId) {
78
+ return loadSerializableQuery(FeatureTestersIdQueryNode, {
79
+ id: variables.collectionId
80
+ }, options);
81
+ }
82
+ if (variables.collectionSlug) {
83
+ return loadSerializableQuery(FeatureTestersSlugQueryNode, {
84
+ slug: variables.collectionSlug
85
+ }, options);
86
+ }
87
+ throw new Error('loadFeatureTestersQuery expected either collectionId or collectionSlug');
88
+ }
89
+ export function FeatureTestersPreloadedIDQueryRenderer(_ref4) {
90
+ let {
91
+ preloadedQuery,
92
+ ...options
93
+ } = _ref4;
94
+ const queryRef = useSerializablePreloadedQuery(preloadedQuery, 'store-or-network', idQuery);
95
+ const data = usePreloadedQuery(idQuery, queryRef);
96
+ return data.node ? /*#__PURE__*/React.createElement(FeatureTestersList, _extends({
97
+ collection: data.node
98
+ }, options)) : null;
99
+ }
100
+ export function FeatureTestersPreloadedSlugQueryRenderer(_ref5) {
101
+ var _data$viewer2, _data$viewer2$slug;
102
+ let {
103
+ preloadedQuery,
104
+ ...options
105
+ } = _ref5;
106
+ const queryRef = useSerializablePreloadedQuery(preloadedQuery, 'store-or-network', slugQuery);
107
+ const data = usePreloadedQuery(slugQuery, queryRef);
108
+ const coll = (_data$viewer2 = data.viewer) === null || _data$viewer2 === void 0 ? void 0 : (_data$viewer2$slug = _data$viewer2.slug) === null || _data$viewer2$slug === void 0 ? void 0 : _data$viewer2$slug.fontCollection;
109
+ return coll ? /*#__PURE__*/React.createElement(FeatureTestersList, _extends({
110
+ collection: coll
111
+ }, options)) : null;
112
+ }
113
+ function FeatureTestersPreloadedRenderer(_ref6) {
114
+ let {
115
+ preloadedQuery,
116
+ ...options
117
+ } = _ref6;
118
+ if (preloadedQuery.params.name === 'FeatureTestersIdQuery') {
119
+ return /*#__PURE__*/React.createElement(FeatureTestersPreloadedIDQueryRenderer, _extends({
120
+ preloadedQuery: preloadedQuery
121
+ }, options));
122
+ }
123
+ return /*#__PURE__*/React.createElement(FeatureTestersPreloadedSlugQueryRenderer, _extends({
124
+ preloadedQuery: preloadedQuery
125
+ }, options));
126
+ }
127
+
128
+ // Renders every Feature Tester card a tenant has configured on a font
129
+ // collection. Accepts a preloaded query (server-side preload path — Astro/RR7
130
+ // frontmatter or a manual loader call) or `{collectionId}`/`{collectionSlug}`
131
+ // for lazy fetch.
132
+ export default function FeatureTesters(_ref7) {
133
+ let {
134
+ config,
135
+ ...props
136
+ } = _ref7;
137
+ const {
138
+ highlightColor,
139
+ toggle,
140
+ autofit
141
+ } = props;
142
+ const options = {
143
+ highlightColor,
144
+ toggle,
145
+ autofit
146
+ };
147
+ return /*#__PURE__*/React.createElement(EnsureFontdueContext, {
148
+ config: config
149
+ }, 'preloadedQuery' in props && props.preloadedQuery ? /*#__PURE__*/React.createElement(FeatureTestersPreloadedRenderer, _extends({
150
+ preloadedQuery: props.preloadedQuery
151
+ }, options)) : 'collectionId' in props && props.collectionId ? /*#__PURE__*/React.createElement(ById, _extends({
152
+ collectionId: props.collectionId
153
+ }, options)) : /*#__PURE__*/React.createElement(BySlug, _extends({
154
+ collectionSlug: props.collectionSlug
155
+ }, options)));
156
+ }
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { FeatureTestersProps } from './FeatureTesters.js';
3
+ export type { FeatureTestersPreloadedQuery } from './FeatureTesters.js';
4
+ export declare function loadFeatureTestersQuery(): never;
5
+ export default function FeatureTesters({ collectionId, collectionSlug, ...rest }: Extract<FeatureTestersProps, {
6
+ collectionId: string;
7
+ } | {
8
+ collectionSlug: string;
9
+ }>): Promise<React.JSX.Element | null>;
@@ -0,0 +1,40 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ import React from 'react';
3
+ import loadSerializableQuery from '../../relay/loadSerializableQuery.js';
4
+ import { FeatureTestersPreloadedIDQueryRenderer, FeatureTestersPreloadedSlugQueryRenderer } from './FeatureTesters.js';
5
+ import FeatureTestersIdQueryNode from '../../__generated__/FeatureTestersIdQuery.graphql.js';
6
+ import FeatureTestersSlugQueryNode from '../../__generated__/FeatureTestersSlugQuery.graphql.js';
7
+ // Stub for the RSC export condition. See FontdueProvider/index.server.tsx
8
+ // for the rationale.
9
+ export function loadFeatureTestersQuery() {
10
+ throw new Error("loadFeatureTestersQuery isn't needed in React Server Components — " + 'the <FeatureTesters> server entrypoint awaits its query automatically. ' + 'Drop the manual call.');
11
+ }
12
+
13
+ // Next RSC variant: awaits the query on the server and hands the response to
14
+ // the client `*PreloadedQueryRenderer`. Lets pages just write
15
+ // `<FeatureTesters collectionSlug="..." />` in an RSC without manually invoking
16
+ // `loadFeatureTestersQuery` + threading `preloadedQuery` through props.
17
+ export default async function FeatureTesters(_ref) {
18
+ let {
19
+ collectionId,
20
+ collectionSlug,
21
+ ...rest
22
+ } = _ref;
23
+ if (collectionId) {
24
+ const preloadedQuery = await loadSerializableQuery(FeatureTestersIdQueryNode, {
25
+ id: collectionId
26
+ });
27
+ return /*#__PURE__*/React.createElement(FeatureTestersPreloadedIDQueryRenderer, _extends({
28
+ preloadedQuery: preloadedQuery
29
+ }, rest));
30
+ }
31
+ if (collectionSlug) {
32
+ const preloadedQuery = await loadSerializableQuery(FeatureTestersSlugQueryNode, {
33
+ slug: collectionSlug
34
+ });
35
+ return /*#__PURE__*/React.createElement(FeatureTestersPreloadedSlugQueryRenderer, _extends({
36
+ preloadedQuery: preloadedQuery
37
+ }, rest));
38
+ }
39
+ return null;
40
+ }
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ interface FeatureTestersElement_props {
3
+ collectionId?: string;
4
+ collectionSlug?: string;
5
+ highlightColor?: string;
6
+ toggle?: string;
7
+ autofit?: string;
8
+ }
9
+ export declare const FeatureTestersElement: React.FC<FeatureTestersElement_props>;
10
+ export default FeatureTestersElement;
@@ -0,0 +1,27 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ import React from 'react';
3
+ import FeatureTesters from './FeatureTesters.js';
4
+ const parseBool = (input, fallback) => input === undefined || input === '' ? fallback : input === 'true';
5
+ export const FeatureTestersElement = _ref => {
6
+ let {
7
+ collectionId,
8
+ collectionSlug,
9
+ highlightColor,
10
+ toggle,
11
+ autofit
12
+ } = _ref;
13
+ const shared = {
14
+ highlightColor: highlightColor || undefined,
15
+ // Only override the per-card dashboard settings when the attribute is
16
+ // actually present on the element; otherwise leave undefined so each card
17
+ // uses its own.
18
+ toggle: toggle === undefined ? undefined : toggle === 'hover' ? 'hover' : 'button',
19
+ autofit: autofit === undefined ? undefined : parseBool(autofit, false)
20
+ };
21
+ return collectionId ? /*#__PURE__*/React.createElement(FeatureTesters, _extends({
22
+ collectionId: collectionId
23
+ }, shared)) : /*#__PURE__*/React.createElement(FeatureTesters, _extends({
24
+ collectionSlug: collectionSlug || ''
25
+ }, shared));
26
+ };
27
+ export default FeatureTestersElement;
@@ -0,0 +1,19 @@
1
+ export interface GlyphNameEntry {
2
+ readonly characters: string;
3
+ readonly features?: readonly string[] | null;
4
+ }
5
+ export interface Segment {
6
+ text: string;
7
+ sensitive: boolean;
8
+ }
9
+ export interface Mark {
10
+ start: number;
11
+ end: number;
12
+ }
13
+ export declare function sensitiveStringsForFeature(glyphNames: readonly GlyphNameEntry[] | null | undefined, feature: string): string[];
14
+ export interface SensitivityOptions {
15
+ autoStrings?: readonly string[];
16
+ addMarks?: readonly Mark[];
17
+ }
18
+ export declare function computeSensitivityFlags(content: string, opts: SensitivityOptions): boolean[];
19
+ export declare function segmentByFlags(content: string, flags: readonly boolean[]): Segment[];
@@ -0,0 +1,71 @@
1
+ // Decide which characters in a sample string are "sensitive" to an OpenType
2
+ // feature.
3
+ //
4
+ // Auto-detection: `FontStyle.glyphNames` lists `{ characters, features }` where
5
+ // `characters` is the INPUT string a feature substitutes (a single character
6
+ // for single substitutions like ss03/smcp, or a sequence for ligatures like
7
+ // dlig). "Which characters does feature X touch" is the set of `characters`
8
+ // whose `features` includes X. That static map only covers single + ligature
9
+ // substitutions; the exact set for any feature comes from the server's shaped
10
+ // diff (`changedRanges`), which FeatureTesterCard passes in as marks.
11
+ //
12
+ // Everything is computed as a boolean-per-codepoint array so the sources
13
+ // compose cleanly. A contiguous run of `true` becomes one highlight span, which
14
+ // keeps ligature clusters whole (we never split a cluster across spans).
15
+
16
+ // An inclusive code-point index range. FeatureTesterCard builds these from the
17
+ // server-materialized `changedRanges`.
18
+
19
+ // The de-duplicated set of input strings the feature substitutes.
20
+ export function sensitiveStringsForFeature(glyphNames, feature) {
21
+ if (!glyphNames) return [];
22
+ const set = new Set();
23
+ for (const g of glyphNames) {
24
+ if (g.characters && g.features && g.features.includes(feature)) {
25
+ set.add(g.characters);
26
+ }
27
+ }
28
+ return Array.from(set);
29
+ }
30
+
31
+ // Set flags[i] = true for every occurrence of `value` (matched by code point).
32
+ function applyText(chars, value, flags) {
33
+ const seq = Array.from(value);
34
+ if (seq.length === 0) return;
35
+ for (let i = 0; i + seq.length <= chars.length; i++) {
36
+ if (seq.every((c, k) => chars[i + k] === c)) {
37
+ for (let k = 0; k < seq.length; k++) flags[i + k] = true;
38
+ }
39
+ }
40
+ }
41
+ export function computeSensitivityFlags(content, opts) {
42
+ const chars = Array.from(content);
43
+ const flags = new Array(chars.length).fill(false);
44
+ if (opts.autoStrings) {
45
+ for (const value of opts.autoStrings) applyText(chars, value, flags);
46
+ }
47
+ if (opts.addMarks) {
48
+ for (const mark of opts.addMarks) {
49
+ for (let i = Math.max(0, mark.start); i <= mark.end && i < chars.length; i++) {
50
+ flags[i] = true;
51
+ }
52
+ }
53
+ }
54
+ return flags;
55
+ }
56
+
57
+ // Collapse a per-codepoint flag array into consecutive sensitive/non-sensitive
58
+ // runs (one highlight span each).
59
+ export function segmentByFlags(content, flags) {
60
+ const chars = Array.from(content);
61
+ const segments = [];
62
+ for (let i = 0; i < chars.length; i++) {
63
+ const sensitive = flags[i] ?? false;
64
+ const last = segments[segments.length - 1];
65
+ if (last && last.sensitive === sensitive) last.text += chars[i];else segments.push({
66
+ text: chars[i],
67
+ sensitive
68
+ });
69
+ }
70
+ return segments;
71
+ }
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import { FeatureTesterCardOptions } from './FeatureTesterCard.js';
3
+ import { Config } from '../ConfigContext.js';
4
+ import { SerializablePreloadedQuery, type LoadQueryOptions } from '../../relay/loadSerializableQuery.js';
5
+ import { FeatureTesterStandaloneQuery } from '../../__generated__/FeatureTesterStandaloneQuery.graphql.js';
6
+ export type FeatureTesterPreloadedQuery = SerializablePreloadedQuery<FeatureTesterStandaloneQuery>;
7
+ export interface LoadFeatureTesterQueryVariables {
8
+ familyName: string;
9
+ styleName: string;
10
+ }
11
+ export declare function loadFeatureTesterQuery(variables: LoadFeatureTesterQueryVariables, options?: LoadQueryOptions): Promise<FeatureTesterPreloadedQuery>;
12
+ export declare function FeatureTesterPreloadedRenderer({ preloadedQuery, ...rest }: FeatureTesterCardOptions & {
13
+ preloadedQuery: FeatureTesterPreloadedQuery;
14
+ }): React.JSX.Element;
15
+ export type FeatureTesterProps = FeatureTesterCardOptions & {
16
+ config?: Config;
17
+ } & ({
18
+ preloadedQuery: FeatureTesterPreloadedQuery;
19
+ familyName?: never;
20
+ styleName?: never;
21
+ } | {
22
+ preloadedQuery?: never;
23
+ familyName: string;
24
+ styleName: string;
25
+ });
26
+ export default function FeatureTester(props: FeatureTesterProps): React.JSX.Element;
@@ -0,0 +1,66 @@
1
+ 'use client';
2
+
3
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
4
+ import _FeatureTesterStandaloneQuery from "../../__generated__/FeatureTesterStandaloneQuery.graphql.js";
5
+ import React from 'react';
6
+ import { graphql, useLazyLoadQuery, usePreloadedQuery } from 'react-relay';
7
+ import FeatureTesterCard from './FeatureTesterCard.js';
8
+ import { EnsureFontdueContext } from '../FontdueContextProvider/index.js';
9
+ import loadSerializableQuery from '../../relay/loadSerializableQuery.js';
10
+ import useSerializablePreloadedQuery from '../../relay/useSerializablePreloadedQuery.js';
11
+ import FeatureTesterStandaloneQueryNode from '../../__generated__/FeatureTesterStandaloneQuery.graphql.js';
12
+ const query = (_FeatureTesterStandaloneQuery.hash && _FeatureTesterStandaloneQuery.hash !== "eddba300b2fd5e283ab1f8f787edc518" && console.error("The definition of 'FeatureTesterStandaloneQuery' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _FeatureTesterStandaloneQuery);
13
+ function FeatureTesterRender(_ref) {
14
+ var _data$viewer;
15
+ let {
16
+ data,
17
+ ...rest
18
+ } = _ref;
19
+ const fontStyle = (_data$viewer = data.viewer) === null || _data$viewer === void 0 ? void 0 : _data$viewer.fontStyle;
20
+ if (!fontStyle) {
21
+ console.log('[FeatureTester]: No FontStyle found');
22
+ return null;
23
+ }
24
+ return /*#__PURE__*/React.createElement(FeatureTesterCard, _extends({
25
+ fontStyle: fontStyle
26
+ }, rest));
27
+ }
28
+ export async function loadFeatureTesterQuery(variables, options) {
29
+ return loadSerializableQuery(FeatureTesterStandaloneQueryNode, {
30
+ familyName: variables.familyName,
31
+ styleName: variables.styleName
32
+ }, options);
33
+ }
34
+ export function FeatureTesterPreloadedRenderer(_ref2) {
35
+ let {
36
+ preloadedQuery,
37
+ ...rest
38
+ } = _ref2;
39
+ const queryRef = useSerializablePreloadedQuery(preloadedQuery, 'store-or-network', query);
40
+ const data = usePreloadedQuery(query, queryRef);
41
+ return /*#__PURE__*/React.createElement(FeatureTesterRender, _extends({
42
+ data: data
43
+ }, rest));
44
+ }
45
+ function FeatureTesterLazyRenderer(_ref3) {
46
+ let {
47
+ familyName,
48
+ styleName,
49
+ ...rest
50
+ } = _ref3;
51
+ const data = useLazyLoadQuery(query, {
52
+ familyName,
53
+ styleName
54
+ });
55
+ return /*#__PURE__*/React.createElement(FeatureTesterRender, _extends({
56
+ data: data
57
+ }, rest));
58
+ }
59
+ // Unified FeatureTester entry point. Accepts either a preloaded query
60
+ // (server-side preload path) or `{familyName, styleName}` (lazy path, used by
61
+ // the CDN custom element and inside an existing `<FontdueProvider>` tree).
62
+ export default function FeatureTester(props) {
63
+ return /*#__PURE__*/React.createElement(EnsureFontdueContext, {
64
+ config: props.config
65
+ }, 'preloadedQuery' in props && props.preloadedQuery ? /*#__PURE__*/React.createElement(FeatureTesterPreloadedRenderer, props) : /*#__PURE__*/React.createElement(FeatureTesterLazyRenderer, props));
66
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import type { FeatureTesterProps } from './index.js';
3
+ export type { FeatureTesterPreloadedQuery } from './index.js';
4
+ export declare function loadFeatureTesterQuery(): never;
5
+ export default function FeatureTester(props: Extract<FeatureTesterProps, {
6
+ familyName: string;
7
+ }>): Promise<React.JSX.Element>;
@@ -0,0 +1,30 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ import React from 'react';
3
+ import loadSerializableQuery from '../../relay/loadSerializableQuery.js';
4
+ import { FeatureTesterPreloadedRenderer } from './index.js';
5
+ import FeatureTesterStandaloneQueryNode from '../../__generated__/FeatureTesterStandaloneQuery.graphql.js';
6
+ // Stub for the RSC export condition. See FontdueProvider/index.server.tsx
7
+ // for the rationale.
8
+ export function loadFeatureTesterQuery() {
9
+ throw new Error("loadFeatureTesterQuery isn't needed in React Server Components — " + 'the <FeatureTester> server entrypoint awaits its query automatically. ' + 'Drop the manual call.');
10
+ }
11
+
12
+ // Next RSC variant: awaits the query on the server and hands the response to
13
+ // the client `FeatureTesterPreloadedRenderer`. Lets pages just write
14
+ // `<FeatureTester familyName="..." styleName="..." feature="..." content="..." />`
15
+ // in an RSC without manually invoking `loadFeatureTesterQuery` + threading
16
+ // `preloadedQuery` through props.
17
+ export default async function FeatureTester(props) {
18
+ const {
19
+ familyName,
20
+ styleName,
21
+ ...rest
22
+ } = props;
23
+ const preloadedQuery = await loadSerializableQuery(FeatureTesterStandaloneQueryNode, {
24
+ familyName,
25
+ styleName
26
+ });
27
+ return /*#__PURE__*/React.createElement(FeatureTesterPreloadedRenderer, _extends({
28
+ preloadedQuery: preloadedQuery
29
+ }, rest));
30
+ }
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { NodePasswordForm_props } from './index.js';
3
+ export default function NodePasswordFormElement({ collectionId, collectionSlug, ...rest }: NodePasswordForm_props): React.JSX.Element;
@@ -0,0 +1,65 @@
1
+ 'use client';
2
+
3
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
4
+ import _NodePasswordFormElementSlugQuery from "../../__generated__/NodePasswordFormElementSlugQuery.graphql.js";
5
+ import _NodePasswordFormElementIDQuery from "../../__generated__/NodePasswordFormElementIDQuery.graphql.js";
6
+ import React from 'react';
7
+ import { graphql, useLazyLoadQuery } from 'react-relay';
8
+ import NodePasswordForm from './index.js';
9
+ // Auto-detecting wrapper behind the <fontdue-node-password-form> custom element.
10
+ // Unlike the presentational React component (the default export of ./index, used
11
+ // when the server has already detected the lock), this queries the collection
12
+ // itself and renders the form only when access is denied — so it works dropped
13
+ // onto any page, hiding itself for a visitor who already has access.
14
+
15
+ const idQuery = (_NodePasswordFormElementIDQuery.hash && _NodePasswordFormElementIDQuery.hash !== "213a61ae079e4f57b7b197b0d2f5256a" && console.error("The definition of 'NodePasswordFormElementIDQuery' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _NodePasswordFormElementIDQuery);
16
+ function NodePasswordFormIDQueryRenderer(_ref) {
17
+ let {
18
+ collectionId,
19
+ ...rest
20
+ } = _ref;
21
+ const data = useLazyLoadQuery(idQuery, {
22
+ collectionId
23
+ });
24
+ // The @catch directive surfaces the password-protection error as ok:false; the
25
+ // node is only locked then, so only then do we render the form (we don't want
26
+ // to show it to a visitor who already has access).
27
+ if (data.collection.ok === false) return /*#__PURE__*/React.createElement(NodePasswordForm, _extends({}, rest, {
28
+ collectionId: collectionId
29
+ }));
30
+ return null;
31
+ }
32
+ const slugQuery = (_NodePasswordFormElementSlugQuery.hash && _NodePasswordFormElementSlugQuery.hash !== "200a33ca6a1f9e4e7e95b7100bbdd261" && console.error("The definition of 'NodePasswordFormElementSlugQuery' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _NodePasswordFormElementSlugQuery);
33
+ function NodePasswordFormSlugQueryRenderer(_ref2) {
34
+ var _data$viewer$slug;
35
+ let {
36
+ collectionSlug,
37
+ ...rest
38
+ } = _ref2;
39
+ const data = useLazyLoadQuery(slugQuery, {
40
+ collectionSlug
41
+ });
42
+ // see note in NodePasswordFormIDQueryRenderer
43
+ if (((_data$viewer$slug = data.viewer.slug) === null || _data$viewer$slug === void 0 ? void 0 : _data$viewer$slug.collection.ok) === false) return /*#__PURE__*/React.createElement(NodePasswordForm, _extends({}, rest, {
44
+ collectionSlug: collectionSlug
45
+ }));
46
+ return null;
47
+ }
48
+ export default function NodePasswordFormElement(_ref3) {
49
+ let {
50
+ collectionId,
51
+ collectionSlug,
52
+ ...rest
53
+ } = _ref3;
54
+ if (collectionId) {
55
+ return /*#__PURE__*/React.createElement(NodePasswordFormIDQueryRenderer, _extends({
56
+ collectionId: collectionId
57
+ }, rest));
58
+ }
59
+ if (collectionSlug) {
60
+ return /*#__PURE__*/React.createElement(NodePasswordFormSlugQueryRenderer, _extends({
61
+ collectionSlug: collectionSlug
62
+ }, rest));
63
+ }
64
+ throw new Error('NodePasswordForm expected either a collectionId or collectionSlug prop');
65
+ }
@@ -3,4 +3,19 @@ export interface NodePasswordForm_props {
3
3
  collectionId?: string | null;
4
4
  collectionSlug?: string | null;
5
5
  }
6
- export default function NodePasswordForm({ collectionId, collectionSlug, ...rest }: NodePasswordForm_props): React.JSX.Element;
6
+ /**
7
+ * Password form for a collection you already know is locked. Render it when a
8
+ * collection comes back password-protected (see the per-framework guides): it
9
+ * commits the `accessNode` mutation, remembers the returned access token, and
10
+ * reloads so the now-unlocked collection renders.
11
+ *
12
+ * Unlike the `<fontdue-node-password-form>` custom element (which detects the
13
+ * locked state itself), this does no data fetching of its own, so it renders
14
+ * immediately on the server with no Suspense flash — the server already detected
15
+ * the lock.
16
+ *
17
+ * Self-wraps in `EnsureFontdueContext` so it works as a standalone island (e.g.
18
+ * an Astro `client:load`) without its own provider, and no-ops inside an outer
19
+ * `<FontdueProvider>` (Next/RR7/TanStack).
20
+ */
21
+ export default function NodePasswordForm(props: NodePasswordForm_props): React.JSX.Element;