type-tester-tdf 2.0.0 → 2.0.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": "type-tester-tdf",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Accessible, dependency-free type tester for the web — a vanilla JS core with an optional React wrapper. Composable OpenType features, variable-font axes, and auto-fit sizing.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -20,7 +20,11 @@
20
20
  "./styles.css": "./dist/styles.css"
21
21
  },
22
22
  "files": [
23
- "dist"
23
+ "dist/**/*.js",
24
+ "dist/**/*.cjs",
25
+ "dist/**/*.d.ts",
26
+ "dist/**/*.d.cts",
27
+ "dist/styles.css"
24
28
  ],
25
29
  "sideEffects": [
26
30
  "**/*.css"
@@ -30,7 +34,8 @@
30
34
  "dev": "tsup --watch",
31
35
  "typecheck": "tsc --noEmit",
32
36
  "test": "vitest run",
33
- "test:watch": "vitest"
37
+ "test:watch": "vitest",
38
+ "prepublishOnly": "npm run build"
34
39
  },
35
40
  "keywords": [
36
41
  "typography",
@@ -71,6 +76,6 @@
71
76
  "react-dom": "^18.3.0",
72
77
  "tsup": "^8.3.0",
73
78
  "typescript": "^5.6.0",
74
- "vitest": "^2.1.0"
79
+ "vitest": "^4.1.9"
75
80
  }
