@thesquad-components/sqd-module-template 0.1.2 → 0.1.6

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.d.mts CHANGED
@@ -1,5 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
 
3
+ declare const HomeScreen: () => react_jsx_runtime.JSX.Element;
4
+
3
5
  type ActivityGaugeDatum = {
4
6
  name: string;
5
7
  value: number;
@@ -31,4 +33,4 @@ type GetTasksCountOptions = {
31
33
  };
32
34
  declare const getTasksCount: (daysBack: number, options?: GetTasksCountOptions) => Promise<number>;
33
35
 
34
- export { type ActivityGaugeDatum, ActivityGaugeLg, type ActivityGaugeProps, TasksActivityGauge, type TasksActivityGaugeProps, type TasksCountResponse, getTasksCount };
36
+ export { type ActivityGaugeDatum, ActivityGaugeLg, type ActivityGaugeProps, TasksActivityGauge, type TasksActivityGaugeProps, type TasksCountResponse, HomeScreen as default, getTasksCount };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
 
3
+ declare const HomeScreen: () => react_jsx_runtime.JSX.Element;
4
+
3
5
  type ActivityGaugeDatum = {
4
6
  name: string;
5
7
  value: number;
@@ -31,4 +33,4 @@ type GetTasksCountOptions = {
31
33
  };
32
34
  declare const getTasksCount: (daysBack: number, options?: GetTasksCountOptions) => Promise<number>;
33
35
 
34
- export { type ActivityGaugeDatum, ActivityGaugeLg, type ActivityGaugeProps, TasksActivityGauge, type TasksActivityGaugeProps, type TasksCountResponse, getTasksCount };
36
+ export { type ActivityGaugeDatum, ActivityGaugeLg, type ActivityGaugeProps, TasksActivityGauge, type TasksActivityGaugeProps, type TasksCountResponse, HomeScreen as default, getTasksCount };
package/dist/index.js CHANGED
@@ -1,11 +1,14 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var react = require('react');
6
+ var nextThemes = require('next-themes');
7
+ var icons = require('@untitledui/icons');
3
8
  var recharts = require('recharts');
4
9
  var tailwindMerge = require('tailwind-merge');
5
10
  var jsxRuntime = require('react/jsx-runtime');
6
- var react = require('react');
7
11
  var reactAriaComponents = require('react-aria-components');
8
- var icons = require('@untitledui/icons');
9
12
 
10
13
  var __defProp = Object.defineProperty;
11
14
  var __defProps = Object.defineProperties;
@@ -38,6 +41,32 @@ var __objRest = (source, exclude) => {
38
41
  }
39
42
  return target;
40
43
  };
44
+
45
+ // src/api/tasks.ts
46
+ var DEFAULT_API_BASE_URL = "https://api.thesqd.com";
47
+ var DEFAULT_MODULE_KEY = "e166f127e73167b6646eeaeff8837566d3c27d4002fb122bc49d4fb06d97d67e";
48
+ var getTasksCount = async (daysBack, options = {}) => {
49
+ var _a, _b, _c, _d, _e;
50
+ const resolvedDaysBack = Number.isFinite(daysBack) && daysBack > 0 ? Math.floor(daysBack) : 7;
51
+ const baseUrl = (_b = (_a = options.baseUrl) != null ? _a : process.env.NEXT_PUBLIC_SQD_API_BASE_URL) != null ? _b : DEFAULT_API_BASE_URL;
52
+ const moduleKey = (_d = (_c = options.moduleKey) != null ? _c : process.env.NEXT_PUBLIC_SQD_MODULE_KEY) != null ? _d : DEFAULT_MODULE_KEY;
53
+ const url = new URL("/module-template/task-count", baseUrl);
54
+ url.searchParams.set("daysBack", String(resolvedDaysBack));
55
+ const response = await fetch(url.toString(), {
56
+ method: "GET",
57
+ headers: {
58
+ "Content-Type": "application/json",
59
+ "x-sqd-module-key": moduleKey
60
+ },
61
+ cache: "no-store",
62
+ signal: options.signal
63
+ });
64
+ if (!response.ok) {
65
+ throw new Error(`Failed to fetch tasks count (${response.status})`);
66
+ }
67
+ const payload = await response.json();
68
+ return (_e = payload.count) != null ? _e : 0;
69
+ };
41
70
  var twMerge = tailwindMerge.extendTailwindMerge({
42
71
  extend: {
43
72
  theme: {
@@ -53,8 +82,9 @@ var ChartTooltipContent = ({ active, payload, label, isRadialChart }) => {
53
82
  if (!active || !payload || payload.length === 0) {
54
83
  return null;
55
84
  }
85
+ const showLabel = Boolean(label) && !isRadialChart;
56
86
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-secondary bg-primary px-3 py-2 shadow-sm", children: [
57
- label && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium text-tertiary", children: label }),
87
+ showLabel && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium text-tertiary", children: label }),
58
88
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 space-y-1", children: payload.map((entry, index) => {
59
89
  var _a, _b, _c;
60
90
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs", children: [
@@ -86,6 +116,8 @@ var ActivityGaugeLg = ({
86
116
  data = radialData,
87
117
  maxValue = 1e3
88
118
  }) => {
119
+ var _a, _b;
120
+ const ringClassName = (_b = (_a = data[0]) == null ? void 0 : _a.className) != null ? _b : "text-utility-brand-700";
89
121
  return /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { height: 356, children: /* @__PURE__ */ jsxRuntime.jsxs(
90
122
  recharts.RadialBarChart,
91
123
  {
@@ -112,6 +144,7 @@ var ActivityGaugeLg = ({
112
144
  dataKey: "value",
113
145
  cornerRadius: 99,
114
146
  fill: "currentColor",
147
+ className: ringClassName,
115
148
  background: {
116
149
  className: "fill-utility-gray-100"
117
150
  }
@@ -142,32 +175,6 @@ var ActivityGaugeLg = ({
142
175
  ) });
143
176
  };
144
177
 
145
- // src/api/tasks.ts
146
- var DEFAULT_API_BASE_URL = "https://api.thesqd.com";
147
- var DEFAULT_MODULE_KEY = "e166f127e73167b6646eeaeff8837566d3c27d4002fb122bc49d4fb06d97d67e";
148
- var getTasksCount = async (daysBack, options = {}) => {
149
- var _a, _b, _c, _d, _e;
150
- const resolvedDaysBack = Number.isFinite(daysBack) && daysBack > 0 ? Math.floor(daysBack) : 7;
151
- const baseUrl = (_b = (_a = options.baseUrl) != null ? _a : process.env.NEXT_PUBLIC_SQD_API_BASE_URL) != null ? _b : DEFAULT_API_BASE_URL;
152
- const moduleKey = (_d = (_c = options.moduleKey) != null ? _c : process.env.NEXT_PUBLIC_SQD_MODULE_KEY) != null ? _d : DEFAULT_MODULE_KEY;
153
- const url = new URL("/module-template/task-count", baseUrl);
154
- url.searchParams.set("daysBack", String(resolvedDaysBack));
155
- const response = await fetch(url.toString(), {
156
- method: "GET",
157
- headers: {
158
- "Content-Type": "application/json",
159
- "x-sqd-module-key": moduleKey
160
- },
161
- cache: "no-store",
162
- signal: options.signal
163
- });
164
- if (!response.ok) {
165
- throw new Error(`Failed to fetch tasks count (${response.status})`);
166
- }
167
- const payload = await response.json();
168
- return (_e = payload.count) != null ? _e : 0;
169
- };
170
-
171
178
  // src/utils/is-react-component.ts
172
179
  var isFunctionComponent = (component) => {
173
180
  return typeof component === "function";
@@ -396,6 +403,110 @@ var Button = (_a) => {
396
403
  })
397
404
  );
398
405
  };
406
+ var ToggleBase = ({ className, isHovered, isDisabled, isFocusVisible, isSelected, slim, size = "sm" }) => {
407
+ const styles2 = {
408
+ default: {
409
+ sm: {
410
+ root: "h-5 w-9 p-0.5",
411
+ switch: cx("size-4", isSelected && "translate-x-4")
412
+ },
413
+ md: {
414
+ root: "h-6 w-11 p-0.5",
415
+ switch: cx("size-5", isSelected && "translate-x-5")
416
+ }
417
+ },
418
+ slim: {
419
+ sm: {
420
+ root: "h-4 w-8",
421
+ switch: cx("size-4", isSelected && "translate-x-4")
422
+ },
423
+ md: {
424
+ root: "h-5 w-10",
425
+ switch: cx("size-5", isSelected && "translate-x-5")
426
+ }
427
+ }
428
+ };
429
+ const classes = slim ? styles2.slim[size] : styles2.default[size];
430
+ return /* @__PURE__ */ jsxRuntime.jsx(
431
+ "div",
432
+ {
433
+ className: cx(
434
+ "cursor-pointer rounded-full bg-tertiary outline-focus-ring transition duration-150 ease-linear",
435
+ isSelected && "bg-brand-solid",
436
+ isSelected && isHovered && "bg-brand-solid_hover",
437
+ isDisabled && "cursor-not-allowed bg-disabled",
438
+ isFocusVisible && "outline-2 outline-offset-2",
439
+ slim && "ring-1 ring-secondary ring-inset",
440
+ slim && isSelected && "ring-transparent",
441
+ classes.root,
442
+ className
443
+ ),
444
+ children: /* @__PURE__ */ jsxRuntime.jsx(
445
+ "div",
446
+ {
447
+ style: {
448
+ transition: "transform 0.15s ease-in-out, translate 0.15s ease-in-out, border-color 0.1s linear, background-color 0.1s linear"
449
+ },
450
+ className: cx(
451
+ "rounded-full bg-fg-white shadow-sm",
452
+ isDisabled && "bg-toggle-button-fg_disabled",
453
+ slim && "shadow-xs",
454
+ slim && "border border-toggle-border",
455
+ slim && isSelected && "border-toggle-slim-border_pressed",
456
+ slim && isSelected && isHovered && "border-toggle-slim-border_pressed-hover",
457
+ classes.switch
458
+ )
459
+ }
460
+ )
461
+ }
462
+ );
463
+ };
464
+ var Toggle = (_a) => {
465
+ var _b = _a, { label, hint, className, size = "sm", slim } = _b, ariaSwitchProps = __objRest(_b, ["label", "hint", "className", "size", "slim"]);
466
+ const sizes = {
467
+ sm: {
468
+ root: "gap-2",
469
+ textWrapper: "",
470
+ label: "text-sm font-medium",
471
+ hint: "text-sm"
472
+ },
473
+ md: {
474
+ root: "gap-3",
475
+ textWrapper: "gap-0.5",
476
+ label: "text-md font-medium",
477
+ hint: "text-md"
478
+ }
479
+ };
480
+ return /* @__PURE__ */ jsxRuntime.jsx(
481
+ reactAriaComponents.Switch,
482
+ __spreadProps(__spreadValues({}, ariaSwitchProps), {
483
+ className: (renderProps) => cx(
484
+ "flex w-max items-start",
485
+ renderProps.isDisabled && "cursor-not-allowed",
486
+ sizes[size].root,
487
+ typeof className === "function" ? className(renderProps) : className
488
+ ),
489
+ children: ({ isSelected, isDisabled, isFocusVisible, isHovered }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
490
+ /* @__PURE__ */ jsxRuntime.jsx(
491
+ ToggleBase,
492
+ {
493
+ slim,
494
+ size,
495
+ isHovered,
496
+ isDisabled,
497
+ isFocusVisible,
498
+ isSelected,
499
+ className: slim ? "mt-0.5" : ""
500
+ }
501
+ ),
502
+ (label || hint) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex flex-col", sizes[size].textWrapper), children: [
503
+ label && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx("text-secondary select-none", sizes[size].label), children: label }),
504
+ hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("text-tertiary", sizes[size].hint), onClick: (event) => event.stopPropagation(), children: hint })
505
+ ] })
506
+ ] })
507
+ })
508
+ );
509
+ };
399
510
  var HintText = (_a) => {
400
511
  var _b = _a, { isInvalid, className } = _b, props = __objRest(_b, ["isInvalid", "className"]);
401
512
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -726,6 +837,7 @@ var Input = (_a) => {
726
837
  };
727
838
  Input.displayName = "Input";
728
839
  var TasksActivityGauge = ({ daysBack = 14, maxValue = 1e3 }) => {
840
+ const { resolvedTheme, setTheme } = nextThemes.useTheme();
729
841
  const [count, setCount] = react.useState(null);
730
842
  const [error, setError] = react.useState(null);
731
843
  const [isLoading, setIsLoading] = react.useState(false);
@@ -786,6 +898,7 @@ var TasksActivityGauge = ({ daysBack = 14, maxValue = 1e3 }) => {
786
898
  setActiveDaysBack(Math.floor(parsed));
787
899
  }
788
900
  };
901
+ const isDarkMode = resolvedTheme === "dark";
789
902
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
790
903
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-end justify-between gap-3", children: [
791
904
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-[180px]", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -811,12 +924,29 @@ var TasksActivityGauge = ({ daysBack = 14, maxValue = 1e3 }) => {
811
924
  }
