react-led-digit
Advanced tools
Comparing version 0.0.8 to 0.0.9
@@ -0,1 +1,4 @@ | ||
/** | ||
* Switches intrnal state periodically (visible), calling subscribers each time. | ||
*/ | ||
type BlinkerSubscriber = (state: BlinkerState['visible']) => void; | ||
@@ -5,12 +8,12 @@ type BlinkerState = { | ||
subscribers: BlinkerSubscriber[]; | ||
ratio: number; | ||
period: number; | ||
ratio: number; | ||
visible: boolean; | ||
blinks: number; | ||
}; | ||
type BlinkerOptions = { | ||
autoRun?: boolean; | ||
ratio?: BlinkerState['ratio']; | ||
period?: BlinkerState['period']; | ||
ratio?: BlinkerState['ratio']; | ||
visible?: BlinkerState['visible']; | ||
singleton?: boolean; | ||
}; | ||
@@ -21,5 +24,5 @@ export declare class Blinker { | ||
constructor(options?: BlinkerOptions); | ||
get period(): BlinkerState['period']; | ||
get ratio(): BlinkerState['ratio']; | ||
get visible(): BlinkerState['visible']; | ||
get period(): BlinkerState["period"]; | ||
get ratio(): BlinkerState["ratio"]; | ||
get visible(): BlinkerState["visible"]; | ||
set period(val: BlinkerState['period']); | ||
@@ -26,0 +29,0 @@ set ratio(val: BlinkerState['ratio']); |
"use strict"; | ||
/** | ||
* Switches intrnal state periodically (visible), calling subscribers each time. | ||
*/ | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
@@ -8,8 +16,3 @@ if (kind === "m") throw new TypeError("Private method is not writable"); | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var _Blinker_instances, _Blinker_initOptions, _Blinker_state, _Blinker_on, _Blinker_off; | ||
var _Blinker_instances, _Blinker_options, _Blinker_state, _Blinker_on, _Blinker_off; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -22,2 +25,3 @@ exports.Blinker = void 0; | ||
visible: true, | ||
singleton: true, | ||
}; | ||
@@ -27,19 +31,25 @@ class Blinker { | ||
_Blinker_instances.add(this); | ||
_Blinker_initOptions.set(this, defaultOptions); // store options | ||
_Blinker_options.set(this, defaultOptions); // initial options | ||
_Blinker_state.set(this, { | ||
ratio: defaultOptions.ratio, | ||
period: defaultOptions.period, | ||
subscribers: [], | ||
timeout: null, | ||
subscribers: [], | ||
period: defaultOptions.period, | ||
ratio: defaultOptions.ratio, | ||
visible: defaultOptions.visible, | ||
blinks: 0, | ||
}); | ||
const init = () => { | ||
__classPrivateFieldSet(this, _Blinker_options, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _Blinker_options, "f")), options), "f"); // merge options | ||
__classPrivateFieldGet(this, _Blinker_state, "f").period = __classPrivateFieldGet(this, _Blinker_options, "f").period; | ||
__classPrivateFieldGet(this, _Blinker_state, "f").ratio = __classPrivateFieldGet(this, _Blinker_options, "f").ratio; | ||
__classPrivateFieldGet(this, _Blinker_state, "f").visible = __classPrivateFieldGet(this, _Blinker_options, "f").visible; | ||
if (__classPrivateFieldGet(this, _Blinker_options, "f").autoRun) | ||
this.start(); | ||
}; | ||
if (options.singleton === false) { | ||
init(); | ||
return this; | ||
} | ||
if (!Blinker.instance) { | ||
Blinker.instance = this; | ||
__classPrivateFieldSet(this, _Blinker_initOptions, Object.assign(Object.assign({}, defaultOptions), options), "f"); | ||
__classPrivateFieldGet(this, _Blinker_state, "f").period = __classPrivateFieldGet(this, _Blinker_initOptions, "f").period; | ||
__classPrivateFieldGet(this, _Blinker_state, "f").ratio = __classPrivateFieldGet(this, _Blinker_initOptions, "f").ratio; | ||
__classPrivateFieldGet(this, _Blinker_state, "f").visible = __classPrivateFieldGet(this, _Blinker_initOptions, "f").visible; | ||
if (__classPrivateFieldGet(this, _Blinker_initOptions, "f").autoRun) | ||
this.start(); | ||
init(); | ||
} | ||
@@ -77,8 +87,10 @@ return Blinker.instance; | ||
if (__classPrivateFieldGet(this, _Blinker_state, "f").timeout) | ||
this.stop(); | ||
return; // already runnning | ||
visible ? __classPrivateFieldGet(this, _Blinker_instances, "m", _Blinker_on).call(this) : __classPrivateFieldGet(this, _Blinker_instances, "m", _Blinker_off).call(this); // start blinking | ||
} | ||
stop() { | ||
__classPrivateFieldGet(this, _Blinker_state, "f").timeout && clearTimeout(__classPrivateFieldGet(this, _Blinker_state, "f").timeout); | ||
__classPrivateFieldGet(this, _Blinker_state, "f").timeout = null; | ||
if (__classPrivateFieldGet(this, _Blinker_state, "f").timeout) { | ||
clearTimeout(__classPrivateFieldGet(this, _Blinker_state, "f").timeout); | ||
__classPrivateFieldGet(this, _Blinker_state, "f").timeout = null; | ||
} | ||
} | ||
@@ -95,4 +107,3 @@ subscribe(fn) { | ||
exports.Blinker = Blinker; | ||
_Blinker_initOptions = new WeakMap(), _Blinker_state = new WeakMap(), _Blinker_instances = new WeakSet(), _Blinker_on = function _Blinker_on() { | ||
__classPrivateFieldGet(this, _Blinker_state, "f").blinks++; | ||
_Blinker_options = new WeakMap(), _Blinker_state = new WeakMap(), _Blinker_instances = new WeakSet(), _Blinker_on = function _Blinker_on() { | ||
__classPrivateFieldGet(this, _Blinker_state, "f").visible = true; | ||
@@ -104,3 +115,2 @@ __classPrivateFieldGet(this, _Blinker_state, "f").subscribers.forEach(fn => fn(true)); | ||
}, _Blinker_off = function _Blinker_off() { | ||
__classPrivateFieldGet(this, _Blinker_state, "f").blinks++; | ||
__classPrivateFieldGet(this, _Blinker_state, "f").visible = false; | ||
@@ -112,8 +122,10 @@ __classPrivateFieldGet(this, _Blinker_state, "f").subscribers.forEach(fn => fn(false)); | ||
}; | ||
// ratio=1, tot=2, on=0.5, off=0.5 | ||
// ratio=2, tot=3, on=0.66, off=0.33 | ||
function getPeriod(state) { | ||
const total = state.ratio + 1; | ||
return { | ||
on: state.period * (1 / total), | ||
off: state.period * (1 - 1 / total), | ||
on: state.period * (1 - 1 / total), | ||
off: state.period * (1 / total), | ||
}; | ||
} |
@@ -8,2 +8,3 @@ import React from 'react'; | ||
ratio?: Blinker['ratio']; | ||
sync?: boolean; | ||
}; | ||
@@ -10,0 +11,0 @@ }; |
@@ -18,9 +18,19 @@ "use strict"; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importStar = (this && this.__importStar) || (function () { | ||
var ownKeys = function(o) { | ||
ownKeys = Object.getOwnPropertyNames || function (o) { | ||
var ar = []; | ||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; | ||
return ar; | ||
}; | ||
return ownKeys(o); | ||
}; | ||
return function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
})(); | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
@@ -47,7 +57,7 @@ var t = {}; | ||
const Blinker_1 = require("../Blinker"); | ||
const blinker = new Blinker_1.Blinker(); // singleton makes all BlinkingDigit's to blink synchronoulsy | ||
exports.BlinkingDigit = react_1.default.memo((_a) => { | ||
var { blinkOptions, className } = _a, rest = __rest(_a, ["blinkOptions", "className"]); | ||
const [visible, setVisible] = (0, react_1.useState)(blinker.visible); | ||
const [visible, setVisible] = (0, react_1.useState)(true); | ||
(0, react_1.useEffect)(() => { | ||
const blinker = new Blinker_1.Blinker(Object.assign(Object.assign({}, blinkOptions), { singleton: blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.sync })); // singleton makes all instances BlinkingDigit to blink in sync | ||
if (blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.period) | ||
@@ -59,3 +69,3 @@ blinker.period = blinkOptions.period; | ||
return () => blinker.unsubscribe(setVisible); | ||
}, [blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.period, blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.ratio]); | ||
}, [blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.period, blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.ratio, blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.sync]); | ||
if ((blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.period) === 0 || | ||
@@ -62,0 +72,0 @@ (blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.ratio) === 0 || |
@@ -24,5 +24,5 @@ "use strict"; | ||
var rest = __rest(_a, []); | ||
const scopeAttribute = (0, useStyleInjection_1.default)(digit_css_js_1.default.content, digit_css_js_1.default.hash); | ||
const scopeAttribute = (0, useStyleInjection_1.default)(digit_css_js_1.default.content, digit_css_js_1.default.hash, []); | ||
return ((0, jsx_runtime_1.jsx)("div", Object.assign({}, scopeAttribute, { style: { display: 'contents' }, children: (0, jsx_runtime_1.jsx)(UnstyledDigit_1.Digit, Object.assign({}, rest)) }))); | ||
}; | ||
exports.Digit = Digit; |
@@ -21,2 +21,3 @@ import React, { CSSProperties } from 'react'; | ||
transitionDuration?: CSSProperties['transitionDuration']; | ||
cornerShift?: CSSProperties['width']; | ||
}; | ||
@@ -23,0 +24,0 @@ export type Digit = DivProps & DigitProps & { |
@@ -26,3 +26,3 @@ "use strict"; | ||
const segments = type && valueToSegments(value); // {A: true, ...} | ||
const sx = Object.assign({ '--segment-color': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.color, '--segment-color-off': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.colorOff, '--segment-thickness': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.thickness, '--segment-spacing': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.spacing, '--segment-length': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.length, '--segment-filament': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.filament, '--segment-opacity-on': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.opacityOn, '--segment-opacity-off': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.opacityOff, '--segment-transition-duration': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.transitionDuration }, rest.style); | ||
const sx = Object.assign({ '--segment-color': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.color, '--segment-color-off': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.colorOff, '--segment-thickness': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.thickness, '--segment-spacing': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.spacing, '--segment-length': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.length, '--segment-filament': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.filament, '--segment-opacity-on': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.opacityOn, '--segment-opacity-off': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.opacityOff, '--segment-transition-duration': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.transitionDuration, '--segment-corner-shift': segmentStyle === null || segmentStyle === void 0 ? void 0 : segmentStyle.cornerShift }, rest.style); | ||
if (type === 'digit') | ||
@@ -36,3 +36,3 @@ return (0, jsx_runtime_1.jsx)(components_1.DigitSegments, Object.assign({}, rest, segments, { style: sx })); | ||
return (0, jsx_runtime_1.jsx)(components_1.DotSegments, Object.assign({}, rest, segments, { style: sx })); | ||
console.warn(`Digit.tsx: incompatible value: ${value.toString()}`); | ||
console.warn(`(at Digit.tsx) incompatible value: ${value.toString()}`); | ||
return (0, jsx_runtime_1.jsx)("div", Object.assign({}, rest, { className: (0, clsx_1.default)('digit unknown', rest.className) })); | ||
@@ -39,0 +39,0 @@ }; |
@@ -1,4 +0,16 @@ | ||
declare const useHeadStyleInjection: (css: string, id: string, dependencies?: never[], scoped?: boolean) => { | ||
"data-style-scope-id": string; | ||
type Style = { | ||
id: string; | ||
content: string; | ||
}; | ||
declare const useHeadStyleInjection: (css: string, cssHash: string, dependencies?: never[], scoped?: boolean) => { | ||
[x: string]: boolean | undefined; | ||
}; | ||
export declare class StyleInjector { | ||
#private; | ||
private static instance; | ||
constructor(); | ||
add(s: Style): void; | ||
remove(s: Style): void; | ||
has(s: Style): boolean; | ||
} | ||
export default useHeadStyleInjection; |
@@ -7,38 +7,43 @@ "use strict"; | ||
}; | ||
var _StyleInjectionState_state; | ||
var _StyleInjector_state; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.StyleInjector = void 0; | ||
const react_1 = require("react"); | ||
const scopeAttribute = 'data-style-scope-id'; | ||
const scopeAttributePrefix = 'data-style-scope-'; | ||
// Runtime style injection | ||
const useHeadStyleInjection = (css, id, dependencies = [], scoped = true // isolate css behind @scope | ||
const useHeadStyleInjection = (css, cssHash, dependencies = [], scoped = true // isolate css behind @scope | ||
) => { | ||
const injected = new StyleInjectionState(); // singleton's state | ||
const _id = `_${id}`; // safe id to make CSS selectors work | ||
const injector = new StyleInjector(); // singleton! | ||
const scopeAttribute = `${scopeAttributePrefix}-${cssHash}`; | ||
const style = { | ||
id: `inject_id_${_id}`, // hash of css content | ||
css: scoped ? wrapWithScope(css, _id) : css, | ||
id: `css_id__${cssHash}`, | ||
content: scoped ? wrapWithScope(css, scopeAttribute) : css, | ||
}; | ||
(0, react_1.useInsertionEffect)(() => { | ||
injected.add(style); | ||
return () => injected.remove(style); | ||
injector.add(style); | ||
return () => injector.remove(style); | ||
}, dependencies); | ||
return { | ||
[scopeAttribute]: _id, | ||
[scopeAttribute]: scoped ? true : undefined, | ||
}; | ||
}; | ||
class StyleInjectionState { | ||
class StyleInjector { | ||
constructor() { | ||
_StyleInjectionState_state.set(this, { | ||
injected: new Set(), | ||
}); | ||
if (!StyleInjectionState.instance) { | ||
StyleInjectionState.instance = this; // create first instance if needed | ||
_StyleInjector_state.set(this, new Map()); | ||
if (!StyleInjector.instance) { | ||
StyleInjector.instance = this; | ||
} | ||
return StyleInjectionState.instance; | ||
return StyleInjector.instance; | ||
} | ||
add(s) { | ||
if (!this.has(s)) { | ||
__classPrivateFieldGet(this, _StyleInjectionState_state, "f").injected.add(s.id); | ||
document.head.appendChild(createStyleElement(s.css, s.id)); | ||
if (this.has(s)) { | ||
const count = __classPrivateFieldGet(this, _StyleInjector_state, "f").get(s.id) + 1; | ||
__classPrivateFieldGet(this, _StyleInjector_state, "f").set(s.id, count); | ||
} | ||
else { | ||
__classPrivateFieldGet(this, _StyleInjector_state, "f").set(s.id, 1); | ||
} | ||
if (__classPrivateFieldGet(this, _StyleInjector_state, "f").get(s.id) === 1) { | ||
document.head.appendChild(createStyleElement(s)); | ||
} | ||
} | ||
@@ -48,3 +53,9 @@ remove(s) { | ||
if (this.has(s)) { | ||
__classPrivateFieldGet(this, _StyleInjectionState_state, "f").injected.delete(s.id); | ||
const count = __classPrivateFieldGet(this, _StyleInjector_state, "f").get(s.id) - 1; | ||
__classPrivateFieldGet(this, _StyleInjector_state, "f").set(s.id, count); | ||
} | ||
else { | ||
console.warn(`(at useStyleInjection.ts) unable to remove style: ${s.id}`); | ||
} | ||
if (__classPrivateFieldGet(this, _StyleInjector_state, "f").get(s.id) === 0) { | ||
(_a = document.head.querySelector(`#${s.id}`)) === null || _a === void 0 ? void 0 : _a.remove(); | ||
@@ -54,20 +65,26 @@ } | ||
has(s) { | ||
return __classPrivateFieldGet(this, _StyleInjectionState_state, "f").injected.has(s.id); | ||
return __classPrivateFieldGet(this, _StyleInjector_state, "f").has(s.id); | ||
} | ||
} | ||
_StyleInjectionState_state = new WeakMap(); | ||
const createStyleElement = (content, id = '') => { | ||
exports.StyleInjector = StyleInjector; | ||
_StyleInjector_state = new WeakMap(); | ||
const createStyleElement = (style) => { | ||
const el = document.createElement('style'); | ||
el.innerHTML = content; | ||
if (id !== '') | ||
el.id = id; | ||
el.innerHTML = style.content; | ||
if (style.id !== '') | ||
el.id = style.id; | ||
return el; | ||
}; | ||
const wrapWithScope = (rules, _id) => { | ||
const isolated = `@scope ([${scopeAttribute}=${_id}]) { | ||
:scope { display: contents; } | ||
${rules} | ||
}`; | ||
const wrapWithScope = (css, scopeAttribute) => { | ||
// unused bc @scope at-rule does not work in Firefox | ||
const scoped = `@scope ([${scopeAttribute}]) {` + | ||
`:scope { display: contents; }` + | ||
`${css}` + | ||
`}`; | ||
const isolated = `[${scopeAttribute}] { display: contents; }` + | ||
`[${scopeAttribute}] {` + | ||
`${css}` + | ||
`}`; | ||
return isolated; | ||
}; | ||
exports.default = useHeadStyleInjection; |
{ | ||
"name": "react-led-digit", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"description": "react component for 7-segment display (digit), includes dot, colon and am-pm digits", | ||
@@ -14,3 +14,3 @@ "main": "./lib/index.js", | ||
"clean": "rimraf lib", | ||
"css-copy": "npx cpy src/**/*.css lib", | ||
"css-copy": "npx cpy src/**/*.css lib && npx cpy src/**/*.css.* lib", | ||
"css-to-js-watch": "node css-to-js --watch", | ||
@@ -17,0 +17,0 @@ "css-to-js": "node css-to-js", |
Sorry, the diff of this file is not supported yet
75882
39
1635