@digilogiclabs/saas-factory-ui 2.1.0 → 2.3.0

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/index.mjs CHANGED
@@ -30463,14 +30463,35 @@ var PIP_POS = {
30463
30463
  [75, 75]
30464
30464
  ]
30465
30465
  };
30466
- var SHOW_ROT = {
30466
+ var D6_FACE_PLACEMENTS = {
30467
30467
  1: { x: 0, y: 0 },
30468
- 2: { x: 0, y: 180 },
30469
- 3: { x: 0, y: -90 },
30470
- 4: { x: 0, y: 90 },
30471
- 5: { x: -90, y: 0 },
30472
- 6: { x: 90, y: 0 }
30468
+ 2: { x: 0, y: 90 },
30469
+ 3: { x: 90, y: 0 },
30470
+ 4: { x: -90, y: 0 },
30471
+ 5: { x: 0, y: -90 },
30472
+ 6: { x: 0, y: 180 }
30473
30473
  };
30474
+ function d6LandingRotation(value) {
30475
+ const p = D6_FACE_PLACEMENTS[value];
30476
+ return {
30477
+ x: Math.abs(p.x) === 180 ? 180 : -p.x || 0,
30478
+ y: Math.abs(p.y) === 180 ? 180 : -p.y || 0
30479
+ };
30480
+ }
30481
+ var POLY_SHAPES = {
30482
+ 4: { points: "50,8 93,86 7,86", textY: 62, fontScale: 0.3 },
30483
+ 8: { points: "50,4 96,50 50,96 4,50", textY: 51, fontScale: 0.33 },
30484
+ 10: { points: "50,4 93,44 50,96 7,44", textY: 47, fontScale: 0.3 },
30485
+ 12: { points: "50,4 95,37 78,93 22,93 5,37", textY: 54, fontScale: 0.33 },
30486
+ 20: {
30487
+ points: "50,3 91,26 91,74 50,97 9,74 9,26",
30488
+ textY: 51,
30489
+ fontScale: 0.33
30490
+ }
30491
+ };
30492
+ function formatDieValue(v, sides) {
30493
+ return sides > 8 && (v === 6 || v === 9) ? `${v}.` : String(v);
30494
+ }
30474
30495
  var MAX_COUNT = 6;
30475
30496
  var TUMBLE_MS = 950;
30476
30497
  var SETTLE_MS = 1100;
@@ -30622,6 +30643,7 @@ function Face({ value, pipColor, pipShadow, pipDiameter }) {
30622
30643
  }
30623
30644
  function DiceRoller({
30624
30645
  count: count2 = 2,
30646
+ sides = 6,
30625
30647
  theme: theme5 = "red",
30626
30648
  darkMode,
30627
30649
  size = 80,
@@ -30650,6 +30672,7 @@ function DiceRoller({
30650
30672
  const dieWrapperRefs = useRef39([]);
30651
30673
  const cubeRefs = useRef39([]);
30652
30674
  const shadowRefs = useRef39([]);
30675
+ const numeralRefs = useRef39([]);
30653
30676
  const currentPositionsRef = useRef39(null);
30654
30677
  const rollingRef = useRef39(false);
30655
30678
  const dieSetters = useRef39([]);
@@ -30679,6 +30702,15 @@ function DiceRoller({
30679
30702
  }
30680
30703
  return shadowSetters.current[i];
30681
30704
  };
30705
+ const numeralSetters = useRef39([]);
30706
+ const getNumeralSetter = (i) => {
30707
+ if (!numeralSetters.current[i]) {
30708
+ numeralSetters.current[i] = (el) => {
30709
+ numeralRefs.current[i] = el;
30710
+ };
30711
+ }
30712
+ return numeralSetters.current[i];
30713
+ };
30682
30714
  const timersRef = useRef39([]);
30683
30715
  const rafHandleRef = useRef39(null);
30684
30716
  const arenaRef = useRef39(null);
@@ -30731,15 +30763,15 @@ function DiceRoller({
30731
30763
  const pipDiameter = Math.round(effectiveSize * 0.2);
30732
30764
  const faceRadius = Math.round(effectiveSize * 0.07);
30733
30765
  const arenaHeight = arenaHeightProp ?? Math.max(effectiveSize * 3, 200);
30734
- const faceTransforms = useMemo28(
30735
- () => [
30736
- `translateZ(${half}px)`,
30737
- `rotateY(180deg) translateZ(${half}px)`,
30738
- `rotateY(-90deg) translateZ(${half}px)`,
30739
- `rotateY(90deg) translateZ(${half}px)`,
30740
- `rotateX(90deg) translateZ(${half}px)`,
30741
- `rotateX(-90deg) translateZ(${half}px)`
30742
- ],
30766
+ const faceTransformFor = useCallback44(
30767
+ (value) => {
30768
+ const p = D6_FACE_PLACEMENTS[value];
30769
+ const parts = [];
30770
+ if (p.x !== 0) parts.push(`rotateX(${p.x}deg)`);
30771
+ if (p.y !== 0) parts.push(`rotateY(${p.y}deg)`);
30772
+ parts.push(`translateZ(${half}px)`);
30773
+ return parts.join(" ");
30774
+ },
30743
30775
  [half]
30744
30776
  );
30745
30777
  const defaultPositions = useCallback44(
@@ -30761,11 +30793,11 @@ function DiceRoller({
30761
30793
  [half]
30762
30794
  );
30763
30795
  const writeCubeRotation = useCallback44(
30764
- (i, rx, ry, rz, withTransition) => {
30796
+ (i, rx, ry, rz, withTransition, tiltZ = 0) => {
30765
30797
  const el = cubeRefs.current[i];
30766
30798
  if (!el) return;
30767
30799
  el.style.transition = withTransition ? "transform 0.95s cubic-bezier(0.12,0.8,0.22,1)" : "none";
30768
- el.style.transform = `rotateX(${rx}deg) rotateY(${ry}deg) rotateZ(${rz}deg)`;
30800
+ el.style.transform = `${tiltZ ? `rotateZ(${tiltZ}deg) ` : ""}rotateX(${rx}deg) rotateY(${ry}deg) rotateZ(${rz}deg)`;
30769
30801
  },
30770
30802
  []
30771
30803
  );
@@ -30795,19 +30827,23 @@ function DiceRoller({
30795
30827
  setResults(null);
30796
30828
  }, [
30797
30829
  clampedCount,
30830
+ sides,
30798
30831
  effectiveSize,
30799
30832
  arena.w,
30800
30833
  arenaHeight,
30801
30834
  defaultPositions,
30802
30835
  half
30803
30836
  ]);
30837
+ useEffect54(() => {
30838
+ setHistory([]);
30839
+ }, [sides]);
30804
30840
  const roll = useCallback44(() => {
30805
30841
  if (rollingRef.current) return;
30806
30842
  rollingRef.current = true;
30807
30843
  setRolling(true);
30808
30844
  const vals = Array.from(
30809
30845
  { length: clampedCount },
30810
- () => Math.floor(Math.random() * 6) + 1
30846
+ () => Math.floor(Math.random() * sides) + 1
30811
30847
  );
30812
30848
  timersRef.current.forEach((t) => clearTimeout(t));
30813
30849
  timersRef.current = [];
@@ -30822,13 +30858,17 @@ function DiceRoller({
30822
30858
  const starts = currentPositionsRef.current ?? defaultPositions(w, h, clampedCount);
30823
30859
  const frames = simulateDice(w, h, effectiveSize, starts, clampedCount);
30824
30860
  for (let i = 0; i < clampedCount; i++) {
30825
- writeCubeRotation(
30826
- i,
30827
- (Math.random() - 0.5) * 720,
30828
- (Math.random() - 0.5) * 720,
30829
- (Math.random() - 0.5) * 720,
30830
- false
30831
- );
30861
+ if (sides === 6) {
30862
+ writeCubeRotation(
30863
+ i,
30864
+ (Math.random() - 0.5) * 720,
30865
+ (Math.random() - 0.5) * 720,
30866
+ (Math.random() - 0.5) * 720,
30867
+ false
30868
+ );
30869
+ } else {
30870
+ writeCubeRotation(i, 0, 0, (Math.random() - 0.5) * 720, false);
30871
+ }
30832
30872
  const el = dieWrapperRefs.current[i];
30833
30873
  if (el) el.style.transition = "none";
30834
30874
  const shadow = shadowRefs.current[i];
@@ -30861,18 +30901,47 @@ function DiceRoller({
30861
30901
  }, capturedStep * stepMs);
30862
30902
  timersRef.current.push(timer);
30863
30903
  }
30904
+ if (sides !== 6) {
30905
+ const flickerTicks = 8;
30906
+ const flickerStep = Math.max(60, Math.floor(TUMBLE_MS / flickerTicks));
30907
+ for (let f = 1; f <= flickerTicks; f++) {
30908
+ const t = setTimeout(() => {
30909
+ for (let i = 0; i < clampedCount; i++) {
30910
+ const el = numeralRefs.current[i];
30911
+ if (el)
30912
+ el.textContent = formatDieValue(
30913
+ Math.floor(Math.random() * sides) + 1,
30914
+ sides
30915
+ );
30916
+ }
30917
+ }, f * flickerStep);
30918
+ timersRef.current.push(t);
30919
+ }
30920
+ }
30864
30921
  requestAnimationFrame(() => {
30865
30922
  requestAnimationFrame(() => {
30866
30923
  for (let i = 0; i < clampedCount; i++) {
30867
- const tgt = SHOW_ROT[vals[i]];
30868
- const lx = tgt.x + (Math.random() > 0.5 ? 720 : -720);
30869
- const ly = tgt.y;
30870
- const lz = (Math.random() > 0.5 ? 1 : -1) * 360;
30871
- writeCubeRotation(i, lx, ly, lz, true);
30924
+ const tilt = (Math.random() - 0.5) * 18;
30925
+ if (sides === 6) {
30926
+ const tgt = d6LandingRotation(vals[i]);
30927
+ const lx = tgt.x + (Math.random() > 0.5 ? 720 : -720);
30928
+ const ly = tgt.y;
30929
+ const lz = (Math.random() > 0.5 ? 1 : -1) * 360;
30930
+ writeCubeRotation(i, lx, ly, lz, true, tilt);
30931
+ } else {
30932
+ const lz = (Math.random() > 0.5 ? 1 : -1) * 720 + tilt;
30933
+ writeCubeRotation(i, 0, 0, lz, true);
30934
+ }
30872
30935
  }
30873
30936
  });
30874
30937
  });
30875
30938
  const settleTimer = setTimeout(() => {
30939
+ if (sides !== 6) {
30940
+ for (let i = 0; i < clampedCount; i++) {
30941
+ const el = numeralRefs.current[i];
30942
+ if (el) el.textContent = formatDieValue(vals[i], sides);
30943
+ }
30944
+ }
30876
30945
  setResults(vals);
30877
30946
  setRolling(false);
30878
30947
  rollingRef.current = false;
@@ -30885,6 +30954,7 @@ function DiceRoller({
30885
30954
  timersRef.current.push(settleTimer);
30886
30955
  }, [
30887
30956
  clampedCount,
30957
+ sides,
30888
30958
  defaultPositions,
30889
30959
  effectiveSize,
30890
30960
  half,
@@ -30930,7 +31000,7 @@ function DiceRoller({
30930
31000
  {
30931
31001
  ref: arenaRef,
30932
31002
  role: "img",
30933
- "aria-label": ariaLabel ?? `${clampedCount} dice`,
31003
+ "aria-label": ariaLabel ?? `${clampedCount} ${sides === 6 ? "dice" : `${sides}-sided dice`}`,
30934
31004
  "aria-live": "polite",
30935
31005
  style: {
30936
31006
  position: "relative",
@@ -30993,7 +31063,7 @@ function DiceRoller({
30993
31063
  transformStyle: "preserve-3d",
30994
31064
  willChange: "transform"
30995
31065
  },
30996
- children: [1, 2, 3, 4, 5, 6].map((val, fi) => /* @__PURE__ */ jsx114(
31066
+ children: sides === 6 ? [1, 2, 3, 4, 5, 6].map((val) => /* @__PURE__ */ jsx114(
30997
31067
  "div",
30998
31068
  {
30999
31069
  style: {
@@ -31003,7 +31073,7 @@ function DiceRoller({
31003
31073
  background: colors.face,
31004
31074
  border: `1px solid ${colors.faceBorder}`,
31005
31075
  borderRadius: faceRadius,
31006
- transform: faceTransforms[fi],
31076
+ transform: faceTransformFor(val),
31007
31077
  transition: "background 0.3s, border-color 0.3s"
31008
31078
  },
31009
31079
  children: /* @__PURE__ */ jsx114(
@@ -31017,7 +31087,64 @@ function DiceRoller({
31017
31087
  )
31018
31088
  },
31019
31089
  val
31020
- ))
31090
+ )) : (() => {
31091
+ const shape = POLY_SHAPES[sides];
31092
+ const shown = results?.[d] ?? sides;
31093
+ return /* @__PURE__ */ jsxs86(
31094
+ "svg",
31095
+ {
31096
+ viewBox: "0 0 100 100",
31097
+ width: "100%",
31098
+ height: "100%",
31099
+ style: { display: "block", overflow: "visible" },
31100
+ "aria-hidden": "true",
31101
+ children: [
31102
+ /* @__PURE__ */ jsx114(
31103
+ "polygon",
31104
+ {
31105
+ points: shape.points,
31106
+ fill: colors.face,
31107
+ stroke: colors.faceBorder,
31108
+ strokeWidth: 2.5,
31109
+ strokeLinejoin: "round",
31110
+ style: { transition: "fill 0.3s, stroke 0.3s" }
31111
+ }
31112
+ ),
31113
+ /* @__PURE__ */ jsx114(
31114
+ "polygon",
31115
+ {
31116
+ points: shape.points,
31117
+ fill: "none",
31118
+ stroke: colors.faceBorder,
31119
+ strokeWidth: 1.5,
31120
+ strokeLinejoin: "round",
31121
+ opacity: 0.55,
31122
+ transform: "translate(50 50) scale(0.76) translate(-50 -50)"
31123
+ }
31124
+ ),
31125
+ /* @__PURE__ */ jsx114(
31126
+ "text",
31127
+ {
31128
+ ref: getNumeralSetter(d),
31129
+ x: 50,
31130
+ y: shape.textY,
31131
+ textAnchor: "middle",
31132
+ dominantBaseline: "central",
31133
+ fontSize: 100 * shape.fontScale,
31134
+ fontWeight: 800,
31135
+ fill: colors.pip,
31136
+ style: {
31137
+ fontVariantNumeric: "tabular-nums",
31138
+ transition: "fill 0.3s",
31139
+ userSelect: "none"
31140
+ },
31141
+ children: formatDieValue(shown, sides)
31142
+ }
31143
+ )
31144
+ ]
31145
+ }
31146
+ );
31147
+ })()
31021
31148
  }
31022
31149
  )
31023
31150
  ] }, d);
@@ -40663,6 +40790,27 @@ function generateSchedule(teams, roundLabel) {
40663
40790
  }
40664
40791
  return rounds;
40665
40792
  }
40793
+ function hydrateResumeRounds(resume, teams) {
40794
+ if (!resume?.length || teams.length < 2) return [];
40795
+ const expected = teams.length % 2 === 0 ? teams.length - 1 : teams.length;
40796
+ if (resume.length !== expected) return [];
40797
+ const roster = new Set(teams.map((t) => t.toLowerCase()));
40798
+ for (const round of resume) {
40799
+ for (const m of round.matchups) {
40800
+ for (const side of [m.home, m.away]) {
40801
+ if (side !== BYE_TOKEN && !roster.has(side.toLowerCase())) return [];
40802
+ }
40803
+ }
40804
+ }
40805
+ return resume.map((round) => ({
40806
+ label: round.label,
40807
+ matchups: round.matchups.map((m) => ({
40808
+ home: m.home,
40809
+ away: m.away,
40810
+ isBye: m.home === BYE_TOKEN || m.away === BYE_TOKEN
40811
+ }))
40812
+ }));
40813
+ }
40666
40814
  var DEFAULT_LABELS4 = {
40667
40815
  inputPlaceholder: "Team or player name (comma-separated for batch)",
40668
40816
  addButton: "Add",
@@ -40683,6 +40831,7 @@ function RoundRobinScheduler({
40683
40831
  darkMode,
40684
40832
  minTeams = 3,
40685
40833
  defaultTeams = [],
40834
+ resumeRounds,
40686
40835
  onTeamsChange,
40687
40836
  onGenerate,
40688
40837
  labels,
@@ -40696,7 +40845,9 @@ function RoundRobinScheduler({
40696
40845
  const L = { ...DEFAULT_LABELS4, ...labels };
40697
40846
  const [teams, setTeams] = useState80(defaultTeams);
40698
40847
  const [input, setInput] = useState80("");
40699
- const [rounds, setRounds] = useState80([]);
40848
+ const [rounds, setRounds] = useState80(
40849
+ () => hydrateResumeRounds(resumeRounds, defaultTeams)
40850
+ );
40700
40851
  const inputRef = useRef49(null);
40701
40852
  useEffect64(() => {
40702
40853
  onTeamsChange?.(teams);
@@ -41222,6 +41373,8 @@ function Scoreboard({
41222
41373
  maxTeams = 8,
41223
41374
  scoreButtons = [-1, 1, 5, 10],
41224
41375
  defaultTeams,
41376
+ initialRound = 1,
41377
+ initialHistory,
41225
41378
  onTeamsChange,
41226
41379
  onRoundAdvance,
41227
41380
  onNewGame,
@@ -41237,8 +41390,12 @@ function Scoreboard({
41237
41390
  const [teams, setTeams] = useState81(
41238
41391
  () => defaultTeams && defaultTeams.length >= minTeams ? defaultTeams.slice(0, maxTeams) : createDefaultTeams(seedCount, L.teamNamePrefix)
41239
41392
  );
41240
- const [round, setRound] = useState81(1);
41241
- const [history, setHistory] = useState81([]);
41393
+ const [round, setRound] = useState81(
41394
+ () => Number.isFinite(initialRound) ? Math.max(1, Math.floor(initialRound)) : 1
41395
+ );
41396
+ const [history, setHistory] = useState81(
41397
+ () => initialHistory && initialHistory.length > 0 ? initialHistory.slice() : []
41398
+ );
41242
41399
  const [historyOpen, setHistoryOpen] = useState81(false);
41243
41400
  const rootRef = useRef50(null);
41244
41401
  const [containerWidth, setContainerWidth] = useState81(0);
@@ -44855,6 +45012,7 @@ export {
44855
45012
  CommentSystem,
44856
45013
  Container,
44857
45014
  ConversionKPI,
45015
+ D6_FACE_PLACEMENTS,
44858
45016
  DISTANCES,
44859
45017
  DURATIONS,
44860
45018
  DashboardGrid,
@@ -45144,6 +45302,7 @@ export {
45144
45302
  createOptimizedStore,
45145
45303
  createSlideVariant,
45146
45304
  createTransition,
45305
+ d6LandingRotation,
45147
45306
  dailyTrendingConfig,
45148
45307
  detectAuthProvider,
45149
45308
  detectDelimiter,