812
925
  )
813
926
  ] }),
814
- /* @__PURE__ */ jsxRuntime.jsx(ActivityGaugeLg, { title, subtitle, data: gaugeData, maxValue: computedMax })
927
+ /* @__PURE__ */ jsxRuntime.jsx(ActivityGaugeLg, { title, subtitle, data: gaugeData, maxValue: computedMax }),
928
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed bottom-4 right-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 rounded-full border border-secondary bg-primary px-3 py-2 shadow-lg", children: [
929
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Sun, { className: "size-4 text-tertiary" }),
930
+ /* @__PURE__ */ jsxRuntime.jsx(
931
+ Toggle,
932
+ {
933
+ size: "md",
934
+ "aria-label": "Toggle theme",
935
+ isSelected: isDarkMode,
936
+ onChange: (value) => setTheme(value ? "dark" : "light")
937
+ }
938
+ ),
939
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Moon01, { className: "size-4 text-tertiary" })
940
+ ] }) })
815
941
  ] });
816
942
  };
943
+ var HomeScreen = () => {
944
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-dvh items-center justify-center px-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full max-w-md", children: /* @__PURE__ */ jsxRuntime.jsx(TasksActivityGauge, { daysBack: 7 }) }) });
945
+ };
817
946
 
818
947
  exports.ActivityGaugeLg = ActivityGaugeLg;
819
948
  exports.TasksActivityGauge = TasksActivityGauge;
949
+ exports.default = HomeScreen;
820
950
  exports.getTasksCount = getTasksCount;
821
951
  //# sourceMappingURL=index.js.map
822
952
  //# sourceMappingURL=index.js.map