76
81
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/opentype.ts","../src/core/dom.ts","../src/core/fit.ts","../src/core/typeTester.ts"],"names":[],"mappings":"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","file":"chunk-TSLTIRBT.js","sourcesContent":["// OpenType feature registry: correct, spec-accurate tags, labels and grouping.\n// Replaces the legacy optValues table which had duplicate/ambiguous labels\n// (\"Contextual\" for both calt and clig, \"Historical\" for both hlig and hist)\n// and a mislabelled `nalt`.\n\n/** A four-character OpenType GSUB/GPOS feature tag. */\nexport type FeatureTag = string;\n\n/** Logical grouping used to organise features in a control UI. */\nexport type FeatureGroup =\n\t| \"Ligatures\"\n\t| \"Letter Case\"\n\t| \"Figures\"\n\t| \"Fractions\"\n\t| \"Alternates\"\n\t| \"Position\"\n\t| \"Stylistic Sets\";\n\n/** Definition of a single OpenType feature exposed by the tester. */\nexport interface FeatureDef {\n\t/** The OpenType feature tag, e.g. \"smcp\". */\n\ttag: FeatureTag;\n\t/** Human-readable, unambiguous label. */\n\tlabel: string;\n\t/** Group the feature belongs to. */\n\tgroup: FeatureGroup;\n}\n\n/**\n * The default, ordered list of supported OpenType features. Labels are unique\n * and follow the Microsoft OpenType feature registry naming.\n */\nexport const FEATURES: readonly FeatureDef[] = [\n\t// Ligatures\n\t{ tag: \"liga\", label: \"Standard Ligatures\", group: \"Ligatures\" },\n\t{ tag: \"dlig\", label: \"Discretionary Ligatures\", group: \"Ligatures\" },\n\t{ tag: \"hlig\", label: \"Historical Ligatures\", group: \"Ligatures\" },\n\t{ tag: \"clig\", label: \"Contextual Ligatures\", group: \"Ligatures\" },\n\n\t// Letter Case\n\t{ tag: \"smcp\", label: \"Small Capitals\", group: \"Letter Case\" },\n\t{ tag: \"c2sc\", label: \"Capitals to Small Capitals\", group: \"Letter Case\" },\n\t{ tag: \"case\", label: \"Case-Sensitive Forms\", group: \"Letter Case\" },\n\t{ tag: \"cpsp\", label: \"Capital Spacing\", group: \"Letter Case\" },\n\n\t// Figures\n\t{ tag: \"lnum\", label: \"Lining Figures\", group: \"Figures\" },\n\t{ tag: \"onum\", label: \"Oldstyle Figures\", group: \"Figures\" },\n\t{ tag: \"pnum\", label: \"Proportional Figures\", group: \"Figures\" },\n\t{ tag: \"tnum\", label: \"Tabular Figures\", group: \"Figures\" },\n\t{ tag: \"zero\", label: \"Slashed Zero\", group: \"Figures\" },\n\t{ tag: \"ordn\", label: \"Ordinals\", group: \"Figures\" },\n\n\t// Fractions\n\t{ tag: \"frac\", label: \"Fractions\", group: \"Fractions\" },\n\t{ tag: \"afrc\", label: \"Alternative Fractions\", group: \"Fractions\" },\n\n\t// Alternates\n\t{ tag: \"swsh\", label: \"Swash\", group: \"Alternates\" },\n\t{ tag: \"calt\", label: \"Contextual Alternates\", group: \"Alternates\" },\n\t{ tag: \"salt\", label: \"Stylistic Alternates\", group: \"Alternates\" },\n\t{ tag: \"hist\", label: \"Historical Forms\", group: \"Alternates\" },\n\t{ tag: \"nalt\", label: \"Alternate Annotation Forms\", group: \"Alternates\" },\n\n\t// Position\n\t{ tag: \"sups\", label: \"Superscript\", group: \"Position\" },\n\t{ tag: \"subs\", label: \"Subscript\", group: \"Position\" },\n\n\t// Stylistic Sets ss01–ss20\n\t...Array.from({ length: 20 }, (_, i): FeatureDef => {\n\t\tconst n = i + 1;\n\t\tconst tag = `ss${String(n).padStart(2, \"0\")}`;\n\t\treturn { tag, label: `Stylistic Set ${n}`, group: \"Stylistic Sets\" };\n\t}),\n];\n\n/** Lookup map from tag to its definition. */\nexport const FEATURE_BY_TAG: ReadonlyMap<FeatureTag, FeatureDef> = new Map(\n\tFEATURES.map((f) => [f.tag, f]),\n);\n\n/** Returns the label for a tag, falling back to the upper-cased tag itself. */\nexport function featureLabel(tag: FeatureTag): string {\n\treturn FEATURE_BY_TAG.get(tag)?.label ?? tag.toUpperCase();\n}\n\n/** True if the tag is a known, supported OpenType feature. */\nexport function isKnownFeature(tag: string): boolean {\n\treturn FEATURE_BY_TAG.has(tag);\n}\n\n/**\n * Builds a CSS `font-feature-settings` value from a set of active tags so that\n * multiple features compose (e.g. small caps + oldstyle figures) instead of\n * each selection overwriting the others. Returns \"normal\" when none are active.\n */\nexport function featureSettings(active: Iterable<FeatureTag>): string {\n\tconst tags = Array.from(active).filter(isKnownFeature);\n\tif (tags.length === 0) return \"normal\";\n\treturn tags.map((tag) => `\"${tag}\" 1`).join(\", \");\n}\n","// Minimal, safe DOM construction helpers. All text is set via textContent and\n// all attributes via setAttribute, so untrusted values can never be interpreted\n// as HTML or script (no innerHTML, no eval).\n\n/** Properties accepted by {@link el}. */\nexport interface ElProps {\n\t/** Space-separated class names. */\n\tclass?: string;\n\t/** Text content (set via textContent — never parsed as HTML). */\n\ttext?: string;\n\t/** Attributes to set via setAttribute. Nullish values are skipped. */\n\tattrs?: Record<string, string | number | boolean | null | undefined>;\n\t/** Child nodes to append. */\n\tchildren?: Node[];\n}\n\n/**\n * Creates an element of the given tag with safe text/attribute/children\n * assignment. Returns the typed element.\n */\nexport function el<K extends keyof HTMLElementTagNameMap>(\n\ttag: K,\n\tprops: ElProps = {},\n): HTMLElementTagNameMap[K] {\n\tconst node = document.createElement(tag);\n\tif (props.class) node.className = props.class;\n\tif (props.text != null) node.textContent = props.text;\n\tif (props.attrs) {\n\t\tfor (const [name, value] of Object.entries(props.attrs)) {\n\t\t\tif (value == null || value === false) continue;\n\t\t\tnode.setAttribute(name, value === true ? \"\" : String(value));\n\t\t}\n\t}\n\tif (props.children) {\n\t\tfor (const child of props.children) node.appendChild(child);\n\t}\n\treturn node;\n}\n\n/** Clamps a number into the inclusive [min, max] range. */\nexport function clamp(value: number, min: number, max: number): number {\n\treturn Math.min(max, Math.max(min, value));\n}\n\n/**\n * Parses a numeric attribute/string, returning the fallback when the value is\n * missing or not a finite number. Prevents NaN leaking into the UI.\n */\nexport function toNumber(value: unknown, fallback: number): number {\n\tif (value == null || value === \"\") return fallback;\n\tconst n = typeof value === \"number\" ? value : Number(value);\n\treturn Number.isFinite(n) ? n : fallback;\n}\n","// Auto-fit engine. Replaces the legacy `bigtext` dependency.\n//\n// Sizing is computed by measuring the text once at a reference size in an\n// offscreen mirror, then scaling linearly: glyph advances and em-based\n// letter-spacing both scale linearly with font-size, so\n// fittedSize = referenceSize * containerWidth / measuredWidth\n// is exact and needs a single read + write per fit (no read/write thrashing,\n// no binary-search loop). Re-fitting is driven by ResizeObserver (so it tracks\n// container resizes) and rAF-debounced (so typing does not thrash layout).\n\nimport { clamp } from \"./dom.js\";\n\nconst REFERENCE_SIZE = 100;\n\n/** Font properties copied to the mirror so measurement matches the real text. */\nconst MIRROR_PROPS = [\n\t\"fontFamily\",\n\t\"fontWeight\",\n\t\"fontStyle\",\n\t\"fontStretch\",\n\t\"letterSpacing\",\n\t\"fontFeatureSettings\",\n\t\"fontVariationSettings\",\n\t\"textTransform\",\n] as const;\n\n/** Drives auto-fit sizing for a single text element. */\nexport class Fitter {\n\tprivate readonly target: HTMLElement;\n\tprivate readonly min: number;\n\tprivate readonly max: number;\n\tprivate mirror: HTMLSpanElement | null = null;\n\tprivate observer: ResizeObserver | null = null;\n\tprivate frame = 0;\n\tprivate onFit: ((size: number) => void) | null = null;\n\tprivate destroyed = false;\n\t// Last container width fitted against. Used to ignore ResizeObserver\n\t// notifications caused purely by height changes (a fit grows the line\n\t// height, which would otherwise re-trigger the observer in a loop).\n\tprivate lastWidth = -1;\n\n\t/**\n\t * @param target Element whose text is being fitted.\n\t * @param min Minimum font-size in px.\n\t * @param max Maximum font-size in px.\n\t */\n\tconstructor(target: HTMLElement, min: number, max: number) {\n\t\tthis.target = target;\n\t\tthis.min = min;\n\t\tthis.max = max;\n\t}\n\n\t/**\n\t * Starts observing the target's container and reports the fitted size via\n\t * `onFit` whenever it should change. Re-fits once fonts have loaded.\n\t */\n\tstart(onFit: (size: number) => void): void {\n\t\tthis.onFit = onFit;\n\t\tif (typeof ResizeObserver !== \"undefined\") {\n\t\t\tconst container = this.target.parentElement ?? this.target;\n\t\t\tthis.observer = new ResizeObserver(() => {\n\t\t\t\t// Only re-fit when the available width changes; height-only changes\n\t\t\t\t// are a consequence of fitting and must not feed back.\n\t\t\t\tif (container.clientWidth !== this.lastWidth) this.schedule();\n\t\t\t});\n\t\t\tthis.observer.observe(container);\n\t\t}\n\t\t// Re-fit after web fonts load so we never measure fallback metrics.\n\t\tconst fonts = (document as Document & { fonts?: FontFaceSet }).fonts;\n\t\tif (fonts?.ready) {\n\t\t\tfonts.ready.then(() => this.schedule()).catch(() => {});\n\t\t}\n\t\tthis.schedule();\n\t}\n\n\t/** Requests a fit on the next animation frame, coalescing rapid calls. */\n\tschedule(): void {\n\t\tif (this.destroyed) return;\n\t\tif (typeof requestAnimationFrame === \"undefined\") {\n\t\t\tthis.fit();\n\t\t\treturn;\n\t\t}\n\t\tif (this.frame) return;\n\t\tthis.frame = requestAnimationFrame(() => {\n\t\t\tthis.frame = 0;\n\t\t\tthis.fit();\n\t\t});\n\t}\n\n\t/** Measures the text and reports the fitted size. */\n\tprivate fit(): void {\n\t\tif (this.destroyed || !this.onFit) return;\n\t\tconst container = this.target.parentElement ?? this.target;\n\t\tconst width = container.clientWidth;\n\t\tif (width <= 0) return;\n\n\t\tconst mirror = this.ensureMirror();\n\t\tconst computed = getComputedStyle(this.target);\n\t\tfor (const prop of MIRROR_PROPS) {\n\t\t\tmirror.style[prop] = computed[prop];\n\t\t}\n\t\tmirror.style.fontSize = `${REFERENCE_SIZE}px`;\n\t\tmirror.textContent = this.target.textContent ?? \"\";\n\n\t\tconst measured = mirror.getBoundingClientRect().width;\n\t\tif (measured <= 0) return;\n\n\t\tthis.lastWidth = width;\n\t\tconst size = clamp((REFERENCE_SIZE * width) / measured, this.min, this.max);\n\t\tthis.onFit(Math.round(size * 100) / 100);\n\t}\n\n\t/** Lazily creates the shared offscreen measurement mirror. */\n\tprivate ensureMirror(): HTMLSpanElement {\n\t\tif (this.mirror) return this.mirror;\n\t\tconst mirror = document.createElement(\"span\");\n\t\tmirror.setAttribute(\"aria-hidden\", \"true\");\n\t\tObject.assign(mirror.style, {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: \"-9999px\",\n\t\t\ttop: \"0\",\n\t\t\tvisibility: \"hidden\",\n\t\t\twhiteSpace: \"nowrap\",\n\t\t\tpointerEvents: \"none\",\n\t\t});\n\t\tdocument.body.appendChild(mirror);\n\t\tthis.mirror = mirror;\n\t\treturn mirror;\n\t}\n\n\t/** Stops observing and removes the mirror. */\n\tdestroy(): void {\n\t\tthis.destroyed = true;\n\t\tif (this.frame) cancelAnimationFrame(this.frame);\n\t\tthis.observer?.disconnect();\n\t\tthis.observer = null;\n\t\tthis.mirror?.remove();\n\t\tthis.mirror = null;\n\t\tthis.onFit = null;\n\t}\n}\n","// Framework-agnostic, dependency-free type tester.\n//\n// Replaces the legacy jQuery/jQuery-UI/bigtext widget. Key differences:\n// - No eval, no innerHTML with user data — DOM is built with createElement and\n// textContent, styles via element.style (no string injection).\n// - Native, accessible controls: <input type=range>, <button aria-pressed>,\n// <select>, and checkbox-based feature toggles with a focus-managed panel.\n// - OpenType features compose (multiple active at once).\n// - Auto-fit via ResizeObserver (tracks container resizes) instead of bigtext.\n// - No global state; each instance owns its DOM, listeners and observers and is\n// fully torn down by destroy().\n\nimport { Fitter } from \"./fit.js\";\nimport { clamp, el, toNumber } from \"./dom.js\";\nimport {\n\tFEATURES,\n\tFEATURE_BY_TAG,\n\ttype FeatureDef,\n\ttype FeatureTag,\n\tfeatureLabel,\n\tfeatureSettings,\n\tisKnownFeature,\n} from \"./opentype.js\";\nimport type {\n\tAlign,\n\tControlsConfig,\n\tRange,\n\tTypeTesterOptions,\n\tTypeTesterState,\n} from \"./types.js\";\n\n/** Default slider ranges, overridable per control. */\nconst DEFAULT_RANGES = {\n\tsize: { min: 8, max: 300, step: 1 },\n\ttracking: { min: -0.1, max: 0.5, step: 0.005 },\n\tweight: { min: 100, max: 900, step: 100 },\n} as const;\n\nconst ALIGNS: readonly Align[] = [\"left\", \"center\", \"right\"];\n\n// Monotonic counter for unique element ids (deterministic, collision-free even\n// for instances created within the same millisecond).\nlet idCounter = 0;\nfunction nextId(): number {\n\treturn ++idCounter;\n}\n\n/** Resolves a boolean|Range control config against a default range. */\nfunction resolveRange(value: boolean | Range | undefined, fallback: Range): Range | null {\n\tif (!value) return null;\n\tif (value === true) return { ...fallback };\n\treturn { min: value.min, max: value.max, step: value.step ?? fallback.step };\n}\n\n/** A type tester instance bound to a host element. */\nexport class TypeTester {\n\tprivate readonly host: HTMLElement;\n\tprivate readonly options: TypeTesterOptions;\n\tprivate readonly controls: ControlsConfig;\n\tprivate readonly state: TypeTesterState;\n\tprivate readonly activeFeatures = new Set<FeatureTag>();\n\tprivate readonly cleanups: Array<() => void> = [];\n\n\tprivate typeEl!: HTMLElement;\n\tprivate textEl!: HTMLElement;\n\tprivate liveEl!: HTMLElement;\n\tprivate sizeOutput: HTMLOutputElement | null = null;\n\tprivate fitter: Fitter | null = null;\n\n\t/**\n\t * @param host Element to render the tester into.\n\t * @param options Configuration; all fields optional.\n\t */\n\tconstructor(host: HTMLElement, options: TypeTesterOptions = {}) {\n\t\tthis.host = host;\n\t\tthis.options = options;\n\t\tthis.controls = options.controls ?? {};\n\n\t\tconst fit = options.size === \"fit\";\n\t\tfor (const tag of options.features ?? []) {\n\t\t\tif (isKnownFeature(tag)) this.activeFeatures.add(tag);\n\t\t}\n\t\tthis.state = {\n\t\t\ttext: options.text ?? \"\",\n\t\t\tsize: fit ? 0 : toNumber(options.size, 80),\n\t\t\tfit,\n\t\t\ttracking: toNumber(options.tracking, 0),\n\t\t\tweight: toNumber(options.weight, 400),\n\t\t\titalic: options.italic ?? false,\n\t\t\talign: options.align ?? \"left\",\n\t\t\twrap: options.wrap ?? true,\n\t\t\tfeatures: Array.from(this.activeFeatures),\n\t\t};\n\n\t\tthis.render();\n\t}\n\n\t/** Returns a snapshot of the current state. */\n\tgetState(): TypeTesterState {\n\t\treturn { ...this.state, features: Array.from(this.activeFeatures) };\n\t}\n\n\t/** Removes all DOM, listeners and observers created by this instance. */\n\tdestroy(): void {\n\t\tthis.fitter?.destroy();\n\t\tthis.fitter = null;\n\t\tfor (const off of this.cleanups.splice(0)) off();\n\t\tthis.host.replaceChildren();\n\t}\n\n\t// ---- rendering -------------------------------------------------------\n\n\tprivate render(): void {\n\t\tthis.host.classList.add(\"tt\");\n\n\t\tthis.textEl = el(\"div\", {\n\t\t\tclass: \"tt__text\",\n\t\t\ttext: this.state.text,\n\t\t\tattrs: {\n\t\t\t\trole: \"textbox\",\n\t\t\t\t\"aria-label\": this.options.ariaLabel ?? \"Sample text\",\n\t\t\t\t\"aria-multiline\": String(this.state.wrap),\n\t\t\t\tcontenteditable: this.options.editable !== false ? \"true\" : null,\n\t\t\t\tspellcheck: \"true\",\n\t\t\t\t\"data-placeholder\": this.options.placeholder ?? \"Type to test…\",\n\t\t\t},\n\t\t});\n\t\tthis.typeEl = el(\"div\", { class: \"tt__type\", children: [this.textEl] });\n\t\tconst stage = el(\"div\", { class: \"tt__stage\", children: [this.typeEl] });\n\n\t\tthis.liveEl = el(\"div\", {\n\t\t\tclass: \"tt__sr-only\",\n\t\t\tattrs: { \"aria-live\": \"polite\", \"aria-atomic\": \"true\" },\n\t\t});\n\n\t\tconst controls = this.buildControls();\n\t\tconst children: Node[] = [stage];\n\t\tif (controls) children.push(controls);\n\t\tchildren.push(this.liveEl);\n\t\tthis.host.replaceChildren(...children);\n\n\t\tif (this.options.editable !== false) this.wireEditable();\n\t\tthis.applyStyles();\n\t\tthis.setupFit();\n\t}\n\n\tprivate buildControls(): HTMLElement | null {\n\t\tconst items: Node[] = [];\n\t\tconst sizeRange = resolveRange(this.controls.size, DEFAULT_RANGES.size);\n\t\tif (sizeRange && !this.state.fit) items.push(this.buildSize(sizeRange));\n\t\tconst trackingRange = resolveRange(this.controls.tracking, DEFAULT_RANGES.tracking);\n\t\tif (trackingRange) items.push(this.buildTracking(trackingRange));\n\t\tconst weightRange = resolveRange(\n\t\t\tthis.controls.weight,\n\t\t\tthis.options.variable?.wght ?? DEFAULT_RANGES.weight,\n\t\t);\n\t\tif (weightRange) items.push(this.buildWeight(weightRange));\n\t\tif (this.controls.italic) items.push(this.buildItalic());\n\t\tif (this.controls.align) items.push(this.buildAlign());\n\t\tif (this.controls.wrap) items.push(this.buildWrap());\n\t\tif (this.controls.features) items.push(this.buildFeatures());\n\n\t\tif (items.length === 0) return null;\n\t\treturn el(\"div\", {\n\t\t\tclass: \"tt__controls\",\n\t\t\tattrs: { role: \"group\", \"aria-label\": \"Typography controls\" },\n\t\t\tchildren: items,\n\t\t});\n\t}\n\n\t// ---- generic control builders (no per-control copy-paste) -------------\n\n\tprivate buildSlider(\n\t\tkey: \"size\" | \"tracking\" | \"weight\",\n\t\tlabel: string,\n\t\trange: Range,\n\t\tvalue: number,\n\t\tunit: string,\n\t\tonInput: (value: number) => void,\n\t): HTMLElement {\n\t\tconst output = el(\"output\", { class: \"tt__value\", text: `${value}${unit}` });\n\t\tconst input = el(\"input\", {\n\t\t\tclass: `tt__slider tt__slider--${key}`,\n\t\t\tattrs: {\n\t\t\t\ttype: \"range\",\n\t\t\t\tmin: range.min,\n\t\t\t\tmax: range.max,\n\t\t\t\tstep: range.step ?? 1,\n\t\t\t\tvalue,\n\t\t\t\t\"aria-label\": label,\n\t\t\t},\n\t\t});\n\t\tconst handler = () => {\n\t\t\tconst v = Number(input.value);\n\t\t\toutput.textContent = `${v}${unit}`;\n\t\t\tonInput(v);\n\t\t\tthis.announce(`${label} ${v}${unit}`);\n\t\t};\n\t\tinput.addEventListener(\"input\", handler);\n\t\tthis.cleanups.push(() => input.removeEventListener(\"input\", handler));\n\t\tif (key === \"size\") this.sizeOutput = output;\n\t\treturn el(\"label\", {\n\t\t\tclass: `tt__control tt__control--${key}`,\n\t\t\tchildren: [el(\"span\", { class: \"tt__label\", text: label }), input, output],\n\t\t});\n\t}\n\n\tprivate buildSize(range: Range): HTMLElement {\n\t\tthis.state.size = clamp(this.state.size, range.min, range.max);\n\t\treturn this.buildSlider(\"size\", \"Size\", range, this.state.size, \"px\", (v) => {\n\t\t\tthis.state.size = v;\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t}\n\n\tprivate buildTracking(range: Range): HTMLElement {\n\t\tthis.state.tracking = clamp(this.state.tracking, range.min, range.max);\n\t\treturn this.buildSlider(\n\t\t\t\"tracking\",\n\t\t\t\"Tracking\",\n\t\t\trange,\n\t\t\tthis.state.tracking,\n\t\t\t\"em\",\n\t\t\t(v) => {\n\t\t\t\tthis.state.tracking = v;\n\t\t\t\tthis.applyStyles();\n\t\t\t\tthis.emitChange();\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate buildWeight(range: Range): HTMLElement {\n\t\tthis.state.weight = clamp(this.state.weight, range.min, range.max);\n\t\treturn this.buildSlider(\"weight\", \"Weight\", range, this.state.weight, \"\", (v) => {\n\t\t\tthis.state.weight = v;\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t}\n\n\tprivate buildToggle(\n\t\tkey: string,\n\t\tlabel: string,\n\t\tpressed: boolean,\n\t\tonToggle: (pressed: boolean) => void,\n\t): HTMLButtonElement {\n\t\tconst button = el(\"button\", {\n\t\t\tclass: `tt__toggle tt__toggle--${key}`,\n\t\t\ttext: label,\n\t\t\t// aria-pressed is a string-valued ARIA state and must always be present\n\t\t\t// (\"false\"), unlike boolean HTML attributes which are omitted when off.\n\t\t\tattrs: { type: \"button\", \"aria-pressed\": String(pressed) },\n\t\t});\n\t\tconst handler = () => {\n\t\t\tconst next = button.getAttribute(\"aria-pressed\") !== \"true\";\n\t\t\tbutton.setAttribute(\"aria-pressed\", String(next));\n\t\t\tonToggle(next);\n\t\t\tthis.announce(`${label} ${next ? \"on\" : \"off\"}`);\n\t\t};\n\t\tbutton.addEventListener(\"click\", handler);\n\t\tthis.cleanups.push(() => button.removeEventListener(\"click\", handler));\n\t\treturn button;\n\t}\n\n\tprivate buildItalic(): HTMLElement {\n\t\tconst button = this.buildToggle(\"italic\", \"Italic\", this.state.italic, (on) => {\n\t\t\tthis.state.italic = on;\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t\treturn el(\"div\", { class: \"tt__control\", children: [button] });\n\t}\n\n\tprivate buildWrap(): HTMLElement {\n\t\tconst button = this.buildToggle(\"wrap\", \"Wrap\", this.state.wrap, (on) => {\n\t\t\tthis.state.wrap = on;\n\t\t\tthis.textEl.setAttribute(\"aria-multiline\", String(on));\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t\treturn el(\"div\", { class: \"tt__control\", children: [button] });\n\t}\n\n\tprivate buildAlign(): HTMLElement {\n\t\tconst select = el(\"select\", {\n\t\t\tclass: \"tt__select tt__select--align\",\n\t\t\tattrs: { \"aria-label\": \"Alignment\" },\n\t\t\tchildren: ALIGNS.map((a) =>\n\t\t\t\tel(\"option\", {\n\t\t\t\t\ttext: a.charAt(0).toUpperCase() + a.slice(1),\n\t\t\t\t\tattrs: { value: a, selected: a === this.state.align },\n\t\t\t\t}),\n\t\t\t),\n\t\t});\n\t\tconst handler = () => {\n\t\t\tconst value = select.value as Align;\n\t\t\tif (ALIGNS.includes(value)) {\n\t\t\t\tthis.state.align = value;\n\t\t\t\tthis.applyStyles();\n\t\t\t\tthis.emitChange();\n\t\t\t\tthis.announce(`Alignment ${value}`);\n\t\t\t}\n\t\t};\n\t\tselect.addEventListener(\"change\", handler);\n\t\tthis.cleanups.push(() => select.removeEventListener(\"change\", handler));\n\t\treturn el(\"label\", {\n\t\t\tclass: \"tt__control tt__control--align\",\n\t\t\tchildren: [el(\"span\", { class: \"tt__label\", text: \"Align\" }), select],\n\t\t});\n\t}\n\n\tprivate buildFeatures(): HTMLElement {\n\t\tconst offered: readonly FeatureDef[] = Array.isArray(this.controls.features)\n\t\t\t? this.controls.features\n\t\t\t\t\t.filter(isKnownFeature)\n\t\t\t\t\t// Preserve each feature's real group/label from the registry rather\n\t\t\t\t\t// than flattening everything into \"Alternates\".\n\t\t\t\t\t.map((tag) => FEATURE_BY_TAG.get(tag) ?? { tag, label: featureLabel(tag), group: \"Alternates\" })\n\t\t\t: FEATURES;\n\n\t\tconst panelId = `tt-feat-${nextId()}`;\n\t\tconst toggle = el(\"button\", {\n\t\t\tclass: \"tt__toggle tt__toggle--features\",\n\t\t\ttext: \"Features\",\n\t\t\tattrs: {\n\t\t\t\ttype: \"button\",\n\t\t\t\t\"aria-haspopup\": \"true\",\n\t\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\t\"aria-controls\": panelId,\n\t\t\t},\n\t\t});\n\n\t\tconst checks = offered.map((f) => {\n\t\t\tconst input = el(\"input\", {\n\t\t\t\tattrs: { type: \"checkbox\", value: f.tag, checked: this.activeFeatures.has(f.tag) },\n\t\t\t});\n\t\t\tconst onChange = () => this.toggleFeature(f.tag, input.checked);\n\t\t\tinput.addEventListener(\"change\", onChange);\n\t\t\tthis.cleanups.push(() => input.removeEventListener(\"change\", onChange));\n\t\t\treturn el(\"label\", {\n\t\t\t\tclass: \"tt__feature\",\n\t\t\t\tchildren: [input, el(\"span\", { text: f.label })],\n\t\t\t});\n\t\t});\n\n\t\tconst panel = el(\"div\", {\n\t\t\tclass: \"tt__panel\",\n\t\t\tattrs: { id: panelId, role: \"group\", \"aria-label\": \"OpenType features\", hidden: true },\n\t\t\tchildren: checks,\n\t\t});\n\n\t\tconst wrapper = el(\"div\", {\n\t\t\tclass: \"tt__control tt__control--features\",\n\t\t\tchildren: [toggle, panel],\n\t\t});\n\n\t\tconst setOpen = (open: boolean) => {\n\t\t\ttoggle.setAttribute(\"aria-expanded\", String(open));\n\t\t\tpanel.toggleAttribute(\"hidden\", !open);\n\t\t\tif (open) {\n\t\t\t\tconst first = panel.querySelector<HTMLInputElement>(\"input\");\n\t\t\t\tfirst?.focus();\n\t\t\t}\n\t\t};\n\t\tconst onToggleClick = () => setOpen(toggle.getAttribute(\"aria-expanded\") !== \"true\");\n\t\tconst onKeydown = (e: KeyboardEvent) => {\n\t\t\tif (e.key === \"Escape\" && toggle.getAttribute(\"aria-expanded\") === \"true\") {\n\t\t\t\tsetOpen(false);\n\t\t\t\ttoggle.focus();\n\t\t\t}\n\t\t};\n\t\tconst onOutside = (e: MouseEvent) => {\n\t\t\tif (toggle.getAttribute(\"aria-expanded\") !== \"true\") return;\n\t\t\tif (!wrapper.contains(e.target as Node)) setOpen(false);\n\t\t};\n\t\ttoggle.addEventListener(\"click\", onToggleClick);\n\t\t// Escape is handled at the document level so it closes the panel no matter\n\t\t// where focus currently is, then restores focus to the toggle.\n\t\tdocument.addEventListener(\"keydown\", onKeydown);\n\t\tdocument.addEventListener(\"click\", onOutside);\n\t\tthis.cleanups.push(() => {\n\t\t\ttoggle.removeEventListener(\"click\", onToggleClick);\n\t\t\tdocument.removeEventListener(\"keydown\", onKeydown);\n\t\t\tdocument.removeEventListener(\"click\", onOutside);\n\t\t});\n\n\t\treturn wrapper;\n\t}\n\n\tprivate toggleFeature(tag: FeatureTag, on: boolean): void {\n\t\tif (on) this.activeFeatures.add(tag);\n\t\telse this.activeFeatures.delete(tag);\n\t\tthis.state.features = Array.from(this.activeFeatures);\n\t\tthis.applyStyles();\n\t\tthis.emitChange();\n\t\tthis.announce(`${featureLabel(tag)} ${on ? \"on\" : \"off\"}`);\n\t}\n\n\t// ---- behaviour -------------------------------------------------------\n\n\tprivate wireEditable(): void {\n\t\tconst handler = () => {\n\t\t\tthis.state.text = this.textEl.textContent ?? \"\";\n\t\t\tif (this.state.fit) this.fitter?.schedule();\n\t\t\tthis.emitChange();\n\t\t};\n\t\tthis.textEl.addEventListener(\"input\", handler);\n\t\tthis.cleanups.push(() => this.textEl.removeEventListener(\"input\", handler));\n\t}\n\n\tprivate setupFit(): void {\n\t\tif (!this.state.fit) return;\n\t\tconst range = resolveRange(this.controls.size, DEFAULT_RANGES.size) ?? DEFAULT_RANGES.size;\n\t\tthis.fitter = new Fitter(this.textEl, range.min, range.max);\n\t\tthis.fitter.start((size) => {\n\t\t\tthis.state.size = size;\n\t\t\tthis.typeEl.style.fontSize = `${size}px`;\n\t\t\tif (this.sizeOutput) this.sizeOutput.textContent = `${size}px`;\n\t\t});\n\t}\n\n\t/** Applies the full typographic state to the type element via element.style. */\n\tprivate applyStyles(): void {\n\t\tconst s = this.typeEl.style;\n\t\tconst family = this.options.fontFamily\n\t\t\t? `\"${this.options.fontFamily}\"${this.options.fallback ? `, ${this.options.fallback}` : \", sans-serif\"}`\n\t\t\t: (this.options.fallback ?? \"sans-serif\");\n\t\ts.fontFamily = family;\n\t\tif (!this.state.fit) s.fontSize = `${this.state.size}px`;\n\t\ts.letterSpacing = `${this.state.tracking}em`;\n\t\ts.fontStyle = this.state.italic ? \"italic\" : \"normal\";\n\t\ts.textAlign = this.state.align;\n\t\tthis.textEl.style.whiteSpace = this.state.wrap ? \"normal\" : \"nowrap\";\n\n\t\tif (this.options.variable?.wght) {\n\t\t\ts.fontVariationSettings = `\"wght\" ${this.state.weight}`;\n\t\t}\n\t\ts.fontWeight = String(this.state.weight);\n\n\t\tconst settings = featureSettings(this.activeFeatures);\n\t\ts.fontFeatureSettings = settings;\n\t\t// Older Safari needs the prefixed property; modern engines ignore it.\n\t\ts.setProperty(\"-webkit-font-feature-settings\", settings);\n\t}\n\n\tprivate announce(message: string): void {\n\t\tthis.liveEl.textContent = message;\n\t}\n\n\tprivate emitChange(): void {\n\t\tthis.options.onChange?.(this.getState());\n\t}\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/dom.ts","../src/core/fit.ts","../src/core/opentype.ts","../src/core/typeTester.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// Minimal, safe DOM construction helpers. All text is set via textContent and\n// all attributes via setAttribute, so untrusted values can never be interpreted\n// as HTML or script (no innerHTML, no eval).\n\n/** Properties accepted by {@link el}. */\nexport interface ElProps {\n\t/** Space-separated class names. */\n\tclass?: string;\n\t/** Text content (set via textContent — never parsed as HTML). */\n\ttext?: string;\n\t/** Attributes to set via setAttribute. Nullish values are skipped. */\n\tattrs?: Record<string, string | number | boolean | null | undefined>;\n\t/** Child nodes to append. */\n\tchildren?: Node[];\n}\n\n/**\n * Creates an element of the given tag with safe text/attribute/children\n * assignment. Returns the typed element.\n */\nexport function el<K extends keyof HTMLElementTagNameMap>(\n\ttag: K,\n\tprops: ElProps = {},\n): HTMLElementTagNameMap[K] {\n\tconst node = document.createElement(tag);\n\tif (props.class) node.className = props.class;\n\tif (props.text != null) node.textContent = props.text;\n\tif (props.attrs) {\n\t\tfor (const [name, value] of Object.entries(props.attrs)) {\n\t\t\tif (value == null || value === false) continue;\n\t\t\tnode.setAttribute(name, value === true ? \"\" : String(value));\n\t\t}\n\t}\n\tif (props.children) {\n\t\tfor (const child of props.children) node.appendChild(child);\n\t}\n\treturn node;\n}\n\n/** Clamps a number into the inclusive [min, max] range. */\nexport function clamp(value: number, min: number, max: number): number {\n\treturn Math.min(max, Math.max(min, value));\n}\n\n/**\n * Parses a numeric attribute/string, returning the fallback when the value is\n * missing or not a finite number. Prevents NaN leaking into the UI.\n */\nexport function toNumber(value: unknown, fallback: number): number {\n\tif (value == null || value === \"\") return fallback;\n\tconst n = typeof value === \"number\" ? value : Number(value);\n\treturn Number.isFinite(n) ? n : fallback;\n}\n","// Auto-fit engine. Replaces the legacy `bigtext` dependency.\n//\n// Sizing is computed by measuring the text once at a reference size in an\n// offscreen mirror, then scaling linearly: glyph advances and em-based\n// letter-spacing both scale linearly with font-size, so\n// fittedSize = referenceSize * containerWidth / measuredWidth\n// is exact and needs a single read + write per fit (no read/write thrashing,\n// no binary-search loop). Re-fitting is driven by ResizeObserver (so it tracks\n// container resizes) and rAF-debounced (so typing does not thrash layout).\n\nimport { clamp } from \"./dom.js\";\n\nconst REFERENCE_SIZE = 100;\n\n/** Font properties copied to the mirror so measurement matches the real text. */\nconst MIRROR_PROPS = [\n\t\"fontFamily\",\n\t\"fontWeight\",\n\t\"fontStyle\",\n\t\"fontStretch\",\n\t\"letterSpacing\",\n\t\"fontFeatureSettings\",\n\t\"fontVariationSettings\",\n\t\"textTransform\",\n] as const;\n\n/** Drives auto-fit sizing for a single text element. */\nexport class Fitter {\n\tprivate readonly target: HTMLElement;\n\tprivate readonly min: number;\n\tprivate readonly max: number;\n\tprivate mirror: HTMLSpanElement | null = null;\n\tprivate observer: ResizeObserver | null = null;\n\tprivate frame = 0;\n\tprivate onFit: ((size: number) => void) | null = null;\n\tprivate destroyed = false;\n\t// Last container width fitted against. Used to ignore ResizeObserver\n\t// notifications caused purely by height changes (a fit grows the line\n\t// height, which would otherwise re-trigger the observer in a loop).\n\tprivate lastWidth = -1;\n\n\t/**\n\t * @param target Element whose text is being fitted.\n\t * @param min Minimum font-size in px.\n\t * @param max Maximum font-size in px.\n\t */\n\tconstructor(target: HTMLElement, min: number, max: number) {\n\t\tthis.target = target;\n\t\tthis.min = min;\n\t\tthis.max = max;\n\t}\n\n\t/**\n\t * Starts observing the target's container and reports the fitted size via\n\t * `onFit` whenever it should change. Re-fits once fonts have loaded.\n\t */\n\tstart(onFit: (size: number) => void): void {\n\t\tthis.onFit = onFit;\n\t\tif (typeof ResizeObserver !== \"undefined\") {\n\t\t\tconst container = this.target.parentElement ?? this.target;\n\t\t\tthis.observer = new ResizeObserver(() => {\n\t\t\t\t// Only re-fit when the available width changes; height-only changes\n\t\t\t\t// are a consequence of fitting and must not feed back.\n\t\t\t\tif (container.clientWidth !== this.lastWidth) this.schedule();\n\t\t\t});\n\t\t\tthis.observer.observe(container);\n\t\t}\n\t\t// Re-fit after web fonts load so we never measure fallback metrics.\n\t\tconst fonts = (document as Document & { fonts?: FontFaceSet }).fonts;\n\t\tif (fonts?.ready) {\n\t\t\tfonts.ready.then(() => this.schedule()).catch(() => {});\n\t\t}\n\t\tthis.schedule();\n\t}\n\n\t/** Requests a fit on the next animation frame, coalescing rapid calls. */\n\tschedule(): void {\n\t\tif (this.destroyed) return;\n\t\tif (typeof requestAnimationFrame === \"undefined\") {\n\t\t\tthis.fit();\n\t\t\treturn;\n\t\t}\n\t\tif (this.frame) return;\n\t\tthis.frame = requestAnimationFrame(() => {\n\t\t\tthis.frame = 0;\n\t\t\tthis.fit();\n\t\t});\n\t}\n\n\t/** Measures the text and reports the fitted size. */\n\tprivate fit(): void {\n\t\tif (this.destroyed || !this.onFit) return;\n\t\tconst container = this.target.parentElement ?? this.target;\n\t\tconst width = container.clientWidth;\n\t\tif (width <= 0) return;\n\n\t\tconst mirror = this.ensureMirror();\n\t\tconst computed = getComputedStyle(this.target);\n\t\tfor (const prop of MIRROR_PROPS) {\n\t\t\tmirror.style[prop] = computed[prop];\n\t\t}\n\t\tmirror.style.fontSize = `${REFERENCE_SIZE}px`;\n\t\tmirror.textContent = this.target.textContent ?? \"\";\n\n\t\tconst measured = mirror.getBoundingClientRect().width;\n\t\tif (measured <= 0) return;\n\n\t\tthis.lastWidth = width;\n\t\tconst size = clamp((REFERENCE_SIZE * width) / measured, this.min, this.max);\n\t\tthis.onFit(Math.round(size * 100) / 100);\n\t}\n\n\t/** Lazily creates the shared offscreen measurement mirror. */\n\tprivate ensureMirror(): HTMLSpanElement {\n\t\tif (this.mirror) return this.mirror;\n\t\tconst mirror = document.createElement(\"span\");\n\t\tmirror.setAttribute(\"aria-hidden\", \"true\");\n\t\tObject.assign(mirror.style, {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: \"-9999px\",\n\t\t\ttop: \"0\",\n\t\t\tvisibility: \"hidden\",\n\t\t\twhiteSpace: \"nowrap\",\n\t\t\tpointerEvents: \"none\",\n\t\t});\n\t\tdocument.body.appendChild(mirror);\n\t\tthis.mirror = mirror;\n\t\treturn mirror;\n\t}\n\n\t/** Stops observing and removes the mirror. */\n\tdestroy(): void {\n\t\tthis.destroyed = true;\n\t\tif (this.frame) cancelAnimationFrame(this.frame);\n\t\tthis.observer?.disconnect();\n\t\tthis.observer = null;\n\t\tthis.mirror?.remove();\n\t\tthis.mirror = null;\n\t\tthis.onFit = null;\n\t}\n}\n","// OpenType feature registry: correct, spec-accurate tags, labels and grouping.\n// Replaces the legacy optValues table which had duplicate/ambiguous labels\n// (\"Contextual\" for both calt and clig, \"Historical\" for both hlig and hist)\n// and a mislabelled `nalt`.\n\n/** A four-character OpenType GSUB/GPOS feature tag. */\nexport type FeatureTag = string;\n\n/** Logical grouping used to organise features in a control UI. */\nexport type FeatureGroup =\n\t| \"Ligatures\"\n\t| \"Letter Case\"\n\t| \"Figures\"\n\t| \"Fractions\"\n\t| \"Alternates\"\n\t| \"Position\"\n\t| \"Stylistic Sets\";\n\n/** Definition of a single OpenType feature exposed by the tester. */\nexport interface FeatureDef {\n\t/** The OpenType feature tag, e.g. \"smcp\". */\n\ttag: FeatureTag;\n\t/** Human-readable, unambiguous label. */\n\tlabel: string;\n\t/** Group the feature belongs to. */\n\tgroup: FeatureGroup;\n}\n\n/**\n * The default, ordered list of supported OpenType features. Labels are unique\n * and follow the Microsoft OpenType feature registry naming.\n */\nexport const FEATURES: readonly FeatureDef[] = [\n\t// Ligatures\n\t{ tag: \"liga\", label: \"Standard Ligatures\", group: \"Ligatures\" },\n\t{ tag: \"dlig\", label: \"Discretionary Ligatures\", group: \"Ligatures\" },\n\t{ tag: \"hlig\", label: \"Historical Ligatures\", group: \"Ligatures\" },\n\t{ tag: \"clig\", label: \"Contextual Ligatures\", group: \"Ligatures\" },\n\n\t// Letter Case\n\t{ tag: \"smcp\", label: \"Small Capitals\", group: \"Letter Case\" },\n\t{ tag: \"c2sc\", label: \"Capitals to Small Capitals\", group: \"Letter Case\" },\n\t{ tag: \"case\", label: \"Case-Sensitive Forms\", group: \"Letter Case\" },\n\t{ tag: \"cpsp\", label: \"Capital Spacing\", group: \"Letter Case\" },\n\n\t// Figures\n\t{ tag: \"lnum\", label: \"Lining Figures\", group: \"Figures\" },\n\t{ tag: \"onum\", label: \"Oldstyle Figures\", group: \"Figures\" },\n\t{ tag: \"pnum\", label: \"Proportional Figures\", group: \"Figures\" },\n\t{ tag: \"tnum\", label: \"Tabular Figures\", group: \"Figures\" },\n\t{ tag: \"zero\", label: \"Slashed Zero\", group: \"Figures\" },\n\t{ tag: \"ordn\", label: \"Ordinals\", group: \"Figures\" },\n\n\t// Fractions\n\t{ tag: \"frac\", label: \"Fractions\", group: \"Fractions\" },\n\t{ tag: \"afrc\", label: \"Alternative Fractions\", group: \"Fractions\" },\n\n\t// Alternates\n\t{ tag: \"swsh\", label: \"Swash\", group: \"Alternates\" },\n\t{ tag: \"calt\", label: \"Contextual Alternates\", group: \"Alternates\" },\n\t{ tag: \"salt\", label: \"Stylistic Alternates\", group: \"Alternates\" },\n\t{ tag: \"hist\", label: \"Historical Forms\", group: \"Alternates\" },\n\t{ tag: \"nalt\", label: \"Alternate Annotation Forms\", group: \"Alternates\" },\n\n\t// Position\n\t{ tag: \"sups\", label: \"Superscript\", group: \"Position\" },\n\t{ tag: \"subs\", label: \"Subscript\", group: \"Position\" },\n\n\t// Stylistic Sets ss01–ss20\n\t...Array.from({ length: 20 }, (_, i): FeatureDef => {\n\t\tconst n = i + 1;\n\t\tconst tag = `ss${String(n).padStart(2, \"0\")}`;\n\t\treturn { tag, label: `Stylistic Set ${n}`, group: \"Stylistic Sets\" };\n\t}),\n];\n\n/** Lookup map from tag to its definition. */\nexport const FEATURE_BY_TAG: ReadonlyMap<FeatureTag, FeatureDef> = new Map(\n\tFEATURES.map((f) => [f.tag, f]),\n);\n\n/** Returns the label for a tag, falling back to the upper-cased tag itself. */\nexport function featureLabel(tag: FeatureTag): string {\n\treturn FEATURE_BY_TAG.get(tag)?.label ?? tag.toUpperCase();\n}\n\n/** True if the tag is a known, supported OpenType feature. */\nexport function isKnownFeature(tag: string): boolean {\n\treturn FEATURE_BY_TAG.has(tag);\n}\n\n/**\n * Builds a CSS `font-feature-settings` value from a set of active tags so that\n * multiple features compose (e.g. small caps + oldstyle figures) instead of\n * each selection overwriting the others. Returns \"normal\" when none are active.\n */\nexport function featureSettings(active: Iterable<FeatureTag>): string {\n\tconst tags = Array.from(active).filter(isKnownFeature);\n\tif (tags.length === 0) return \"normal\";\n\treturn tags.map((tag) => `\"${tag}\" 1`).join(\", \");\n}\n","// Framework-agnostic, dependency-free type tester.\n//\n// Replaces the legacy jQuery/jQuery-UI/bigtext widget. Key differences:\n// - No eval, no innerHTML with user data — DOM is built with createElement and\n// textContent, styles via element.style (no string injection).\n// - Native, accessible controls: <input type=range>, <button aria-pressed>,\n// <select>, and checkbox-based feature toggles with a focus-managed panel.\n// - OpenType features compose (multiple active at once).\n// - Auto-fit via ResizeObserver (tracks container resizes) instead of bigtext.\n// - No global state; each instance owns its DOM, listeners and observers and is\n// fully torn down by destroy().\n\nimport { Fitter } from \"./fit.js\";\nimport { clamp, el, toNumber } from \"./dom.js\";\nimport {\n\tFEATURES,\n\tFEATURE_BY_TAG,\n\ttype FeatureDef,\n\ttype FeatureTag,\n\tfeatureLabel,\n\tfeatureSettings,\n\tisKnownFeature,\n} from \"./opentype.js\";\nimport type {\n\tAlign,\n\tControlsConfig,\n\tRange,\n\tTypeTesterOptions,\n\tTypeTesterState,\n} from \"./types.js\";\n\n/** Default slider ranges, overridable per control. */\nconst DEFAULT_RANGES = {\n\tsize: { min: 8, max: 300, step: 1 },\n\ttracking: { min: -0.1, max: 0.5, step: 0.005 },\n\tweight: { min: 100, max: 900, step: 100 },\n} as const;\n\nconst ALIGNS: readonly Align[] = [\"left\", \"center\", \"right\"];\n\n// Monotonic counter for unique element ids (deterministic, collision-free even\n// for instances created within the same millisecond).\nlet idCounter = 0;\nfunction nextId(): number {\n\treturn ++idCounter;\n}\n\n/** Resolves a boolean|Range control config against a default range. */\nfunction resolveRange(value: boolean | Range | undefined, fallback: Range): Range | null {\n\tif (!value) return null;\n\tif (value === true) return { ...fallback };\n\treturn { min: value.min, max: value.max, step: value.step ?? fallback.step };\n}\n\n/** A type tester instance bound to a host element. */\nexport class TypeTester {\n\tprivate readonly host: HTMLElement;\n\tprivate readonly options: TypeTesterOptions;\n\tprivate readonly controls: ControlsConfig;\n\tprivate readonly state: TypeTesterState;\n\tprivate readonly activeFeatures = new Set<FeatureTag>();\n\tprivate readonly cleanups: Array<() => void> = [];\n\n\tprivate typeEl!: HTMLElement;\n\tprivate textEl!: HTMLElement;\n\tprivate liveEl!: HTMLElement;\n\tprivate sizeOutput: HTMLOutputElement | null = null;\n\tprivate fitter: Fitter | null = null;\n\n\t/**\n\t * @param host Element to render the tester into.\n\t * @param options Configuration; all fields optional.\n\t */\n\tconstructor(host: HTMLElement, options: TypeTesterOptions = {}) {\n\t\tthis.host = host;\n\t\tthis.options = options;\n\t\tthis.controls = options.controls ?? {};\n\n\t\tconst fit = options.size === \"fit\";\n\t\tfor (const tag of options.features ?? []) {\n\t\t\tif (isKnownFeature(tag)) this.activeFeatures.add(tag);\n\t\t}\n\t\tthis.state = {\n\t\t\ttext: options.text ?? \"\",\n\t\t\tsize: fit ? 0 : toNumber(options.size, 80),\n\t\t\tfit,\n\t\t\ttracking: toNumber(options.tracking, 0),\n\t\t\tweight: toNumber(options.weight, 400),\n\t\t\titalic: options.italic ?? false,\n\t\t\talign: options.align ?? \"left\",\n\t\t\twrap: options.wrap ?? true,\n\t\t\tfeatures: Array.from(this.activeFeatures),\n\t\t};\n\n\t\tthis.render();\n\t}\n\n\t/** Returns a snapshot of the current state. */\n\tgetState(): TypeTesterState {\n\t\treturn { ...this.state, features: Array.from(this.activeFeatures) };\n\t}\n\n\t/** Removes all DOM, listeners and observers created by this instance. */\n\tdestroy(): void {\n\t\tthis.fitter?.destroy();\n\t\tthis.fitter = null;\n\t\tfor (const off of this.cleanups.splice(0)) off();\n\t\tthis.host.replaceChildren();\n\t}\n\n\t// ---- rendering -------------------------------------------------------\n\n\tprivate render(): void {\n\t\tthis.host.classList.add(\"tt\");\n\n\t\tthis.textEl = el(\"div\", {\n\t\t\tclass: \"tt__text\",\n\t\t\ttext: this.state.text,\n\t\t\tattrs: {\n\t\t\t\trole: \"textbox\",\n\t\t\t\t\"aria-label\": this.options.ariaLabel ?? \"Sample text\",\n\t\t\t\t\"aria-multiline\": String(this.state.wrap),\n\t\t\t\tcontenteditable: this.options.editable !== false ? \"true\" : null,\n\t\t\t\tspellcheck: \"true\",\n\t\t\t\t\"data-placeholder\": this.options.placeholder ?? \"Type to test…\",\n\t\t\t},\n\t\t});\n\t\tthis.typeEl = el(\"div\", { class: \"tt__type\", children: [this.textEl] });\n\t\tconst stage = el(\"div\", { class: \"tt__stage\", children: [this.typeEl] });\n\n\t\tthis.liveEl = el(\"div\", {\n\t\t\tclass: \"tt__sr-only\",\n\t\t\tattrs: { \"aria-live\": \"polite\", \"aria-atomic\": \"true\" },\n\t\t});\n\n\t\tconst controls = this.buildControls();\n\t\tconst children: Node[] = [stage];\n\t\tif (controls) children.push(controls);\n\t\tchildren.push(this.liveEl);\n\t\tthis.host.replaceChildren(...children);\n\n\t\tif (this.options.editable !== false) this.wireEditable();\n\t\tthis.applyStyles();\n\t\tthis.setupFit();\n\t}\n\n\tprivate buildControls(): HTMLElement | null {\n\t\tconst items: Node[] = [];\n\t\tconst sizeRange = resolveRange(this.controls.size, DEFAULT_RANGES.size);\n\t\tif (sizeRange && !this.state.fit) items.push(this.buildSize(sizeRange));\n\t\tconst trackingRange = resolveRange(this.controls.tracking, DEFAULT_RANGES.tracking);\n\t\tif (trackingRange) items.push(this.buildTracking(trackingRange));\n\t\tconst weightRange = resolveRange(\n\t\t\tthis.controls.weight,\n\t\t\tthis.options.variable?.wght ?? DEFAULT_RANGES.weight,\n\t\t);\n\t\tif (weightRange) items.push(this.buildWeight(weightRange));\n\t\tif (this.controls.italic) items.push(this.buildItalic());\n\t\tif (this.controls.align) items.push(this.buildAlign());\n\t\tif (this.controls.wrap) items.push(this.buildWrap());\n\t\tif (this.controls.features) items.push(this.buildFeatures());\n\n\t\tif (items.length === 0) return null;\n\t\treturn el(\"div\", {\n\t\t\tclass: \"tt__controls\",\n\t\t\tattrs: { role: \"group\", \"aria-label\": \"Typography controls\" },\n\t\t\tchildren: items,\n\t\t});\n\t}\n\n\t// ---- generic control builders (no per-control copy-paste) -------------\n\n\tprivate buildSlider(\n\t\tkey: \"size\" | \"tracking\" | \"weight\",\n\t\tlabel: string,\n\t\trange: Range,\n\t\tvalue: number,\n\t\tunit: string,\n\t\tonInput: (value: number) => void,\n\t): HTMLElement {\n\t\tconst output = el(\"output\", { class: \"tt__value\", text: `${value}${unit}` });\n\t\tconst input = el(\"input\", {\n\t\t\tclass: `tt__slider tt__slider--${key}`,\n\t\t\tattrs: {\n\t\t\t\ttype: \"range\",\n\t\t\t\tmin: range.min,\n\t\t\t\tmax: range.max,\n\t\t\t\tstep: range.step ?? 1,\n\t\t\t\tvalue,\n\t\t\t\t\"aria-label\": label,\n\t\t\t},\n\t\t});\n\t\tconst handler = () => {\n\t\t\tconst v = Number(input.value);\n\t\t\toutput.textContent = `${v}${unit}`;\n\t\t\tonInput(v);\n\t\t\tthis.announce(`${label} ${v}${unit}`);\n\t\t};\n\t\tinput.addEventListener(\"input\", handler);\n\t\tthis.cleanups.push(() => input.removeEventListener(\"input\", handler));\n\t\tif (key === \"size\") this.sizeOutput = output;\n\t\treturn el(\"label\", {\n\t\t\tclass: `tt__control tt__control--${key}`,\n\t\t\tchildren: [el(\"span\", { class: \"tt__label\", text: label }), input, output],\n\t\t});\n\t}\n\n\tprivate buildSize(range: Range): HTMLElement {\n\t\tthis.state.size = clamp(this.state.size, range.min, range.max);\n\t\treturn this.buildSlider(\"size\", \"Size\", range, this.state.size, \"px\", (v) => {\n\t\t\tthis.state.size = v;\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t}\n\n\tprivate buildTracking(range: Range): HTMLElement {\n\t\tthis.state.tracking = clamp(this.state.tracking, range.min, range.max);\n\t\treturn this.buildSlider(\n\t\t\t\"tracking\",\n\t\t\t\"Tracking\",\n\t\t\trange,\n\t\t\tthis.state.tracking,\n\t\t\t\"em\",\n\t\t\t(v) => {\n\t\t\t\tthis.state.tracking = v;\n\t\t\t\tthis.applyStyles();\n\t\t\t\tthis.emitChange();\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate buildWeight(range: Range): HTMLElement {\n\t\tthis.state.weight = clamp(this.state.weight, range.min, range.max);\n\t\treturn this.buildSlider(\"weight\", \"Weight\", range, this.state.weight, \"\", (v) => {\n\t\t\tthis.state.weight = v;\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t}\n\n\tprivate buildToggle(\n\t\tkey: string,\n\t\tlabel: string,\n\t\tpressed: boolean,\n\t\tonToggle: (pressed: boolean) => void,\n\t): HTMLButtonElement {\n\t\tconst button = el(\"button\", {\n\t\t\tclass: `tt__toggle tt__toggle--${key}`,\n\t\t\ttext: label,\n\t\t\t// aria-pressed is a string-valued ARIA state and must always be present\n\t\t\t// (\"false\"), unlike boolean HTML attributes which are omitted when off.\n\t\t\tattrs: { type: \"button\", \"aria-pressed\": String(pressed) },\n\t\t});\n\t\tconst handler = () => {\n\t\t\tconst next = button.getAttribute(\"aria-pressed\") !== \"true\";\n\t\t\tbutton.setAttribute(\"aria-pressed\", String(next));\n\t\t\tonToggle(next);\n\t\t\tthis.announce(`${label} ${next ? \"on\" : \"off\"}`);\n\t\t};\n\t\tbutton.addEventListener(\"click\", handler);\n\t\tthis.cleanups.push(() => button.removeEventListener(\"click\", handler));\n\t\treturn button;\n\t}\n\n\tprivate buildItalic(): HTMLElement {\n\t\tconst button = this.buildToggle(\"italic\", \"Italic\", this.state.italic, (on) => {\n\t\t\tthis.state.italic = on;\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t\treturn el(\"div\", { class: \"tt__control\", children: [button] });\n\t}\n\n\tprivate buildWrap(): HTMLElement {\n\t\tconst button = this.buildToggle(\"wrap\", \"Wrap\", this.state.wrap, (on) => {\n\t\t\tthis.state.wrap = on;\n\t\t\tthis.textEl.setAttribute(\"aria-multiline\", String(on));\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t\treturn el(\"div\", { class: \"tt__control\", children: [button] });\n\t}\n\n\tprivate buildAlign(): HTMLElement {\n\t\tconst select = el(\"select\", {\n\t\t\tclass: \"tt__select tt__select--align\",\n\t\t\tattrs: { \"aria-label\": \"Alignment\" },\n\t\t\tchildren: ALIGNS.map((a) =>\n\t\t\t\tel(\"option\", {\n\t\t\t\t\ttext: a.charAt(0).toUpperCase() + a.slice(1),\n\t\t\t\t\tattrs: { value: a, selected: a === this.state.align },\n\t\t\t\t}),\n\t\t\t),\n\t\t});\n\t\tconst handler = () => {\n\t\t\tconst value = select.value as Align;\n\t\t\tif (ALIGNS.includes(value)) {\n\t\t\t\tthis.state.align = value;\n\t\t\t\tthis.applyStyles();\n\t\t\t\tthis.emitChange();\n\t\t\t\tthis.announce(`Alignment ${value}`);\n\t\t\t}\n\t\t};\n\t\tselect.addEventListener(\"change\", handler);\n\t\tthis.cleanups.push(() => select.removeEventListener(\"change\", handler));\n\t\treturn el(\"label\", {\n\t\t\tclass: \"tt__control tt__control--align\",\n\t\t\tchildren: [el(\"span\", { class: \"tt__label\", text: \"Align\" }), select],\n\t\t});\n\t}\n\n\tprivate buildFeatures(): HTMLElement {\n\t\tconst offered: readonly FeatureDef[] = Array.isArray(this.controls.features)\n\t\t\t? this.controls.features\n\t\t\t\t\t.filter(isKnownFeature)\n\t\t\t\t\t// Preserve each feature's real group/label from the registry rather\n\t\t\t\t\t// than flattening everything into \"Alternates\".\n\t\t\t\t\t.map((tag) => FEATURE_BY_TAG.get(tag) ?? { tag, label: featureLabel(tag), group: \"Alternates\" })\n\t\t\t: FEATURES;\n\n\t\tconst panelId = `tt-feat-${nextId()}`;\n\t\tconst toggle = el(\"button\", {\n\t\t\tclass: \"tt__toggle tt__toggle--features\",\n\t\t\ttext: \"Features\",\n\t\t\tattrs: {\n\t\t\t\ttype: \"button\",\n\t\t\t\t\"aria-haspopup\": \"true\",\n\t\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\t\"aria-controls\": panelId,\n\t\t\t},\n\t\t});\n\n\t\tconst checks = offered.map((f) => {\n\t\t\tconst input = el(\"input\", {\n\t\t\t\tattrs: { type: \"checkbox\", value: f.tag, checked: this.activeFeatures.has(f.tag) },\n\t\t\t});\n\t\t\tconst onChange = () => this.toggleFeature(f.tag, input.checked);\n\t\t\tinput.addEventListener(\"change\", onChange);\n\t\t\tthis.cleanups.push(() => input.removeEventListener(\"change\", onChange));\n\t\t\treturn el(\"label\", {\n\t\t\t\tclass: \"tt__feature\",\n\t\t\t\tchildren: [input, el(\"span\", { text: f.label })],\n\t\t\t});\n\t\t});\n\n\t\tconst panel = el(\"div\", {\n\t\t\tclass: \"tt__panel\",\n\t\t\tattrs: { id: panelId, role: \"group\", \"aria-label\": \"OpenType features\", hidden: true },\n\t\t\tchildren: checks,\n\t\t});\n\n\t\tconst wrapper = el(\"div\", {\n\t\t\tclass: \"tt__control tt__control--features\",\n\t\t\tchildren: [toggle, panel],\n\t\t});\n\n\t\tconst setOpen = (open: boolean) => {\n\t\t\ttoggle.setAttribute(\"aria-expanded\", String(open));\n\t\t\tpanel.toggleAttribute(\"hidden\", !open);\n\t\t\tif (open) {\n\t\t\t\tconst first = panel.querySelector<HTMLInputElement>(\"input\");\n\t\t\t\tfirst?.focus();\n\t\t\t}\n\t\t};\n\t\tconst onToggleClick = () => setOpen(toggle.getAttribute(\"aria-expanded\") !== \"true\");\n\t\tconst onKeydown = (e: KeyboardEvent) => {\n\t\t\tif (e.key === \"Escape\" && toggle.getAttribute(\"aria-expanded\") === \"true\") {\n\t\t\t\tsetOpen(false);\n\t\t\t\ttoggle.focus();\n\t\t\t}\n\t\t};\n\t\tconst onOutside = (e: MouseEvent) => {\n\t\t\tif (toggle.getAttribute(\"aria-expanded\") !== \"true\") return;\n\t\t\tif (!wrapper.contains(e.target as Node)) setOpen(false);\n\t\t};\n\t\ttoggle.addEventListener(\"click\", onToggleClick);\n\t\t// Escape is handled at the document level so it closes the panel no matter\n\t\t// where focus currently is, then restores focus to the toggle.\n\t\tdocument.addEventListener(\"keydown\", onKeydown);\n\t\tdocument.addEventListener(\"click\", onOutside);\n\t\tthis.cleanups.push(() => {\n\t\t\ttoggle.removeEventListener(\"click\", onToggleClick);\n\t\t\tdocument.removeEventListener(\"keydown\", onKeydown);\n\t\t\tdocument.removeEventListener(\"click\", onOutside);\n\t\t});\n\n\t\treturn wrapper;\n\t}\n\n\tprivate toggleFeature(tag: FeatureTag, on: boolean): void {\n\t\tif (on) this.activeFeatures.add(tag);\n\t\telse this.activeFeatures.delete(tag);\n\t\tthis.state.features = Array.from(this.activeFeatures);\n\t\tthis.applyStyles();\n\t\tthis.emitChange();\n\t\tthis.announce(`${featureLabel(tag)} ${on ? \"on\" : \"off\"}`);\n\t}\n\n\t// ---- behaviour -------------------------------------------------------\n\n\tprivate wireEditable(): void {\n\t\tconst handler = () => {\n\t\t\tthis.state.text = this.textEl.textContent ?? \"\";\n\t\t\tif (this.state.fit) this.fitter?.schedule();\n\t\t\tthis.emitChange();\n\t\t};\n\t\tthis.textEl.addEventListener(\"input\", handler);\n\t\tthis.cleanups.push(() => this.textEl.removeEventListener(\"input\", handler));\n\t}\n\n\tprivate setupFit(): void {\n\t\tif (!this.state.fit) return;\n\t\tconst range = resolveRange(this.controls.size, DEFAULT_RANGES.size) ?? DEFAULT_RANGES.size;\n\t\tthis.fitter = new Fitter(this.textEl, range.min, range.max);\n\t\tthis.fitter.start((size) => {\n\t\t\tthis.state.size = size;\n\t\t\tthis.typeEl.style.fontSize = `${size}px`;\n\t\t\tif (this.sizeOutput) this.sizeOutput.textContent = `${size}px`;\n\t\t});\n\t}\n\n\t/** Applies the full typographic state to the type element via element.style. */\n\tprivate applyStyles(): void {\n\t\tconst s = this.typeEl.style;\n\t\tconst family = this.options.fontFamily\n\t\t\t? `\"${this.options.fontFamily}\"${this.options.fallback ? `, ${this.options.fallback}` : \", sans-serif\"}`\n\t\t\t: (this.options.fallback ?? \"sans-serif\");\n\t\ts.fontFamily = family;\n\t\tif (!this.state.fit) s.fontSize = `${this.state.size}px`;\n\t\ts.letterSpacing = `${this.state.tracking}em`;\n\t\ts.fontStyle = this.state.italic ? \"italic\" : \"normal\";\n\t\ts.textAlign = this.state.align;\n\t\tthis.textEl.style.whiteSpace = this.state.wrap ? \"normal\" : \"nowrap\";\n\n\t\tif (this.options.variable?.wght) {\n\t\t\ts.fontVariationSettings = `\"wght\" ${this.state.weight}`;\n\t\t}\n\t\ts.fontWeight = String(this.state.weight);\n\n\t\tconst settings = featureSettings(this.activeFeatures);\n\t\ts.fontFeatureSettings = settings;\n\t\t// Older Safari needs the prefixed property; modern engines ignore it.\n\t\ts.setProperty(\"-webkit-font-feature-settings\", settings);\n\t}\n\n\tprivate announce(message: string): void {\n\t\tthis.liveEl.textContent = message;\n\t}\n\n\tprivate emitChange(): void {\n\t\tthis.options.onChange?.(this.getState());\n\t}\n}\n","// Main entry: re-exports the core plus a vanilla, declarative auto-initialiser\n// that reads `data-*` attributes — the modern replacement for the legacy\n// attribute-driven `.typeTester` markup (without eval or magic-word strings).\n\nimport { TypeTester } from \"./core/typeTester.js\";\nimport { isKnownFeature, type FeatureTag } from \"./core/opentype.js\";\nimport type { Align, ControlsConfig, Size, TypeTesterOptions } from \"./core/types.js\";\n\nexport * from \"./core/index.js\";\n\n/** Parses a comma/space list, e.g. data-features=\"smcp,onum\". */\nfunction parseList(value: string | null): string[] {\n\tif (!value) return [];\n\treturn value\n\t\t.split(/[\\s,]+/)\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean);\n}\n\n/** Parses the data-controls list into a ControlsConfig. */\nfunction parseControls(value: string | null): ControlsConfig {\n\tconst keys = parseList(value);\n\tconst config: ControlsConfig = {};\n\tfor (const key of keys) {\n\t\tif (key === \"size\") config.size = true;\n\t\telse if (key === \"tracking\") config.tracking = true;\n\t\telse if (key === \"weight\") config.weight = true;\n\t\telse if (key === \"italic\") config.italic = true;\n\t\telse if (key === \"align\") config.align = true;\n\t\telse if (key === \"wrap\") config.wrap = true;\n\t\telse if (key === \"features\") config.features = true;\n\t}\n\treturn config;\n}\n\n/** Builds options from a host element's dataset. */\nfunction optionsFromDataset(host: HTMLElement): TypeTesterOptions {\n\tconst d = host.dataset;\n\tconst sizeAttr = d.size;\n\tlet size: Size | undefined;\n\tif (sizeAttr === \"fit\") size = \"fit\";\n\telse if (sizeAttr != null && sizeAttr !== \"\") size = Number(sizeAttr);\n\n\tconst align = d.align as Align | undefined;\n\tconst features = parseList(d.features ?? null).filter((t): t is FeatureTag =>\n\t\tisKnownFeature(t),\n\t);\n\n\treturn {\n\t\ttext: d.text ?? host.textContent?.trim() ?? \"\",\n\t\tfontFamily: d.font,\n\t\tfallback: d.fallback,\n\t\tsize,\n\t\ttracking: d.tracking != null ? Number(d.tracking) : undefined,\n\t\tweight: d.weight != null ? Number(d.weight) : undefined,\n\t\titalic: d.italic != null ? d.italic !== \"false\" : undefined,\n\t\talign: align && [\"left\", \"center\", \"right\"].includes(align) ? align : undefined,\n\t\twrap: d.wrap != null ? d.wrap !== \"false\" : undefined,\n\t\tfeatures: features.length ? features : undefined,\n\t\teditable: d.editable !== \"false\",\n\t\tplaceholder: d.placeholder,\n\t\tariaLabel: d.ariaLabel,\n\t\tcontrols: parseControls(d.controls ?? null),\n\t};\n}\n\n/**\n * Initialises a single host element as a tester from its `data-*` attributes.\n */\nexport function createFromElement(host: HTMLElement): TypeTester {\n\treturn new TypeTester(host, optionsFromDataset(host));\n}\n\n/**\n * Finds and initialises every `[data-type-tester]` element within `root`\n * (default: document). Returns the created instances. Idempotent: elements\n * already initialised (marked with `data-tt-ready`) are skipped.\n */\nexport function autoInit(root: ParentNode = document): TypeTester[] {\n\tconst hosts = Array.from(\n\t\troot.querySelectorAll<HTMLElement>(\"[data-type-tester]\"),\n\t).filter((host) => host.dataset.ttReady !== \"true\");\n\treturn hosts.map((host) => {\n\t\thost.dataset.ttReady = \"true\";\n\t\treturn createFromElement(host);\n\t});\n}\n"]}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// Main entry: re-exports the core plus a vanilla, declarative auto-initialiser\n// that reads `data-*` attributes — the modern replacement for the legacy\n// attribute-driven `.typeTester` markup (without eval or magic-word strings).\n\nimport { TypeTester } from \"./core/typeTester.js\";\nimport { isKnownFeature, type FeatureTag } from \"./core/opentype.js\";\nimport type { Align, ControlsConfig, Size, TypeTesterOptions } from \"./core/types.js\";\n\nexport * from \"./core/index.js\";\n\n/** Parses a comma/space list, e.g. data-features=\"smcp,onum\". */\nfunction parseList(value: string | null): string[] {\n\tif (!value) return [];\n\treturn value\n\t\t.split(/[\\s,]+/)\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean);\n}\n\n/** Parses the data-controls list into a ControlsConfig. */\nfunction parseControls(value: string | null): ControlsConfig {\n\tconst keys = parseList(value);\n\tconst config: ControlsConfig = {};\n\tfor (const key of keys) {\n\t\tif (key === \"size\") config.size = true;\n\t\telse if (key === \"tracking\") config.tracking = true;\n\t\telse if (key === \"weight\") config.weight = true;\n\t\telse if (key === \"italic\") config.italic = true;\n\t\telse if (key === \"align\") config.align = true;\n\t\telse if (key === \"wrap\") config.wrap = true;\n\t\telse if (key === \"features\") config.features = true;\n\t}\n\treturn config;\n}\n\n/** Builds options from a host element's dataset. */\nfunction optionsFromDataset(host: HTMLElement): TypeTesterOptions {\n\tconst d = host.dataset;\n\tconst sizeAttr = d.size;\n\tlet size: Size | undefined;\n\tif (sizeAttr === \"fit\") size = \"fit\";\n\telse if (sizeAttr != null && sizeAttr !== \"\") size = Number(sizeAttr);\n\n\tconst align = d.align as Align | undefined;\n\tconst features = parseList(d.features ?? null).filter((t): t is FeatureTag =>\n\t\tisKnownFeature(t),\n\t);\n\n\treturn {\n\t\ttext: d.text ?? host.textContent?.trim() ?? \"\",\n\t\tfontFamily: d.font,\n\t\tfallback: d.fallback,\n\t\tsize,\n\t\ttracking: d.tracking != null ? Number(d.tracking) : undefined,\n\t\tweight: d.weight != null ? Number(d.weight) : undefined,\n\t\titalic: d.italic != null ? d.italic !== \"false\" : undefined,\n\t\talign: align && [\"left\", \"center\", \"right\"].includes(align) ? align : undefined,\n\t\twrap: d.wrap != null ? d.wrap !== \"false\" : undefined,\n\t\tfeatures: features.length ? features : undefined,\n\t\teditable: d.editable !== \"false\",\n\t\tplaceholder: d.placeholder,\n\t\tariaLabel: d.ariaLabel,\n\t\tcontrols: parseControls(d.controls ?? null),\n\t};\n}\n\n/**\n * Initialises a single host element as a tester from its `data-*` attributes.\n */\nexport function createFromElement(host: HTMLElement): TypeTester {\n\treturn new TypeTester(host, optionsFromDataset(host));\n}\n\n/**\n * Finds and initialises every `[data-type-tester]` element within `root`\n * (default: document). Returns the created instances. Idempotent: elements\n * already initialised (marked with `data-tt-ready`) are skipped.\n */\nexport function autoInit(root: ParentNode = document): TypeTester[] {\n\tconst hosts = Array.from(\n\t\troot.querySelectorAll<HTMLElement>(\"[data-type-tester]\"),\n\t).filter((host) => host.dataset.ttReady !== \"true\");\n\treturn hosts.map((host) => {\n\t\thost.dataset.ttReady = \"true\";\n\t\treturn createFromElement(host);\n\t});\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/dom.ts","../src/core/fit.ts","../src/core/opentype.ts","../src/core/typeTester.ts","../src/react/index.tsx"],"names":["useRef","useEffect","jsx"],"mappings":"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","file":"react.cjs","sourcesContent":["// Minimal, safe DOM construction helpers. All text is set via textContent and\n// all attributes via setAttribute, so untrusted values can never be interpreted\n// as HTML or script (no innerHTML, no eval).\n\n/** Properties accepted by {@link el}. */\nexport interface ElProps {\n\t/** Space-separated class names. */\n\tclass?: string;\n\t/** Text content (set via textContent — never parsed as HTML). */\n\ttext?: string;\n\t/** Attributes to set via setAttribute. Nullish values are skipped. */\n\tattrs?: Record<string, string | number | boolean | null | undefined>;\n\t/** Child nodes to append. */\n\tchildren?: Node[];\n}\n\n/**\n * Creates an element of the given tag with safe text/attribute/children\n * assignment. Returns the typed element.\n */\nexport function el<K extends keyof HTMLElementTagNameMap>(\n\ttag: K,\n\tprops: ElProps = {},\n): HTMLElementTagNameMap[K] {\n\tconst node = document.createElement(tag);\n\tif (props.class) node.className = props.class;\n\tif (props.text != null) node.textContent = props.text;\n\tif (props.attrs) {\n\t\tfor (const [name, value] of Object.entries(props.attrs)) {\n\t\t\tif (value == null || value === false) continue;\n\t\t\tnode.setAttribute(name, value === true ? \"\" : String(value));\n\t\t}\n\t}\n\tif (props.children) {\n\t\tfor (const child of props.children) node.appendChild(child);\n\t}\n\treturn node;\n}\n\n/** Clamps a number into the inclusive [min, max] range. */\nexport function clamp(value: number, min: number, max: number): number {\n\treturn Math.min(max, Math.max(min, value));\n}\n\n/**\n * Parses a numeric attribute/string, returning the fallback when the value is\n * missing or not a finite number. Prevents NaN leaking into the UI.\n */\nexport function toNumber(value: unknown, fallback: number): number {\n\tif (value == null || value === \"\") return fallback;\n\tconst n = typeof value === \"number\" ? value : Number(value);\n\treturn Number.isFinite(n) ? n : fallback;\n}\n","// Auto-fit engine. Replaces the legacy `bigtext` dependency.\n//\n// Sizing is computed by measuring the text once at a reference size in an\n// offscreen mirror, then scaling linearly: glyph advances and em-based\n// letter-spacing both scale linearly with font-size, so\n// fittedSize = referenceSize * containerWidth / measuredWidth\n// is exact and needs a single read + write per fit (no read/write thrashing,\n// no binary-search loop). Re-fitting is driven by ResizeObserver (so it tracks\n// container resizes) and rAF-debounced (so typing does not thrash layout).\n\nimport { clamp } from \"./dom.js\";\n\nconst REFERENCE_SIZE = 100;\n\n/** Font properties copied to the mirror so measurement matches the real text. */\nconst MIRROR_PROPS = [\n\t\"fontFamily\",\n\t\"fontWeight\",\n\t\"fontStyle\",\n\t\"fontStretch\",\n\t\"letterSpacing\",\n\t\"fontFeatureSettings\",\n\t\"fontVariationSettings\",\n\t\"textTransform\",\n] as const;\n\n/** Drives auto-fit sizing for a single text element. */\nexport class Fitter {\n\tprivate readonly target: HTMLElement;\n\tprivate readonly min: number;\n\tprivate readonly max: number;\n\tprivate mirror: HTMLSpanElement | null = null;\n\tprivate observer: ResizeObserver | null = null;\n\tprivate frame = 0;\n\tprivate onFit: ((size: number) => void) | null = null;\n\tprivate destroyed = false;\n\t// Last container width fitted against. Used to ignore ResizeObserver\n\t// notifications caused purely by height changes (a fit grows the line\n\t// height, which would otherwise re-trigger the observer in a loop).\n\tprivate lastWidth = -1;\n\n\t/**\n\t * @param target Element whose text is being fitted.\n\t * @param min Minimum font-size in px.\n\t * @param max Maximum font-size in px.\n\t */\n\tconstructor(target: HTMLElement, min: number, max: number) {\n\t\tthis.target = target;\n\t\tthis.min = min;\n\t\tthis.max = max;\n\t}\n\n\t/**\n\t * Starts observing the target's container and reports the fitted size via\n\t * `onFit` whenever it should change. Re-fits once fonts have loaded.\n\t */\n\tstart(onFit: (size: number) => void): void {\n\t\tthis.onFit = onFit;\n\t\tif (typeof ResizeObserver !== \"undefined\") {\n\t\t\tconst container = this.target.parentElement ?? this.target;\n\t\t\tthis.observer = new ResizeObserver(() => {\n\t\t\t\t// Only re-fit when the available width changes; height-only changes\n\t\t\t\t// are a consequence of fitting and must not feed back.\n\t\t\t\tif (container.clientWidth !== this.lastWidth) this.schedule();\n\t\t\t});\n\t\t\tthis.observer.observe(container);\n\t\t}\n\t\t// Re-fit after web fonts load so we never measure fallback metrics.\n\t\tconst fonts = (document as Document & { fonts?: FontFaceSet }).fonts;\n\t\tif (fonts?.ready) {\n\t\t\tfonts.ready.then(() => this.schedule()).catch(() => {});\n\t\t}\n\t\tthis.schedule();\n\t}\n\n\t/** Requests a fit on the next animation frame, coalescing rapid calls. */\n\tschedule(): void {\n\t\tif (this.destroyed) return;\n\t\tif (typeof requestAnimationFrame === \"undefined\") {\n\t\t\tthis.fit();\n\t\t\treturn;\n\t\t}\n\t\tif (this.frame) return;\n\t\tthis.frame = requestAnimationFrame(() => {\n\t\t\tthis.frame = 0;\n\t\t\tthis.fit();\n\t\t});\n\t}\n\n\t/** Measures the text and reports the fitted size. */\n\tprivate fit(): void {\n\t\tif (this.destroyed || !this.onFit) return;\n\t\tconst container = this.target.parentElement ?? this.target;\n\t\tconst width = container.clientWidth;\n\t\tif (width <= 0) return;\n\n\t\tconst mirror = this.ensureMirror();\n\t\tconst computed = getComputedStyle(this.target);\n\t\tfor (const prop of MIRROR_PROPS) {\n\t\t\tmirror.style[prop] = computed[prop];\n\t\t}\n\t\tmirror.style.fontSize = `${REFERENCE_SIZE}px`;\n\t\tmirror.textContent = this.target.textContent ?? \"\";\n\n\t\tconst measured = mirror.getBoundingClientRect().width;\n\t\tif (measured <= 0) return;\n\n\t\tthis.lastWidth = width;\n\t\tconst size = clamp((REFERENCE_SIZE * width) / measured, this.min, this.max);\n\t\tthis.onFit(Math.round(size * 100) / 100);\n\t}\n\n\t/** Lazily creates the shared offscreen measurement mirror. */\n\tprivate ensureMirror(): HTMLSpanElement {\n\t\tif (this.mirror) return this.mirror;\n\t\tconst mirror = document.createElement(\"span\");\n\t\tmirror.setAttribute(\"aria-hidden\", \"true\");\n\t\tObject.assign(mirror.style, {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: \"-9999px\",\n\t\t\ttop: \"0\",\n\t\t\tvisibility: \"hidden\",\n\t\t\twhiteSpace: \"nowrap\",\n\t\t\tpointerEvents: \"none\",\n\t\t});\n\t\tdocument.body.appendChild(mirror);\n\t\tthis.mirror = mirror;\n\t\treturn mirror;\n\t}\n\n\t/** Stops observing and removes the mirror. */\n\tdestroy(): void {\n\t\tthis.destroyed = true;\n\t\tif (this.frame) cancelAnimationFrame(this.frame);\n\t\tthis.observer?.disconnect();\n\t\tthis.observer = null;\n\t\tthis.mirror?.remove();\n\t\tthis.mirror = null;\n\t\tthis.onFit = null;\n\t}\n}\n","// OpenType feature registry: correct, spec-accurate tags, labels and grouping.\n// Replaces the legacy optValues table which had duplicate/ambiguous labels\n// (\"Contextual\" for both calt and clig, \"Historical\" for both hlig and hist)\n// and a mislabelled `nalt`.\n\n/** A four-character OpenType GSUB/GPOS feature tag. */\nexport type FeatureTag = string;\n\n/** Logical grouping used to organise features in a control UI. */\nexport type FeatureGroup =\n\t| \"Ligatures\"\n\t| \"Letter Case\"\n\t| \"Figures\"\n\t| \"Fractions\"\n\t| \"Alternates\"\n\t| \"Position\"\n\t| \"Stylistic Sets\";\n\n/** Definition of a single OpenType feature exposed by the tester. */\nexport interface FeatureDef {\n\t/** The OpenType feature tag, e.g. \"smcp\". */\n\ttag: FeatureTag;\n\t/** Human-readable, unambiguous label. */\n\tlabel: string;\n\t/** Group the feature belongs to. */\n\tgroup: FeatureGroup;\n}\n\n/**\n * The default, ordered list of supported OpenType features. Labels are unique\n * and follow the Microsoft OpenType feature registry naming.\n */\nexport const FEATURES: readonly FeatureDef[] = [\n\t// Ligatures\n\t{ tag: \"liga\", label: \"Standard Ligatures\", group: \"Ligatures\" },\n\t{ tag: \"dlig\", label: \"Discretionary Ligatures\", group: \"Ligatures\" },\n\t{ tag: \"hlig\", label: \"Historical Ligatures\", group: \"Ligatures\" },\n\t{ tag: \"clig\", label: \"Contextual Ligatures\", group: \"Ligatures\" },\n\n\t// Letter Case\n\t{ tag: \"smcp\", label: \"Small Capitals\", group: \"Letter Case\" },\n\t{ tag: \"c2sc\", label: \"Capitals to Small Capitals\", group: \"Letter Case\" },\n\t{ tag: \"case\", label: \"Case-Sensitive Forms\", group: \"Letter Case\" },\n\t{ tag: \"cpsp\", label: \"Capital Spacing\", group: \"Letter Case\" },\n\n\t// Figures\n\t{ tag: \"lnum\", label: \"Lining Figures\", group: \"Figures\" },\n\t{ tag: \"onum\", label: \"Oldstyle Figures\", group: \"Figures\" },\n\t{ tag: \"pnum\", label: \"Proportional Figures\", group: \"Figures\" },\n\t{ tag: \"tnum\", label: \"Tabular Figures\", group: \"Figures\" },\n\t{ tag: \"zero\", label: \"Slashed Zero\", group: \"Figures\" },\n\t{ tag: \"ordn\", label: \"Ordinals\", group: \"Figures\" },\n\n\t// Fractions\n\t{ tag: \"frac\", label: \"Fractions\", group: \"Fractions\" },\n\t{ tag: \"afrc\", label: \"Alternative Fractions\", group: \"Fractions\" },\n\n\t// Alternates\n\t{ tag: \"swsh\", label: \"Swash\", group: \"Alternates\" },\n\t{ tag: \"calt\", label: \"Contextual Alternates\", group: \"Alternates\" },\n\t{ tag: \"salt\", label: \"Stylistic Alternates\", group: \"Alternates\" },\n\t{ tag: \"hist\", label: \"Historical Forms\", group: \"Alternates\" },\n\t{ tag: \"nalt\", label: \"Alternate Annotation Forms\", group: \"Alternates\" },\n\n\t// Position\n\t{ tag: \"sups\", label: \"Superscript\", group: \"Position\" },\n\t{ tag: \"subs\", label: \"Subscript\", group: \"Position\" },\n\n\t// Stylistic Sets ss01–ss20\n\t...Array.from({ length: 20 }, (_, i): FeatureDef => {\n\t\tconst n = i + 1;\n\t\tconst tag = `ss${String(n).padStart(2, \"0\")}`;\n\t\treturn { tag, label: `Stylistic Set ${n}`, group: \"Stylistic Sets\" };\n\t}),\n];\n\n/** Lookup map from tag to its definition. */\nexport const FEATURE_BY_TAG: ReadonlyMap<FeatureTag, FeatureDef> = new Map(\n\tFEATURES.map((f) => [f.tag, f]),\n);\n\n/** Returns the label for a tag, falling back to the upper-cased tag itself. */\nexport function featureLabel(tag: FeatureTag): string {\n\treturn FEATURE_BY_TAG.get(tag)?.label ?? tag.toUpperCase();\n}\n\n/** True if the tag is a known, supported OpenType feature. */\nexport function isKnownFeature(tag: string): boolean {\n\treturn FEATURE_BY_TAG.has(tag);\n}\n\n/**\n * Builds a CSS `font-feature-settings` value from a set of active tags so that\n * multiple features compose (e.g. small caps + oldstyle figures) instead of\n * each selection overwriting the others. Returns \"normal\" when none are active.\n */\nexport function featureSettings(active: Iterable<FeatureTag>): string {\n\tconst tags = Array.from(active).filter(isKnownFeature);\n\tif (tags.length === 0) return \"normal\";\n\treturn tags.map((tag) => `\"${tag}\" 1`).join(\", \");\n}\n","// Framework-agnostic, dependency-free type tester.\n//\n// Replaces the legacy jQuery/jQuery-UI/bigtext widget. Key differences:\n// - No eval, no innerHTML with user data — DOM is built with createElement and\n// textContent, styles via element.style (no string injection).\n// - Native, accessible controls: <input type=range>, <button aria-pressed>,\n// <select>, and checkbox-based feature toggles with a focus-managed panel.\n// - OpenType features compose (multiple active at once).\n// - Auto-fit via ResizeObserver (tracks container resizes) instead of bigtext.\n// - No global state; each instance owns its DOM, listeners and observers and is\n// fully torn down by destroy().\n\nimport { Fitter } from \"./fit.js\";\nimport { clamp, el, toNumber } from \"./dom.js\";\nimport {\n\tFEATURES,\n\tFEATURE_BY_TAG,\n\ttype FeatureDef,\n\ttype FeatureTag,\n\tfeatureLabel,\n\tfeatureSettings,\n\tisKnownFeature,\n} from \"./opentype.js\";\nimport type {\n\tAlign,\n\tControlsConfig,\n\tRange,\n\tTypeTesterOptions,\n\tTypeTesterState,\n} from \"./types.js\";\n\n/** Default slider ranges, overridable per control. */\nconst DEFAULT_RANGES = {\n\tsize: { min: 8, max: 300, step: 1 },\n\ttracking: { min: -0.1, max: 0.5, step: 0.005 },\n\tweight: { min: 100, max: 900, step: 100 },\n} as const;\n\nconst ALIGNS: readonly Align[] = [\"left\", \"center\", \"right\"];\n\n// Monotonic counter for unique element ids (deterministic, collision-free even\n// for instances created within the same millisecond).\nlet idCounter = 0;\nfunction nextId(): number {\n\treturn ++idCounter;\n}\n\n/** Resolves a boolean|Range control config against a default range. */\nfunction resolveRange(value: boolean | Range | undefined, fallback: Range): Range | null {\n\tif (!value) return null;\n\tif (value === true) return { ...fallback };\n\treturn { min: value.min, max: value.max, step: value.step ?? fallback.step };\n}\n\n/** A type tester instance bound to a host element. */\nexport class TypeTester {\n\tprivate readonly host: HTMLElement;\n\tprivate readonly options: TypeTesterOptions;\n\tprivate readonly controls: ControlsConfig;\n\tprivate readonly state: TypeTesterState;\n\tprivate readonly activeFeatures = new Set<FeatureTag>();\n\tprivate readonly cleanups: Array<() => void> = [];\n\n\tprivate typeEl!: HTMLElement;\n\tprivate textEl!: HTMLElement;\n\tprivate liveEl!: HTMLElement;\n\tprivate sizeOutput: HTMLOutputElement | null = null;\n\tprivate fitter: Fitter | null = null;\n\n\t/**\n\t * @param host Element to render the tester into.\n\t * @param options Configuration; all fields optional.\n\t */\n\tconstructor(host: HTMLElement, options: TypeTesterOptions = {}) {\n\t\tthis.host = host;\n\t\tthis.options = options;\n\t\tthis.controls = options.controls ?? {};\n\n\t\tconst fit = options.size === \"fit\";\n\t\tfor (const tag of options.features ?? []) {\n\t\t\tif (isKnownFeature(tag)) this.activeFeatures.add(tag);\n\t\t}\n\t\tthis.state = {\n\t\t\ttext: options.text ?? \"\",\n\t\t\tsize: fit ? 0 : toNumber(options.size, 80),\n\t\t\tfit,\n\t\t\ttracking: toNumber(options.tracking, 0),\n\t\t\tweight: toNumber(options.weight, 400),\n\t\t\titalic: options.italic ?? false,\n\t\t\talign: options.align ?? \"left\",\n\t\t\twrap: options.wrap ?? true,\n\t\t\tfeatures: Array.from(this.activeFeatures),\n\t\t};\n\n\t\tthis.render();\n\t}\n\n\t/** Returns a snapshot of the current state. */\n\tgetState(): TypeTesterState {\n\t\treturn { ...this.state, features: Array.from(this.activeFeatures) };\n\t}\n\n\t/** Removes all DOM, listeners and observers created by this instance. */\n\tdestroy(): void {\n\t\tthis.fitter?.destroy();\n\t\tthis.fitter = null;\n\t\tfor (const off of this.cleanups.splice(0)) off();\n\t\tthis.host.replaceChildren();\n\t}\n\n\t// ---- rendering -------------------------------------------------------\n\n\tprivate render(): void {\n\t\tthis.host.classList.add(\"tt\");\n\n\t\tthis.textEl = el(\"div\", {\n\t\t\tclass: \"tt__text\",\n\t\t\ttext: this.state.text,\n\t\t\tattrs: {\n\t\t\t\trole: \"textbox\",\n\t\t\t\t\"aria-label\": this.options.ariaLabel ?? \"Sample text\",\n\t\t\t\t\"aria-multiline\": String(this.state.wrap),\n\t\t\t\tcontenteditable: this.options.editable !== false ? \"true\" : null,\n\t\t\t\tspellcheck: \"true\",\n\t\t\t\t\"data-placeholder\": this.options.placeholder ?? \"Type to test…\",\n\t\t\t},\n\t\t});\n\t\tthis.typeEl = el(\"div\", { class: \"tt__type\", children: [this.textEl] });\n\t\tconst stage = el(\"div\", { class: \"tt__stage\", children: [this.typeEl] });\n\n\t\tthis.liveEl = el(\"div\", {\n\t\t\tclass: \"tt__sr-only\",\n\t\t\tattrs: { \"aria-live\": \"polite\", \"aria-atomic\": \"true\" },\n\t\t});\n\n\t\tconst controls = this.buildControls();\n\t\tconst children: Node[] = [stage];\n\t\tif (controls) children.push(controls);\n\t\tchildren.push(this.liveEl);\n\t\tthis.host.replaceChildren(...children);\n\n\t\tif (this.options.editable !== false) this.wireEditable();\n\t\tthis.applyStyles();\n\t\tthis.setupFit();\n\t}\n\n\tprivate buildControls(): HTMLElement | null {\n\t\tconst items: Node[] = [];\n\t\tconst sizeRange = resolveRange(this.controls.size, DEFAULT_RANGES.size);\n\t\tif (sizeRange && !this.state.fit) items.push(this.buildSize(sizeRange));\n\t\tconst trackingRange = resolveRange(this.controls.tracking, DEFAULT_RANGES.tracking);\n\t\tif (trackingRange) items.push(this.buildTracking(trackingRange));\n\t\tconst weightRange = resolveRange(\n\t\t\tthis.controls.weight,\n\t\t\tthis.options.variable?.wght ?? DEFAULT_RANGES.weight,\n\t\t);\n\t\tif (weightRange) items.push(this.buildWeight(weightRange));\n\t\tif (this.controls.italic) items.push(this.buildItalic());\n\t\tif (this.controls.align) items.push(this.buildAlign());\n\t\tif (this.controls.wrap) items.push(this.buildWrap());\n\t\tif (this.controls.features) items.push(this.buildFeatures());\n\n\t\tif (items.length === 0) return null;\n\t\treturn el(\"div\", {\n\t\t\tclass: \"tt__controls\",\n\t\t\tattrs: { role: \"group\", \"aria-label\": \"Typography controls\" },\n\t\t\tchildren: items,\n\t\t});\n\t}\n\n\t// ---- generic control builders (no per-control copy-paste) -------------\n\n\tprivate buildSlider(\n\t\tkey: \"size\" | \"tracking\" | \"weight\",\n\t\tlabel: string,\n\t\trange: Range,\n\t\tvalue: number,\n\t\tunit: string,\n\t\tonInput: (value: number) => void,\n\t): HTMLElement {\n\t\tconst output = el(\"output\", { class: \"tt__value\", text: `${value}${unit}` });\n\t\tconst input = el(\"input\", {\n\t\t\tclass: `tt__slider tt__slider--${key}`,\n\t\t\tattrs: {\n\t\t\t\ttype: \"range\",\n\t\t\t\tmin: range.min,\n\t\t\t\tmax: range.max,\n\t\t\t\tstep: range.step ?? 1,\n\t\t\t\tvalue,\n\t\t\t\t\"aria-label\": label,\n\t\t\t},\n\t\t});\n\t\tconst handler = () => {\n\t\t\tconst v = Number(input.value);\n\t\t\toutput.textContent = `${v}${unit}`;\n\t\t\tonInput(v);\n\t\t\tthis.announce(`${label} ${v}${unit}`);\n\t\t};\n\t\tinput.addEventListener(\"input\", handler);\n\t\tthis.cleanups.push(() => input.removeEventListener(\"input\", handler));\n\t\tif (key === \"size\") this.sizeOutput = output;\n\t\treturn el(\"label\", {\n\t\t\tclass: `tt__control tt__control--${key}`,\n\t\t\tchildren: [el(\"span\", { class: \"tt__label\", text: label }), input, output],\n\t\t});\n\t}\n\n\tprivate buildSize(range: Range): HTMLElement {\n\t\tthis.state.size = clamp(this.state.size, range.min, range.max);\n\t\treturn this.buildSlider(\"size\", \"Size\", range, this.state.size, \"px\", (v) => {\n\t\t\tthis.state.size = v;\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t}\n\n\tprivate buildTracking(range: Range): HTMLElement {\n\t\tthis.state.tracking = clamp(this.state.tracking, range.min, range.max);\n\t\treturn this.buildSlider(\n\t\t\t\"tracking\",\n\t\t\t\"Tracking\",\n\t\t\trange,\n\t\t\tthis.state.tracking,\n\t\t\t\"em\",\n\t\t\t(v) => {\n\t\t\t\tthis.state.tracking = v;\n\t\t\t\tthis.applyStyles();\n\t\t\t\tthis.emitChange();\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate buildWeight(range: Range): HTMLElement {\n\t\tthis.state.weight = clamp(this.state.weight, range.min, range.max);\n\t\treturn this.buildSlider(\"weight\", \"Weight\", range, this.state.weight, \"\", (v) => {\n\t\t\tthis.state.weight = v;\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t}\n\n\tprivate buildToggle(\n\t\tkey: string,\n\t\tlabel: string,\n\t\tpressed: boolean,\n\t\tonToggle: (pressed: boolean) => void,\n\t): HTMLButtonElement {\n\t\tconst button = el(\"button\", {\n\t\t\tclass: `tt__toggle tt__toggle--${key}`,\n\t\t\ttext: label,\n\t\t\t// aria-pressed is a string-valued ARIA state and must always be present\n\t\t\t// (\"false\"), unlike boolean HTML attributes which are omitted when off.\n\t\t\tattrs: { type: \"button\", \"aria-pressed\": String(pressed) },\n\t\t});\n\t\tconst handler = () => {\n\t\t\tconst next = button.getAttribute(\"aria-pressed\") !== \"true\";\n\t\t\tbutton.setAttribute(\"aria-pressed\", String(next));\n\t\t\tonToggle(next);\n\t\t\tthis.announce(`${label} ${next ? \"on\" : \"off\"}`);\n\t\t};\n\t\tbutton.addEventListener(\"click\", handler);\n\t\tthis.cleanups.push(() => button.removeEventListener(\"click\", handler));\n\t\treturn button;\n\t}\n\n\tprivate buildItalic(): HTMLElement {\n\t\tconst button = this.buildToggle(\"italic\", \"Italic\", this.state.italic, (on) => {\n\t\t\tthis.state.italic = on;\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t\treturn el(\"div\", { class: \"tt__control\", children: [button] });\n\t}\n\n\tprivate buildWrap(): HTMLElement {\n\t\tconst button = this.buildToggle(\"wrap\", \"Wrap\", this.state.wrap, (on) => {\n\t\t\tthis.state.wrap = on;\n\t\t\tthis.textEl.setAttribute(\"aria-multiline\", String(on));\n\t\t\tthis.applyStyles();\n\t\t\tthis.emitChange();\n\t\t});\n\t\treturn el(\"div\", { class: \"tt__control\", children: [button] });\n\t}\n\n\tprivate buildAlign(): HTMLElement {\n\t\tconst select = el(\"select\", {\n\t\t\tclass: \"tt__select tt__select--align\",\n\t\t\tattrs: { \"aria-label\": \"Alignment\" },\n\t\t\tchildren: ALIGNS.map((a) =>\n\t\t\t\tel(\"option\", {\n\t\t\t\t\ttext: a.charAt(0).toUpperCase() + a.slice(1),\n\t\t\t\t\tattrs: { value: a, selected: a === this.state.align },\n\t\t\t\t}),\n\t\t\t),\n\t\t});\n\t\tconst handler = () => {\n\t\t\tconst value = select.value as Align;\n\t\t\tif (ALIGNS.includes(value)) {\n\t\t\t\tthis.state.align = value;\n\t\t\t\tthis.applyStyles();\n\t\t\t\tthis.emitChange();\n\t\t\t\tthis.announce(`Alignment ${value}`);\n\t\t\t}\n\t\t};\n\t\tselect.addEventListener(\"change\", handler);\n\t\tthis.cleanups.push(() => select.removeEventListener(\"change\", handler));\n\t\treturn el(\"label\", {\n\t\t\tclass: \"tt__control tt__control--align\",\n\t\t\tchildren: [el(\"span\", { class: \"tt__label\", text: \"Align\" }), select],\n\t\t});\n\t}\n\n\tprivate buildFeatures(): HTMLElement {\n\t\tconst offered: readonly FeatureDef[] = Array.isArray(this.controls.features)\n\t\t\t? this.controls.features\n\t\t\t\t\t.filter(isKnownFeature)\n\t\t\t\t\t// Preserve each feature's real group/label from the registry rather\n\t\t\t\t\t// than flattening everything into \"Alternates\".\n\t\t\t\t\t.map((tag) => FEATURE_BY_TAG.get(tag) ?? { tag, label: featureLabel(tag), group: \"Alternates\" })\n\t\t\t: FEATURES;\n\n\t\tconst panelId = `tt-feat-${nextId()}`;\n\t\tconst toggle = el(\"button\", {\n\t\t\tclass: \"tt__toggle tt__toggle--features\",\n\t\t\ttext: \"Features\",\n\t\t\tattrs: {\n\t\t\t\ttype: \"button\",\n\t\t\t\t\"aria-haspopup\": \"true\",\n\t\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\t\"aria-controls\": panelId,\n\t\t\t},\n\t\t});\n\n\t\tconst checks = offered.map((f) => {\n\t\t\tconst input = el(\"input\", {\n\t\t\t\tattrs: { type: \"checkbox\", value: f.tag, checked: this.activeFeatures.has(f.tag) },\n\t\t\t});\n\t\t\tconst onChange = () => this.toggleFeature(f.tag, input.checked);\n\t\t\tinput.addEventListener(\"change\", onChange);\n\t\t\tthis.cleanups.push(() => input.removeEventListener(\"change\", onChange));\n\t\t\treturn el(\"label\", {\n\t\t\t\tclass: \"tt__feature\",\n\t\t\t\tchildren: [input, el(\"span\", { text: f.label })],\n\t\t\t});\n\t\t});\n\n\t\tconst panel = el(\"div\", {\n\t\t\tclass: \"tt__panel\",\n\t\t\tattrs: { id: panelId, role: \"group\", \"aria-label\": \"OpenType features\", hidden: true },\n\t\t\tchildren: checks,\n\t\t});\n\n\t\tconst wrapper = el(\"div\", {\n\t\t\tclass: \"tt__control tt__control--features\",\n\t\t\tchildren: [toggle, panel],\n\t\t});\n\n\t\tconst setOpen = (open: boolean) => {\n\t\t\ttoggle.setAttribute(\"aria-expanded\", String(open));\n\t\t\tpanel.toggleAttribute(\"hidden\", !open);\n\t\t\tif (open) {\n\t\t\t\tconst first = panel.querySelector<HTMLInputElement>(\"input\");\n\t\t\t\tfirst?.focus();\n\t\t\t}\n\t\t};\n\t\tconst onToggleClick = () => setOpen(toggle.getAttribute(\"aria-expanded\") !== \"true\");\n\t\tconst onKeydown = (e: KeyboardEvent) => {\n\t\t\tif (e.key === \"Escape\" && toggle.getAttribute(\"aria-expanded\") === \"true\") {\n\t\t\t\tsetOpen(false);\n\t\t\t\ttoggle.focus();\n\t\t\t}\n\t\t};\n\t\tconst onOutside = (e: MouseEvent) => {\n\t\t\tif (toggle.getAttribute(\"aria-expanded\") !== \"true\") return;\n\t\t\tif (!wrapper.contains(e.target as Node)) setOpen(false);\n\t\t};\n\t\ttoggle.addEventListener(\"click\", onToggleClick);\n\t\t// Escape is handled at the document level so it closes the panel no matter\n\t\t// where focus currently is, then restores focus to the toggle.\n\t\tdocument.addEventListener(\"keydown\", onKeydown);\n\t\tdocument.addEventListener(\"click\", onOutside);\n\t\tthis.cleanups.push(() => {\n\t\t\ttoggle.removeEventListener(\"click\", onToggleClick);\n\t\t\tdocument.removeEventListener(\"keydown\", onKeydown);\n\t\t\tdocument.removeEventListener(\"click\", onOutside);\n\t\t});\n\n\t\treturn wrapper;\n\t}\n\n\tprivate toggleFeature(tag: FeatureTag, on: boolean): void {\n\t\tif (on) this.activeFeatures.add(tag);\n\t\telse this.activeFeatures.delete(tag);\n\t\tthis.state.features = Array.from(this.activeFeatures);\n\t\tthis.applyStyles();\n\t\tthis.emitChange();\n\t\tthis.announce(`${featureLabel(tag)} ${on ? \"on\" : \"off\"}`);\n\t}\n\n\t// ---- behaviour -------------------------------------------------------\n\n\tprivate wireEditable(): void {\n\t\tconst handler = () => {\n\t\t\tthis.state.text = this.textEl.textContent ?? \"\";\n\t\t\tif (this.state.fit) this.fitter?.schedule();\n\t\t\tthis.emitChange();\n\t\t};\n\t\tthis.textEl.addEventListener(\"input\", handler);\n\t\tthis.cleanups.push(() => this.textEl.removeEventListener(\"input\", handler));\n\t}\n\n\tprivate setupFit(): void {\n\t\tif (!this.state.fit) return;\n\t\tconst range = resolveRange(this.controls.size, DEFAULT_RANGES.size) ?? DEFAULT_RANGES.size;\n\t\tthis.fitter = new Fitter(this.textEl, range.min, range.max);\n\t\tthis.fitter.start((size) => {\n\t\t\tthis.state.size = size;\n\t\t\tthis.typeEl.style.fontSize = `${size}px`;\n\t\t\tif (this.sizeOutput) this.sizeOutput.textContent = `${size}px`;\n\t\t});\n\t}\n\n\t/** Applies the full typographic state to the type element via element.style. */\n\tprivate applyStyles(): void {\n\t\tconst s = this.typeEl.style;\n\t\tconst family = this.options.fontFamily\n\t\t\t? `\"${this.options.fontFamily}\"${this.options.fallback ? `, ${this.options.fallback}` : \", sans-serif\"}`\n\t\t\t: (this.options.fallback ?? \"sans-serif\");\n\t\ts.fontFamily = family;\n\t\tif (!this.state.fit) s.fontSize = `${this.state.size}px`;\n\t\ts.letterSpacing = `${this.state.tracking}em`;\n\t\ts.fontStyle = this.state.italic ? \"italic\" : \"normal\";\n\t\ts.textAlign = this.state.align;\n\t\tthis.textEl.style.whiteSpace = this.state.wrap ? \"normal\" : \"nowrap\";\n\n\t\tif (this.options.variable?.wght) {\n\t\t\ts.fontVariationSettings = `\"wght\" ${this.state.weight}`;\n\t\t}\n\t\ts.fontWeight = String(this.state.weight);\n\n\t\tconst settings = featureSettings(this.activeFeatures);\n\t\ts.fontFeatureSettings = settings;\n\t\t// Older Safari needs the prefixed property; modern engines ignore it.\n\t\ts.setProperty(\"-webkit-font-feature-settings\", settings);\n\t}\n\n\tprivate announce(message: string): void {\n\t\tthis.liveEl.textContent = message;\n\t}\n\n\tprivate emitChange(): void {\n\t\tthis.options.onChange?.(this.getState());\n\t}\n}\n","// React wrapper around the framework-agnostic TypeTester core. React is a peer\n// dependency, externalised at build time, so the core stays dependency-free.\n\nimport { useEffect, useRef } from \"react\";\nimport { TypeTester } from \"../core/typeTester.js\";\nimport type { TypeTesterOptions, TypeTesterState } from \"../core/types.js\";\n\n/** Props for {@link TypeTesterComponent}. Mirrors {@link TypeTesterOptions}. */\nexport interface TypeTesterProps extends TypeTesterOptions {\n\t/** Class applied to the host element. */\n\tclassName?: string;\n}\n\n/**\n * Renders a {@link TypeTester} into a host div. The instance is recreated when\n * any structural option changes and is always torn down on unmount.\n */\nexport function TypeTesterComponent(props: TypeTesterProps): JSX.Element {\n\tconst { className, onChange, ...options } = props;\n\tconst hostRef = useRef<HTMLDivElement>(null);\n\t// Keep the latest onChange without forcing a tester rebuild on each render.\n\tconst onChangeRef = useRef<((state: TypeTesterState) => void) | undefined>(onChange);\n\tonChangeRef.current = onChange;\n\n\t// Serialise structural options so the effect only re-runs on real changes.\n\tconst key = JSON.stringify(options);\n\n\tuseEffect(() => {\n\t\tconst host = hostRef.current;\n\t\tif (!host) return;\n\t\tconst instance = new TypeTester(host, {\n\t\t\t...options,\n\t\t\tonChange: (state) => onChangeRef.current?.(state),\n\t\t});\n\t\treturn () => instance.destroy();\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [key]);\n\n\treturn <div ref={hostRef} className={className} />;\n}\n\nexport { TypeTester } from \"../core/typeTester.js\";\nexport type {\n\tAlign,\n\tControlsConfig,\n\tRange,\n\tSize,\n\tTypeTesterOptions,\n\tTypeTesterState,\n\tVariableConfig,\n} from \"../core/types.js\";\nexport type { FeatureTag } from \"../core/opentype.js\";\n"]}
package/dist/react.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/index.tsx"],"names":[],"mappings":";;;;;AAiBO,SAAS,oBAAoB,KAAA,EAAqC;AACxE,EAAA,MAAM,EAAE,SAAA,EAAW,QAAA,EAAU,GAAG,SAAQ,GAAI,KAAA;AAC5C,EAAA,MAAM,OAAA,GAAU,OAAuB,IAAI,CAAA;AAE3C,EAAA,MAAM,WAAA,GAAc,OAAuD,QAAQ,CAAA;AACnF,EAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AAGtB,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA;AAElC,EAAA,SAAA,CAAU,MAAM;AACf,IAAA,MAAM,OAAO,OAAA,CAAQ,OAAA;AACrB,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,QAAA,GAAW,IAAI,UAAA,CAAW,IAAA,EAAM;AAAA,MACrC,GAAG,OAAA;AAAA,MACH,QAAA,EAAU,CAAC,KAAA,KAAU,WAAA,CAAY,UAAU,KAAK;AAAA,KAChD,CAAA;AACD,IAAA,OAAO,MAAM,SAAS,OAAA,EAAQ;AAAA,EAE/B,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,OAAA,EAAS,SAAA,EAAsB,CAAA;AACjD","file":"react.js","sourcesContent":["// React wrapper around the framework-agnostic TypeTester core. React is a peer\n// dependency, externalised at build time, so the core stays dependency-free.\n\nimport { useEffect, useRef } from \"react\";\nimport { TypeTester } from \"../core/typeTester.js\";\nimport type { TypeTesterOptions, TypeTesterState } from \"../core/types.js\";\n\n/** Props for {@link TypeTesterComponent}. Mirrors {@link TypeTesterOptions}. */\nexport interface TypeTesterProps extends TypeTesterOptions {\n\t/** Class applied to the host element. */\n\tclassName?: string;\n}\n\n/**\n * Renders a {@link TypeTester} into a host div. The instance is recreated when\n * any structural option changes and is always torn down on unmount.\n */\nexport function TypeTesterComponent(props: TypeTesterProps): JSX.Element {\n\tconst { className, onChange, ...options } = props;\n\tconst hostRef = useRef<HTMLDivElement>(null);\n\t// Keep the latest onChange without forcing a tester rebuild on each render.\n\tconst onChangeRef = useRef<((state: TypeTesterState) => void) | undefined>(onChange);\n\tonChangeRef.current = onChange;\n\n\t// Serialise structural options so the effect only re-runs on real changes.\n\tconst key = JSON.stringify(options);\n\n\tuseEffect(() => {\n\t\tconst host = hostRef.current;\n\t\tif (!host) return;\n\t\tconst instance = new TypeTester(host, {\n\t\t\t...options,\n\t\t\tonChange: (state) => onChangeRef.current?.(state),\n\t\t});\n\t\treturn () => instance.destroy();\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [key]);\n\n\treturn <div ref={hostRef} className={className} />;\n}\n\nexport { TypeTester } from \"../core/typeTester.js\";\nexport type {\n\tAlign,\n\tControlsConfig,\n\tRange,\n\tSize,\n\tTypeTesterOptions,\n\tTypeTesterState,\n\tVariableConfig,\n} from \"../core/types.js\";\nexport type { FeatureTag } from \"../core/opentype.js\";\n"]}