react-led-digit 0.0.7 → 0.0.9
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/lib/Blinker/Blinker.d.ts +9 -6
- package/lib/Blinker/Blinker.js +37 -25
- package/lib/BlinkingDigit/BlinkingDigit.d.ts +1 -0
- package/lib/BlinkingDigit/BlinkingDigit.js +20 -10
- package/lib/Digit/Digit.js +1 -1
- package/lib/Digit/Digit.stories.d.ts +26 -0
- package/lib/Digit/Digit.stories.js +172 -0
- package/lib/Digit/UnstyledDigit.d.ts +1 -0
- package/lib/Digit/UnstyledDigit.js +2 -2
- package/lib/Digit/digit.css +8 -7
- package/lib/Digit/digit.css.js +333 -0
- package/lib/Digit/useStyleInjection.d.ts +14 -2
- package/lib/Digit/useStyleInjection.js +49 -32
- package/package.json +15 -13
package/lib/Blinker/Blinker.d.ts
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Switches intrnal state periodically (visible), calling subscribers each time.
|
|
3
|
+
*/
|
|
1
4
|
type BlinkerSubscriber = (state: BlinkerState['visible']) => void;
|
|
2
5
|
type BlinkerState = {
|
|
3
6
|
timeout: null | ReturnType<typeof setTimeout>;
|
|
4
7
|
subscribers: BlinkerSubscriber[];
|
|
5
|
-
period: number;
|
|
6
8
|
ratio: number;
|
|
9
|
+
period: number;
|
|
7
10
|
visible: boolean;
|
|
8
|
-
blinks: number;
|
|
9
11
|
};
|
|
10
12
|
type BlinkerOptions = {
|
|
11
13
|
autoRun?: boolean;
|
|
12
|
-
period?: BlinkerState['period'];
|
|
13
14
|
ratio?: BlinkerState['ratio'];
|
|
15
|
+
period?: BlinkerState['period'];
|
|
14
16
|
visible?: BlinkerState['visible'];
|
|
17
|
+
singleton?: boolean;
|
|
15
18
|
};
|
|
16
19
|
export declare class Blinker {
|
|
17
20
|
#private;
|
|
18
21
|
private static instance;
|
|
19
22
|
constructor(options?: BlinkerOptions);
|
|
20
|
-
get period(): BlinkerState[
|
|
21
|
-
get ratio(): BlinkerState[
|
|
22
|
-
get visible(): BlinkerState[
|
|
23
|
+
get period(): BlinkerState["period"];
|
|
24
|
+
get ratio(): BlinkerState["ratio"];
|
|
25
|
+
get visible(): BlinkerState["visible"];
|
|
23
26
|
set period(val: BlinkerState['period']);
|
|
24
27
|
set ratio(val: BlinkerState['ratio']);
|
|
25
28
|
set visible(val: BlinkerState['visible']);
|
package/lib/Blinker/Blinker.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Switches intrnal state periodically (visible), calling subscribers each time.
|
|
4
|
+
*/
|
|
5
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
6
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
7
|
+
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");
|
|
8
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
9
|
+
};
|
|
2
10
|
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
11
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
12
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
13
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
14
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
15
|
};
|
|
8
|
-
var
|
|
9
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
-
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");
|
|
11
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
-
};
|
|
13
|
-
var _Blinker_instances, _Blinker_initOptions, _Blinker_state, _Blinker_on, _Blinker_off;
|
|
16
|
+
var _Blinker_instances, _Blinker_options, _Blinker_state, _Blinker_on, _Blinker_off;
|
|
14
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
18
|
exports.Blinker = void 0;
|
|
16
19
|
const defaultOptions = {
|
|
@@ -18,27 +21,34 @@ const defaultOptions = {
|
|
|
18
21
|
period: 1000,
|
|
19
22
|
ratio: 1,
|
|
20
23
|
visible: true,
|
|
24
|
+
singleton: true,
|
|
21
25
|
};
|
|
22
26
|
class Blinker {
|
|
23
27
|
constructor(options = defaultOptions) {
|
|
24
28
|
_Blinker_instances.add(this);
|
|
25
|
-
|
|
29
|
+
_Blinker_options.set(this, defaultOptions); // initial options
|
|
26
30
|
_Blinker_state.set(this, {
|
|
27
|
-
timeout: null,
|
|
28
|
-
subscribers: [],
|
|
29
|
-
period: defaultOptions.period,
|
|
30
31
|
ratio: defaultOptions.ratio,
|
|
32
|
+
period: defaultOptions.period,
|
|
33
|
+
subscribers: [],
|
|
34
|
+
timeout: null,
|
|
31
35
|
visible: defaultOptions.visible,
|
|
32
|
-
blinks: 0,
|
|
33
36
|
});
|
|
37
|
+
const init = () => {
|
|
38
|
+
__classPrivateFieldSet(this, _Blinker_options, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _Blinker_options, "f")), options), "f"); // merge options
|
|
39
|
+
__classPrivateFieldGet(this, _Blinker_state, "f").period = __classPrivateFieldGet(this, _Blinker_options, "f").period;
|
|
40
|
+
__classPrivateFieldGet(this, _Blinker_state, "f").ratio = __classPrivateFieldGet(this, _Blinker_options, "f").ratio;
|
|
41
|
+
__classPrivateFieldGet(this, _Blinker_state, "f").visible = __classPrivateFieldGet(this, _Blinker_options, "f").visible;
|
|
42
|
+
if (__classPrivateFieldGet(this, _Blinker_options, "f").autoRun)
|
|
43
|
+
this.start();
|
|
44
|
+
};
|
|
45
|
+
if (options.singleton === false) {
|
|
46
|
+
init();
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
34
49
|
if (!Blinker.instance) {
|
|
35
50
|
Blinker.instance = this;
|
|
36
|
-
|
|
37
|
-
__classPrivateFieldGet(this, _Blinker_state, "f").period = __classPrivateFieldGet(this, _Blinker_initOptions, "f").period;
|
|
38
|
-
__classPrivateFieldGet(this, _Blinker_state, "f").ratio = __classPrivateFieldGet(this, _Blinker_initOptions, "f").ratio;
|
|
39
|
-
__classPrivateFieldGet(this, _Blinker_state, "f").visible = __classPrivateFieldGet(this, _Blinker_initOptions, "f").visible;
|
|
40
|
-
if (__classPrivateFieldGet(this, _Blinker_initOptions, "f").autoRun)
|
|
41
|
-
this.start();
|
|
51
|
+
init();
|
|
42
52
|
}
|
|
43
53
|
return Blinker.instance;
|
|
44
54
|
}
|
|
@@ -71,12 +81,14 @@ class Blinker {
|
|
|
71
81
|
}
|
|
72
82
|
start(visible = __classPrivateFieldGet(this, _Blinker_state, "f").visible) {
|
|
73
83
|
if (__classPrivateFieldGet(this, _Blinker_state, "f").timeout)
|
|
74
|
-
|
|
84
|
+
return; // already runnning
|
|
75
85
|
visible ? __classPrivateFieldGet(this, _Blinker_instances, "m", _Blinker_on).call(this) : __classPrivateFieldGet(this, _Blinker_instances, "m", _Blinker_off).call(this); // start blinking
|
|
76
86
|
}
|
|
77
87
|
stop() {
|
|
78
|
-
|
|
79
|
-
|
|
88
|
+
if (__classPrivateFieldGet(this, _Blinker_state, "f").timeout) {
|
|
89
|
+
clearTimeout(__classPrivateFieldGet(this, _Blinker_state, "f").timeout);
|
|
90
|
+
__classPrivateFieldGet(this, _Blinker_state, "f").timeout = null;
|
|
91
|
+
}
|
|
80
92
|
}
|
|
81
93
|
subscribe(fn) {
|
|
82
94
|
if (!__classPrivateFieldGet(this, _Blinker_state, "f").subscribers.includes(fn)) {
|
|
@@ -88,25 +100,25 @@ class Blinker {
|
|
|
88
100
|
}
|
|
89
101
|
}
|
|
90
102
|
exports.Blinker = Blinker;
|
|
91
|
-
|
|
92
|
-
__classPrivateFieldGet(this, _Blinker_state, "f").blinks++;
|
|
103
|
+
_Blinker_options = new WeakMap(), _Blinker_state = new WeakMap(), _Blinker_instances = new WeakSet(), _Blinker_on = function _Blinker_on() {
|
|
93
104
|
__classPrivateFieldGet(this, _Blinker_state, "f").visible = true;
|
|
94
105
|
__classPrivateFieldGet(this, _Blinker_state, "f").subscribers.forEach(fn => fn(true));
|
|
95
106
|
__classPrivateFieldGet(this, _Blinker_state, "f").timeout = setTimeout(() => {
|
|
96
107
|
__classPrivateFieldGet(this, _Blinker_instances, "m", _Blinker_off).call(this);
|
|
97
108
|
}, getPeriod(__classPrivateFieldGet(this, _Blinker_state, "f")).on);
|
|
98
109
|
}, _Blinker_off = function _Blinker_off() {
|
|
99
|
-
__classPrivateFieldGet(this, _Blinker_state, "f").blinks++;
|
|
100
110
|
__classPrivateFieldGet(this, _Blinker_state, "f").visible = false;
|
|
101
111
|
__classPrivateFieldGet(this, _Blinker_state, "f").subscribers.forEach(fn => fn(false));
|
|
102
112
|
__classPrivateFieldGet(this, _Blinker_state, "f").timeout = setTimeout(() => {
|
|
103
113
|
__classPrivateFieldGet(this, _Blinker_instances, "m", _Blinker_on).call(this);
|
|
104
114
|
}, getPeriod(__classPrivateFieldGet(this, _Blinker_state, "f")).off);
|
|
105
115
|
};
|
|
116
|
+
// ratio=1, tot=2, on=0.5, off=0.5
|
|
117
|
+
// ratio=2, tot=3, on=0.66, off=0.33
|
|
106
118
|
function getPeriod(state) {
|
|
107
119
|
const total = state.ratio + 1;
|
|
108
120
|
return {
|
|
109
|
-
on: state.period * (1 / total),
|
|
110
|
-
off: state.period * (1
|
|
121
|
+
on: state.period * (1 - 1 / total),
|
|
122
|
+
off: state.period * (1 / total),
|
|
111
123
|
};
|
|
112
124
|
}
|
|
@@ -5,6 +5,7 @@ type BlinkingDigit = Digit & {
|
|
|
5
5
|
blinkOptions?: {
|
|
6
6
|
period?: Blinker['period'];
|
|
7
7
|
ratio?: Blinker['ratio'];
|
|
8
|
+
sync?: boolean;
|
|
8
9
|
};
|
|
9
10
|
};
|
|
10
11
|
export declare const BlinkingDigit: React.MemoExoticComponent<({ blinkOptions, className, ...rest }: BlinkingDigit) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
26
36
|
var t = {};
|
|
27
37
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -43,18 +53,18 @@ const react_1 = __importStar(require("react"));
|
|
|
43
53
|
const clsx_1 = __importDefault(require("clsx"));
|
|
44
54
|
const Digit_1 = require("../Digit");
|
|
45
55
|
const Blinker_1 = require("../Blinker");
|
|
46
|
-
const blinker = new Blinker_1.Blinker(); // singleton makes all BlinkingDigit's to blink synchronoulsy
|
|
47
56
|
exports.BlinkingDigit = react_1.default.memo((_a) => {
|
|
48
57
|
var { blinkOptions, className } = _a, rest = __rest(_a, ["blinkOptions", "className"]);
|
|
49
|
-
const [visible, setVisible] = (0, react_1.useState)(
|
|
58
|
+
const [visible, setVisible] = (0, react_1.useState)(true);
|
|
50
59
|
(0, react_1.useEffect)(() => {
|
|
60
|
+
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
|
|
51
61
|
if (blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.period)
|
|
52
62
|
blinker.period = blinkOptions.period;
|
|
53
63
|
if (blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.ratio)
|
|
54
64
|
blinker.ratio = blinkOptions.ratio;
|
|
55
65
|
blinker.subscribe(setVisible);
|
|
56
66
|
return () => blinker.unsubscribe(setVisible);
|
|
57
|
-
}, [blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.period, blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.ratio]);
|
|
67
|
+
}, [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]);
|
|
58
68
|
if ((blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.period) === 0 ||
|
|
59
69
|
(blinkOptions === null || blinkOptions === void 0 ? void 0 : blinkOptions.ratio) === 0 ||
|
|
60
70
|
typeof (rest === null || rest === void 0 ? void 0 : rest.off) === 'boolean')
|
package/lib/Digit/Digit.js
CHANGED
|
@@ -21,7 +21,7 @@ const useStyleInjection_1 = __importDefault(require("./useStyleInjection"));
|
|
|
21
21
|
const digit_css_js_1 = __importDefault(require("./digit.css.js"));
|
|
22
22
|
const Digit = (_a) => {
|
|
23
23
|
var rest = __rest(_a, []);
|
|
24
|
-
const scopeAttribute = (0, useStyleInjection_1.default)(digit_css_js_1.default.content, digit_css_js_1.default.hash);
|
|
24
|
+
const scopeAttribute = (0, useStyleInjection_1.default)(digit_css_js_1.default.content, digit_css_js_1.default.hash, []);
|
|
25
25
|
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)) })));
|
|
26
26
|
};
|
|
27
27
|
exports.Digit = Digit;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { StoryObj } from '@storybook/react';
|
|
3
|
+
import { Digit } from '../';
|
|
4
|
+
declare const meta: {
|
|
5
|
+
title: string;
|
|
6
|
+
component: ({ ...rest }: Digit) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
tags: string[];
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: string;
|
|
10
|
+
};
|
|
11
|
+
argTypes: {
|
|
12
|
+
off: {
|
|
13
|
+
control: "boolean";
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export default meta;
|
|
18
|
+
type Story = StoryObj<typeof meta>;
|
|
19
|
+
export type DisplayProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
20
|
+
scale?: number;
|
|
21
|
+
segmentStyle?: Digit['segmentStyle'];
|
|
22
|
+
value: string;
|
|
23
|
+
};
|
|
24
|
+
export declare const Clock: Story;
|
|
25
|
+
export declare const Digits: Story;
|
|
26
|
+
export declare const Blinking: Story;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.Blinking = exports.Digits = exports.Clock = void 0;
|
|
15
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
16
|
+
const react_1 = require("react");
|
|
17
|
+
const __1 = require("../");
|
|
18
|
+
const _1 = require("./");
|
|
19
|
+
const meta = {
|
|
20
|
+
title: 'Example/Digit',
|
|
21
|
+
component: __1.Digit,
|
|
22
|
+
tags: ['autodocs'],
|
|
23
|
+
parameters: {
|
|
24
|
+
layout: 'fullscreen', // https://storybook.js.org/docs/configure/story-layout
|
|
25
|
+
},
|
|
26
|
+
argTypes: {
|
|
27
|
+
off: { control: 'boolean' },
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
exports.default = meta;
|
|
31
|
+
const grid = {
|
|
32
|
+
display: 'flex',
|
|
33
|
+
gap: '.35rem',
|
|
34
|
+
padding: '1rem',
|
|
35
|
+
placeItems: 'center center',
|
|
36
|
+
};
|
|
37
|
+
const CustomDigit = (_a) => {
|
|
38
|
+
var rest = __rest(_a, []);
|
|
39
|
+
return ((0, jsx_runtime_1.jsx)(__1.Digit, Object.assign({}, rest, { shape: "pill", segmentStyle: {
|
|
40
|
+
thickness: '.25rem',
|
|
41
|
+
length: '1.5rem',
|
|
42
|
+
spacing: '0.25rem',
|
|
43
|
+
filament: '.0625rem',
|
|
44
|
+
} })));
|
|
45
|
+
};
|
|
46
|
+
const DigitTest = () => {
|
|
47
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("style", { children: `.digit { outline: 0.1px solid rgba(255, 0, 0, 0.2); }` }), (0, jsx_runtime_1.jsxs)("div", { style: grid, children: [(0, jsx_runtime_1.jsx)(__1.Digit, { value: 0, className: "test" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: 1, shape: "round", segmentStyle: {
|
|
48
|
+
thickness: '.35rem',
|
|
49
|
+
color: 'green',
|
|
50
|
+
colorOff: 'blue',
|
|
51
|
+
} }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: 2, shape: "pill", segmentStyle: { thickness: '.5rem' } }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: 3, shape: "rect", segmentStyle: { spacing: '.25rem' } }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: 4, style: { color: 'red' } }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: ":" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: 5 }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: 6 }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: 7 }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: 8, off: true }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: 9 }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "." }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "pm" })] }), (0, jsx_runtime_1.jsxs)("div", { style: grid, children: [(0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: "pm", blinkOptions: { period: 2000 } }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: ":", shape: "round" }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: "pm", shape: "rect" }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: "am", shape: "round" }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: ":", shape: "pill" }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: "pm", shape: "pill" }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: "-", shape: "pill" }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: "_", shape: "pill" }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: 2, shape: "pill", segmentStyle: { thickness: '.5rem' } }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: ":", shape: "pill", segmentStyle: { thickness: '1rem' } })] }), (0, jsx_runtime_1.jsxs)("div", { style: grid, children: [(0, jsx_runtime_1.jsx)(__1.Digit, { value: "A" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "C" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "E" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "F" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "G" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "H" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "J" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "L" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "O" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "P" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "S" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "U" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "Y" })] }), (0, jsx_runtime_1.jsxs)("div", { style: grid, children: [(0, jsx_runtime_1.jsx)(__1.Digit, { value: "c" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "b" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "d" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "h" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "n" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "o" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "r" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "u" })] }), (0, jsx_runtime_1.jsxs)("div", { style: grid, children: [(0, jsx_runtime_1.jsx)(CustomDigit, { value: 0 }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: 1 }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: ":" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: 2 }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: 3 }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "am" })] }), (0, jsx_runtime_1.jsxs)("div", { style: grid, children: [(0, jsx_runtime_1.jsx)(__1.Digit, { value: "E" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "r" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "r" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "o" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "r" }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "." })] }), (0, jsx_runtime_1.jsxs)("div", { style: grid, children: [(0, jsx_runtime_1.jsx)(CustomDigit, { value: "A" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "C" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "E" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "F" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "H" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "J" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "L" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "O" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "P" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "U" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "Y" })] }), (0, jsx_runtime_1.jsxs)("div", { style: grid, children: [(0, jsx_runtime_1.jsx)(CustomDigit, { value: "c" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "b" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "d" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "h" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "n" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "o" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "r" }), (0, jsx_runtime_1.jsx)(CustomDigit, { value: "u" }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: "2", shape: "round", segmentStyle: {
|
|
52
|
+
color: 'green',
|
|
53
|
+
colorOff: 'red',
|
|
54
|
+
length: '1.5rem',
|
|
55
|
+
spacing: '-0.025rem',
|
|
56
|
+
thickness: '0.5rem',
|
|
57
|
+
opacityOff: 0.2,
|
|
58
|
+
} })] })] }));
|
|
59
|
+
};
|
|
60
|
+
const charset = new Set(Object.keys(_1.charToSevenSegments));
|
|
61
|
+
function setCharAt(str, index, chr) {
|
|
62
|
+
if (index > str.length - 1)
|
|
63
|
+
return str;
|
|
64
|
+
return str.substr(0, index) + chr + str.substr(index + 1);
|
|
65
|
+
}
|
|
66
|
+
const BlinkingDigitTest = () => {
|
|
67
|
+
const input = (0, react_1.useRef)(null);
|
|
68
|
+
const [dgts, setDgts] = (0, react_1.useState)('');
|
|
69
|
+
const addDigit = () => {
|
|
70
|
+
if (input.current.value) {
|
|
71
|
+
setDgts(prev => prev + input.current.value);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const removeDigit = (idx) => {
|
|
75
|
+
const next = setCharAt(dgts, idx, '');
|
|
76
|
+
setDgts(next);
|
|
77
|
+
};
|
|
78
|
+
const handleChange = () => {
|
|
79
|
+
if (!charset.has(input.current.value)) {
|
|
80
|
+
input.current.value = '';
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const handleInputKeypress = (e) => {
|
|
84
|
+
if (e.key === 'Enter') {
|
|
85
|
+
addDigit();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
(0, react_1.useEffect)(() => {
|
|
89
|
+
var _a;
|
|
90
|
+
(_a = input.current) === null || _a === void 0 ? void 0 : _a.addEventListener('keydown', handleInputKeypress);
|
|
91
|
+
return () => {
|
|
92
|
+
var _a;
|
|
93
|
+
(_a = input.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('keydown', handleInputKeypress);
|
|
94
|
+
};
|
|
95
|
+
}, []);
|
|
96
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("style", { children: `
|
|
97
|
+
.digit { outline: 0.1px solid rgba(255, 0, 0, 0.2); }
|
|
98
|
+
input { border: 1px solid black; border-radius: .5rem; padding: .5rem .25rem;}
|
|
99
|
+
button { border: none; border-radius: .5rem; padding: .5rem 1rem;}
|
|
100
|
+
button, input, p { font-size: 100%; font-family: sans-serif; margin: .25rem;}
|
|
101
|
+
` }), (0, jsx_runtime_1.jsxs)("p", { children: ["charset: ", Array.from(charset).join(', ')] }), (0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: "digit", ref: input, onChange: handleChange, maxLength: 1 }), (0, jsx_runtime_1.jsx)("button", { onClick: addDigit, children: "Add digit" }), (0, jsx_runtime_1.jsxs)("div", { style: grid, children: [(0, jsx_runtime_1.jsx)(__1.Digit, { value: "8", segmentStyle: { thickness: '.35rem' } }), (0, jsx_runtime_1.jsx)(__1.Digit, { value: "b" }), (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: ":", blinkOptions: {
|
|
102
|
+
period: 2000,
|
|
103
|
+
ratio: 3,
|
|
104
|
+
} }), dgts.split('').map((char, idx) => ((0, jsx_runtime_1.jsx)(__1.BlinkingDigit, { value: char, onClick: () => removeDigit(idx), segmentStyle: {
|
|
105
|
+
transitionDuration: '0.5s',
|
|
106
|
+
}, blinkOptions: { sync: false } }, idx)))] })] }));
|
|
107
|
+
};
|
|
108
|
+
const getDigits = (str) => {
|
|
109
|
+
let s = str.trim().toLowerCase();
|
|
110
|
+
const am = s.includes('am');
|
|
111
|
+
const pm = s.includes('pm');
|
|
112
|
+
s = s.replace('am', '').replace('pm', '').replace(' ', '');
|
|
113
|
+
const result = s.split('');
|
|
114
|
+
if (am)
|
|
115
|
+
result.push('am');
|
|
116
|
+
if (pm)
|
|
117
|
+
result.push('pm');
|
|
118
|
+
return result;
|
|
119
|
+
};
|
|
120
|
+
const Display = (_a) => {
|
|
121
|
+
var { scale = 1, value } = _a, rest = __rest(_a, ["scale", "value"]);
|
|
122
|
+
const digits = getDigits(value);
|
|
123
|
+
return ((0, jsx_runtime_1.jsx)("div", Object.assign({}, rest, { children: digits.map((digit, idx) => {
|
|
124
|
+
const props = {
|
|
125
|
+
value: digit,
|
|
126
|
+
style: {
|
|
127
|
+
fontSize: `${scale * 100}%`,
|
|
128
|
+
},
|
|
129
|
+
segmentStyle: {
|
|
130
|
+
color: 'green',
|
|
131
|
+
cornerShift: 'calc(var(--thickness) / 8)',
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
if (digit === ':') {
|
|
135
|
+
return (0, jsx_runtime_1.jsx)(__1.BlinkingDigit, Object.assign({}, props), idx);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
return (0, jsx_runtime_1.jsx)(__1.Digit, Object.assign({}, props), idx);
|
|
139
|
+
}
|
|
140
|
+
}) })));
|
|
141
|
+
};
|
|
142
|
+
const getTime = () => new Date().toLocaleTimeString();
|
|
143
|
+
const SimpleClock = () => {
|
|
144
|
+
const [time, setTime] = (0, react_1.useState)(getTime());
|
|
145
|
+
const blinker = new __1.Blinker();
|
|
146
|
+
blinker.period = 2000;
|
|
147
|
+
blinker.ratio = 1;
|
|
148
|
+
const handleBlinkerChange = () => setTime(getTime());
|
|
149
|
+
(0, react_1.useEffect)(() => {
|
|
150
|
+
blinker.subscribe(handleBlinkerChange);
|
|
151
|
+
return () => blinker.unsubscribe(handleBlinkerChange);
|
|
152
|
+
}, []);
|
|
153
|
+
return (0, jsx_runtime_1.jsx)(Display, { scale: 2, style: grid, value: time });
|
|
154
|
+
};
|
|
155
|
+
exports.Clock = {
|
|
156
|
+
args: {
|
|
157
|
+
value: '0',
|
|
158
|
+
},
|
|
159
|
+
render: SimpleClock,
|
|
160
|
+
};
|
|
161
|
+
exports.Digits = {
|
|
162
|
+
args: {
|
|
163
|
+
value: '0',
|
|
164
|
+
},
|
|
165
|
+
render: DigitTest,
|
|
166
|
+
};
|
|
167
|
+
exports.Blinking = {
|
|
168
|
+
args: {
|
|
169
|
+
value: '0',
|
|
170
|
+
},
|
|
171
|
+
render: BlinkingDigitTest,
|
|
172
|
+
};
|
|
@@ -18,6 +18,7 @@ type SegmentStyle = {
|
|
|
18
18
|
opacityOn?: CSSProperties['opacity'];
|
|
19
19
|
opacityOff?: CSSProperties['opacity'];
|
|
20
20
|
transitionDuration?: CSSProperties['transitionDuration'];
|
|
21
|
+
cornerShift?: CSSProperties['width'];
|
|
21
22
|
};
|
|
22
23
|
export type Digit = DivProps & DigitProps & {
|
|
23
24
|
segmentStyle?: SegmentStyle;
|
|
@@ -23,7 +23,7 @@ const Digit = (_a) => {
|
|
|
23
23
|
var { segmentStyle, value } = _a, rest = __rest(_a, ["segmentStyle", "value"]);
|
|
24
24
|
const type = valueToType(value);
|
|
25
25
|
const segments = type && valueToSegments(value); // {A: true, ...}
|
|
26
|
-
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);
|
|
26
|
+
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);
|
|
27
27
|
if (type === 'digit')
|
|
28
28
|
return (0, jsx_runtime_1.jsx)(components_1.DigitSegments, Object.assign({}, rest, segments, { style: sx }));
|
|
29
29
|
if (type === 'colon')
|
|
@@ -32,7 +32,7 @@ const Digit = (_a) => {
|
|
|
32
32
|
return (0, jsx_runtime_1.jsx)(components_1.AmpmSegments, Object.assign({}, rest, segments, { style: sx }));
|
|
33
33
|
if (type === 'dot')
|
|
34
34
|
return (0, jsx_runtime_1.jsx)(components_1.DotSegments, Object.assign({}, rest, segments, { style: sx }));
|
|
35
|
-
console.warn(`Digit.tsx
|
|
35
|
+
console.warn(`(at Digit.tsx) incompatible value: ${value.toString()}`);
|
|
36
36
|
return (0, jsx_runtime_1.jsx)("div", Object.assign({}, rest, { className: (0, clsx_1.default)('digit unknown', rest.className) }));
|
|
37
37
|
};
|
|
38
38
|
exports.Digit = Digit;
|
package/lib/Digit/digit.css
CHANGED
|
@@ -9,20 +9,21 @@
|
|
|
9
9
|
.digit {
|
|
10
10
|
--color: var(--segment-color, currentColor);
|
|
11
11
|
--color-off: var(--segment-color-off, var(--color));
|
|
12
|
-
--
|
|
13
|
-
--length: var(--segment-length,
|
|
14
|
-
--spacing: var(--segment-spacing, 0.
|
|
15
|
-
--filament: var(--segment-filament,
|
|
12
|
+
--thickness: var(--segment-thickness, 0.25em); /* =4px */
|
|
13
|
+
--length: var(--segment-length, 1em);
|
|
14
|
+
--spacing: var(--segment-spacing, 0.0625em); /* =1px */
|
|
15
|
+
--filament: var(--segment-filament, 0em); /* vertical squeeze for A, D */
|
|
16
16
|
--opacity-on: var(--segment-opacity-on, 1);
|
|
17
17
|
--opacity-off: var(--segment-opacity-off, 0.1);
|
|
18
18
|
--transition-duration: var(--segment-transition-duration, 0.25s);
|
|
19
|
-
/* distortion of diamond
|
|
20
|
-
--corner-shift: var(--
|
|
19
|
+
/* distortion of diamond corners */
|
|
20
|
+
--corner-shift: var(--segment-corner-shift, 0em);
|
|
21
21
|
|
|
22
22
|
--svg-am: url('data:image/svg+xml,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 16 16" xml:space="preserve"><style type="text/css">.st0{fill:none;stroke:black;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:10;stroke-width:1;}</style><polyline class="st0" points="1.4,11.5 1.4,11.4 3.8,3.5 4.2,3.5 6.6,11.4 6.6,11.5 "/><polyline class="st0" points="14.5,11.5 14.5,3.5 14.1,3.5 11.5,9.9 11.3,9.9 8.9,3.5 8.5,3.5 8.5,11.5 "/><line class="st0" x1="2.6" y1="9.5" x2="5.4" y2="9.5"/></svg>');
|
|
23
23
|
--svg-pm: url('data:image/svg+xml,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 16 16" xml:space="preserve"><style type="text/css">.st0{fill:none;stroke:black;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:10;stroke-width:1;}</style><path class="st0" d="M1.5,11.5V3.4h2.1c1.6,0,2.5,1,2.5,2.2s-1,2.3-2.5,2.3H2.2"/><polyline class="st0" points="14.5,11.5 14.5,3.5 14.1,3.5 11.5,9.9 11.3,9.9 8.9,3.5 8.5,3.5 8.5,11.5 "/></svg>');
|
|
24
24
|
|
|
25
25
|
/* computed values */
|
|
26
|
+
--thick: var(--thickness);
|
|
26
27
|
--digit-width: calc(var(--length) + var(--thick) + var(--spacing));
|
|
27
28
|
--digit-height: calc(var(--length) * 2 + var(--thick) + var(--spacing) * 2);
|
|
28
29
|
|
|
@@ -91,7 +92,7 @@
|
|
|
91
92
|
/* segments */
|
|
92
93
|
.segment {
|
|
93
94
|
--th-half-100: calc(100% - var(--th-half));
|
|
94
|
-
--shft:
|
|
95
|
+
--shft: var(--corner-shift);
|
|
95
96
|
|
|
96
97
|
background-color: var(--color);
|
|
97
98
|
display: block;
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/* This file is auto-generated */
|
|
2
|
+
|
|
3
|
+
const css = {
|
|
4
|
+
src: `src/Digit/digit.css`,
|
|
5
|
+
hash: `21rs68w6m0r`,
|
|
6
|
+
content: `
|
|
7
|
+
/**
|
|
8
|
+
* A
|
|
9
|
+
* F B D2 AM
|
|
10
|
+
* G
|
|
11
|
+
* E C D1 PM
|
|
12
|
+
* D DP
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
.digit {
|
|
16
|
+
--color: var(--segment-color, currentColor);
|
|
17
|
+
--color-off: var(--segment-color-off, var(--color));
|
|
18
|
+
--thickness: var(--segment-thickness, 0.25em); /* =4px */
|
|
19
|
+
--length: var(--segment-length, 1em);
|
|
20
|
+
--spacing: var(--segment-spacing, 0.0625em); /* =1px */
|
|
21
|
+
--filament: var(--segment-filament, 0em); /* vertical squeeze for A, D */
|
|
22
|
+
--opacity-on: var(--segment-opacity-on, 1);
|
|
23
|
+
--opacity-off: var(--segment-opacity-off, 0.1);
|
|
24
|
+
--transition-duration: var(--segment-transition-duration, 0.25s);
|
|
25
|
+
/* distortion of diamond corners */
|
|
26
|
+
--corner-shift: var(--segment-corner-shift, 0em);
|
|
27
|
+
|
|
28
|
+
--svg-am: url('data:image/svg+xml,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 16 16" xml:space="preserve"><style type="text/css">.st0{fill:none;stroke:black;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:10;stroke-width:1;}</style><polyline class="st0" points="1.4,11.5 1.4,11.4 3.8,3.5 4.2,3.5 6.6,11.4 6.6,11.5 "/><polyline class="st0" points="14.5,11.5 14.5,3.5 14.1,3.5 11.5,9.9 11.3,9.9 8.9,3.5 8.5,3.5 8.5,11.5 "/><line class="st0" x1="2.6" y1="9.5" x2="5.4" y2="9.5"/></svg>');
|
|
29
|
+
--svg-pm: url('data:image/svg+xml,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 16 16" xml:space="preserve"><style type="text/css">.st0{fill:none;stroke:black;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:10;stroke-width:1;}</style><path class="st0" d="M1.5,11.5V3.4h2.1c1.6,0,2.5,1,2.5,2.2s-1,2.3-2.5,2.3H2.2"/><polyline class="st0" points="14.5,11.5 14.5,3.5 14.1,3.5 11.5,9.9 11.3,9.9 8.9,3.5 8.5,3.5 8.5,11.5 "/></svg>');
|
|
30
|
+
|
|
31
|
+
/* computed values */
|
|
32
|
+
--thick: var(--thickness);
|
|
33
|
+
--digit-width: calc(var(--length) + var(--thick) + var(--spacing));
|
|
34
|
+
--digit-height: calc(var(--length) * 2 + var(--thick) + var(--spacing) * 2);
|
|
35
|
+
|
|
36
|
+
--thick-minus: calc(var(--thick) * -1);
|
|
37
|
+
--th-half: calc(var(--thick) / 2);
|
|
38
|
+
--th-half-minus: calc(var(--th-half) * -1);
|
|
39
|
+
--spacing-minus: calc(var(--spacing) * -1);
|
|
40
|
+
--sp-half: calc(var(--spacing) / 2);
|
|
41
|
+
--sp-half-minus: calc(var(--sp-half) * -1);
|
|
42
|
+
|
|
43
|
+
--radius-round: calc(var(--thick) * 0.33);
|
|
44
|
+
--radius-pill: 100em;
|
|
45
|
+
|
|
46
|
+
display: inline-block;
|
|
47
|
+
position: relative;
|
|
48
|
+
width: var(--digit-width);
|
|
49
|
+
height: var(--digit-height);
|
|
50
|
+
|
|
51
|
+
/* prevents flex-shrink effect */
|
|
52
|
+
min-width: var(--digit-width);
|
|
53
|
+
min-height: var(--digit-height);
|
|
54
|
+
|
|
55
|
+
&.unknown {
|
|
56
|
+
width: var(--thick);
|
|
57
|
+
min-width: var(--thick);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.opacity-wrapper {
|
|
61
|
+
position: absolute;
|
|
62
|
+
width: 100%;
|
|
63
|
+
height: 100%;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.opacity-wrapper,
|
|
67
|
+
.opacity-wrapper .segment {
|
|
68
|
+
transition-property: background-color, border-color, opacity, visibility;
|
|
69
|
+
transition-duration: var(--transition-duration);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.opacity-wrapper.off.on .segment.off,
|
|
73
|
+
.opacity-wrapper.on .segment.off,
|
|
74
|
+
.opacity-wrapper.off .segment.on {
|
|
75
|
+
visibility: hidden;
|
|
76
|
+
}
|
|
77
|
+
.opacity-wrapper.off .segment.off,
|
|
78
|
+
.opacity-wrapper.on .segment.on {
|
|
79
|
+
visibility: visible;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.opacity-wrapper.on {
|
|
83
|
+
opacity: var(--opacity-on);
|
|
84
|
+
}
|
|
85
|
+
.opacity-wrapper.off {
|
|
86
|
+
opacity: var(--opacity-off);
|
|
87
|
+
}
|
|
88
|
+
.opacity-wrapper.off.on {
|
|
89
|
+
opacity: 0;
|
|
90
|
+
}
|
|
91
|
+
.opacity-wrapper.on:not(.off) .segment.on {
|
|
92
|
+
opacity: 1;
|
|
93
|
+
}
|
|
94
|
+
.opacity-wrapper.on:not(.off) .segment.off {
|
|
95
|
+
opacity: 0;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* segments */
|
|
99
|
+
.segment {
|
|
100
|
+
--th-half-100: calc(100% - var(--th-half));
|
|
101
|
+
--shft: var(--corner-shift);
|
|
102
|
+
|
|
103
|
+
background-color: var(--color);
|
|
104
|
+
display: block;
|
|
105
|
+
position: absolute;
|
|
106
|
+
|
|
107
|
+
&.segment.off {
|
|
108
|
+
background-color: var(--color-off);
|
|
109
|
+
border-color: var(--color-off);
|
|
110
|
+
}
|
|
111
|
+
/* vertical segments */
|
|
112
|
+
&.vertical {
|
|
113
|
+
width: var(--thick);
|
|
114
|
+
height: var(--length);
|
|
115
|
+
left: 0;
|
|
116
|
+
|
|
117
|
+
&.B,
|
|
118
|
+
&.C {
|
|
119
|
+
left: auto;
|
|
120
|
+
right: 0;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
&.E,
|
|
124
|
+
&.C {
|
|
125
|
+
bottom: calc(var(--th-half) + var(--sp-half));
|
|
126
|
+
}
|
|
127
|
+
&.F,
|
|
128
|
+
&.B {
|
|
129
|
+
top: calc(var(--th-half) + var(--sp-half));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* horizontal segments */
|
|
133
|
+
&.horizontal {
|
|
134
|
+
width: var(--length);
|
|
135
|
+
height: var(--thick);
|
|
136
|
+
left: calc(var(--th-half) + var(--sp-half));
|
|
137
|
+
|
|
138
|
+
&.A,
|
|
139
|
+
&.D {
|
|
140
|
+
width: calc(var(--length) + var(--shft) * 2);
|
|
141
|
+
left: calc(var(--th-half) + var(--sp-half) - var(--shft));
|
|
142
|
+
}
|
|
143
|
+
&.A {
|
|
144
|
+
top: calc(var(--filament) + var(--shft));
|
|
145
|
+
}
|
|
146
|
+
&.D {
|
|
147
|
+
bottom: calc(var(--filament) + var(--shft));
|
|
148
|
+
}
|
|
149
|
+
&.G {
|
|
150
|
+
bottom: calc(var(--length) + var(--spacing));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* spearheads */
|
|
155
|
+
&.horizontal {
|
|
156
|
+
clip-path: polygon(
|
|
157
|
+
0 50%,
|
|
158
|
+
var(--th-half) 0,
|
|
159
|
+
var(--th-half-100) 0,
|
|
160
|
+
100% 50%,
|
|
161
|
+
var(--th-half-100) 100%,
|
|
162
|
+
var(--th-half) 100%
|
|
163
|
+
);
|
|
164
|
+
&.A {
|
|
165
|
+
/* x y */
|
|
166
|
+
clip-path: polygon(
|
|
167
|
+
0 calc(50% - var(--shft)),
|
|
168
|
+
calc(var(--th-half) - var(--shft)) 0,
|
|
169
|
+
calc(var(--th-half-100) + var(--shft)) 0,
|
|
170
|
+
100% calc(50% - var(--shft)),
|
|
171
|
+
calc(var(--th-half-100) - var(--shft)) 100%,
|
|
172
|
+
calc(var(--th-half) + var(--shft)) 100%
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
&.D {
|
|
176
|
+
/* x y */
|
|
177
|
+
clip-path: polygon(
|
|
178
|
+
0 calc(50% + var(--shft)),
|
|
179
|
+
calc(var(--th-half) + var(--shft)) 0,
|
|
180
|
+
calc(var(--th-half-100) - var(--shft)) 0,
|
|
181
|
+
100% calc(50% + var(--shft)),
|
|
182
|
+
calc(var(--th-half-100) + var(--shft)) 100%,
|
|
183
|
+
calc(var(--th-half) - var(--shft)) 100%
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
&.vertical {
|
|
188
|
+
clip-path: polygon(
|
|
189
|
+
50% 0,
|
|
190
|
+
0 var(--th-half),
|
|
191
|
+
0 var(--th-half-100),
|
|
192
|
+
50% 100%,
|
|
193
|
+
100% var(--th-half-100),
|
|
194
|
+
100% var(--th-half)
|
|
195
|
+
);
|
|
196
|
+
&.B {
|
|
197
|
+
/* x y */
|
|
198
|
+
clip-path: polygon(
|
|
199
|
+
calc(50% + var(--shft)) 0,
|
|
200
|
+
0 calc(var(--th-half) + var(--shft)),
|
|
201
|
+
0 var(--th-half-100),
|
|
202
|
+
50% 100%,
|
|
203
|
+
100% var(--th-half-100),
|
|
204
|
+
100% calc(var(--th-half) - var(--shft))
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
&.C {
|
|
208
|
+
/* x y */
|
|
209
|
+
clip-path: polygon(
|
|
210
|
+
50% 0,
|
|
211
|
+
0 var(--th-half),
|
|
212
|
+
0 calc(var(--th-half-100) - var(--shft)),
|
|
213
|
+
calc(50% + var(--shft)) 100%,
|
|
214
|
+
100% calc(var(--th-half-100) + var(--shft)),
|
|
215
|
+
100% var(--th-half)
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
&.E {
|
|
219
|
+
/* x y */
|
|
220
|
+
clip-path: polygon(
|
|
221
|
+
50% 0,
|
|
222
|
+
0 var(--th-half),
|
|
223
|
+
0 calc(var(--th-half-100) + var(--shft)),
|
|
224
|
+
calc(50% - var(--shft)) 100%,
|
|
225
|
+
100% calc(var(--th-half-100) - var(--shft)),
|
|
226
|
+
100% var(--th-half)
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
&.F {
|
|
230
|
+
/* x y */
|
|
231
|
+
clip-path: polygon(
|
|
232
|
+
calc(50% - var(--shft)) 0,
|
|
233
|
+
0 calc(var(--th-half) - var(--shft)),
|
|
234
|
+
0 var(--th-half-100),
|
|
235
|
+
50% 100%,
|
|
236
|
+
100% var(--th-half-100),
|
|
237
|
+
100% calc(var(--th-half) + var(--shft))
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/* segment shapes */
|
|
244
|
+
&.shape-rect .segment.segment {
|
|
245
|
+
clip-path: unset;
|
|
246
|
+
}
|
|
247
|
+
&.shape-round .segment.segment {
|
|
248
|
+
border-radius: var(--radius-round);
|
|
249
|
+
clip-path: unset;
|
|
250
|
+
}
|
|
251
|
+
&.shape-pill .segment.segment {
|
|
252
|
+
border-radius: var(--radius-pill);
|
|
253
|
+
clip-path: unset;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
&.ampm {
|
|
257
|
+
--digit-width: calc(var(--length) + var(--thick) + var(--spacing));
|
|
258
|
+
|
|
259
|
+
.segment {
|
|
260
|
+
background: var(--color);
|
|
261
|
+
width: var(--digit-width);
|
|
262
|
+
height: var(--length);
|
|
263
|
+
|
|
264
|
+
mask-origin: fill-box;
|
|
265
|
+
mask-position: center;
|
|
266
|
+
mask-repeat: no-repeat;
|
|
267
|
+
mask-size:
|
|
268
|
+
auto 85%,
|
|
269
|
+
contain;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.AM {
|
|
273
|
+
bottom: calc(var(--digit-height) / 2 + var(--thick) / 4);
|
|
274
|
+
mask-image: var(--svg-am);
|
|
275
|
+
}
|
|
276
|
+
&.shape-rect .AM,
|
|
277
|
+
&.shape-pill .AM,
|
|
278
|
+
&.shape-round .AM {
|
|
279
|
+
mask-composite: exclude;
|
|
280
|
+
mask-image: var(--svg-am), linear-gradient(var(--color) 0 0);
|
|
281
|
+
}
|
|
282
|
+
.PM {
|
|
283
|
+
top: calc(var(--digit-height) / 2 + var(--thick) / 4);
|
|
284
|
+
mask-image: var(--svg-pm);
|
|
285
|
+
}
|
|
286
|
+
&.shape-rect .PM,
|
|
287
|
+
&.shape-pill .PM,
|
|
288
|
+
&.shape-round .PM {
|
|
289
|
+
mask-composite: exclude;
|
|
290
|
+
mask-image: var(--svg-pm), linear-gradient(var(--color) 0 0);
|
|
291
|
+
}
|
|
292
|
+
&.shape-round .segment {
|
|
293
|
+
border-radius: var(--radius-round);
|
|
294
|
+
}
|
|
295
|
+
&.shape-pill .segment {
|
|
296
|
+
border-radius: var(--radius-pill);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
&.dot,
|
|
301
|
+
&.colon {
|
|
302
|
+
--digit-width: calc(var(--thick) * 3);
|
|
303
|
+
|
|
304
|
+
& .segment {
|
|
305
|
+
--dot-border-width: calc(var(--thick) * 0.6);
|
|
306
|
+
|
|
307
|
+
border: var(--dot-border-width) solid var(--color); /* dot made from border to have same size on zoom */
|
|
308
|
+
position: absolute;
|
|
309
|
+
width: 0;
|
|
310
|
+
height: 0;
|
|
311
|
+
left: calc(var(--digit-width) / 2 - var(--dot-border-width));
|
|
312
|
+
}
|
|
313
|
+
/* lower part of a colon */
|
|
314
|
+
.segment.D1 {
|
|
315
|
+
top: calc(var(--digit-height) / 3 - var(--thick) / 2);
|
|
316
|
+
}
|
|
317
|
+
/* upper part of a colon */
|
|
318
|
+
.segment.D2 {
|
|
319
|
+
bottom: calc(var(--digit-height) / 3 - var(--thick) / 2);
|
|
320
|
+
}
|
|
321
|
+
/* dot itself */
|
|
322
|
+
.segment.DP {
|
|
323
|
+
bottom: 0;
|
|
324
|
+
}
|
|
325
|
+
&.shape-default .segment {
|
|
326
|
+
border-radius: var(--radius-pill);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
`,
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
export default css;
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
type Style = {
|
|
2
|
+
id: string;
|
|
3
|
+
content: string;
|
|
3
4
|
};
|
|
5
|
+
declare const useHeadStyleInjection: (css: string, cssHash: string, dependencies?: never[], scoped?: boolean) => {
|
|
6
|
+
[x: string]: boolean | undefined;
|
|
7
|
+
};
|
|
8
|
+
export declare class StyleInjector {
|
|
9
|
+
#private;
|
|
10
|
+
private static instance;
|
|
11
|
+
constructor();
|
|
12
|
+
add(s: Style): void;
|
|
13
|
+
remove(s: Style): void;
|
|
14
|
+
has(s: Style): boolean;
|
|
15
|
+
}
|
|
4
16
|
export default useHeadStyleInjection;
|
|
@@ -4,67 +4,84 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
4
4
|
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");
|
|
5
5
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
6
|
};
|
|
7
|
-
var
|
|
7
|
+
var _StyleInjector_state;
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.StyleInjector = void 0;
|
|
9
10
|
const react_1 = require("react");
|
|
10
|
-
const
|
|
11
|
+
const scopeAttributePrefix = 'data-style-scope-';
|
|
11
12
|
// Runtime style injection
|
|
12
|
-
const useHeadStyleInjection = (css,
|
|
13
|
+
const useHeadStyleInjection = (css, cssHash, dependencies = [], scoped = true // isolate css behind @scope
|
|
13
14
|
) => {
|
|
14
|
-
const
|
|
15
|
-
const
|
|
15
|
+
const injector = new StyleInjector(); // singleton!
|
|
16
|
+
const scopeAttribute = `${scopeAttributePrefix}-${cssHash}`;
|
|
16
17
|
const style = {
|
|
17
|
-
id: `
|
|
18
|
-
|
|
18
|
+
id: `css_id__${cssHash}`,
|
|
19
|
+
content: scoped ? wrapWithScope(css, scopeAttribute) : css,
|
|
19
20
|
};
|
|
20
21
|
(0, react_1.useInsertionEffect)(() => {
|
|
21
|
-
|
|
22
|
-
return () =>
|
|
22
|
+
injector.add(style);
|
|
23
|
+
return () => injector.remove(style);
|
|
23
24
|
}, dependencies);
|
|
24
25
|
return {
|
|
25
|
-
[scopeAttribute]:
|
|
26
|
+
[scopeAttribute]: scoped ? true : undefined,
|
|
26
27
|
};
|
|
27
28
|
};
|
|
28
|
-
class
|
|
29
|
+
class StyleInjector {
|
|
29
30
|
constructor() {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (!StyleInjectionState.instance) {
|
|
34
|
-
StyleInjectionState.instance = this; // create first instance if needed
|
|
31
|
+
_StyleInjector_state.set(this, new Map());
|
|
32
|
+
if (!StyleInjector.instance) {
|
|
33
|
+
StyleInjector.instance = this;
|
|
35
34
|
}
|
|
36
|
-
return
|
|
35
|
+
return StyleInjector.instance;
|
|
37
36
|
}
|
|
38
37
|
add(s) {
|
|
39
|
-
if (
|
|
40
|
-
__classPrivateFieldGet(this,
|
|
41
|
-
|
|
38
|
+
if (this.has(s)) {
|
|
39
|
+
const count = __classPrivateFieldGet(this, _StyleInjector_state, "f").get(s.id) + 1;
|
|
40
|
+
__classPrivateFieldGet(this, _StyleInjector_state, "f").set(s.id, count);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
__classPrivateFieldGet(this, _StyleInjector_state, "f").set(s.id, 1);
|
|
44
|
+
}
|
|
45
|
+
if (__classPrivateFieldGet(this, _StyleInjector_state, "f").get(s.id) === 1) {
|
|
46
|
+
document.head.appendChild(createStyleElement(s));
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
remove(s) {
|
|
45
50
|
var _a;
|
|
46
51
|
if (this.has(s)) {
|
|
47
|
-
__classPrivateFieldGet(this,
|
|
52
|
+
const count = __classPrivateFieldGet(this, _StyleInjector_state, "f").get(s.id) - 1;
|
|
53
|
+
__classPrivateFieldGet(this, _StyleInjector_state, "f").set(s.id, count);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
console.warn(`(at useStyleInjection.ts) unable to remove style: ${s.id}`);
|
|
57
|
+
}
|
|
58
|
+
if (__classPrivateFieldGet(this, _StyleInjector_state, "f").get(s.id) === 0) {
|
|
48
59
|
(_a = document.head.querySelector(`#${s.id}`)) === null || _a === void 0 ? void 0 : _a.remove();
|
|
49
60
|
}
|
|
50
61
|
}
|
|
51
62
|
has(s) {
|
|
52
|
-
return __classPrivateFieldGet(this,
|
|
63
|
+
return __classPrivateFieldGet(this, _StyleInjector_state, "f").has(s.id);
|
|
53
64
|
}
|
|
54
65
|
}
|
|
55
|
-
|
|
56
|
-
|
|
66
|
+
exports.StyleInjector = StyleInjector;
|
|
67
|
+
_StyleInjector_state = new WeakMap();
|
|
68
|
+
const createStyleElement = (style) => {
|
|
57
69
|
const el = document.createElement('style');
|
|
58
|
-
el.innerHTML = content;
|
|
59
|
-
if (id !== '')
|
|
60
|
-
el.id = id;
|
|
70
|
+
el.innerHTML = style.content;
|
|
71
|
+
if (style.id !== '')
|
|
72
|
+
el.id = style.id;
|
|
61
73
|
return el;
|
|
62
74
|
};
|
|
63
|
-
const wrapWithScope = (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
75
|
+
const wrapWithScope = (css, scopeAttribute) => {
|
|
76
|
+
// unused bc @scope at-rule does not work in Firefox
|
|
77
|
+
const scoped = `@scope ([${scopeAttribute}]) {` +
|
|
78
|
+
`:scope { display: contents; }` +
|
|
79
|
+
`${css}` +
|
|
80
|
+
`}`;
|
|
81
|
+
const isolated = `[${scopeAttribute}] { display: contents; }` +
|
|
82
|
+
`[${scopeAttribute}] {` +
|
|
83
|
+
`${css}` +
|
|
84
|
+
`}`;
|
|
68
85
|
return isolated;
|
|
69
86
|
};
|
|
70
87
|
exports.default = useHeadStyleInjection;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-led-digit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "react component for 7-segment display (digit), includes dot, colon and am-pm digits",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"build-storybook": "storybook build",
|
|
12
12
|
"build-ts": "tsc --project tsconfig.build.json",
|
|
13
13
|
"clean": "rimraf lib",
|
|
14
|
-
"css-copy": "npx cpy src/**/*.css lib",
|
|
14
|
+
"css-copy": "npx cpy src/**/*.css lib && npx cpy src/**/*.css.* lib",
|
|
15
15
|
"css-to-js-watch": "node css-to-js --watch",
|
|
16
16
|
"css-to-js": "node css-to-js",
|
|
17
17
|
"dev": "npm-run-all --parallel storybook css-to-js-watch",
|
|
@@ -36,16 +36,9 @@
|
|
|
36
36
|
"engines": {
|
|
37
37
|
"node": ">=12.0"
|
|
38
38
|
},
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
"digit",
|
|
43
|
-
"react",
|
|
44
|
-
"component",
|
|
45
|
-
"seven-segments",
|
|
46
|
-
"display",
|
|
47
|
-
"clock"
|
|
48
|
-
],
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"clsx": "^2.1.1"
|
|
41
|
+
},
|
|
49
42
|
"devDependencies": {
|
|
50
43
|
"@chromatic-com/storybook": "^1.6.1",
|
|
51
44
|
"@storybook/addon-essentials": "^8.2.4",
|
|
@@ -61,7 +54,6 @@
|
|
|
61
54
|
"@typescript-eslint/eslint-plugin": "^7.16.1",
|
|
62
55
|
"@typescript-eslint/parser": "^7.16.1",
|
|
63
56
|
"chokidar": "^4.0.1",
|
|
64
|
-
"clsx": "^2.1.1",
|
|
65
57
|
"cpy-cli": "^5.0.0",
|
|
66
58
|
"eslint": "^8.57.0",
|
|
67
59
|
"eslint-config-prettier": "^9.1.0",
|
|
@@ -79,6 +71,16 @@
|
|
|
79
71
|
"ts-jest": "^29.2.3",
|
|
80
72
|
"typescript": "^5.5.3"
|
|
81
73
|
},
|
|
74
|
+
"keywords": [
|
|
75
|
+
"7-segment",
|
|
76
|
+
"led",
|
|
77
|
+
"digit",
|
|
78
|
+
"react",
|
|
79
|
+
"component",
|
|
80
|
+
"seven-segments",
|
|
81
|
+
"display",
|
|
82
|
+
"clock"
|
|
83
|
+
],
|
|
82
84
|
"lint-staged": {
|
|
83
85
|
"*.ts": "eslint --cache --cache-location .eslintcache --fix"
|
|
84
86
|
},
|