@seedgrid/fe-components 0.2.9 → 2026.3.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/dist/buttons/SgFloatActionButton.d.ts.map +1 -1
- package/dist/buttons/SgFloatActionButton.js +168 -38
- package/dist/commons/SgAvatar.d.ts +66 -0
- package/dist/commons/SgAvatar.d.ts.map +1 -0
- package/dist/commons/SgAvatar.js +136 -0
- package/dist/commons/SgSkeleton.d.ts +16 -0
- package/dist/commons/SgSkeleton.d.ts.map +1 -0
- package/dist/commons/SgSkeleton.js +58 -0
- package/dist/commons/SgToaster.d.ts +9 -0
- package/dist/commons/SgToaster.d.ts.map +1 -1
- package/dist/commons/SgToaster.js +86 -17
- package/dist/digits/discard-digit/SgDiscardDigit.d.ts +39 -0
- package/dist/digits/discard-digit/SgDiscardDigit.d.ts.map +1 -0
- package/dist/digits/discard-digit/SgDiscardDigit.js +303 -0
- package/dist/digits/discard-digit/index.d.ts +3 -0
- package/dist/digits/discard-digit/index.d.ts.map +1 -0
- package/dist/digits/discard-digit/index.js +1 -0
- package/dist/digits/fade-digit/SgFadeDigit.d.ts +27 -0
- package/dist/digits/fade-digit/SgFadeDigit.d.ts.map +1 -0
- package/dist/digits/fade-digit/SgFadeDigit.js +85 -0
- package/dist/digits/fade-digit/index.d.ts +3 -0
- package/dist/digits/fade-digit/index.d.ts.map +1 -0
- package/dist/digits/fade-digit/index.js +1 -0
- package/dist/digits/flip-digit/SgFlipDigit.d.ts +27 -0
- package/dist/digits/flip-digit/SgFlipDigit.d.ts.map +1 -0
- package/dist/digits/flip-digit/SgFlipDigit.js +70 -0
- package/dist/digits/flip-digit/index.d.ts.map +1 -0
- package/dist/digits/matrix-digit/SgMatrixDigit.d.ts +32 -0
- package/dist/digits/matrix-digit/SgMatrixDigit.d.ts.map +1 -0
- package/dist/digits/matrix-digit/SgMatrixDigit.js +86 -0
- package/dist/digits/matrix-digit/index.d.ts +3 -0
- package/dist/digits/matrix-digit/index.d.ts.map +1 -0
- package/dist/digits/matrix-digit/index.js +1 -0
- package/dist/digits/neon-digit/SgNeonDigit.d.ts +37 -0
- package/dist/digits/neon-digit/SgNeonDigit.d.ts.map +1 -0
- package/dist/digits/neon-digit/SgNeonDigit.js +59 -0
- package/dist/digits/neon-digit/index.d.ts +3 -0
- package/dist/digits/neon-digit/index.d.ts.map +1 -0
- package/dist/digits/neon-digit/index.js +1 -0
- package/dist/digits/roller3d-digit/SgRoller3DDigit.d.ts +37 -0
- package/dist/digits/roller3d-digit/SgRoller3DDigit.d.ts.map +1 -0
- package/dist/digits/roller3d-digit/SgRoller3DDigit.js +47 -0
- package/dist/digits/roller3d-digit/index.d.ts +3 -0
- package/dist/digits/roller3d-digit/index.d.ts.map +1 -0
- package/dist/digits/roller3d-digit/index.js +1 -0
- package/dist/environment/SgEnvironmentProvider.d.ts +1 -0
- package/dist/environment/SgEnvironmentProvider.d.ts.map +1 -1
- package/dist/environment/SgEnvironmentProvider.js +51 -12
- package/dist/gadgets/clock/SgClock.d.ts +3 -1
- package/dist/gadgets/clock/SgClock.d.ts.map +1 -1
- package/dist/gadgets/clock/SgClock.js +111 -180
- package/dist/gadgets/clock/SgTimeProvider.d.ts +1 -0
- package/dist/gadgets/clock/SgTimeProvider.d.ts.map +1 -1
- package/dist/gadgets/clock/SgTimeProvider.js +11 -4
- package/dist/gadgets/gauge/SgLinearGauge.d.ts +59 -0
- package/dist/gadgets/gauge/SgLinearGauge.d.ts.map +1 -0
- package/dist/gadgets/gauge/SgLinearGauge.js +258 -0
- package/dist/gadgets/gauge/SgRadialGauge.d.ts +73 -0
- package/dist/gadgets/gauge/SgRadialGauge.d.ts.map +1 -0
- package/dist/gadgets/gauge/SgRadialGauge.js +311 -0
- package/dist/gadgets/gauge/index.d.ts +5 -0
- package/dist/gadgets/gauge/index.d.ts.map +1 -0
- package/dist/gadgets/gauge/index.js +2 -0
- package/dist/gadgets/qr-code/SgQRCode.d.ts +25 -0
- package/dist/gadgets/qr-code/SgQRCode.d.ts.map +1 -0
- package/dist/gadgets/qr-code/SgQRCode.js +75 -0
- package/dist/gadgets/qr-code/index.d.ts +3 -0
- package/dist/gadgets/qr-code/index.d.ts.map +1 -0
- package/dist/gadgets/qr-code/index.js +1 -0
- package/dist/gadgets/string-animator/SgStringAnimator.d.ts +91 -0
- package/dist/gadgets/string-animator/SgStringAnimator.d.ts.map +1 -0
- package/dist/gadgets/string-animator/SgStringAnimator.js +145 -0
- package/dist/gadgets/string-animator/index.d.ts +3 -0
- package/dist/gadgets/string-animator/index.d.ts.map +1 -0
- package/dist/gadgets/string-animator/index.js +1 -0
- package/dist/i18n/en-US.json +9 -1
- package/dist/i18n/es.json +55 -47
- package/dist/i18n/index.d.ts +32 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/pt-BR.json +9 -1
- package/dist/i18n/pt-PT.json +9 -1
- package/dist/index.d.ts +53 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -1
- package/dist/inputs/SgAutocomplete.js +21 -5
- package/dist/inputs/SgCombobox.d.ts +26 -0
- package/dist/inputs/SgCombobox.d.ts.map +1 -0
- package/dist/inputs/SgCombobox.js +354 -0
- package/dist/inputs/SgInputOTP.d.ts.map +1 -1
- package/dist/inputs/SgInputOTP.js +9 -2
- package/dist/inputs/SgRadioGroup.d.ts +37 -0
- package/dist/inputs/SgRadioGroup.d.ts.map +1 -0
- package/dist/inputs/SgRadioGroup.js +139 -0
- package/dist/inputs/SgRating.d.ts +55 -0
- package/dist/inputs/SgRating.d.ts.map +1 -0
- package/dist/inputs/SgRating.js +135 -0
- package/dist/inputs/SgSlider.d.ts +20 -0
- package/dist/inputs/SgSlider.d.ts.map +1 -0
- package/dist/inputs/SgSlider.js +40 -0
- package/dist/inputs/SgStepperInput.d.ts +22 -0
- package/dist/inputs/SgStepperInput.d.ts.map +1 -0
- package/dist/inputs/SgStepperInput.js +51 -0
- package/dist/inputs/SgTextEditor.d.ts +1 -0
- package/dist/inputs/SgTextEditor.d.ts.map +1 -1
- package/dist/inputs/SgTextEditor.js +19 -3
- package/dist/inputs/SgToggleSwitch.d.ts +36 -0
- package/dist/inputs/SgToggleSwitch.d.ts.map +1 -0
- package/dist/inputs/SgToggleSwitch.js +174 -0
- package/dist/layout/SgAccordion.d.ts +39 -0
- package/dist/layout/SgAccordion.d.ts.map +1 -0
- package/dist/layout/SgAccordion.js +116 -0
- package/dist/layout/SgBreadcrumb.d.ts +33 -0
- package/dist/layout/SgBreadcrumb.d.ts.map +1 -0
- package/dist/layout/SgBreadcrumb.js +121 -0
- package/dist/layout/SgCarousel.d.ts +43 -0
- package/dist/layout/SgCarousel.d.ts.map +1 -0
- package/dist/layout/SgCarousel.js +166 -0
- package/dist/layout/SgDockLayout.d.ts +14 -0
- package/dist/layout/SgDockLayout.d.ts.map +1 -1
- package/dist/layout/SgDockLayout.js +145 -13
- package/dist/layout/SgDockScreen.d.ts +15 -0
- package/dist/layout/SgDockScreen.d.ts.map +1 -0
- package/dist/layout/SgDockScreen.js +13 -0
- package/dist/layout/SgDockZone.d.ts.map +1 -1
- package/dist/layout/SgDockZone.js +36 -2
- package/dist/layout/SgExpandablePanel.d.ts +50 -0
- package/dist/layout/SgExpandablePanel.d.ts.map +1 -0
- package/dist/layout/SgExpandablePanel.js +302 -0
- package/dist/layout/SgMainPanel.d.ts.map +1 -1
- package/dist/layout/SgMainPanel.js +36 -14
- package/dist/layout/SgMenu.d.ts +91 -0
- package/dist/layout/SgMenu.d.ts.map +1 -0
- package/dist/layout/SgMenu.js +939 -0
- package/dist/layout/SgPageControl.d.ts +49 -0
- package/dist/layout/SgPageControl.d.ts.map +1 -0
- package/dist/layout/SgPageControl.js +152 -0
- package/dist/layout/SgPanel.d.ts.map +1 -1
- package/dist/layout/SgPanel.js +10 -1
- package/dist/layout/SgScreen.d.ts +2 -0
- package/dist/layout/SgScreen.d.ts.map +1 -1
- package/dist/layout/SgScreen.js +4 -2
- package/dist/layout/SgToolBar.d.ts +9 -3
- package/dist/layout/SgToolBar.d.ts.map +1 -1
- package/dist/layout/SgToolBar.js +461 -55
- package/dist/menus/SgDockMenu.d.ts +62 -0
- package/dist/menus/SgDockMenu.d.ts.map +1 -0
- package/dist/menus/SgDockMenu.js +480 -0
- package/dist/others/SgPlayground.js +73 -73
- package/package.json +72 -57
- package/dist/gadgets/flip-digit/SgFlipDigit.d.ts +0 -23
- package/dist/gadgets/flip-digit/SgFlipDigit.d.ts.map +0 -1
- package/dist/gadgets/flip-digit/SgFlipDigit.js +0 -118
- package/dist/gadgets/flip-digit/index.d.ts.map +0 -1
- /package/dist/{gadgets → digits}/flip-digit/index.d.ts +0 -0
- /package/dist/{gadgets → digits}/flip-digit/index.js +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
// CSS from @pqina/flip v1.8.4 (MIT) — embedded to avoid CSS import in tsc-only build
|
|
4
|
+
const FLIP_CSS = `.tick{box-sizing:border-box;-webkit-user-select:none;-ms-user-select:none;user-select:none;cursor:default;position:relative;z-index:1;line-height:1.4}.tick *{box-sizing:inherit}.tick [data-view]{max-width:100%}.tick span[data-view]{display:inline-block}.tick .tick-credits{display:none}.tick [data-layout~=pad]{margin:-.25em}.tick [data-layout~=pad]>*{margin:.25em}.tick [data-layout~=horizontal]{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-pack:center;justify-content:center}.tick [data-layout~=horizontal][data-layout~=baseline]{-ms-flex-align:baseline;align-items:baseline}.tick [data-layout~=horizontal][data-layout~=center]{-ms-flex-pack:center;justify-content:center}.tick [data-layout~=horizontal][data-layout~=right]{-ms-flex-pack:end;justify-content:flex-end}.tick [data-layout~=horizontal][data-layout~=left]{-ms-flex-pack:start;justify-content:flex-start}.tick [data-layout~=horizontal][data-layout~=fill],.tick [data-layout~=horizontal][data-layout~=stretch]{-ms-flex-line-pack:stretch;align-content:stretch;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.tick [data-layout~=horizontal][data-layout~=fill]>*,.tick [data-layout~=horizontal][data-layout~=stretch]>*{-ms-flex:1 0 0px;flex:1 0 0;width:100%}.tick [data-layout~=horizontal][data-layout~=multi-line]{-ms-flex-wrap:wrap;flex-wrap:wrap}.tick [data-layout~=horizontal][data-layout~=fit]{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-ms-flex-line-pack:center;align-content:center;white-space:nowrap;-ms-flex-pack:start;justify-content:flex-start}.tick [data-layout~=vertical]{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center}.tick [data-layout~=vertical][data-layout~=top]{-ms-flex-pack:start;justify-content:flex-start}.tick [data-layout~=vertical][data-layout~=bottom]{-ms-flex-pack:end;justify-content:flex-end;min-height:100%}.tick [data-layout~=vertical][data-layout~=middle]{-ms-flex-pack:center;justify-content:center;min-height:100%}.tick [data-layout~=vertical][data-layout~=left]{-ms-flex-align:start;align-items:flex-start}.tick [data-layout~=vertical][data-layout~=right]{-ms-flex-align:end;align-items:flex-end}.tick [data-layout~=vertical][data-layout~=center]{text-align:center}.tick [data-layout~=vertical][data-layout~=fill],.tick [data-layout~=vertical][data-layout~=stretch]{-ms-flex-align:stretch;align-items:stretch;min-height:100%}.tick [data-layout~=vertical][data-layout~=fill]>*,.tick [data-layout~=vertical][data-layout~=stretch]>*{-ms-flex:1 0 0px;flex:1 0 0}.tick [data-layout~=vertical]>*+*{margin-top:.5em}.tick [data-layout~=overlay]{position:relative}.tick [data-layout~=overlay]>*{margin:0}.tick [data-layout~=overlay][data-layout~=center]{text-align:center}.tick [data-layout~=overlay][data-layout~=left]{text-align:left}.tick [data-layout~=overlay][data-layout~=right]{text-align:right}.tick [data-layout~=overlay]>[data-overlay=fill],.tick [data-layout~=overlay]>[data-overlay=stretch]{position:absolute;left:0;right:0;top:0;bottom:0}.tick [data-layout~=overlay]>[data-overlay=center]{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;position:absolute;left:0;right:0;top:0;bottom:0}.tick-flip{position:relative;text-align:center}.tick-flip *{border-radius:inherit;white-space:pre;letter-spacing:inherit;text-indent:inherit}.tick-flip-front{border-bottom-left-radius:0;border-bottom-right-radius:0}.tick-flip-back{border-top-left-radius:0;border-top-right-radius:0}.tick-flip-spacer{display:block;visibility:hidden}.tick-flip-shadow{position:absolute;left:1px;right:1px;top:1px;bottom:1px;color:transparent!important;background:transparent!important}.tick-flip-shadow-top{bottom:calc(50% - 1px)}.tick-flip-shadow-bottom{top:calc(50% + 1px)}.tick-flip-card-shadow{position:absolute;left:.15em;right:.15em;bottom:.125em;height:.5em;background-color:transparent;border-radius:0;opacity:0;transform-origin:0 100%;box-shadow:0 .125em .25em rgba(0,0,0,.5),0 .125em .5em rgba(0,0,0,.75);z-index:0}.tick-flip-card{position:absolute;z-index:1;left:0;top:0;width:100%;height:100%;perspective:4em}.tick-flip-panel-back,.tick-flip-panel-front{position:absolute;left:0;width:100%;height:51%;backface-visibility:hidden;transform-style:preserve-3d}.tick-flip-panel-back-text,.tick-flip-panel-front-text{position:absolute;left:-1px;top:0;right:-1px;height:100%;overflow:hidden}.tick-flip-panel-text-wrapper{position:absolute;left:0;top:0;right:0;height:100%}.tick-flip-panel-back-text .tick-flip-panel-text-wrapper{height:200%;top:-100%}.tick-flip-panel-front{transform-origin:center bottom;top:0;z-index:2;box-shadow:inset 0 1px hsla(0,0%,100%,.05)}.tick-flip-panel-back{transform-origin:center top;top:50%;z-index:1;box-shadow:inset 0 -1px rgba(0,0,0,.1)}.tick-flip-panel-back:after{z-index:1;content:"";position:absolute;left:0;top:0;width:100%;height:100%;background-image:linear-gradient(180deg,rgba(0,0,0,.3) 1px,rgba(0,0,0,.15) 0,transparent 30%)}.tick-flip-panel-back-shadow{z-index:2}.tick-flip-panel-back-highlight{z-index:3}.tick-flip-panel-back-highlight,.tick-flip-panel-back-shadow{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.tick-flip-panel-back-highlight,.tick-flip-panel-back-shadow,.tick-flip-panel-front-shadow{position:absolute;left:0;top:0;right:0;bottom:0;opacity:0}.tick-flip-panel-front-shadow{background-image:linear-gradient(0deg,rgba(0,0,0,.8),rgba(0,0,0,.3))}.tick-flip-panel-back-shadow{background-image:linear-gradient(180deg,rgba(0,0,0,.7),rgba(0,0,0,.5))}.tick-flip-panel-back-highlight{background-image:linear-gradient(180deg,hsla(0,0%,100%,.15),hsla(0,0%,100%,.3))}.tick [data-style*="shadow:inner"],.tick [data-style*="shadow:inner"] .tick-flip-card-shadow,.tick [data-style*="shadow:none"] .tick-flip-card-shadow,.tick [data-style*="shadow:none"] .tick-flip-panel-back,.tick [data-style*="shadow:none"] .tick-flip-panel-front,.tick [data-style*="shadow:none"] .tick-flip-shadow{box-shadow:none}.tick [data-style*="shadow:none"] .tick-flip-back:after,.tick [data-style*="shadow:none"] .tick-flip-panel-back-shadow,.tick [data-style*="shadow:none"] .tick-flip-panel-back-text:after,.tick [data-style*="shadow:none"] .tick-flip-panel-front-shadow{background-image:none}.tick [data-style*="rounded:none"]{border-radius:0}.tick [data-style*="rounded:panels"] .tick-flip-front,.tick [data-style*="rounded:panels"] .tick-flip-shadow-bottom{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.tick [data-style*="rounded:panels"] .tick-flip-back,.tick [data-style*="rounded:panels"] .tick-flip-panel-back:after,.tick [data-style*="rounded:panels"] .tick-flip-shadow-top{border-top-left-radius:inherit;border-top-right-radius:inherit}.tick-flip{margin-left:.0625em;margin-right:.0625em;min-width:1.125em;border-radius:.125em;letter-spacing:.25em;text-indent:.25em}.tick-flip-panel{color:#edebeb;background-color:#333232}.tick-flip-shadow{box-shadow:0 .125em .3125em rgba(0,0,0,.25),0 .02125em .06125em rgba(0,0,0,.25)}`;
|
|
5
|
+
let flipCssInjected = false;
|
|
6
|
+
function ensureFlipCss() {
|
|
7
|
+
if (flipCssInjected || typeof document === "undefined")
|
|
8
|
+
return;
|
|
9
|
+
if (document.getElementById("pqina-flip-css")) {
|
|
10
|
+
flipCssInjected = true;
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const style = document.createElement("style");
|
|
14
|
+
style.id = "pqina-flip-css";
|
|
15
|
+
style.textContent = FLIP_CSS;
|
|
16
|
+
document.head.appendChild(style);
|
|
17
|
+
flipCssInjected = true;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* SgFlipDigit - Animated flip card powered by @pqina/flip (MIT)
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* const [digit, setDigit] = useState("0");
|
|
25
|
+
* <SgFlipDigit value={digit} fontSize={70} />
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function SgFlipDigit({ value, fontSize = 70, className, }) {
|
|
29
|
+
const containerRef = React.useRef(null);
|
|
30
|
+
const tickRef = React.useRef(null);
|
|
31
|
+
const valueRef = React.useRef(value);
|
|
32
|
+
// Mount: inject CSS + create Tick instance
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
ensureFlipCss();
|
|
35
|
+
const el = containerRef.current;
|
|
36
|
+
if (!el)
|
|
37
|
+
return;
|
|
38
|
+
let cancelled = false;
|
|
39
|
+
let destroyFn = null;
|
|
40
|
+
// Dynamic import: @pqina/flip touches window/document at module evaluation,
|
|
41
|
+
// so it must never run on the server (SSR). useEffect is client-only.
|
|
42
|
+
import("@pqina/flip").then(({ default: Tick }) => {
|
|
43
|
+
if (cancelled || !el.isConnected)
|
|
44
|
+
return;
|
|
45
|
+
// Build the required inner DOM structure for @pqina/flip
|
|
46
|
+
const repeat = document.createElement("div");
|
|
47
|
+
repeat.setAttribute("data-repeat", "true");
|
|
48
|
+
repeat.setAttribute("aria-hidden", "true");
|
|
49
|
+
const flipSpan = document.createElement("span");
|
|
50
|
+
flipSpan.setAttribute("data-view", "flip");
|
|
51
|
+
repeat.appendChild(flipSpan);
|
|
52
|
+
el.appendChild(repeat);
|
|
53
|
+
tickRef.current = Tick.DOM.create(el, { value: valueRef.current });
|
|
54
|
+
destroyFn = () => Tick.DOM.destroy(el);
|
|
55
|
+
});
|
|
56
|
+
return () => {
|
|
57
|
+
cancelled = true;
|
|
58
|
+
destroyFn?.();
|
|
59
|
+
tickRef.current = null;
|
|
60
|
+
};
|
|
61
|
+
}, []);
|
|
62
|
+
// Update value
|
|
63
|
+
React.useEffect(() => {
|
|
64
|
+
valueRef.current = value;
|
|
65
|
+
if (tickRef.current) {
|
|
66
|
+
tickRef.current.value = value;
|
|
67
|
+
}
|
|
68
|
+
}, [value]);
|
|
69
|
+
return (_jsx("div", { ref: containerRef, className: ["tick", className].filter(Boolean).join(" "), style: { fontSize, display: "inline-block" } }));
|
|
70
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/digits/flip-digit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type SgMatrixDigitProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Text to render using matrix dots.
|
|
5
|
+
* Supports letters, numbers and common symbols.
|
|
6
|
+
*/
|
|
7
|
+
value: string;
|
|
8
|
+
/** Color of active dots. */
|
|
9
|
+
color?: string;
|
|
10
|
+
/** Background color of the matrix container. */
|
|
11
|
+
backgroundColor?: string;
|
|
12
|
+
/** Color of inactive dots. */
|
|
13
|
+
offColor?: string;
|
|
14
|
+
/** Dot size in pixels. */
|
|
15
|
+
dotSize?: number;
|
|
16
|
+
/** Gap between dots in pixels. */
|
|
17
|
+
gap?: number;
|
|
18
|
+
/** Gap between characters in pixels. */
|
|
19
|
+
charGap?: number;
|
|
20
|
+
/** Internal padding in pixels. */
|
|
21
|
+
padding?: number;
|
|
22
|
+
/** Border radius of the matrix container in pixels. */
|
|
23
|
+
rounded?: number;
|
|
24
|
+
/** Add a subtle glow around active dots. */
|
|
25
|
+
glow?: boolean;
|
|
26
|
+
/** Additional CSS classes for the outer wrapper. */
|
|
27
|
+
className?: string;
|
|
28
|
+
/** Additional CSS style for the outer wrapper. */
|
|
29
|
+
style?: React.CSSProperties;
|
|
30
|
+
};
|
|
31
|
+
export declare function SgMatrixDigit({ value, color, backgroundColor, offColor, dotSize, gap, charGap, padding, rounded, glow, className, style }: Readonly<SgMatrixDigitProps>): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
//# sourceMappingURL=SgMatrixDigit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SgMatrixDigit.d.ts","sourceRoot":"","sources":["../../../src/digits/matrix-digit/SgMatrixDigit.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AAuDF,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAiB,EACjB,eAA2B,EAC3B,QAAsC,EACtC,OAAW,EACX,GAAO,EACP,OAAW,EACX,OAAW,EACX,OAAY,EACZ,IAAW,EACX,SAAS,EACT,KAAK,EACN,EAAE,QAAQ,CAAC,kBAAkB,CAAC,2CAyD9B"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
function cn(...parts) {
|
|
4
|
+
return parts.filter(Boolean).join(" ");
|
|
5
|
+
}
|
|
6
|
+
const MATRIX_GLYPHS = {
|
|
7
|
+
" ": ["00000", "00000", "00000", "00000", "00000", "00000", "00000"],
|
|
8
|
+
"0": ["01110", "10001", "10011", "10101", "11001", "10001", "01110"],
|
|
9
|
+
"1": ["00100", "01100", "00100", "00100", "00100", "00100", "01110"],
|
|
10
|
+
"2": ["01110", "10001", "00001", "00010", "00100", "01000", "11111"],
|
|
11
|
+
"3": ["11110", "00001", "00001", "01110", "00001", "00001", "11110"],
|
|
12
|
+
"4": ["00010", "00110", "01010", "10010", "11111", "00010", "00010"],
|
|
13
|
+
"5": ["11111", "10000", "11110", "00001", "00001", "10001", "01110"],
|
|
14
|
+
"6": ["00110", "01000", "10000", "11110", "10001", "10001", "01110"],
|
|
15
|
+
"7": ["11111", "00001", "00010", "00100", "01000", "01000", "01000"],
|
|
16
|
+
"8": ["01110", "10001", "10001", "01110", "10001", "10001", "01110"],
|
|
17
|
+
"9": ["01110", "10001", "10001", "01111", "00001", "00010", "11100"],
|
|
18
|
+
A: ["01110", "10001", "10001", "11111", "10001", "10001", "10001"],
|
|
19
|
+
B: ["11110", "10001", "10001", "11110", "10001", "10001", "11110"],
|
|
20
|
+
C: ["01111", "10000", "10000", "10000", "10000", "10000", "01111"],
|
|
21
|
+
D: ["11110", "10001", "10001", "10001", "10001", "10001", "11110"],
|
|
22
|
+
E: ["11111", "10000", "10000", "11110", "10000", "10000", "11111"],
|
|
23
|
+
F: ["11111", "10000", "10000", "11110", "10000", "10000", "10000"],
|
|
24
|
+
G: ["01111", "10000", "10000", "10111", "10001", "10001", "01110"],
|
|
25
|
+
H: ["10001", "10001", "10001", "11111", "10001", "10001", "10001"],
|
|
26
|
+
I: ["01110", "00100", "00100", "00100", "00100", "00100", "01110"],
|
|
27
|
+
J: ["00001", "00001", "00001", "00001", "10001", "10001", "01110"],
|
|
28
|
+
K: ["10001", "10010", "10100", "11000", "10100", "10010", "10001"],
|
|
29
|
+
L: ["10000", "10000", "10000", "10000", "10000", "10000", "11111"],
|
|
30
|
+
M: ["10001", "11011", "10101", "10101", "10001", "10001", "10001"],
|
|
31
|
+
N: ["10001", "10001", "11001", "10101", "10011", "10001", "10001"],
|
|
32
|
+
O: ["01110", "10001", "10001", "10001", "10001", "10001", "01110"],
|
|
33
|
+
P: ["11110", "10001", "10001", "11110", "10000", "10000", "10000"],
|
|
34
|
+
Q: ["01110", "10001", "10001", "10001", "10101", "10010", "01101"],
|
|
35
|
+
R: ["11110", "10001", "10001", "11110", "10100", "10010", "10001"],
|
|
36
|
+
S: ["01111", "10000", "10000", "01110", "00001", "00001", "11110"],
|
|
37
|
+
T: ["11111", "00100", "00100", "00100", "00100", "00100", "00100"],
|
|
38
|
+
U: ["10001", "10001", "10001", "10001", "10001", "10001", "01110"],
|
|
39
|
+
V: ["10001", "10001", "10001", "10001", "10001", "01010", "00100"],
|
|
40
|
+
W: ["10001", "10001", "10001", "10101", "10101", "10101", "01010"],
|
|
41
|
+
X: ["10001", "10001", "01010", "00100", "01010", "10001", "10001"],
|
|
42
|
+
Y: ["10001", "10001", "01010", "00100", "00100", "00100", "00100"],
|
|
43
|
+
Z: ["11111", "00001", "00010", "00100", "01000", "10000", "11111"],
|
|
44
|
+
"-": ["00000", "00000", "00000", "11111", "00000", "00000", "00000"],
|
|
45
|
+
"_": ["00000", "00000", "00000", "00000", "00000", "00000", "11111"],
|
|
46
|
+
".": ["00000", "00000", "00000", "00000", "00000", "00110", "00110"],
|
|
47
|
+
":": ["00000", "00110", "00110", "00000", "00110", "00110", "00000"],
|
|
48
|
+
"/": ["00001", "00010", "00100", "01000", "10000", "00000", "00000"],
|
|
49
|
+
"?": ["01110", "10001", "00001", "00010", "00100", "00000", "00100"],
|
|
50
|
+
"!": ["00100", "00100", "00100", "00100", "00100", "00000", "00100"]
|
|
51
|
+
};
|
|
52
|
+
const FALLBACK_GLYPH = ["01110", "10001", "00001", "00010", "00100", "00000", "00100"];
|
|
53
|
+
function getGlyph(char) {
|
|
54
|
+
return MATRIX_GLYPHS[char] ?? FALLBACK_GLYPH;
|
|
55
|
+
}
|
|
56
|
+
export function SgMatrixDigit({ value, color = "#22d3ee", backgroundColor = "#0b1220", offColor = "rgba(148, 163, 184, 0.22)", dotSize = 9, gap = 3, charGap = 7, padding = 8, rounded = 10, glow = true, className, style }) {
|
|
57
|
+
const chars = React.useMemo(() => {
|
|
58
|
+
const normalized = (value ?? "").toUpperCase();
|
|
59
|
+
return normalized.length > 0 ? Array.from(normalized) : [" "];
|
|
60
|
+
}, [value]);
|
|
61
|
+
const glowSize = Math.max(2, Math.round(dotSize * 0.55));
|
|
62
|
+
return (_jsx("div", { role: "img", "aria-label": value, className: cn("inline-flex items-center", className), style: {
|
|
63
|
+
gap: charGap,
|
|
64
|
+
padding,
|
|
65
|
+
borderRadius: rounded,
|
|
66
|
+
backgroundColor,
|
|
67
|
+
...style
|
|
68
|
+
}, children: chars.map((char, charIndex) => {
|
|
69
|
+
const glyph = getGlyph(char);
|
|
70
|
+
return (_jsx("div", { className: "grid", style: {
|
|
71
|
+
gridTemplateColumns: `repeat(5, ${dotSize}px)`,
|
|
72
|
+
gridTemplateRows: `repeat(7, ${dotSize}px)`,
|
|
73
|
+
gap
|
|
74
|
+
}, children: glyph.map((row, rowIndex) => Array.from(row).map((bit, colIndex) => {
|
|
75
|
+
const active = bit === "1";
|
|
76
|
+
return (_jsx("span", { "aria-hidden": "true", style: {
|
|
77
|
+
width: dotSize,
|
|
78
|
+
height: dotSize,
|
|
79
|
+
borderRadius: 9999,
|
|
80
|
+
backgroundColor: active ? color : offColor,
|
|
81
|
+
boxShadow: active && glow ? `0 0 ${glowSize}px ${color}` : "none",
|
|
82
|
+
transition: "background-color 160ms ease, box-shadow 160ms ease"
|
|
83
|
+
} }, `${rowIndex}-${colIndex}`));
|
|
84
|
+
})) }, `${char}-${charIndex}`));
|
|
85
|
+
}) }));
|
|
86
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/digits/matrix-digit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SgMatrixDigit } from "./SgMatrixDigit";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type SgNeonDigitProps = {
|
|
3
|
+
/** Text/character rendered with neon style. */
|
|
4
|
+
value: string;
|
|
5
|
+
/** Enables fade-out/fade-in animation when value changes. */
|
|
6
|
+
animateOnChange?: boolean;
|
|
7
|
+
/** Total animation time in milliseconds when value changes. */
|
|
8
|
+
transitionMs?: number;
|
|
9
|
+
/** Main text color. */
|
|
10
|
+
color?: string;
|
|
11
|
+
/** Background color of the component surface. */
|
|
12
|
+
backgroundColor?: string;
|
|
13
|
+
/** Glow/shadow color around the text. */
|
|
14
|
+
shadowColor?: string;
|
|
15
|
+
/** Extra intensity factor for the glow effect. */
|
|
16
|
+
shadowStrength?: number;
|
|
17
|
+
/** Font size in pixels. */
|
|
18
|
+
fontSize?: number;
|
|
19
|
+
/** Font weight of the text. */
|
|
20
|
+
fontWeight?: number | string;
|
|
21
|
+
/** Font family alias (same effect as fontFamily). */
|
|
22
|
+
font?: string;
|
|
23
|
+
/** Letter spacing in pixels. */
|
|
24
|
+
letterSpacing?: number;
|
|
25
|
+
/** Internal padding in pixels. */
|
|
26
|
+
padding?: number;
|
|
27
|
+
/** Border radius in pixels. */
|
|
28
|
+
rounded?: number;
|
|
29
|
+
/** Custom font family. */
|
|
30
|
+
fontFamily?: string;
|
|
31
|
+
/** Additional classes on container. */
|
|
32
|
+
className?: string;
|
|
33
|
+
/** Additional style on container. */
|
|
34
|
+
style?: React.CSSProperties;
|
|
35
|
+
};
|
|
36
|
+
export declare function SgNeonDigit({ value, animateOnChange, transitionMs, color, backgroundColor, shadowColor, shadowStrength, fontSize, fontWeight, font, letterSpacing, padding, rounded, fontFamily, className, style }: Readonly<SgNeonDigitProps>): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
//# sourceMappingURL=SgNeonDigit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SgNeonDigit.d.ts","sourceRoot":"","sources":["../../../src/digits/neon-digit/SgNeonDigit.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,MAAM,gBAAgB,GAAG;IAC7B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,eAAsB,EACtB,YAAkB,EAClB,KAAiB,EACjB,eAA2B,EAC3B,WAAW,EACX,cAAkB,EAClB,QAAa,EACb,UAAgB,EAChB,IAAI,EACJ,aAAiB,EACjB,OAAY,EACZ,OAAY,EACZ,UAAU,EACV,SAAS,EACT,KAAK,EACN,EAAE,QAAQ,CAAC,gBAAgB,CAAC,2CAoE5B"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
function cn(...parts) {
|
|
4
|
+
return parts.filter(Boolean).join(" ");
|
|
5
|
+
}
|
|
6
|
+
export function SgNeonDigit({ value, animateOnChange = true, transitionMs = 320, color = "#e2e8f0", backgroundColor = "#120f2b", shadowColor, shadowStrength = 1, fontSize = 46, fontWeight = 600, font, letterSpacing = 0, padding = 14, rounded = 12, fontFamily, className, style }) {
|
|
7
|
+
const [displayValue, setDisplayValue] = React.useState(value);
|
|
8
|
+
const [lit, setLit] = React.useState(true);
|
|
9
|
+
React.useEffect(() => {
|
|
10
|
+
if (!animateOnChange) {
|
|
11
|
+
setDisplayValue(value);
|
|
12
|
+
setLit(true);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (value === displayValue)
|
|
16
|
+
return;
|
|
17
|
+
const halfDuration = Math.max(40, Math.round(transitionMs / 2));
|
|
18
|
+
const swapTimer = window.setTimeout(() => {
|
|
19
|
+
setDisplayValue(value);
|
|
20
|
+
setLit(true);
|
|
21
|
+
}, halfDuration);
|
|
22
|
+
setLit(false);
|
|
23
|
+
return () => window.clearTimeout(swapTimer);
|
|
24
|
+
}, [animateOnChange, displayValue, transitionMs, value]);
|
|
25
|
+
const glowColor = shadowColor ?? color;
|
|
26
|
+
const glowFactor = Math.max(0.2, shadowStrength);
|
|
27
|
+
const fadeFactor = lit ? 1 : 0.2;
|
|
28
|
+
const halfDuration = Math.max(40, Math.round(transitionMs / 2));
|
|
29
|
+
const inner = Math.max(1, Math.round(fontSize * 0.07 * glowFactor));
|
|
30
|
+
const near = Math.max(3, Math.round(fontSize * 0.2 * glowFactor));
|
|
31
|
+
const mid = Math.max(6, Math.round(fontSize * 0.42 * glowFactor));
|
|
32
|
+
const outer = Math.max(12, Math.round(fontSize * 0.78 * glowFactor));
|
|
33
|
+
const ambient = Math.max(18, Math.round(fontSize * 1.2 * glowFactor));
|
|
34
|
+
const resolvedFontFamily = font ?? fontFamily;
|
|
35
|
+
const fullTextShadow = `0 0 ${inner}px #ffffff, 0 0 ${near}px ${color}, 0 0 ${mid}px ${glowColor}, 0 0 ${outer}px ${glowColor}, 0 0 ${ambient}px ${glowColor}`;
|
|
36
|
+
const dimTextShadow = `0 0 ${Math.max(1, Math.round(inner * 0.5))}px ${glowColor}`;
|
|
37
|
+
const fullContainerShadow = `inset 0 0 ${Math.round(ambient * 0.6)}px rgba(0, 0, 0, 0.24), 0 0 ${Math.round(ambient * 0.7)}px ${glowColor}, 0 0 ${Math.round(ambient * 1.35)}px ${glowColor}`;
|
|
38
|
+
const dimContainerShadow = `inset 0 0 ${Math.round(ambient * 0.4)}px rgba(0, 0, 0, 0.24), 0 0 ${Math.round(ambient * 0.22)}px ${glowColor}`;
|
|
39
|
+
return (_jsx("div", { role: "img", "aria-label": value, className: cn("inline-flex items-center justify-center", className), style: {
|
|
40
|
+
padding,
|
|
41
|
+
borderRadius: rounded,
|
|
42
|
+
backgroundColor,
|
|
43
|
+
boxShadow: lit ? fullContainerShadow : dimContainerShadow,
|
|
44
|
+
transition: `box-shadow ${halfDuration}ms ease, filter ${halfDuration}ms ease`,
|
|
45
|
+
filter: lit ? "brightness(1)" : "brightness(0.85)",
|
|
46
|
+
...style
|
|
47
|
+
}, children: _jsx("span", { style: {
|
|
48
|
+
color,
|
|
49
|
+
fontSize,
|
|
50
|
+
fontWeight,
|
|
51
|
+
lineHeight: 1.05,
|
|
52
|
+
letterSpacing,
|
|
53
|
+
fontFamily: resolvedFontFamily,
|
|
54
|
+
opacity: fadeFactor,
|
|
55
|
+
textShadow: lit ? fullTextShadow : dimTextShadow,
|
|
56
|
+
transition: `opacity ${halfDuration}ms ease, text-shadow ${halfDuration}ms ease, filter ${halfDuration}ms ease`,
|
|
57
|
+
filter: lit ? "saturate(1)" : "saturate(0.55)"
|
|
58
|
+
}, children: displayValue }) }));
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/digits/neon-digit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SgNeonDigit } from "./SgNeonDigit";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type SgRoller3DDigitProps = {
|
|
2
|
+
/** Current value to display — must be present in `items` */
|
|
3
|
+
value: string;
|
|
4
|
+
/**
|
|
5
|
+
* Ordered list of all possible values this roller can show.
|
|
6
|
+
* The drum scrolls to the position of `value` in this list.
|
|
7
|
+
* @default ["0","1","2","3","4","5","6","7","8","9"]
|
|
8
|
+
*/
|
|
9
|
+
items?: string[];
|
|
10
|
+
/** Font size in pixels — controls overall scale */
|
|
11
|
+
fontSize?: number;
|
|
12
|
+
/** Additional CSS classes on the outer wrapper */
|
|
13
|
+
className?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* SgRoller3DDigit — a vertical drum/roller that animates between values.
|
|
17
|
+
*
|
|
18
|
+
* Renders a scrolling strip of items and smoothly transitions to the
|
|
19
|
+
* position of `value` in the `items` list using a CSS transform.
|
|
20
|
+
* Works with digits, letters, padded numbers or any custom strings.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Digit roller (default 0–9)
|
|
24
|
+
* <SgRoller3DDigit value="7" fontSize={32} />
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Padded time roller (e.g. minutes 00–59)
|
|
28
|
+
* const MINUTES = Array.from({ length: 60 }, (_, i) => String(i).padStart(2, "0"));
|
|
29
|
+
* <SgRoller3DDigit value="42" items={MINUTES} fontSize={22} />
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* // Letter roller (A–Z) — animate names character by character
|
|
33
|
+
* const ALPHA = Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
|
34
|
+
* <SgRoller3DDigit value="M" items={ALPHA} fontSize={32} />
|
|
35
|
+
*/
|
|
36
|
+
export declare function SgRoller3DDigit({ value, items, fontSize, className, }: SgRoller3DDigitProps): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
//# sourceMappingURL=SgRoller3DDigit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SgRoller3DDigit.d.ts","sourceRoot":"","sources":["../../../src/digits/roller3d-digit/SgRoller3DDigit.tsx"],"names":[],"mappings":"AAMA,MAAM,MAAM,oBAAoB,GAAG;IACjC,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,KAAqB,EACrB,QAAa,EACb,SAAS,GACV,EAAE,oBAAoB,2CAoDtB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
function cn(...parts) {
|
|
3
|
+
return parts.filter(Boolean).join(" ");
|
|
4
|
+
}
|
|
5
|
+
const DEFAULT_ITEMS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
6
|
+
/**
|
|
7
|
+
* SgRoller3DDigit — a vertical drum/roller that animates between values.
|
|
8
|
+
*
|
|
9
|
+
* Renders a scrolling strip of items and smoothly transitions to the
|
|
10
|
+
* position of `value` in the `items` list using a CSS transform.
|
|
11
|
+
* Works with digits, letters, padded numbers or any custom strings.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // Digit roller (default 0–9)
|
|
15
|
+
* <SgRoller3DDigit value="7" fontSize={32} />
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Padded time roller (e.g. minutes 00–59)
|
|
19
|
+
* const MINUTES = Array.from({ length: 60 }, (_, i) => String(i).padStart(2, "0"));
|
|
20
|
+
* <SgRoller3DDigit value="42" items={MINUTES} fontSize={22} />
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Letter roller (A–Z) — animate names character by character
|
|
24
|
+
* const ALPHA = Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
|
25
|
+
* <SgRoller3DDigit value="M" items={ALPHA} fontSize={32} />
|
|
26
|
+
*/
|
|
27
|
+
export function SgRoller3DDigit({ value, items = DEFAULT_ITEMS, fontSize = 32, className, }) {
|
|
28
|
+
const idx = Math.max(0, items.indexOf(value));
|
|
29
|
+
// Dimensions are derived from fontSize so the component scales uniformly.
|
|
30
|
+
// The ratios match the original SgClock roller3d proportions exactly when
|
|
31
|
+
// charCount=2 and fontSize = sizePx * 1.35.
|
|
32
|
+
const charCount = Math.max(...items.map((s) => s.length), 1);
|
|
33
|
+
const itemH = Math.round(fontSize * 1.2);
|
|
34
|
+
const w = Math.round(fontSize * (0.7 * charCount + 0.7));
|
|
35
|
+
const h = Math.round(fontSize * 2.7);
|
|
36
|
+
const translateY = -idx * itemH + h / 2 - itemH / 2;
|
|
37
|
+
return (_jsxs("div", { className: cn("relative overflow-hidden rounded-2xl", "bg-white dark:bg-neutral-800", "ring-1 ring-black/5 dark:ring-white/10", "shadow-[inset_0_0_28px_rgba(0,0,0,0.08),0_8px_28px_rgba(0,0,0,0.12)]",
|
|
38
|
+
// top fade
|
|
39
|
+
"before:absolute before:inset-0 before:z-10 before:bg-gradient-to-b before:from-black/[0.06] before:to-transparent before:content-['']",
|
|
40
|
+
// bottom fade
|
|
41
|
+
"after:absolute after:inset-0 after:z-10 after:bg-gradient-to-t after:from-black/[0.12] after:to-transparent after:content-['']", className), style: { width: w, height: h }, children: [_jsx("div", { className: "absolute left-0 right-0 top-1/2 z-20 h-px bg-red-500/70" }), _jsx("div", { className: "absolute left-0 top-0 w-full transition-transform duration-500 [transition-timing-function:cubic-bezier(0.22,1,0.36,1)] [mask-image:linear-gradient(to_bottom,transparent,black_22%,black_78%,transparent)]", style: { transform: `translateY(${translateY}px)` }, children: items.map((item, i) => (_jsx("div", { className: "flex select-none items-center justify-center font-medium tabular-nums", style: {
|
|
42
|
+
height: itemH,
|
|
43
|
+
fontSize,
|
|
44
|
+
lineHeight: 1,
|
|
45
|
+
color: i === idx ? "rgb(30 30 34)" : "rgb(163 163 170)",
|
|
46
|
+
}, children: item }, `${item}-${i}`))) })] }));
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/digits/roller3d-digit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SgRoller3DDigit } from "./SgRoller3DDigit";
|
|
@@ -7,6 +7,7 @@ export declare function SgEnvironmentProvider(props: {
|
|
|
7
7
|
children: React.ReactNode;
|
|
8
8
|
}): import("react/jsx-runtime").JSX.Element;
|
|
9
9
|
export declare function useSgEnvironment(): SgEnvironmentValue;
|
|
10
|
+
export declare function useHasSgEnvironmentProvider(): boolean;
|
|
10
11
|
export declare function useSgNamespaceProvider(): NamespaceProvider;
|
|
11
12
|
export declare function useSgPersistence(): {
|
|
12
13
|
namespace: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgEnvironmentProvider.d.ts","sourceRoot":"","sources":["../../src/environment/SgEnvironmentProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACd,MAAM,eAAe,CAAC;AAGvB,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,GACd,CAAC;AACF,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,4BAA4B,EAC5B,kCAAkC,GACnC,MAAM,eAAe,CAAC;AAkBvB,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACpC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAyBA;AAED,wBAAgB,gBAAgB,IAAI,kBAAkB,CAErD;AAED,wBAAgB,sBAAsB,IAAI,iBAAiB,CAE1D;AAED,wBAAgB,gBAAgB;;;;;oBAOZ,MAAM;oBASN,MAAM,SAAS,OAAO;qBAStB,MAAM;EAiBzB;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,CAAC,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;IAClC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,CAAC;CACrC;;
|
|
1
|
+
{"version":3,"file":"SgEnvironmentProvider.d.ts","sourceRoot":"","sources":["../../src/environment/SgEnvironmentProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACd,MAAM,eAAe,CAAC;AAGvB,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,GACd,CAAC;AACF,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,4BAA4B,EAC5B,kCAAkC,GACnC,MAAM,eAAe,CAAC;AAkBvB,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACpC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAyBA;AAED,wBAAgB,gBAAgB,IAAI,kBAAkB,CAErD;AAED,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAED,wBAAgB,sBAAsB,IAAI,iBAAiB,CAE1D;AAED,wBAAgB,gBAAgB;;;;;oBAOZ,MAAM;oBASN,MAAM,SAAS,OAAO;qBAStB,MAAM;EAiBzB;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,CAAC,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;IAClC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,CAAC;CACrC;;qBAgEU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;;;EAoB9B"}
|
|
@@ -37,6 +37,9 @@ export function SgEnvironmentProvider(props) {
|
|
|
37
37
|
export function useSgEnvironment() {
|
|
38
38
|
return React.useContext(SgEnvironmentContext) ?? defaultEnvironment;
|
|
39
39
|
}
|
|
40
|
+
export function useHasSgEnvironmentProvider() {
|
|
41
|
+
return React.useContext(SgEnvironmentContext) !== null;
|
|
42
|
+
}
|
|
40
43
|
export function useSgNamespaceProvider() {
|
|
41
44
|
return useSgEnvironment().namespaceProvider;
|
|
42
45
|
}
|
|
@@ -74,16 +77,30 @@ export function useSgPersistence() {
|
|
|
74
77
|
}
|
|
75
78
|
export function useSgPersistentState(args) {
|
|
76
79
|
const { baseKey, defaultValue } = args;
|
|
77
|
-
const serialize = args.serialize ?? ((value) => value);
|
|
78
|
-
const deserialize = args.deserialize ?? ((value) => value);
|
|
80
|
+
const serialize = React.useMemo(() => args.serialize ?? ((value) => value), [args.serialize]);
|
|
81
|
+
const deserialize = React.useMemo(() => args.deserialize ?? ((value) => value), [args.deserialize]);
|
|
82
|
+
const hasProvider = useHasSgEnvironmentProvider();
|
|
79
83
|
const persistence = useSgPersistence();
|
|
80
84
|
const [value, setValue] = React.useState(defaultValue);
|
|
81
85
|
const [hydrated, setHydrated] = React.useState(false);
|
|
86
|
+
// Load from persistence on mount
|
|
82
87
|
React.useEffect(() => {
|
|
83
88
|
let alive = true;
|
|
84
89
|
(async () => {
|
|
85
90
|
try {
|
|
86
|
-
|
|
91
|
+
let loaded;
|
|
92
|
+
if (hasProvider) {
|
|
93
|
+
loaded = await persistence.load(baseKey);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
try {
|
|
97
|
+
const raw = localStorage.getItem(baseKey);
|
|
98
|
+
loaded = raw !== null ? JSON.parse(raw) : null;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
loaded = null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
87
104
|
if (!alive)
|
|
88
105
|
return;
|
|
89
106
|
if (loaded !== null && loaded !== undefined) {
|
|
@@ -104,17 +121,39 @@ export function useSgPersistentState(args) {
|
|
|
104
121
|
return () => {
|
|
105
122
|
alive = false;
|
|
106
123
|
};
|
|
107
|
-
}, [baseKey, persistence.load, deserialize]);
|
|
124
|
+
}, [baseKey, defaultValue, hasProvider, persistence.load, deserialize]);
|
|
125
|
+
// Save to persistence whenever value changes after hydration
|
|
126
|
+
React.useEffect(() => {
|
|
127
|
+
if (!hydrated)
|
|
128
|
+
return;
|
|
129
|
+
if (hasProvider) {
|
|
130
|
+
void persistence.save(baseKey, serialize(value));
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
try {
|
|
134
|
+
localStorage.setItem(baseKey, JSON.stringify(value));
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// ignore
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}, [value, hydrated, hasProvider, baseKey, persistence.save, serialize]);
|
|
108
141
|
const setAndPersist = React.useCallback((next) => {
|
|
109
|
-
setValue(
|
|
110
|
-
|
|
111
|
-
void persistence.save(baseKey, serialize(computed));
|
|
112
|
-
return computed;
|
|
113
|
-
});
|
|
114
|
-
}, [baseKey, persistence.save, serialize]);
|
|
142
|
+
setValue(next);
|
|
143
|
+
}, []);
|
|
115
144
|
const clear = React.useCallback(async () => {
|
|
116
|
-
|
|
145
|
+
if (hasProvider) {
|
|
146
|
+
await persistence.clear(baseKey);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
try {
|
|
150
|
+
localStorage.removeItem(baseKey);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// ignore
|
|
154
|
+
}
|
|
155
|
+
}
|
|
117
156
|
setValue(defaultValue);
|
|
118
|
-
}, [baseKey, persistence.clear, defaultValue]);
|
|
157
|
+
}, [baseKey, hasProvider, persistence.clear, defaultValue]);
|
|
119
158
|
return { value, setValue: setAndPersist, clear, hydrated };
|
|
120
159
|
}
|
|
@@ -3,16 +3,18 @@ import type { SgClockTheme } from "./themes/types";
|
|
|
3
3
|
export type SgClockProps = {
|
|
4
4
|
variant?: "digital" | "analog";
|
|
5
5
|
size?: "sm" | "md" | "lg" | number;
|
|
6
|
+
initialServerTime?: string;
|
|
6
7
|
timezone?: string;
|
|
7
8
|
locale?: string;
|
|
8
9
|
format?: "12h" | "24h";
|
|
9
10
|
showSeconds?: boolean;
|
|
10
|
-
digitalStyle?:
|
|
11
|
+
digitalStyle?: SgClockDigitalStyle;
|
|
11
12
|
secondHandMode?: "step" | "smooth";
|
|
12
13
|
themeId?: string;
|
|
13
14
|
theme?: SgClockTheme;
|
|
14
15
|
className?: string;
|
|
15
16
|
centerOverlay?: React.ReactNode;
|
|
16
17
|
};
|
|
18
|
+
export type SgClockDigitalStyle = "default" | "segment" | "roller3d" | "flip" | "fade" | "matrix" | "neon" | "discard";
|
|
17
19
|
export declare function SgClock(props: SgClockProps): import("react/jsx-runtime").JSX.Element;
|
|
18
20
|
//# sourceMappingURL=SgClock.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgClock.d.ts","sourceRoot":"","sources":["../../../src/gadgets/clock/SgClock.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"SgClock.d.ts","sourceRoot":"","sources":["../../../src/gadgets/clock/SgClock.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAiDnD,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAC3B,SAAS,GACT,SAAS,GACT,UAAU,GACV,MAAM,GACN,MAAM,GACN,QAAQ,GACR,MAAM,GACN,SAAS,CAAC;AA4iBd,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,2CA+C1C"}
|