JSDoc Example: Emotion
JSDoc Example: Emotion
JSDoc Example: Emotion
As mentioned, I don't use TypeScript, but write
many of my apps in pure Javascript.
As such, in order to describe types,
I use JSDoc extensively in many of my codebases.
Hoping someone would find it interesting,
I have a several pages presenting
JSDoc examples as to how you could effectively
utilize JSDoc's classical doctrine syntax.
Here is one of the modules that I currently use
on my website, specifically,
the Emotion context module.
/**
* A module providing a context for sharing an Emotion instance
* throughout components.<br />
* The Emotion instance is created internally inside the Provider
* and exposed to consumers through a `getter` function,<br />
* allowing components to use utilities like `cx` and `css`
* without importing Emotion directly.<br />
* Note: Only the `getter` is exposed; the `setter` is kept internal.
*
* @module contexts/Emotion
*/
import {
createContext,
createSignal,
createEffect,
} from 'solid-js';
import createEmotion from '@emotion/css/create-instance';
/**
* This is the actual Emotion instance created internally
* by `createInstance()` within Provider, and is exposed
* only via `getter`.
*
* I could have done `import('@emotion/css/create-instance~Emotion`'),
* but JSDoc does not generate for _external_ types.<br />
* Thus, using `@typedef` so that it generates documents.
*
* I also wanted `Cx` and `Css` to be documented, but JSDoc does not do that<br />
* because `@callback` means it has no actual functions corresponding to the type.<br />
* Therefore, I have `Cx` and `Css` as properties here so that generates documents.
*
* @typedef EmotionEntity
* @type {Object}
* @property {Cx} cx - Combines class names.
* @property {Css} css - Generates CSS class names.
* @see {@link https://github.com/emotion-js/emotion/blob/85772c33ecb01c70bc8afafa627c9fb7140b593c/packages/css/src/create-instance.ts#L47|@emotion/css/create-instance.Emotion}
*/
/**
* `getter` returning Emotion (or undefined).<br />
* Backed by `Accessor<EmotionEntity>` (SolidJS).
* @typedef {import("solid-js").Accessor<EmotionEntity>} EmotionGetter
*/
/**
* `setter` updating the Emotion instance.<br />
* Backed by `Setter<EmotionEntity>` (SolidJS).
* @typedef {import("solid-js").Setter<EmotionEntity>} EmotionSetter
*/
// Notice that I use `@callback` for `cx` and `css` bellow
// because `@callback` is for functions do not actually exists.
/**
* A method in Emotion for combining class names.
* @callback
* @name Cx
* @param {...string} args - Class names to combine.
* @returns {string} Combined class name.
* @see {@link https://github.com/emotion-js/emotion/blob/85772c33ecb01c70bc8afafa627c9fb7140b593c/packages/css/src/create-instance.ts#L47|@emotion/css/create-instance.Emotion}
*/
/**
* A method in Emotion for generating CSS.
* @callback
* @name Css
* @param {...(string|Object)} args - CSS strings or style objects.
* @returns {string} Generated CSS class name.
* @see {@link https://github.com/emotion-js/emotion/blob/85772c33ecb01c70bc8afafa627c9fb7140b593c/packages/css/src/create-instance.ts#L47|@emotion/css/create-instance.Emotion}
*/
/**
* A context having `getter`.<br />
* Though `EmotionGetter[]` maybe interpreted as Array,
* but I mean to express Tuple having only 1 element: a getter for Emotion.
* @typedef {EmotionGetter[]} EmotionContextValue
*/
/**
* This is the SolidJS' context provided by Provider,<br />
* specifically, for this app, it is exposed as `value="{[getter]}"`.
* @type {import("solid-js").Context<EmotionContextValue>}
*/
export const Context = createContext([]);
/**
* This is the Provider. By wrapping compnents with this Provider,
* it will provide `getter` which is the only way for users
* to obtain the Emotion instance (`EmotionEntity`).
*
* IMPORTANT: Do NOT destructure `children` from `props`.<br />
* If destructured, SolidJS treats them as if rendered *outside* the provider.
*
* @function
* @param {Object} props - Props for the provider.
* @param {string} [props.key] - Optional key for Emotion instance.
* @param {HTMLElement|ShadowRoot} [props.element] - Container for injecting styles.
* @param {JSX.Element|JSX.Element[]} props.children - Child components receiving context.
* @returns {JSX.Element} Emotion context provider wrapping children.
* @see {@link https://github.com/solidjs/solid/discussions/713} - Issue on Destructured Children
*/
export const Provider = props => {
const { key, element } = props || {};
/**
* I'm not destructuring because JSDoc does not attatch
* types to individual variables within destructures.
* @type {{
* 0: EmotionGetter,
* 1: EmotionSetter
* }}
*/
const signal = createSignal();
const [getter, setter] = signal;
createEffect(() => {
const { shadowRoot: container } = element || {};
if (container) {
/**
* Exposed only via `getter`.
* @type {EmotionEntity}
*/
const emotion = createEmotion({
key,
container,
});
setter(emotion);
}
});
return (
<Context.Provider value={[getter]}>
{props.children}
</Context.Provider>
);
};
Your privacy
By clicking "OK" you agree Astralscience can store cookies on your device and disclose information in accordance with our Cookie Policy.
個人情報の保護について
以下 OK をクリックすることにより、Astralscience があなたの端末にクッキーを保存し、クッキー・ポリシー に従って情報を開示することに同意します。
Quyền riêng tư của bạn
Bằng cách nhấn "OK", bạn đồng ý rằng Astralscience có thể lưu cookie trên thiết bị của bạn và xử lý thông tin theo Chính sách Cookie của chúng tôi.
