@phun-ky/speccer
Version:
A script to annotate, show spacing specs and to display typography information in documentation/website on HTML elements
534 lines (528 loc) • 14.6 kB
TypeScript
/**
* Extends the global Window interface to add custom properties.
*/
declare global {
interface Window {
/**
* Represents the DrawSVGCurlyBracket class for drawing curly brackets.
*/
DrawSVGCurlyBracket: any;
/**
* Represents the DrawCircle class for drawing circles.
*/
DrawCircle: any;
/**
* Represents the DrawSVGLine class for drawing lines.
*/
DrawSVGLine: any;
/**
* Represents the speccer object for additional functionality.
*/
speccer: any;
/**
* Represents the custom literals to be used.
* 
* @example
* ```js
* window.SPECCER_LITERALS = [あ,い,う,え,お,か,き,く,け,こ,さ,し,す,せ,そ,た,ち,つ,て,と,な,に,ぬ,ね,の,は,ひ,ふ,へ,ほ,ま,み,む,め,も,や,ゆ,よ,ら,り,る,れ,ろ,わ,を];
* speccer();
* ```
*/
SPECCER_LITERALS: string[];
}
}
/**
* Initializes the accessibility elements on the document.
*
* This feature will annotate or highlight accessibility areas like landmarks and region. It can also display tab stops/sequence and any keyboard shortcuts assigned
*
* 
*
* @example
*
* Use the following code, either for html or js:
*
* ```html
* <div
* data-speccer="a11y [shortcuts|tabstops|landmark|headings|autocomplete]"
* class="…"
* >
* …
* </div>
* ```
*
* ```ts
* const targetElement = document.getElementById('target');
* a11y(targetElement);
* ```
*
*
*/
declare const a11y: () => void;
type SpeccerFunctionType = () => void;
type SpeccerFeatureType = 'pin' | 'grid' | 'mark' | 'typography' | 'measure' | 'spacing';
type SpeccerPositionType = 'top' | 'left' | 'right' | 'bottom';
/**
* Configuration object that tells Speccer **what** to render and **how** to render it.
*
* ### Feature flags
* Only one top-level {@link SpeccerOptionsInterface.type | type} is active at a time
* (`"pin" | "grid" | "mark" | "typography" | "measure" | "spacing"`). The corresponding
* nested section (e.g. `pin`, `grid`, `typography`, `measure`, `spacing`) becomes relevant
* and other sections are typically omitted.
*
* @example Basic "pin" annotation
* ```ts
* import type { SpeccerOptionsInterface } from "@phun-ky/speccer";
*
* const options: SpeccerOptionsInterface = {
* slug: "pinBracketSubtle",
* position: "left",
* type: "pin",
* pin: {
* bracket: true,
* enclose: false,
* subtle: true,
* parent: false,
* text: false,
* useSVGLine: true,
* useCurlyBrackets: false
* }
* };
* ```
*
* @example Measure width, slim style
* ```ts
* const options: SpeccerOptionsInterface = {
* slug: "measureWidthSlim",
* position: "bottom",
* type: "measure",
* measure: {
* slim: true,
* height: false,
* width: true
* }
* };
* ```
*
* @example Typography with syntax highlighting
* ```ts
* const options: SpeccerOptionsInterface = {
* slug: "codeSample",
* position: "right",
* type: "typography",
* typography: {
* useSyntaxHighlighting: true
* }
* };
* ```
*
* @example Spacing overlays (margin vs. padding vs. both)
* ```ts
* const marginOnly: SpeccerOptionsInterface = {
* slug: "spacingMargin",
* position: "top",
* type: "spacing",
* spacing: {
* margin: true,
* padding: false,
* both: false,
* bound: false
* }
* };
*
* const bothWithBounds: SpeccerOptionsInterface = {
* slug: "spacingBothBound",
* position: "top",
* type: "spacing",
* spacing: {
* margin: false,
* padding: false,
* both: true,
* bound: true
* }
* };
* ```
*
* @example Grid overlays (rows, columns, or both)
* ```ts
* const gridBoth: SpeccerOptionsInterface = {
* slug: "gridBoth",
* position: "bottom",
* type: "grid",
* grid: {
* toggle: "both", // allowed: "rows" | "columns" | "both"
* both: true,
* rows: false,
* columns: false
* }
* };
*
* const gridRows: SpeccerOptionsInterface = {
* slug: "gridRows",
* position: "bottom",
* type: "grid",
* grid: {
* toggle: "rows",
* both: false,
* rows: true,
* columns: false
* }
* };
* ```
*/
interface SpeccerOptionsInterface {
/**
* Machine-readable identifier for this option set.
*
* @remarks
* When produced by {@link getOptions}, this is derived from the input `areaString`
* using a camel-casing strategy (e.g., `"pin bracket subtle"` → `"pinBracketSubtle"`).
*/
slug: string;
/**
* Preferred anchor side for rendering or label placement.
*
* @remarks
* Use to hint where visual affordances (e.g., labels, callouts) should appear
* relative to the annotated element.
*/
position: SpeccerPositionType;
/**
* Which Speccer feature this option set activates.
*
* @remarks
* This field determines which nested section is relevant (`pin`, `grid`, `mark`,
* `typography`, `measure`, or `spacing`). Only one feature is active at a time.
*/
type: SpeccerFeatureType;
/**
* Options for the `"pin"` feature.
*
* @remarks
* Present only when {@link SpeccerOptionsInterface.type | type} is `"pin"`.
* Each flag toggles a specific pin decoration or behavior.
*/
pin?: {
/** Draw bracket-style markers around the pin. */
bracket: boolean;
/** Enclose the pin target (e.g., a boxed/outlined emphasis). */
enclose: boolean;
/** Reduce visual weight for a subtler presentation. */
subtle: boolean;
/** Indicate that the pin references a parent container/element. */
parent: boolean;
/** Render an inline text label along with the pin. */
text: boolean;
/** Use an SVG line primitive instead of a DOM line. */
useSVGLine: boolean;
/** Use curly brackets for bracketed pins instead of straight brackets. */
useCurlyBrackets: boolean;
};
/**
* Options for the `"measure"` feature.
*
* @remarks
* Present only when {@link SpeccerOptionsInterface.type | type} is `"measure"`.
* Use `height` and/or `width` to select the axis to measure; `slim` switches to
* a compact rendering style for tight layouts.
*/
measure?: {
/** Use a compact (thinner) measurement style. */
slim: boolean;
/** Show a vertical measurement (element height). */
height: boolean;
/** Show a horizontal measurement (element width). */
width: boolean;
};
/**
* Options for the `"typography"` feature.
*
* @remarks
* Present only when {@link SpeccerOptionsInterface.type | type} is `"typography"`.
* Enables code-like styling or syntax coloring when appropriate.
*/
typography?: {
/** Enable syntax highlighting for textual samples. */
useSyntaxHighlighting: boolean;
};
/**
* Options for the `"spacing"` feature.
*
* @remarks
* Present only when {@link SpeccerOptionsInterface.type | type} is `"spacing"`.
* Exactly one of `margin`, `padding`, or `both` is typically `true`.
* `bound` can be used to visualize the outer bound in addition to spacing.
*/
spacing?: {
/** Visualize the element's margins. */
margin?: boolean;
/** Visualize the element's padding. */
padding?: boolean;
/**
* Visualize both margin and padding in a combined overlay.
* @remarks Mutually exclusive with `margin` and `padding` where applicable.
*/
both?: boolean;
/**
* Emphasize the bounding outline of the target in addition to spacing.
* @remarks Often used to show the element's overall occupied box.
*/
bound?: boolean;
};
/**
* Options for the `"grid"` feature.
*
* @remarks
* Present only when {@link SpeccerOptionsInterface.type | type} is `"grid"`.
* `toggle` indicates the primary axis selection and should be `"rows" | "columns" | "both"`.
* The convenience flags (`both`, `rows`, `columns`) mirror the current state for easy checks.
*/
grid?: {
/**
* Controls which grid axes are active.
* @remarks Allowed values: `"rows" | "columns" | "both"`.
*/
toggle: string;
/** Convenience flag set when both rows and columns are active. */
both?: boolean;
/** Convenience flag set when only rows are active. */
rows?: boolean;
/** Convenience flag set when only columns are active. */
columns?: boolean;
};
}
/**
* Remove a speccer element by removing associated elements and SVG paths.
*
* This function removes any speccer elements linked to the specified element and
* also removes any SVG paths that might be associated with it.
*
* @param {HTMLElement} el - The HTML element to unpin.
* @returns {void} This function does not return a value.
*
* @example
* ```ts
* const element = document.getElementById('my-element');
* if (element) {
* removeSpeccerElement(element);
* }
* ```
*/
declare const removeSpeccerElement: (el: HTMLElement) => void;
/**
* This feature will highlight the grid spacing in a `display: grid;` element.
*
* 
*
* @example
*
* Use the following code, either for html or js:
*
* ```html
* <div
* data-speccer="grid [columns|rows]"
* class="…"
* >
* …
* </div>
* ```
*
* ```ts
* const targetElement = document.getElementById('target');
* const options = {
* type: 'grid',
* grid: {
* toggle: 'both'
* }
* };
*
* grid(targetElement, options);
* ```
*
*/
declare const grid: {
create: (targetElement: HTMLElement, options?: SpeccerOptionsInterface) => Promise<void>;
element: (targetElement: HTMLElement, options?: SpeccerOptionsInterface) => Promise<void>;
};
/**
* This feature highlights the spacing of an element.
*
* 
* *
* @example
*
* Use the following code, either for html or js:
*
* ```html
* <div
* data-speccer="spacing [padding|margin][bound]"
* class="…"
* >
* …
* </div>
* ```
* ```ts
* const targetElement = document.getElementById('target');
* element(targetElement);
* ```
*/
declare const spacing: {
create: (text?: string | number, tag?: string) => HTMLElement;
element: (targetElement: HTMLElement, options?: SpeccerOptionsInterface) => Promise<void>;
};
/**
* This feature annotate or highlight the anatomy of an element.
*
* 
*
* In your component examples, use the following attribute. Remember to use the `data-speccer="pin-area"`-attribute on a parent element to scope the marking.
*
* @example
* ```html
* <div data-speccer="pin-area">
* <div
* data-speccer="pin [bracket [curly] |enclose] [left|right|top|bottom]"
* class="..."
* ></div>
* </div>
* ```
*
*/
declare const pin: {
createPinElement: (content: string | undefined, options: SpeccerOptionsInterface, id?: string, n?: string) => HTMLElement;
pinElement: (targetElement: HTMLElement, parentElement: HTMLElement, content: string, options: SpeccerOptionsInterface) => Promise<string | undefined>;
pinElements: (sectionElement: HTMLElement, options?: SpeccerOptionsInterface) => Promise<void>;
};
/**
* This feature measures given element
*
* 
*
* @example
*
* Use the following code, either for html or js:
*
* ```html
* <div
* data-speccer="measure [height left|right] | [width top|bottom]"
* class="..."
* >
* …
* </div>
* ```
*
* ```ts
* const targetElement = document.getElementById('target');
* const options = {
* position: 'right',
* measure: {
* height: true
* }
* };
*
* measure(targetElement, options);
* ```
*
*/
declare const measure: {
create: (text: string | number | undefined, options: SpeccerOptionsInterface, id: string, tag?: string) => HTMLElement;
element: (targetElement: HTMLElement, options?: SpeccerOptionsInterface) => Promise<void>;
};
/**
* This feature marks given element
*
* 
*
* @example
*
* Use the following code, either for html or js:
*
* ```html
* <div
* data-speccer="mark"
* class="..."
* >
* …
* </div>
* ```
*
* ```ts
* const targetElement = document.getElementById('target');
* const options = {
* type: 'mark'
* };
*
* mark(targetElement, options);
* ```
*
*/
declare const mark: {
create: (id: string, n?: string) => HTMLElement;
element: (targetElement: HTMLElement) => Promise<void>;
};
/**
* This feature presents typography
*
* 
*
* @example
*
* Use the following code, either for html or js:
*
* ```html
* <div
* data-speccer="typography [top|right|bottom|left] [syntax]"
* class="..."
* >
* …
* </div>
* ```
*
* ```ts
* const targetElement = document.getElementById('target');
* const options = {
* position: 'right',
* type: 'typography',
* typography: {
* useSyntaxHighlighting: false
* }
* };
*
* typography(targetElement, options);
* ```
*
*/
declare const typography: {
create: (html: string, options: SpeccerOptionsInterface, id: string) => HTMLElement;
element: (targetElement: HTMLElement, options?: SpeccerOptionsInterface) => Promise<void>;
};
/**
* The available modes to run SPECCER with
*
*/
declare const modes: {
dom: (speccer: SpeccerFunctionType) => void;
lazy: () => void;
manual: (speccer: SpeccerFunctionType) => void;
activate: (speccer: SpeccerFunctionType) => void;
};
/**
*
* @example
* ```typescript
* import '@phun-ky/speccer/dist/speccer.min.css';
* import speccer from '@phun-ky/speccer';
*
* // do stuff
* speccer();
* ```
* @example
* ```html
* <link rel="stylesheet" href="../path/to/speccer.min.css" />
* <script src="../path/to/speccer.js"></script>
* ```
*/
declare const speccer: () => void;
export { a11y, speccer as default, grid, mark, measure, modes, pin, removeSpeccerElement, spacing, typography };
export type { SpeccerFunctionType, SpeccerOptionsInterface };